public void setUp() throws Exception {
    pm = new SimplePrefixManager();
    OBDADataFactory pfac = OBDADataFactoryImpl.getInstance();
    OBDADataFactory tfac = OBDADataFactoryImpl.getInstance();
    query = tfac.getDatalogProgram();

    LinkedList<Term> innerterms = new LinkedList<Term>();
    innerterms.add(tfac.getVariable("id"));

    //		IRIFactory fact = new IRIFactory();

    List<Term> terms = new LinkedList<Term>();
    terms.add(
        tfac.getFunction(
            pfac.getPredicate("http://obda.org/onto.owl#person-individual", 1), innerterms));

    Function body =
        tfac.getFunction(pfac.getClassPredicate("http://obda.org/onto.owl#Person"), terms);

    terms = new LinkedList<Term>();
    terms.add(tfac.getVariable("id"));
    Function head = tfac.getFunction(pfac.getPredicate("http://obda.org/predicates#q", 1), terms);

    rule1 = tfac.getCQIE(head, Collections.singletonList(body));
    query.appendRule(rule1);
  }
Beispiel #2
0
public class SigmaTest extends TestCase {

  private static final OBDADataFactory predicateFactory = OBDADataFactoryImpl.getInstance();
  private static final OntologyFactory descFactory = new OntologyFactoryImpl();

