code: package it.unibz.inf.vig_mappings_analyzer.core;
  
  import it.unibz.inf.ontop.model.Function;
  import it.unibz.inf.ontop.model.OBDAMappingAxiom;
  import it.unibz.inf.ontop.model.OBDAModel;
  import it.unibz.inf.ontop.model.OBDASQLQuery;
  import it.unibz.inf.ontop.parser.SQLQueryDeepParser;
  import it.unibz.inf.ontop.sql.DBMetadata;
  import it.unibz.inf.ontop.sql.api.ParsedSQLQuery;
  import it.unibz.inf.vig_mappings_analyzer.core.utils.QualifiedName;
  import it.unibz.inf.vig_mappings_analyzer.obda.OBDAModelFactory;
  
  import java.io.BufferedReader;
  import java.io.FileReader;
  import java.net.URI;
  import java.util.Arrays;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Set;
  
  import org.junit.Test;
  
  public class FixedDomColsFinder extends OntopConnection {
      
      private FixedDomColsFinder(OBDAModel obdaModel, DBMetadata meta) {
  	super(obdaModel, meta);
      }
      
      public static FixedDomColsFinder makeInstance(OBDAModel model, DBMetadata meta){
  	return new FixedDomColsFinder(model, meta);
      }
  
      public Set<QualifiedName> findFixedDomainCols() throws Exception {
  
  	Set<QualifiedName> result = new HashSet<>();
  
  	// Y shall do something similar for each dataproperty, and object property
  	for( URI uri : obdaModel.getMappings().keySet() ){
  	    logger.info(uri);
  	    for( OBDAMappingAxiom a : obdaModel.getMappings(uri) ){
  
  		List<Function> targetQuery =  a.getTargetQuery();
  
  		for( int i = 0; i < targetQuery.size(); ++i ){
  
  		    OBDASQLQuery sourceQuery = (OBDASQLQuery) a.getSourceQuery();
  
  		    // Construct the SQL query tree from the source query
  		    String viewString = sourceQuery.toString();
  		    logger.info(viewString);
  		    ParsedSQLQuery queryParsed = SQLQueryDeepParser.parse(meta, viewString); 
  		    if( queryParsed.getTables().size() != 1 ){ /*++skipped;*/ continue; } // Support for single table only
  		    
  		    if( queryParsed.getWhereClause() != null ){
  			// Format: colName = 'JACK-UP 3 LEGS'
  			
  			String raw = queryParsed.getWhereClause().toString();
  			List<String> splits = Arrays.asList( raw.split("\\s*=\\s*") );
  			if( splits.size() == 2 ){
  			    String value = splits.get(1);
  			    if( value.startsWith("'") ){ // String only, for the moment
  				String tableName = queryParsed.getTables().values().iterator().next().toString();
  				QualifiedName toAdd = new QualifiedName( tableName, splits.get(0) );
  				result.add(toAdd);
  			    }
  			}
  		    }
  		}
  	    }
  	}
  	return result;
      }
      
      public static class FixedDomColsFinderTester{
  
  	private static final String OUTFILE_NPD="src/main/resources/FixedColsFinderOutTest.txt";
  
  	@Test
  	public void testFinderNPD(){
  	    try {
  		OBDAModel model = OBDAModelFactory.getSingletonOBDAModel("src/main/resources/npd-v2-ql_a.obda");
  		DBMetadata meta = OBDAModelFactory.makeDBMetadata(model);
  
  		FixedDomColsFinder instance = FixedDomColsFinder.makeInstance(model, meta);
  
  		StringBuilder testString = new StringBuilder();
  		try(BufferedReader in = new BufferedReader(
  			new FileReader(OUTFILE_NPD))){
  		    String s;
  		    while ((s = in.readLine()) != null){
  			testString.append(s);
  			testString.append("\n");
  		    }
  		}
  		org.junit.Assert.assertEquals(testString.toString(), instance.findFixedDomainCols()+"\n");
  	    }catch(Exception e){
  		e.printStackTrace();
  	    }
  	}
      }
      
      public static void main(String[] args){
  	
  	try {
  	    OBDAModel model = OBDAModelFactory.getSingletonOBDAModel("src/main/resources/test/npd-v2-ql_a.obda");
  	    DBMetadata meta = OBDAModelFactory.makeDBMetadata(model);
  
  	    
  	    FixedDomColsFinder instance = FixedDomColsFinder.makeInstance(model, meta);
  	    System.out.println( instance.findFixedDomainCols() );
  	}catch(Exception e){
  	    e.printStackTrace();
  	}
      }
  };
  
  
  