  public void test_exists_simple() {
    Ontology ontology = OntologyFactoryImpl.getInstance().createOntology("");

    Predicate a = predicateFactory.getPredicate("a", 1);
    Predicate c = predicateFactory.getPredicate("c", 1);
    Predicate r = predicateFactory.getPredicate("r", 2);
    OClass ac = descFactory.createClass(a);
    OClass cc = descFactory.createClass(c);
    PropertySomeRestriction er = descFactory.getPropertySomeRestriction(r, false);
    ontology.addConcept(ac.getPredicate());
    ontology.addConcept(cc.getPredicate());
    ontology.addRole(er.getPredicate());

    ontology.addAssertion(OntologyFactoryImpl.getInstance().createSubClassAxiom(er, ac));
    ontology.addAssertion(OntologyFactoryImpl.getInstance().createSubClassAxiom(cc, er));

    DAG res = DAGConstructor.getSigma(ontology);
    res.clean();

    assertTrue(res.getClassNode(ac).getDescendants().contains(res.getClassNode(er)));

    assertEquals(1, res.getClassNode(ac).getDescendants().size());

    assertEquals(0, res.getClassNode(er).getDescendants().size());

    assertEquals(0, res.getClassNode(cc).getDescendants().size());
  }
}
  private void runWithSeparateFiles() {
    if (owlFile == null) {
      throw new NullPointerException("You have to specify an ontology file!");
    }

    OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
    OWLOntology ontology = null;
    OBDADataFactory obdaDataFactory = OBDADataFactoryImpl.getInstance();
    try {
      ontology = manager.loadOntologyFromOntologyDocument((new File(owlFile)));

      if (disableReasoning) {
        /*
         * when reasoning is disabled, we extract only the declaration assertions for the vocabulary
         */
        ontology = extractDeclarations(manager, ontology);
      }

      Collection<Predicate> predicates = new ArrayList<>();

      for (OWLClass owlClass : ontology.getClassesInSignature()) {
        Predicate predicate = obdaDataFactory.getClassPredicate(owlClass.getIRI().toString());
        predicates.add(predicate);
      }
      for (OWLDataProperty owlDataProperty : ontology.getDataPropertiesInSignature()) {
        Predicate predicate =
            obdaDataFactory.getDataPropertyPredicate(owlDataProperty.getIRI().toString());
        predicates.add(predicate);
      }
      for (OWLObjectProperty owlObjectProperty : ontology.getObjectPropertiesInSignature()) {
        Predicate predicate =
            obdaDataFactory.getObjectPropertyPredicate(owlObjectProperty.getIRI().toString());
        predicates.add(predicate);
      }

      OBDAModel obdaModel = loadMappingFile(mappingFile);

      Ontology inputOntology = OWLAPI3TranslatorUtility.translate(ontology);

      obdaModel.declareAll(inputOntology.getVocabulary());

      int numPredicates = predicates.size();

      int i = 1;
      for (Predicate predicate : predicates) {
        System.err.println(String.format("Materializing %s (%d/%d)", predicate, i, numPredicates));
        serializePredicate(ontology, inputOntology, obdaModel, predicate, outputFile, format);
        i++;
      }

    } catch (OWLOntologyCreationException e) {
      e.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  private void createTables() throws IOException, SQLException {
    String createDDL = readSQLFile("src/test/resources/property-characteristics/sqlcreate.sql");

    // Initializing and H2 database with the stock exchange data
    // String driver = "org.h2.Driver";
    String url = "jdbc:h2:mem:questjunitdb";
    String username = "******";
    String password = "";

    ofac = OBDADataFactoryImpl.getInstance();

    jdbcconn = DriverManager.getConnection(url, username, password);
    Statement st = jdbcconn.createStatement();

    st.executeUpdate(createDDL);
    jdbcconn.commit();
  }
public class OBDAModelManager implements Disposable {

  private static final String OBDA_EXT = "obda"; // The default OBDA file extension.
  private static final String QUERY_EXT = "q"; // The default query file extension.
  private static final String DBPREFS_EXT =
      "db_prefs"; // The default db_prefs (currently only user constraints) file extension.

  private OWLEditorKit owlEditorKit;

  private OWLOntologyManager mmgr;

  private QueryController queryController;

  private Map<URI, OBDAModel> obdamodels;

  private List<OBDAModelManagerListener> obdaManagerListeners;

  private JDBCConnectionManager connectionManager =
      JDBCConnectionManager.getJDBCConnectionManager();

  private static final OBDADataFactory dfac = OBDADataFactoryImpl.getInstance();
  private static final OntologyFactory ofac = OntologyFactoryImpl.getInstance();

  private boolean applyUserConstraints = false;
  private ImplicitDBConstraints userConstraints;

  private static final Logger log = LoggerFactory.getLogger(OBDAModelManager.class);

  /**
   * * This is the instance responsible for listening for Protege ontology events
   * (loading/saving/changing ontology)
   */
  private final OWLModelManagerListener modelManagerListener =
      new OBDAPLuginOWLModelManagerListener();

  private ProtegeQueryControllerListener qlistener = new ProtegeQueryControllerListener();
  private ProtegeMappingControllerListener mlistener = new ProtegeMappingControllerListener();
  private ProtegeDatasourcesControllerListener dlistener =
      new ProtegeDatasourcesControllerListener();

  /**
   * * This flag is used to avoid triggering a "Ontology Changed" event when new
   * mappings/sources/queries are inserted into the model not by the user, but by a ontology load
   * call.
   */
  private boolean loadingData;

  public OBDAModelManager(EditorKit editorKit) {
    super();

    if (!(editorKit instanceof OWLEditorKit)) {
      throw new IllegalArgumentException("The OBDA PLugin only works with OWLEditorKit instances.");
    }
    this.owlEditorKit = (OWLEditorKit) editorKit;
    mmgr = ((OWLModelManager) owlEditorKit.getModelManager()).getOWLOntologyManager();
    OWLModelManager owlmmgr = (OWLModelManager) editorKit.getModelManager();
    owlmmgr.addListener(modelManagerListener);
    obdaManagerListeners = new LinkedList<OBDAModelManagerListener>();
    obdamodels = new HashMap<URI, OBDAModel>();

    // Adding ontology change listeners to synchronize with the mappings
    mmgr.addOntologyChangeListener(new OntologyRefactoringListener());

    // Initialize the query controller
    queryController = new QueryController();

    // Printing the version information to the console
    //	System.out.println("Using " + VersionInfo.getVersionInfo().toString() + "\n");
  }

  /**
   * * This ontology change listener has some euristics that determine if the user is refactoring
   * his ontology. In particular, this listener will try to determine if some add/remove axioms are
   * in fact a "renaming" operation. This happens when a list of axioms has a
   * remove(DeclarationAxiom(x)) immediatly followed by an add(DeclarationAxiom(y)), in this case, y
   * is a renaming for x.
   */
  public class OntologyRefactoringListener implements OWLOntologyChangeListener {

    @Override
    public void ontologiesChanged(List<? extends OWLOntologyChange> changes) throws OWLException {
      Map<OWLEntity, OWLEntity> renamings = new HashMap<OWLEntity, OWLEntity>();
      Set<OWLEntity> removals = new HashSet<OWLEntity>();

      for (int idx = 0; idx < changes.size(); idx++) {
        OWLOntologyChange change = changes.get(idx);
        if (change instanceof SetOntologyID) {
          IRI newiri = ((SetOntologyID) change).getNewOntologyID().getOntologyIRI();

          if (newiri == null) continue;

          IRI oldiri = ((SetOntologyID) change).getOriginalOntologyID().getOntologyIRI();

          log.debug("Ontology ID changed");
          log.debug("Old ID: {}", oldiri);
          log.debug("New ID: {}", newiri);

          OBDAModel model = obdamodels.get(oldiri.toURI());

          if (model == null) {
            setupNewOBDAModel();
            model = getActiveOBDAModel();
          }

          PrefixManager prefixManager = model.getPrefixManager();
          prefixManager.addPrefix(PrefixManager.DEFAULT_PREFIX, newiri.toURI().toString());

          obdamodels.remove(oldiri.toURI());
          obdamodels.put(newiri.toURI(), model);
          continue;

        } else if (change instanceof AddAxiom) {
          OWLAxiom axiom = change.getAxiom();
          if (axiom instanceof OWLDeclarationAxiom) {
            OWLEntity entity = ((OWLDeclarationAxiom) axiom).getEntity();
            OBDAModel activeOBDAModel = getActiveOBDAModel();
            if (entity instanceof OWLClass) {
              OWLClass oc = (OWLClass) entity;
              OClass c = ofac.createClass(oc.getIRI().toString());
              activeOBDAModel.declareClass(c);
            } else if (entity instanceof OWLObjectProperty) {
              OWLObjectProperty or = (OWLObjectProperty) entity;
              ObjectPropertyExpression r = ofac.createObjectProperty(or.getIRI().toString());
              activeOBDAModel.declareObjectProperty(r);
            } else if (entity instanceof OWLDataProperty) {
              OWLDataProperty op = (OWLDataProperty) entity;
              DataPropertyExpression p = ofac.createDataProperty(op.getIRI().toString());
              activeOBDAModel.declareDataProperty(p);
            }
          }

        } else if (change instanceof RemoveAxiom) {
          OWLAxiom axiom = change.getAxiom();
          if (axiom instanceof OWLDeclarationAxiom) {
            OWLEntity entity = ((OWLDeclarationAxiom) axiom).getEntity();
            OBDAModel activeOBDAModel = getActiveOBDAModel();
            if (entity instanceof OWLClass) {
              OWLClass oc = (OWLClass) entity;
              OClass c = ofac.createClass(oc.getIRI().toString());
              activeOBDAModel.unDeclareClass(c);
            } else if (entity instanceof OWLObjectProperty) {
              OWLObjectProperty or = (OWLObjectProperty) entity;
              ObjectPropertyExpression r = ofac.createObjectProperty(or.getIRI().toString());
              activeOBDAModel.unDeclareObjectProperty(r);
            } else if (entity instanceof OWLDataProperty) {
              OWLDataProperty op = (OWLDataProperty) entity;
              DataPropertyExpression p = ofac.createDataProperty(op.getIRI().toString());
              activeOBDAModel.unDeclareDataProperty(p);
            }
          }
        }

        if (idx + 1 >= changes.size()) {
          continue;
        }

        if (change instanceof RemoveAxiom && changes.get(idx + 1) instanceof AddAxiom) {
          // Found the pattern of a renaming refactoring
          RemoveAxiom remove = (RemoveAxiom) change;
          AddAxiom add = (AddAxiom) changes.get(idx + 1);

          if (!(remove.getAxiom() instanceof OWLDeclarationAxiom
              && add.getAxiom() instanceof OWLDeclarationAxiom)) {
            continue;
          }
          // Found the patter we are looking for, a remove and add of
          // declaration axioms
          OWLEntity olde = ((OWLDeclarationAxiom) remove.getAxiom()).getEntity();
          OWLEntity newe = ((OWLDeclarationAxiom) add.getAxiom()).getEntity();
          renamings.put(olde, newe);

        } else if (change instanceof RemoveAxiom
            && ((RemoveAxiom) change).getAxiom() instanceof OWLDeclarationAxiom) {
          // Found the pattern of a deletion
          OWLDeclarationAxiom declaration = (OWLDeclarationAxiom) ((RemoveAxiom) change).getAxiom();
          OWLEntity removedEntity = declaration.getEntity();
          removals.add(removedEntity);
        }
      }

      // Applying the renaming to the OBDA model
      OBDAModel obdamodel = getActiveOBDAModel();
      for (OWLEntity olde : renamings.keySet()) {
        OWLEntity removedEntity = olde;
        OWLEntity newEntity = renamings.get(removedEntity);

        // This set of changes appears to be a "renaming" operation,
        // hence we will modify the OBDA model accordingly
        Predicate removedPredicate = getPredicate(removedEntity);
        Predicate newPredicate = getPredicate(newEntity);

        obdamodel.renamePredicate(removedPredicate, newPredicate);
      }

      // Applying the deletions to the obda model
      for (OWLEntity removede : removals) {
        Predicate removedPredicate = getPredicate(removede);
        obdamodel.deletePredicate(removedPredicate);
      }
    }
  }

  private static Predicate getPredicate(OWLEntity entity) {
    Predicate p = null;
    if (entity instanceof OWLClass) {
      /* We ignore TOP and BOTTOM (Thing and Nothing) */
      if (((OWLClass) entity).isOWLThing() || ((OWLClass) entity).isOWLNothing()) {
        return null;
      }
      String uri = entity.getIRI().toString();

      p = dfac.getClassPredicate(uri);
    } else if (entity instanceof OWLObjectProperty) {
      String uri = entity.getIRI().toString();

      p = dfac.getObjectPropertyPredicate(uri);
    } else if (entity instanceof OWLDataProperty) {
      String uri = entity.getIRI().toString();

      p = dfac.getDataPropertyPredicate(uri);
    }
    return p;
  }

  public void addListener(OBDAModelManagerListener listener) {
    obdaManagerListeners.add(listener);
  }

  public void removeListener(OBDAModelManagerListener listener) {
    obdaManagerListeners.remove(listener);
  }

  public OBDAModel getActiveOBDAModel() {
    OWLOntology ontology = owlEditorKit.getOWLModelManager().getActiveOntology();
    if (ontology != null) {
      OWLOntologyID ontologyID = ontology.getOntologyID();
      IRI ontologyIRI = ontologyID.getOntologyIRI();
      URI uri = null;
      if (ontologyIRI != null) {
        uri = ontologyIRI.toURI();
      } else {
        uri = URI.create(ontologyID.toString());
      }
      return obdamodels.get(uri);
    }
    return null;
  }

  /**
   * This method makes sure is used to setup a new/fresh OBDA model. This is done by replacing the
   * instance this.obdacontroller (the OBDA model) with a new object. On creation listeners for the
   * datasources, mappings and queries are setup so that changes in these trigger and ontology
   * change.
   *
   * <p>Additionally, this method configures all available OBDAOWLReasonerFacotry objects to have a
   * reference to the newly created OBDA model and to the global preference object. This is
   * necessary so that the factories are able to pass the OBDA model to the reasoner instances when
   * they are created.
   */
  private void setupNewOBDAModel() {
    OBDAModel activeOBDAModel = getActiveOBDAModel();

    if (activeOBDAModel != null) {
      return;
    }
    activeOBDAModel = dfac.getOBDAModel();

    activeOBDAModel.addSourcesListener(dlistener);
    activeOBDAModel.addMappingsListener(mlistener);
    queryController.addListener(qlistener);

    OWLModelManager mmgr = owlEditorKit.getOWLWorkspace().getOWLModelManager();

    Set<OWLOntology> ontologies = mmgr.getOntologies();
    for (OWLOntology ontology : ontologies) {
      // Setup the entity declarations
      for (OWLClass c : ontology.getClassesInSignature()) {
        OClass pred = ofac.createClass(c.getIRI().toString());
        activeOBDAModel.declareClass(pred);
      }
      for (OWLObjectProperty r : ontology.getObjectPropertiesInSignature()) {
        ObjectPropertyExpression pred = ofac.createObjectProperty(r.getIRI().toString());
        activeOBDAModel.declareObjectProperty(pred);
      }
      for (OWLDataProperty p : ontology.getDataPropertiesInSignature()) {
        DataPropertyExpression pred = ofac.createDataProperty(p.getIRI().toString());
        activeOBDAModel.declareDataProperty(pred);
      }
    }

    // Setup the prefixes
    PrefixOWLOntologyFormat prefixManager =
        PrefixUtilities.getPrefixOWLOntologyFormat(mmgr.getActiveOntology());
    //		addOBDACommonPrefixes(prefixManager);

    PrefixManagerWrapper prefixwrapper = new PrefixManagerWrapper(prefixManager);
    activeOBDAModel.setPrefixManager(prefixwrapper);

    OWLOntology activeOntology = mmgr.getActiveOntology();

    String defaultPrefix = prefixManager.getDefaultPrefix();
    if (defaultPrefix == null) {
      OWLOntologyID ontologyID = activeOntology.getOntologyID();
      defaultPrefix = ontologyID.getOntologyIRI().toURI().toString();
    }
    activeOBDAModel.getPrefixManager().addPrefix(PrefixManager.DEFAULT_PREFIX, defaultPrefix);

    // Add the model
    URI modelUri = activeOntology.getOntologyID().getOntologyIRI().toURI();
    obdamodels.put(modelUri, activeOBDAModel);
  }

  //	/**
  //	 * Append here all default prefixes used by the system.
  //	 */
  //	private void addOBDACommonPrefixes(PrefixOWLOntologyFormat prefixManager) {
  //		if (!prefixManager.containsPrefixMapping("quest")) {
  ////			sb.append("@PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> .\n");
  ////			sb.append("@PREFIX rdfs: <http:  //www.w3.org/2000/01/rdf-schema#> .\n");
  ////			sb.append("@PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n");
  ////			sb.append("@PREFIX owl: <http://www.w3.org/2002/07/owl#> .\n");
  //
  //			prefixManager.setPrefix("quest", OBDAVocabulary.QUEST_NS);
  //		}
  //	}

  public QueryController getQueryController() {
    if (queryController == null) {
      queryController = new QueryController();
    }
    return queryController;
  }

  /**
   * Internal class responsible for coordinating actions related to updates in the ontology
   * environment.
   */
  private class OBDAPLuginOWLModelManagerListener implements OWLModelManagerListener {

    public boolean inititializing = false;

    @Override
    public void handleChange(OWLModelManagerChangeEvent event) {

      // Get the active ontology
      OWLModelManager source = event.getSource();
      OWLOntology activeOntology = source.getActiveOntology();

      // Initialize the active OBDA model
      OBDAModel activeOBDAModel = null;

      // Perform a proper handling for each type of event
      final EventType eventType = event.getType();
      switch (eventType) {
        case ABOUT_TO_CLASSIFY:
          log.debug("ABOUT TO CLASSIFY");
          loadingData = true;
          break;

        case ENTITY_RENDERER_CHANGED:
          log.debug("RENDERER CHANGED");
          break;

        case ONTOLOGY_CLASSIFIED:
          loadingData = false;
          break;

        case ACTIVE_ONTOLOGY_CHANGED:
          log.debug("ACTIVE ONTOLOGY CHANGED");
          inititializing = true; // flag on

          // Setting up a new OBDA model and retrieve the object.
          setupNewOBDAModel();
          activeOBDAModel = getActiveOBDAModel();

          OWLModelManager mmgr = owlEditorKit.getOWLWorkspace().getOWLModelManager();

          OWLOntology ontology = mmgr.getActiveOntology();
          PrefixOWLOntologyFormat prefixManager =
              PrefixUtilities.getPrefixOWLOntologyFormat(ontology);

          String defaultPrefix = prefixManager.getDefaultPrefix();
          if (defaultPrefix == null) {
            OWLOntologyID ontologyID = ontology.getOntologyID();
            defaultPrefix = ontologyID.getOntologyIRI().toURI().toString();
          }
          activeOBDAModel.getPrefixManager().addPrefix(PrefixManager.DEFAULT_PREFIX, defaultPrefix);

          ProtegeOWLReasonerInfo factory =
              owlEditorKit.getOWLModelManager().getOWLReasonerManager().getCurrentReasonerFactory();
          if (factory instanceof ProtegeOBDAOWLReformulationPlatformFactory) {
            ProtegeOBDAOWLReformulationPlatformFactory questfactory =
                (ProtegeOBDAOWLReformulationPlatformFactory) factory;
            ProtegeReformulationPlatformPreferences reasonerPreference =
                (ProtegeReformulationPlatformPreferences)
                    owlEditorKit.get(QuestPreferences.class.getName());
            questfactory.setPreferences(reasonerPreference);
            questfactory.setOBDAModel(getActiveOBDAModel());
            if (applyUserConstraints) questfactory.setImplicitDBConstraints(userConstraints);
          }
          fireActiveOBDAModelChange();

          inititializing = false; // flag off
          break;

        case ENTITY_RENDERING_CHANGED:
          break;

        case ONTOLOGY_CREATED:
          log.debug("ONTOLOGY CREATED");
          break;

        case ONTOLOGY_LOADED:
        case ONTOLOGY_RELOADED:
          log.debug("ONTOLOGY LOADED/RELOADED");
          loadingData = true; // flag on
          try {
            // Get the active OBDA model
            activeOBDAModel = getActiveOBDAModel();

            String owlDocumentIri =
                source.getOWLOntologyManager().getOntologyDocumentIRI(activeOntology).toString();
            String obdaDocumentIri =
                owlDocumentIri.substring(0, owlDocumentIri.length() - 3) + OBDA_EXT;
            String queryDocumentIri =
                owlDocumentIri.substring(0, owlDocumentIri.length() - 3) + QUERY_EXT;
            String dbprefsDocumentIri =
                owlDocumentIri.substring(0, owlDocumentIri.length() - 3) + DBPREFS_EXT;

            File obdaFile = new File(URI.create(obdaDocumentIri));
            File queryFile = new File(URI.create(queryDocumentIri));
            File dbprefsFile = new File(URI.create(dbprefsDocumentIri));
            IRI ontologyIRI = activeOntology.getOntologyID().getOntologyIRI();

            activeOBDAModel
                .getPrefixManager()
                .addPrefix(PrefixManager.DEFAULT_PREFIX, ontologyIRI.toString());
            if (obdaFile.exists()) {
              try {
                // Load the OBDA model
                ModelIOManager modelIO = new ModelIOManager(activeOBDAModel);
                modelIO.load(obdaFile);
              } catch (Exception ex) {
                activeOBDAModel.reset();
                throw new Exception(
                    "Exception occurred while loading OBDA document: "
                        + obdaFile
                        + "\n\n"
                        + ex.getMessage());
              }
              try {
                // Load the saved queries
                QueryIOManager queryIO = new QueryIOManager(queryController);
                queryIO.load(queryFile);
              } catch (Exception ex) {
                queryController.reset();
                throw new Exception(
                    "Exception occurred while loading Query document: "
                        + queryFile
                        + "\n\n"
                        + ex.getMessage());
              }
              applyUserConstraints = false;
              if (dbprefsFile.exists()) {
                try {
                  // Load user-supplied constraints
                  userConstraints = new ImplicitDBConstraints(dbprefsFile);
                  applyUserConstraints = true;
                } catch (Exception ex) {
                  throw new Exception(
                      "Exception occurred while loading database preference file : "
                          + dbprefsFile
                          + "\n\n"
                          + ex.getMessage());
                }
              }
            } else {
              log.warn(
                  "OBDA model couldn't be loaded because no .obda file exists in the same location as the .owl file");
            }
            OBDAModelValidator refactorer = new OBDAModelValidator(activeOBDAModel, activeOntology);
            refactorer.run(); // adding type information to the mapping predicates.
          } catch (Exception e) {
            OBDAException ex =
                new OBDAException(
                    "An exception has occurred when loading input file.\nMessage: "
                        + e.getMessage());
            DialogUtils.showQuickErrorDialog(null, ex, "Open file error");
            log.error(e.getMessage());
          } finally {
            loadingData = false; // flag off
          }
          break;

        case ONTOLOGY_SAVED:
          log.debug("ACTIVE ONTOLOGY SAVED");
          try {
            // Get the active OBDA model
            activeOBDAModel = getActiveOBDAModel();

            String owlDocumentIri =
                source.getOWLOntologyManager().getOntologyDocumentIRI(activeOntology).toString();
            String obdaDocumentIri =
                owlDocumentIri.substring(0, owlDocumentIri.length() - 3) + OBDA_EXT;
            String queryDocumentIri =
                owlDocumentIri.substring(0, owlDocumentIri.length() - 3) + QUERY_EXT;

            // Save the OBDA model
            File obdaFile = new File(URI.create(obdaDocumentIri));
            ModelIOManager ModelIO = new ModelIOManager(activeOBDAModel);
            ModelIO.save(obdaFile);

            // Save the queries
            File queryFile = new File(URI.create(queryDocumentIri));
            QueryIOManager queryIO = new QueryIOManager(queryController);
            queryIO.save(queryFile);

          } catch (IOException e) {
            log.error(e.getMessage());
            Exception newException =
                new Exception(
                    "Error saving the OBDA file. Closing Protege now can result in losing changes in your data sources or mappings. Please resolve the issue that prevents saving in the current location, or do \"Save as..\" to save in an alternative location. \n\nThe error message was: \n"
                        + e.getMessage());
            DialogUtils.showQuickErrorDialog(null, newException, "Error saving OBDA file");
            triggerOntologyChanged();
          }
          break;

        case ONTOLOGY_VISIBILITY_CHANGED:
          log.debug("VISIBILITY CHANGED");
          break;

        case REASONER_CHANGED:
          log.info("REASONER CHANGED");

          // Get the active OBDA model
          activeOBDAModel = getActiveOBDAModel();

          if ((!inititializing)
              && (obdamodels != null)
              && (owlEditorKit != null)
              && (getActiveOBDAModel() != null)) {
            ProtegeOWLReasonerInfo fac =
                owlEditorKit
                    .getOWLModelManager()
                    .getOWLReasonerManager()
                    .getCurrentReasonerFactory();
            if (fac instanceof ProtegeOBDAOWLReformulationPlatformFactory) {
              ProtegeOBDAOWLReformulationPlatformFactory questfactory =
                  (ProtegeOBDAOWLReformulationPlatformFactory) fac;
              ProtegeReformulationPlatformPreferences reasonerPreference =
                  (ProtegeReformulationPlatformPreferences)
                      owlEditorKit.get(QuestPreferences.class.getName());
              questfactory.setPreferences(reasonerPreference);
              questfactory.setOBDAModel(getActiveOBDAModel());
            }
            break;
          }
      }
    }
  }

  public void fireActiveOBDAModelChange() {
    for (OBDAModelManagerListener listener : obdaManagerListeners) {
      try {
        listener.activeOntologyChanged();
      } catch (Exception e) {
        log.debug("Badly behaved listener: {}", listener.getClass().toString());
        log.debug(e.getMessage(), e);
      }
    }
  }

  /**
   * * Protege wont trigger a save action unless it detects that the OWLOntology currently opened
   * has suffered a change. The OBDA plugin requires that protege triggers a save action also in the
   * case when only the OBDA model has suffered chagnes. To acomplish this, this method will "fake"
   * an ontology change by inserting and removing a class into the OWLModel.
   */
  private void triggerOntologyChanged() {
    if (loadingData) {
      return;
    }
    OWLModelManager owlmm = owlEditorKit.getOWLModelManager();
    OWLOntology ontology = owlmm.getActiveOntology();

    if (ontology == null) {
      return;
    }

    OWLClass newClass =
        owlmm
            .getOWLDataFactory()
            .getOWLClass(IRI.create("http://www.unibz.it/krdb/obdaplugin#RandomClass6677841155"));
    OWLAxiom axiom = owlmm.getOWLDataFactory().getOWLDeclarationAxiom(newClass);

    try {
      AddAxiom addChange = new AddAxiom(ontology, axiom);
      owlmm.applyChange(addChange);
      RemoveAxiom removeChange = new RemoveAxiom(ontology, axiom);
      owlmm.applyChange(removeChange);
    } catch (Exception e) {
      log.warn(
          "Exception forcing an ontology change. Your OWL model might contain a new class that you need to remove manually: {}",
          newClass.getIRI());
      log.warn(e.getMessage());
      log.debug(e.getMessage(), e);
    }
  }

  /**
   * * Called from ModelManager dispose method since this object is setup as the
   * APIController.class.getName() property with the put method.
   */
  public void dispose() throws Exception {
    try {
      owlEditorKit.getModelManager().removeListener(getModelManagerListener());
      connectionManager.dispose();
    } catch (Exception e) {
      log.warn(e.getMessage());
    }
  }

  protected OWLModelManagerListener getModelManagerListener() {
    return modelManagerListener;
  }

  /*
   * The following are internal helpers that dispatch "needs save" messages to
   * the OWL ontology model when OBDA model changes.
   */

  private class ProtegeDatasourcesControllerListener implements OBDAModelListener {

    private static final long serialVersionUID = -1633463551656406417L;

    public void datasourceUpdated(String oldname, OBDADataSource currendata) {
      triggerOntologyChanged();
    }

    public void datasourceDeleted(OBDADataSource source) {
      triggerOntologyChanged();
    }

    public void datasourceAdded(OBDADataSource source) {
      triggerOntologyChanged();
    }

    public void alldatasourcesDeleted() {
      triggerOntologyChanged();
    }

    public void datasourcParametersUpdated() {
      triggerOntologyChanged();
    }
  }

  private class ProtegeMappingControllerListener implements OBDAMappingListener {

    private static final long serialVersionUID = -5794145688669702879L;

    public void allMappingsRemoved() {
      triggerOntologyChanged();
    }

    public void currentSourceChanged(URI oldsrcuri, URI newsrcuri) {
      // Do nothing!
    }

    public void mappingDeleted(URI srcuri, String mapping_id) {
      triggerOntologyChanged();
    }

    public void mappingInserted(URI srcuri, String mapping_id) {
      triggerOntologyChanged();
    }

    public void mappingUpdated(URI srcuri, String mapping_id, OBDAMappingAxiom mapping) {
      triggerOntologyChanged();
    }
  }

  private class ProtegeQueryControllerListener implements QueryControllerListener {

    private static final long serialVersionUID = 4536639410306364312L;

    public void elementAdded(QueryControllerEntity element) {
      triggerOntologyChanged();
    }

    public void elementAdded(QueryControllerQuery query, QueryControllerGroup group) {
      triggerOntologyChanged();
    }

    public void elementRemoved(QueryControllerEntity element) {
      triggerOntologyChanged();
    }

    public void elementRemoved(QueryControllerQuery query, QueryControllerGroup group) {
      triggerOntologyChanged();
    }

    public void elementChanged(QueryControllerQuery query) {
      triggerOntologyChanged();
    }

    public void elementChanged(QueryControllerQuery query, QueryControllerGroup group) {
      triggerOntologyChanged();
    }
  }
}
Beispiel #6
0
public class MappingAnalyzer {

  private List<OBDAMappingAxiom> mappingList;
  private DBMetadata dbMetaData;

  private SQLQueryTranslator translator;

  private static final OBDADataFactory dfac = OBDADataFactoryImpl.getInstance();

  /** Creates a mapping analyzer by taking into account the OBDA model. */
  public MappingAnalyzer(List<OBDAMappingAxiom> mappingList, DBMetadata dbMetaData) {
    this.mappingList = mappingList;
    this.dbMetaData = dbMetaData;

    translator = new SQLQueryTranslator(dbMetaData);
  }

  public DatalogProgram constructDatalogProgram() {
    DatalogProgram datalog = dfac.getDatalogProgram();
    LinkedList<String> errorMessage = new LinkedList<String>();
    for (OBDAMappingAxiom axiom : mappingList) {
      try {
        // Obtain the target and source query from each mapping axiom in
        // the model.
        CQIE targetQuery = (CQIE) axiom.getTargetQuery();

        // Get the parsed sql, since it is already parsed by the mapping
        // parser
        // consider also MetaMappingExpander
        // VisitedQuery queryParsed = ...;

        OBDASQLQuery sourceQuery = (OBDASQLQuery) axiom.getSourceQuery();

        // Construct the SQL query tree from the source query
        VisitedQuery queryParsed = translator.constructParser(sourceQuery.toString());

        // Create a lookup table for variable swapping
        LookupTable lookupTable = createLookupTable(queryParsed);

        // We can get easily the table from the SQL
        ArrayList<RelationJSQL> tableList = queryParsed.getTableSet();

        // Construct the body from the source query
        ArrayList<Function> atoms = new ArrayList<Function>();
        for (RelationJSQL table : tableList) {
          // Construct the URI from the table name
          String tableName = table.getGivenName();
          String predicateName = tableName;

          // Construct the predicate using the table name
          int arity = dbMetaData.getDefinition(tableName).countAttribute();
          Predicate predicate = dfac.getPredicate(predicateName, arity);

          // Swap the column name with a new variable from the lookup
          // table
          List<Term> terms = new ArrayList<Term>();
          for (int i = 1; i <= arity; i++) {
            String columnName =
                dbMetaData.getFullQualifiedAttributeName(tableName, table.getAlias(), i);
            String termName = lookupTable.lookup(columnName);
            if (termName == null) {
              throw new RuntimeException(
                  "Column '" + columnName + "'was not found in the lookup table: ");
            }
            Term term = dfac.getVariable(termName);
            terms.add(term);
          }
          // Create an atom for a particular table
          Function atom = dfac.getFunction(predicate, terms);
          atoms.add(atom);
        }

        // For the join conditions WE STILL NEED TO CONSIDER NOT EQUI
        // JOIN
        ArrayList<Expression> joinConditions = queryParsed.getJoinCondition();
        for (Expression predicate : joinConditions) {

          Function atom = getFunction(predicate, lookupTable);
          atoms.add(atom);
        }

        // For the selection "where" clause conditions
        SelectionJSQL selection = queryParsed.getSelection();
        if (selection != null) {

          // Stack for filter function
          Stack<Function> filterFunctionStack = new Stack<Function>();

          Expression conditions = selection.getRawConditions();
          Function filterFunction = getFunction(conditions, lookupTable);
          filterFunctionStack.push(filterFunction);

          // The filter function stack must have 1 element left
          if (filterFunctionStack.size() == 1) {
            Function filterFunct = filterFunctionStack.pop();
            Function atom =
                dfac.getFunction(filterFunct.getFunctionSymbol(), filterFunct.getTerms());
            atoms.add(atom);
          } else {
            throwInvalidFilterExpressionException(filterFunctionStack);
          }
        }

        // Construct the head from the target query.
        List<Function> atomList = targetQuery.getBody();
        // for (Function atom : atomList) {
        Iterator<Function> atomListIter = atomList.iterator();

        while (atomListIter.hasNext()) {
          Function atom = atomListIter.next();
          List<Term> terms = atom.getTerms();
          List<Term> newterms = new LinkedList<Term>();
          for (Term term : terms) {
            newterms.add(updateTerm(term, lookupTable));
          }
          Function newhead = dfac.getFunction(atom.getPredicate(), newterms);
          CQIE rule = dfac.getCQIE(newhead, atoms);
          datalog.appendRule(rule);
        }

      } catch (Exception e) {
        errorMessage.add(
            "Error in mapping with id: "
                + axiom.getId()
                + " \n Description: "
                + e.getMessage()
                + " \nMapping: ["
                + axiom.toString()
                + "]");
      }
    }

    if (errorMessage.size() > 0) {
      StringBuilder errors = new StringBuilder();
      for (String error : errorMessage) {
        errors.append(error + "\n");
      }
      final String msg =
          "There was an error analyzing the following mappings. Please correct the issue(s) to continue.\n"
              + errors.toString();
      RuntimeException r = new RuntimeException(msg);
      throw r;
    }
    return datalog;
  }

  private void throwInvalidFilterExpressionException(Stack<Function> filterFunctionStack) {
    StringBuilder filterExpression = new StringBuilder();
    while (!filterFunctionStack.isEmpty()) {
      filterExpression.append(filterFunctionStack.pop());
    }
    throw new RuntimeException("Illegal filter expression: " + filterExpression.toString());
  }

  /**
   * Methods to create a {@link Function} starting from a {@link IsNullExpression}
   *
   * @param pred IsNullExpression
   * @param lookupTable
   * @return a function from the OBDADataFactory
   */
  private Function getFunction(IsNullExpression pred, LookupTable lookupTable) {

    Expression column = pred.getLeftExpression();
    String columnName = column.toString();
    String variableName = lookupTable.lookup(columnName);
    if (variableName == null) {
      throw new RuntimeException("Unable to find column name for variable: " + columnName);
    }
    Term var = dfac.getVariable(variableName);

    if (!pred.isNot()) {
      return dfac.getFunctionIsNull(var);
    } else {
      return dfac.getFunctionIsNotNull(var);
    }
  }

  /**
   * Recursive methods to create a {@link Function} starting from a {@link BinaryExpression} We
   * consider all possible values of the left and right expressions
   *
   * @param pred
   * @param lookupTable
   * @return
   */
  private Function getFunction(Expression pred, LookupTable lookupTable) {
    if (pred instanceof BinaryExpression) {
      return getFunction((BinaryExpression) pred, lookupTable);
    } else if (pred instanceof IsNullExpression) {
      return getFunction((IsNullExpression) pred, lookupTable);
    } else if (pred instanceof Parenthesis) {
      Expression inside = ((Parenthesis) pred).getExpression();
      return getFunction(inside, lookupTable);
    } else if (pred instanceof Between) {
      Between between = (Between) pred;
      Expression left = between.getLeftExpression();
      Expression e1 = between.getBetweenExpressionStart();
      Expression e2 = between.getBetweenExpressionEnd();

      GreaterThanEquals gte = new GreaterThanEquals();
      gte.setLeftExpression(left);
      gte.setRightExpression(e1);

      MinorThanEquals mte = new MinorThanEquals();
      mte.setLeftExpression(left);
      mte.setRightExpression(e2);

      AndExpression ande = new AndExpression(gte, mte);
      return getFunction(ande, lookupTable);
    } else if (pred instanceof InExpression) {
      InExpression inExpr = (InExpression) pred;
      Expression left = inExpr.getLeftExpression();
      ExpressionList ilist = (ExpressionList) inExpr.getRightItemsList();

      List<EqualsTo> eqList = new ArrayList<EqualsTo>();
      for (Expression item : ilist.getExpressions()) {
        EqualsTo eq = new EqualsTo();
        eq.setLeftExpression(left);
        eq.setRightExpression(item);
        eqList.add(eq);
      }
      int size = eqList.size();
      if (size > 1) {
        OrExpression or = new OrExpression(eqList.get(size - 1), eqList.get(size - 2));
        for (int i = size - 3; i >= 0; i--) {
          OrExpression orexpr = new OrExpression(eqList.get(i), or);
          or = orexpr;
        }
        return getFunction(or, lookupTable);
      } else {
        return getFunction(eqList.get(0), lookupTable);
      }
    } else return null;
  }

  /**
   * Recursive methods to create a {@link Function} starting from a {@link BinaryExpression} We
   * consider all possible values of the left and right expressions
   *
   * @param pred
   * @param lookupTable
   * @return
   */
  private Function getFunction(BinaryExpression pred, LookupTable lookupTable) {
    Expression left = pred.getLeftExpression();
    Expression right = pred.getRightExpression();

    // left term can be function or column variable
    Term t1 = null;
    t1 = getFunction(left, lookupTable);
    if (t1 == null) {
      t1 = getVariable(left, lookupTable);
    }
    if (t1 == null) throw new RuntimeException("Unable to find column name for variable: " + left);

    // right term can be function, column variable or data value
    Term t2 = null;
    t2 = getFunction(right, lookupTable);
    if (t2 == null) {
      t2 = getVariable(right, lookupTable);
    }
    if (t2 == null) {
      t2 = getValueConstant(right, lookupTable);
    }

    // get boolean operation
    String op = pred.getStringExpression();
    Function funct = null;
    if (op.equals("=")) funct = dfac.getFunctionEQ(t1, t2);
    else if (op.equals(">")) funct = dfac.getFunctionGT(t1, t2);
    else if (op.equals("<")) funct = dfac.getFunctionLT(t1, t2);
    else if (op.equals(">=")) funct = dfac.getFunctionGTE(t1, t2);
    else if (op.equals("<=")) funct = dfac.getFunctionLTE(t1, t2);
    else if (op.equals("<>")) funct = dfac.getFunctionNEQ(t1, t2);
    else if (op.equals("AND")) funct = dfac.getFunctionAND(t1, t2);
    else if (op.equals("OR")) funct = dfac.getFunctionOR(t1, t2);
    else if (op.equals("+")) funct = dfac.getFunctionAdd(t1, t2);
    else if (op.equals("-")) funct = dfac.getFunctionSubstract(t1, t2);
    else if (op.equals("*")) funct = dfac.getFunctionMultiply(t1, t2);
    else if (op.equals("LIKE")) funct = dfac.getFunctionLike(t1, t2);
    else throw new RuntimeException("Unknown opertor: " + op);

    return funct;
  }

  private Term getVariable(Expression pred, LookupTable lookupTable) {
    String termName = "";
    if (pred instanceof Column) {
      termName = lookupTable.lookup(pred.toString());
      if (termName == null) {
        return null;
      }
      return dfac.getVariable(termName);
    }
    return null;
  }
  /**
   * Return a valueConstant or Variable constructed from the given expression
   *
   * @param pred the expression to process
   * @param lookupTable in case of variable
   * @return constructed valueconstant or variable
   */
  private Term getValueConstant(Expression pred, LookupTable lookupTable) {
    String termRightName = "";
    if (pred instanceof Column) {
      // if the columns contains a boolean value
      String columnName = ((Column) pred).getColumnName();
      if (columnName.toLowerCase().equals("true") || columnName.toLowerCase().equals("false")) {
        return dfac.getConstantLiteral(columnName, COL_TYPE.BOOLEAN);
      } else throw new RuntimeException("Unable to find column name for variable: " + columnName);

    } else if (pred instanceof StringValue) {
      termRightName = ((StringValue) pred).getValue();
      return dfac.getConstantLiteral(termRightName, COL_TYPE.STRING);

    } else if (pred instanceof DateValue) {
      termRightName = ((DateValue) pred).getValue().toString();
      return dfac.getConstantLiteral(termRightName, COL_TYPE.DATETIME);

    } else if (pred instanceof TimeValue) {
      termRightName = ((TimeValue) pred).getValue().toString();
      return dfac.getConstantLiteral(termRightName, COL_TYPE.DATETIME);

    } else if (pred instanceof TimestampValue) {
      termRightName = ((TimestampValue) pred).getValue().toString();
      return dfac.getConstantLiteral(termRightName, COL_TYPE.DATETIME);

    } else if (pred instanceof LongValue) {
      termRightName = ((LongValue) pred).getStringValue();
      return dfac.getConstantLiteral(termRightName, COL_TYPE.INTEGER);

    } else if (pred instanceof DoubleValue) {
      termRightName = ((DoubleValue) pred).toString();
      return dfac.getConstantLiteral(termRightName, COL_TYPE.DOUBLE);

    } else {
      termRightName = pred.toString();
      return dfac.getConstantLiteral(termRightName, COL_TYPE.LITERAL);
    }
  }

  /** Returns a new term with the updated references. */
  private Term updateTerm(Term term, LookupTable lookupTable) {
    Term result = null;

    if (term instanceof Variable) {
      Variable var = (Variable) term;
      String varName = var.getName();
      String termName = lookupTable.lookup(varName);
      if (termName == null) {
        final String msg =
            String.format(
                "Error in identifying column name \"%s\", please check the query source in the mappings.\nPossible reasons:\n1. The name is ambiguous, or\n2. The name is not defined in the database schema.",
                var);
        throw new RuntimeException(msg);
      }
      result = dfac.getVariable(termName);

    } else if (term instanceof Function) {
      Function func = (Function) term;
      List<Term> terms = func.getTerms();
      List<Term> newterms = new LinkedList<Term>();
      for (Term innerTerm : terms) {
        newterms.add(updateTerm(innerTerm, lookupTable));
      }
      result = dfac.getFunction(func.getFunctionSymbol(), newterms);
    } else if (term instanceof Constant) {
      result = term.clone();
    }
    return result;
  }

  private LookupTable createLookupTable(VisitedQuery queryParsed) throws JSQLParserException {
    LookupTable lookupTable = new LookupTable();

    // Collect all the possible column names from tables.
    ArrayList<RelationJSQL> tableList = queryParsed.getTableSet();

    // Collect all known column aliases
    HashMap<String, String> aliasMap = queryParsed.getAliasMap();

    int offset = 0; // the index offset

    for (RelationJSQL table : tableList) {

      String tableName = table.getTableName();
      String tableGivenName = table.getGivenName();
      DataDefinition def = dbMetaData.getDefinition(tableGivenName);
      if (def == null) {
        def = dbMetaData.getDefinition(tableName);
        if (def == null) {
          throw new RuntimeException("Definition not found for table '" + tableGivenName + "'.");
        }
      }
      int size = def.countAttribute();

      for (int i = 1; i <= size; i++) {
        // assigned index number
        int index = i + offset;

        // simple attribute name
        String columnName = dbMetaData.getAttributeName(tableGivenName, i);

        lookupTable.add(columnName, index);

        String lowercaseColumn = columnName.toLowerCase();

        if (aliasMap.containsKey(lowercaseColumn)) { // register the alias name, if any
          lookupTable.add(aliasMap.get(lowercaseColumn), columnName);
        }

        // attribute name with table name prefix
        String tableColumnName = tableName + "." + columnName;
        lookupTable.add(tableColumnName, index);

        // attribute name with table name prefix
        String tablecolumnname = tableColumnName.toLowerCase();
        if (aliasMap.containsKey(tablecolumnname)) { // register the alias name, if any
          lookupTable.add(aliasMap.get(tablecolumnname), tableColumnName);
        }

        // attribute name with table given name prefix
        String givenTableColumnName = tableGivenName + "." + columnName;
        lookupTable.add(givenTableColumnName, tableColumnName);

        String giventablecolumnname = givenTableColumnName.toLowerCase();
        if (aliasMap.containsKey(giventablecolumnname)) { // register the alias name, if any
          lookupTable.add(aliasMap.get(giventablecolumnname), tableColumnName);
        }

        // full qualified attribute name
        String qualifiedColumnName = dbMetaData.getFullQualifiedAttributeName(tableGivenName, i);
        lookupTable.add(qualifiedColumnName, tableColumnName);
        String qualifiedcolumnname = qualifiedColumnName.toLowerCase();
        if (aliasMap.containsKey(qualifiedcolumnname)) { // register the alias name, if any
          lookupTable.add(aliasMap.get(qualifiedcolumnname), tableColumnName);
        }

        // full qualified attribute name using table alias
        String tableAlias = table.getAlias();
        if (tableAlias != null) {
          String qualifiedColumnAlias =
              dbMetaData.getFullQualifiedAttributeName(tableGivenName, tableAlias, i);
          lookupTable.add(qualifiedColumnAlias, index);
          String aliasColumnName = tableAlias.toLowerCase() + "." + lowercaseColumn;
          if (aliasMap.containsKey(aliasColumnName)) { // register the alias name, if any
            lookupTable.add(aliasMap.get(aliasColumnName), qualifiedColumnAlias);
          }
        }

        // check if we do not have subselect with alias name assigned
        for (SelectJSQL subSelect : queryParsed.getSubSelectSet()) {
          String subSelectAlias = subSelect.getAlias();
          if (subSelectAlias != null) {
            String aliasColumnName = subSelectAlias.toLowerCase() + "." + lowercaseColumn;
            lookupTable.add(aliasColumnName, index);
            if (aliasMap.containsKey(aliasColumnName)) { // register the alias name, if any
              lookupTable.add(aliasMap.get(aliasColumnName), aliasColumnName);
            }
          }
        }
      }
      offset += size;
    }
    return lookupTable;
  }
}
public class NewMappingDialogPanel extends javax.swing.JPanel
    implements DatasourceSelectorListener {

  private static final long serialVersionUID = 4351696247473906680L;

  /** Fields */
  private OBDAModel obdaModel;

  private OBDADataSource dataSource;
  private JDialog parent;
  private TargetQueryVocabularyValidator validator;
  private OBDADataFactory dataFactory = OBDADataFactoryImpl.getInstance();

  private PrefixManager prefixManager;

  /** Logger */
  private final Logger log = LoggerFactory.getLogger(this.getClass());

  /** Create the dialog for inserting a new mapping. */
  public NewMappingDialogPanel(
      OBDAModel obdaModel,
      JDialog parent,
      OBDADataSource dataSource,
      TargetQueryVocabularyValidator validator) {

    DialogUtils.installEscapeCloseOperation(parent);
    this.obdaModel = obdaModel;
    this.parent = parent;
    this.dataSource = dataSource;
    this.validator = validator;

    prefixManager = obdaModel.getPrefixManager();

    initComponents();

    // Formatting the src query
    StyledDocument doc = txtSourceQuery.getStyledDocument();
    Style plainStyle = doc.addStyle("PLAIN_STYLE", null);
    StyleConstants.setItalic(plainStyle, false);
    StyleConstants.setSpaceAbove(plainStyle, 0);
    StyleConstants.setFontSize(plainStyle, 12);
    StyleConstants.setFontFamily(plainStyle, new Font("Dialog", Font.PLAIN, 12).getFamily());
    doc.setParagraphAttributes(0, doc.getLength(), plainStyle, true);

    txtMappingID.setFont(new Font("Dialog", Font.BOLD, 12));

    cmdInsertMapping.setEnabled(false);
    QueryPainter painter = new QueryPainter(obdaModel, txtTargetQuery, validator);
    painter.addValidatorListener(
        new ValidatorListener() {

          @Override
          public void validated(boolean result) {
            cmdInsertMapping.setEnabled(result);
          }
        });

    cmdInsertMapping.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            cmdInsertMappingActionPerformed(e);
          }
        });

    txtTargetQuery.addKeyListener(new TABKeyListener());
    txtSourceQuery.addKeyListener(new TABKeyListener());
    tblQueryResult.setFocusable(false);

    txtTargetQuery.addKeyListener(new CTRLEnterKeyListener());
    txtSourceQuery.addKeyListener(new CTRLEnterKeyListener());
    txtMappingID.addKeyListener(new CTRLEnterKeyListener());

    cmdTestQuery.setFocusable(true);
    Vector<Component> order = new Vector<Component>(7);
    order.add(this.txtMappingID);
    order.add(this.txtTargetQuery);
    order.add(this.txtSourceQuery);
    order.add(this.cmdTestQuery);
    order.add(this.cmdInsertMapping);
    order.add(this.cmdCancel);
    this.setFocusTraversalPolicy(new CustomTraversalPolicy(order));
  }

  private class TABKeyListener implements KeyListener {
    @Override
    public void keyTyped(KeyEvent e) {
      if (e.getKeyCode() == KeyEvent.VK_TAB) {
        if (e.getModifiers() == KeyEvent.SHIFT_MASK) {
          e.getComponent().transferFocusBackward();
        } else {
          e.getComponent().transferFocus();
        }
        e.consume();
      }
    }

    @Override
    public void keyReleased(KeyEvent e) {
      // if (e.getKeyCode() == KeyEvent.VK_TAB) {
      // e.getComponent().transferFocus();
      // e.consume();
      // }
    }

    @Override
    public void keyPressed(KeyEvent e) {
      if (e.getKeyCode() == KeyEvent.VK_TAB) {
        if (e.getModifiers() == KeyEvent.SHIFT_MASK) {
          e.getComponent().transferFocusBackward();
        } else {
          e.getComponent().transferFocus();
        }
        e.consume();
      }
    }
  }

  private class CTRLEnterKeyListener implements KeyListener {
    @Override
    public void keyTyped(KeyEvent e) {
      // NO-OP
    }

    @Override
    public void keyPressed(KeyEvent e) {
      if (cmdInsertMapping.isEnabled()
          && (e.getModifiers() == KeyEvent.CTRL_MASK && e.getKeyCode() == KeyEvent.VK_ENTER)) {
        cmdInsertMappingActionPerformed(null);
      } else if ((e.getModifiers() == KeyEvent.CTRL_MASK && e.getKeyCode() == KeyEvent.VK_T)) {
        cmdTestQueryActionPerformed(null);
      }
    }

    @Override
    public void keyReleased(KeyEvent e) {}
  }

  private void insertMapping(String target, String source) {
    List<Function> targetQuery = parse(target);
    if (targetQuery != null) {
      final boolean isValid = validator.validate(targetQuery);
      if (isValid) {
        try {
          OBDAModel mapcon = obdaModel;
          URI sourceID = dataSource.getSourceID();
          System.out.println(sourceID.toString() + " \n");

          OBDASQLQuery body = dataFactory.getSQLQuery(source);
          System.out.println(body.toString() + " \n");

          OBDAMappingAxiom newmapping =
              dataFactory.getRDBMSMappingAxiom(txtMappingID.getText().trim(), body, targetQuery);
          System.out.println(newmapping.toString() + " \n");

          if (mapping == null) {
            // Case when we are creating a new mapping
            mapcon.addMapping(sourceID, newmapping);
          } else {
            // Case when we are updating an existing mapping
            mapcon.updateMappingsSourceQuery(sourceID, mapping.getId(), body);
            mapcon.updateTargetQueryMapping(sourceID, mapping.getId(), targetQuery);
            mapcon.updateMapping(sourceID, mapping.getId(), txtMappingID.getText().trim());
          }
        } catch (DuplicateMappingException e) {
          JOptionPane.showMessageDialog(
              this, "Error while inserting mapping: " + e.getMessage() + " is already taken");
          return;
        }
        parent.setVisible(false);
        parent.dispose();

      } else {
        // List of invalid predicates that are found by the validator.
        Vector<String> invalidPredicates = validator.getInvalidPredicates();
        String invalidList = "";
        for (String predicate : invalidPredicates) {
          invalidList += "- " + predicate + "\n";
        }
        JOptionPane.showMessageDialog(
            this,
            "This list of predicates is unknown by the ontology: \n" + invalidList,
            "New Mapping",
            JOptionPane.WARNING_MESSAGE);
      }
    }
  }

  /**
   * This method is called from within the constructor to initialize the form. WARNING: Do NOT
   * modify this code. The content of this method is always regenerated by the Form Editor.
   */
  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed"
  // desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {
    java.awt.GridBagConstraints gridBagConstraints;

    lblMappingID = new javax.swing.JLabel();
    cmdTestQuery = new javax.swing.JButton();
    pnlCommandButton = new javax.swing.JPanel();
    cmdInsertMapping = new javax.swing.JButton();
    cmdCancel = new javax.swing.JButton();
    txtMappingID = new javax.swing.JTextField();
    splitTargetSource = new javax.swing.JSplitPane();
    pnlTargetQueryEditor = new javax.swing.JPanel();
    lblTargetQuery = new javax.swing.JLabel();
    scrTargetQuery = new javax.swing.JScrollPane();
    txtTargetQuery = new javax.swing.JTextPane();
    splitSQL = new javax.swing.JSplitPane();
    pnlSourceQueryEditor = new javax.swing.JPanel();
    lblSourceQuery = new javax.swing.JLabel();
    scrSourceQuery = new javax.swing.JScrollPane();
    txtSourceQuery = new javax.swing.JTextPane();
    pnlQueryResult = new javax.swing.JPanel();
    scrQueryResult = new javax.swing.JScrollPane();
    tblQueryResult = new javax.swing.JTable();

    setFocusable(false);
    setMinimumSize(new java.awt.Dimension(600, 500));
    setPreferredSize(new java.awt.Dimension(600, 500));
    setLayout(new java.awt.GridBagLayout());

    lblMappingID.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
    lblMappingID.setText("Mapping ID:");
    lblMappingID.setFocusable(false);
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints.insets = new java.awt.Insets(8, 10, 8, 0);
    add(lblMappingID, gridBagConstraints);

    cmdTestQuery.setIcon(IconLoader.getImageIcon("images/execute.png"));
    cmdTestQuery.setMnemonic('t');
    cmdTestQuery.setText("Test SQL Query");
    cmdTestQuery.setToolTipText(
        "Execute the SQL query in the SQL query text pane<p> and display the results in the table bellow.");
    cmdTestQuery.setActionCommand("Test SQL query");
    cmdTestQuery.setBorder(javax.swing.BorderFactory.createEtchedBorder());
    cmdTestQuery.setContentAreaFilled(false);
    cmdTestQuery.setIconTextGap(5);
    cmdTestQuery.setMaximumSize(new java.awt.Dimension(115, 25));
    cmdTestQuery.setMinimumSize(new java.awt.Dimension(115, 25));
    cmdTestQuery.setPreferredSize(new java.awt.Dimension(115, 25));
    cmdTestQuery.addActionListener(
        new java.awt.event.ActionListener() {
          public void actionPerformed(java.awt.event.ActionEvent evt) {
            cmdTestQueryActionPerformed(evt);
          }
        });
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 5;
    gridBagConstraints.insets = new java.awt.Insets(4, 10, 4, 4);
    add(cmdTestQuery, gridBagConstraints);

    pnlCommandButton.setFocusable(false);
    pnlCommandButton.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT));

    cmdInsertMapping.setIcon(IconLoader.getImageIcon("images/accept.png"));
    cmdInsertMapping.setText("Accept");
    cmdInsertMapping.setToolTipText("This will add/edit the current mapping into the OBDA model");
    cmdInsertMapping.setActionCommand("OK");
    cmdInsertMapping.setBorder(javax.swing.BorderFactory.createEtchedBorder());
    cmdInsertMapping.setContentAreaFilled(false);
    cmdInsertMapping.setIconTextGap(5);
    cmdInsertMapping.setPreferredSize(new java.awt.Dimension(90, 25));
    pnlCommandButton.add(cmdInsertMapping);

    cmdCancel.setIcon(IconLoader.getImageIcon("images/cancel.png"));
    cmdCancel.setText("Cancel");
    cmdCancel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
    cmdCancel.setContentAreaFilled(false);
    cmdCancel.setIconTextGap(5);
    cmdCancel.setPreferredSize(new java.awt.Dimension(90, 25));
    cmdCancel.addActionListener(
        new java.awt.event.ActionListener() {
          public void actionPerformed(java.awt.event.ActionEvent evt) {
            cmdCancelActionPerformed(evt);
          }
        });
    pnlCommandButton.add(cmdCancel);

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridy = 7;
    gridBagConstraints.gridwidth = 2;
    gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints.insets = new java.awt.Insets(0, 0, 10, 4);
    add(pnlCommandButton, gridBagConstraints);
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 1;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
    gridBagConstraints.weightx = 1.0;
    gridBagConstraints.insets = new java.awt.Insets(8, 0, 8, 10);
    add(txtMappingID, gridBagConstraints);

    splitTargetSource.setBorder(null);
    splitTargetSource.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
    splitTargetSource.setResizeWeight(0.5);
    splitTargetSource.setDoubleBuffered(true);
    splitTargetSource.setFocusable(false);
    splitTargetSource.setMinimumSize(new java.awt.Dimension(600, 430));
    splitTargetSource.setOneTouchExpandable(true);
    splitTargetSource.setPreferredSize(new java.awt.Dimension(600, 430));

    pnlTargetQueryEditor.setFocusable(false);
    pnlTargetQueryEditor.setMinimumSize(new java.awt.Dimension(600, 180));
    pnlTargetQueryEditor.setPreferredSize(new java.awt.Dimension(600, 180));
    pnlTargetQueryEditor.setLayout(new java.awt.BorderLayout());

    lblTargetQuery.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
    lblTargetQuery.setText("Target (Triples Template):");
    lblTargetQuery.setFocusable(false);
    pnlTargetQueryEditor.add(lblTargetQuery, java.awt.BorderLayout.NORTH);

    scrTargetQuery.setFocusable(false);
    scrTargetQuery.setMinimumSize(new java.awt.Dimension(600, 170));
    scrTargetQuery.setPreferredSize(new java.awt.Dimension(600, 170));

    txtTargetQuery.setFocusCycleRoot(false);
    txtTargetQuery.setMinimumSize(new java.awt.Dimension(600, 170));
    txtTargetQuery.setPreferredSize(new java.awt.Dimension(600, 170));
    scrTargetQuery.setViewportView(txtTargetQuery);

    pnlTargetQueryEditor.add(scrTargetQuery, java.awt.BorderLayout.CENTER);

    splitTargetSource.setLeftComponent(pnlTargetQueryEditor);

    splitSQL.setBorder(null);
    splitSQL.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
    splitSQL.setResizeWeight(0.8);
    splitSQL.setFocusable(false);
    splitSQL.setMinimumSize(new java.awt.Dimension(600, 280));
    splitSQL.setOneTouchExpandable(true);
    splitSQL.setPreferredSize(new java.awt.Dimension(600, 280));

    pnlSourceQueryEditor.setFocusable(false);
    pnlSourceQueryEditor.setMinimumSize(new java.awt.Dimension(600, 150));
    pnlSourceQueryEditor.setPreferredSize(new java.awt.Dimension(600, 150));
    pnlSourceQueryEditor.setLayout(new java.awt.BorderLayout());

    lblSourceQuery.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
    lblSourceQuery.setText("Source (SQL Query):");
    lblSourceQuery.setFocusable(false);
    pnlSourceQueryEditor.add(lblSourceQuery, java.awt.BorderLayout.NORTH);

    scrSourceQuery.setFocusable(false);

    txtSourceQuery.setFocusCycleRoot(false);
    scrSourceQuery.setViewportView(txtSourceQuery);

    pnlSourceQueryEditor.add(scrSourceQuery, java.awt.BorderLayout.CENTER);

    splitSQL.setTopComponent(pnlSourceQueryEditor);

    pnlQueryResult.setFocusable(false);
    pnlQueryResult.setMinimumSize(new java.awt.Dimension(600, 120));
    pnlQueryResult.setPreferredSize(new java.awt.Dimension(600, 120));
    pnlQueryResult.setLayout(new java.awt.BorderLayout());

    scrQueryResult.setFocusable(false);
    scrQueryResult.setPreferredSize(new java.awt.Dimension(454, 70));

    tblQueryResult.setModel(
        new javax.swing.table.DefaultTableModel(new Object[][] {}, new String[] {}));

    tblQueryResult.setMinimumSize(new java.awt.Dimension(600, 180));
    tblQueryResult.setPreferredSize(new java.awt.Dimension(600, 180));
    scrQueryResult.setViewportView(tblQueryResult);

    pnlQueryResult.add(scrQueryResult, java.awt.BorderLayout.CENTER);

    splitSQL.setBottomComponent(pnlQueryResult);

    splitTargetSource.setRightComponent(splitSQL);

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 2;
    gridBagConstraints.gridwidth = 2;
    gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
    gridBagConstraints.weightx = 1.0;
    gridBagConstraints.weighty = 1.0;
    gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 10);
    add(splitTargetSource, gridBagConstraints);

    getAccessibleContext().setAccessibleName("Mapping editor");
  } // </editor-fold>//GEN-END:initComponents

  private void releaseResultset() {
    TableModel model = tblQueryResult.getModel();
    if (model == null) return;
    if (!(model instanceof IncrementalResultSetTableModel)) return;
    IncrementalResultSetTableModel imodel = (IncrementalResultSetTableModel) model;
    imodel.close();
  }

  private void cmdTestQueryActionPerformed(
      java.awt.event.ActionEvent evt) { // GEN-FIRST:event_jButtonTestActionPerformed
    // Cleaning the existing table and releasing resources
    releaseResultset();

    OBDAProgessMonitor progMonitor = new OBDAProgessMonitor("Executing query...");
    CountDownLatch latch = new CountDownLatch(1);
    ExecuteSQLQueryAction action = new ExecuteSQLQueryAction(latch);
    progMonitor.addProgressListener(action);
    progMonitor.start();
    try {
      action.run();
      latch.await();
      progMonitor.stop();
      ResultSet set = action.getResult();
      if (set != null) {
        IncrementalResultSetTableModel model = new IncrementalResultSetTableModel(set);
        tblQueryResult.setModel(model);
      }
    } catch (Exception e) {
      log.error(e.getMessage());
    }
  } // GEN-LAST:event_jButtonTestActionPerformed

  private class ExecuteSQLQueryAction implements OBDAProgressListener {

    CountDownLatch latch = null;
    Thread thread = null;
    ResultSet result = null;
    Statement statement = null;
    private boolean isCancelled = false;
    private boolean errorShown = false;

    private ExecuteSQLQueryAction(CountDownLatch latch) {
      this.latch = latch;
    }

    @Override
    public void actionCanceled() throws SQLException {
      this.isCancelled = true;
      if (thread != null) {
        thread.interrupt();
      }
      if (statement != null && !statement.isClosed()) {
        statement.close();
      }
      result = null;
      latch.countDown();
    }

    public ResultSet getResult() {
      return result;
    }

    public void run() {
      thread =
          new Thread() {
            public void run() {
              try {
                TableModel oldmodel = tblQueryResult.getModel();

                if ((oldmodel != null) && (oldmodel instanceof IncrementalResultSetTableModel)) {
                  IncrementalResultSetTableModel rstm = (IncrementalResultSetTableModel) oldmodel;
                  rstm.close();
                }
                JDBCConnectionManager man = JDBCConnectionManager.getJDBCConnectionManager();

                Connection c = man.getConnection(dataSource);

                //						String driver =
                // dataSource.getParameter(RDBMSourceParameterConstants.DATABASE_DRIVER);

                Statement st =
                    c.createStatement(
                        java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);
                // if (driver.equals("com.mysql.jdbc.Driver")) {
                // st.setFetchSize(Integer.MIN_VALUE);
                // }

                result = st.executeQuery(txtSourceQuery.getText().trim());
                latch.countDown();
              } catch (Exception e) {
                latch.countDown();
                DialogUtils.showQuickErrorDialog(null, e);
                errorShown = true;
              }
            }
          };
      thread.start();
    }

    @Override
    public boolean isCancelled() {
      return this.isCancelled;
    }

    @Override
    public boolean isErrorShown() {
      return this.errorShown;
    }
  }

  private void cmdInsertMappingActionPerformed(
      ActionEvent e) { // GEN-FIRST:event_cmdInsertMappingActionPerformed

    releaseResultset();

    final String targetQueryString = txtTargetQuery.getText();
    final String sourceQueryString = txtSourceQuery.getText();

    if (txtMappingID.getText().trim().length() == 0) {
      JOptionPane.showMessageDialog(
          this, "ERROR: The ID cannot be empty", "Error", JOptionPane.ERROR_MESSAGE);
      return;
    }
    if (targetQueryString.isEmpty()) {
      JOptionPane.showMessageDialog(
          this, "ERROR: The target cannot be empty", "Error", JOptionPane.ERROR_MESSAGE);
      return;
    }
    if (sourceQueryString.isEmpty()) {
      JOptionPane.showMessageDialog(
          this, "ERROR: The source cannot be empty", "Error", JOptionPane.ERROR_MESSAGE);
      return;
    }
    insertMapping(targetQueryString, sourceQueryString);
  } // GEN-LAST:event_cmdInsertMappingActionPerformed

  private void cmdCancelActionPerformed(
      java.awt.event.ActionEvent evt) { // GEN-FIRST:event_cmdCancelActionPerformed
    parent.setVisible(false);
    parent.dispose();
    releaseResultset();
  } // GEN-LAST:event_cmdCancelActionPerformed

  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JButton cmdCancel;
  private javax.swing.JButton cmdInsertMapping;
  private javax.swing.JButton cmdTestQuery;
  private javax.swing.JLabel lblMappingID;
  private javax.swing.JLabel lblSourceQuery;
  private javax.swing.JLabel lblTargetQuery;
  private javax.swing.JPanel pnlCommandButton;
  private javax.swing.JPanel pnlQueryResult;
  private javax.swing.JPanel pnlSourceQueryEditor;
  private javax.swing.JPanel pnlTargetQueryEditor;
  private javax.swing.JScrollPane scrQueryResult;
  private javax.swing.JScrollPane scrSourceQuery;
  private javax.swing.JScrollPane scrTargetQuery;
  private javax.swing.JSplitPane splitSQL;
  private javax.swing.JSplitPane splitTargetSource;
  private javax.swing.JTable tblQueryResult;
  private javax.swing.JTextField txtMappingID;
  private javax.swing.JTextPane txtSourceQuery;
  private javax.swing.JTextPane txtTargetQuery;
  // End of variables declaration//GEN-END:variables

  private OBDAMappingAxiom mapping;

  private List<Function> parse(String query) {
    TurtleOBDASyntaxParser textParser = new TurtleOBDASyntaxParser(obdaModel.getPrefixManager());
    try {
      return textParser.parse(query);
    } catch (TargetQueryParserException e) {
      return null;
    } catch (Exception e) {
      return null;
    }
  }

  @Override
  public void datasourceChanged(OBDADataSource oldSource, OBDADataSource newSource) {
    dataSource = newSource;
  }

  public void setID(String id) {
    this.txtMappingID.setText(id);
  }

  @Override
  public void finalize() {
    releaseResultset();
  }

  /**
   * * Sets the current mapping to the input. Note, if the current mapping is set, this means that
   * this dialog is "updating" a mapping, and not creating a new one.
   */
  public void setMapping(OBDAMappingAxiom mapping) {
    this.mapping = mapping;

    cmdInsertMapping.setText("Update");
    txtMappingID.setText(mapping.getId());

    OBDASQLQuery sourceQuery = mapping.getSourceQuery();
    String srcQuery = SourceQueryRenderer.encode(sourceQuery);
    txtSourceQuery.setText(srcQuery);

    List<Function> targetQuery = mapping.getTargetQuery();
    String trgQuery = TargetQueryRenderer.encode(targetQuery, prefixManager);
    txtTargetQuery.setText(trgQuery);
  }
}
public class PropertyCharacteristicTest extends TestCase {

  private QuestOWLConnection conn = null;
  private QuestOWLStatement stmt = null;
  private QuestOWL reasoner = null;

  private Connection jdbcconn = null;
  private Logger log = LoggerFactory.getLogger(this.getClass());
  private static OBDADataFactory ofac = OBDADataFactoryImpl.getInstance();

  private static QuestPreferences prefs;

  static {
    prefs = new QuestPreferences();
    prefs.setCurrentValueOf(QuestPreferences.ABOX_MODE, QuestConstants.VIRTUAL);
    prefs.setCurrentValueOf(QuestPreferences.REWRITE, QuestConstants.TRUE);
  }

  @Override
  public void setUp() throws Exception {
    createTables();
  }

  private String readSQLFile(String file) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader(file));
    StringBuilder bf = new StringBuilder();
    String line = reader.readLine();
    while (line != null) {
      bf.append(line + "\n");
      line = reader.readLine();
    }
    return bf.toString();
  }

  private void createTables() throws IOException, SQLException {
    String createDDL = readSQLFile("src/test/resources/property-characteristics/sqlcreate.sql");

    // Initializing and H2 database with the stock exchange data
    // String driver = "org.h2.Driver";
    String url = "jdbc:h2:mem:questjunitdb";
    String username = "******";
    String password = "";

    ofac = OBDADataFactoryImpl.getInstance();

    jdbcconn = DriverManager.getConnection(url, username, password);
    Statement st = jdbcconn.createStatement();

    st.executeUpdate(createDDL);
    jdbcconn.commit();
  }

  @Override
  public void tearDown() throws Exception {
    try {
      dropTables();
      conn.close();
      jdbcconn.close();
    } catch (Exception e) {
      log.debug(e.getMessage());
    }
  }

  private void dropTables() throws SQLException, IOException {
    String dropDDL = readSQLFile("src/test/resources/property-characteristics/drop.sql");
    Statement st = jdbcconn.createStatement();
    st.executeUpdate(dropDDL);
    st.close();
    jdbcconn.commit();
  }

  public void testNoProperty() throws Exception {
    final File owlFile = new File("src/test/resources/property-characteristics/noproperty.owl");
    final File obdaFile = new File("src/test/resources/property-characteristics/noproperty.obda");

    setupReasoner(owlFile, obdaFile);
    QuestOWLResultSet rs =
        executeQuery(
            ""
                + "PREFIX : <http://www.semanticweb.org/johardi/ontologies/2013/3/Ontology1365668829973.owl#> \n"
                + "SELECT ?x ?y \n"
                + "WHERE { ?x :knows ?y . }");
    final int count = countResult(rs, true);
    assertEquals(3, count);
  }

  public void testSymmetricProperty() throws Exception {
    final File owlFile = new File("src/test/resources/property-characteristics/symmetric.owl");
    final File obdaFile = new File("src/test/resources/property-characteristics/symmetric.obda");

    setupReasoner(owlFile, obdaFile);
    QuestOWLResultSet rs =
        executeQuery(
            ""
                + "PREFIX : <http://www.semanticweb.org/johardi/ontologies/2013/3/Ontology1365668829973.owl#> \n"
                + "SELECT ?x ?y \n"
                + "WHERE { ?x :knows ?y . }");
    final int count = countResult(rs, true);
    assertEquals(6, count);
  }

  private void setupReasoner(File owlFile, File obdaFile) throws Exception {
    OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
    OWLOntology ontology = manager.loadOntologyFromOntologyDocument(owlFile);

    OBDAModel obdaModel = ofac.getOBDAModel();
    ModelIOManager ioManager = new ModelIOManager(obdaModel);
    ioManager.load(obdaFile);

    QuestOWLFactory factory = new QuestOWLFactory();
    factory.setOBDAController(obdaModel);
    factory.setPreferenceHolder(prefs);

    reasoner = (QuestOWL) factory.createReasoner(ontology, new SimpleConfiguration());
  }

  private QuestOWLResultSet executeQuery(String sparql) throws Exception {
    conn = reasoner.getConnection();
    stmt = conn.createStatement();
    return stmt.executeTuple(sparql);
  }

  private int countResult(QuestOWLResultSet rs, boolean stdout) throws OWLException {
    int counter = 0;
    while (rs.nextRow()) {
      counter++;
      if (stdout) {
        for (int column = 1; column <= rs.getColumCount(); column++) {
          OWLObject binding = rs.getOWLObject(column);
          System.out.print(binding.toString() + ", ");
        }
        System.out.print("\n");
      }
    }
    return counter;
  }
}