/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.foundation.ontology.owl;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.filter.ElementFilter;
import org.jdom2.input.SAXBuilder;
import org.openflexo.foundation.FlexoEditor;
import org.openflexo.foundation.ontology.DuplicateURIException;
import org.openflexo.foundation.ontology.FlexoOntology;
import org.openflexo.foundation.ontology.OntologicDataType;
import org.openflexo.foundation.ontology.OntologyClass;
import org.openflexo.foundation.ontology.OntologyDataProperty;
import org.openflexo.foundation.ontology.OntologyIndividual;
import org.openflexo.foundation.ontology.OntologyLibrary;
import org.openflexo.foundation.ontology.OntologyObject;
import org.openflexo.foundation.ontology.OntologyObjectProperty;
import org.openflexo.foundation.ontology.dm.OntologyClassInserted;
import org.openflexo.foundation.ontology.dm.OntologyClassRemoved;
import org.openflexo.foundation.ontology.dm.OntologyDataPropertyInserted;
import org.openflexo.foundation.ontology.dm.OntologyDataPropertyRemoved;
import org.openflexo.foundation.ontology.dm.OntologyIndividualInserted;
import org.openflexo.foundation.ontology.dm.OntologyIndividualRemoved;
import org.openflexo.foundation.ontology.dm.OntologyObjectPropertyInserted;
import org.openflexo.foundation.ontology.dm.OntologyObjectPropertyRemoved;
import org.openflexo.foundation.ontology.dm.OntologyObjectRenamed;
import org.openflexo.foundation.ontology.owl.action.CreateDataProperty;
import org.openflexo.foundation.ontology.owl.action.CreateObjectProperty;
import org.openflexo.foundation.ontology.owl.action.CreateOntologyClass;
import org.openflexo.foundation.ontology.owl.action.CreateOntologyIndividual;
import org.openflexo.foundation.ontology.owl.action.DeleteOntologyObjects;
import org.openflexo.foundation.resource.FlexoResourceCenter;
import org.openflexo.foundation.resource.LocalResourceCenterImplementation;
import org.openflexo.foundation.rm.SaveResourceException;
import org.openflexo.toolbox.StringUtils;
import com.hp.hpl.jena.ontology.AnnotationProperty;
import com.hp.hpl.jena.ontology.ComplementClass;
import com.hp.hpl.jena.ontology.DatatypeProperty;
import com.hp.hpl.jena.ontology.Individual;
import com.hp.hpl.jena.ontology.IntersectionClass;
import com.hp.hpl.jena.ontology.ObjectProperty;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.ontology.OntProperty;
import com.hp.hpl.jena.ontology.OntResource;
import com.hp.hpl.jena.ontology.Restriction;
import com.hp.hpl.jena.ontology.UnionClass;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.NodeIterator;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.RDFWriter;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.util.ResourceUtils;
public abstract class OWLOntology extends OWLObject implements FlexoOntology {
private static final Logger logger = Logger.getLogger(FlexoOntology.class.getPackage().getName());
private String name;
private final String ontologyURI;
protected OntModel ontModel;
private final File alternativeLocalFile;
private final OntologyLibrary _library;
protected boolean isLoaded = false;
protected boolean isLoading = false;
private boolean readOnly = true;
private final Vector<OWLOntology> importedOntologies;
private final Hashtable<String, OWLClass> classes;
private final Hashtable<String, OWLIndividual> individuals;
private final Hashtable<String, OWLDataProperty> dataProperties;
private final Hashtable<String, OWLObjectProperty> objectProperties;
private final Hashtable<OntClass, OWLClass> _classes;
private final Hashtable<Individual, OWLIndividual> _individuals;
private final Hashtable<OntProperty, OWLDataProperty> _dataProperties;
private final Hashtable<OntProperty, OWLObjectProperty> _objectProperties;
private final Vector<OWLClass> orderedClasses;
private final Vector<OWLIndividual> orderedIndividuals;
private final Vector<OWLDataProperty> orderedDataProperties;
private final Vector<OWLObjectProperty> orderedObjectProperties;
private OWLClass THING_CONCEPT;
public OWLOntology(String anURI, File owlFile, OntologyLibrary library) {
super(null, null);
logger.info("Register ontology " + anURI + " file: " + owlFile);
ontologyURI = anURI;
if (owlFile != null && owlFile.exists()) {
name = findOntologyName(owlFile);
}
if (name == null) {
name = ontologyURI.substring(ontologyURI.lastIndexOf("/") + 1);
}
alternativeLocalFile = owlFile;
_library = library;
importedOntologies = new Vector<OWLOntology>();
classes = new Hashtable<String, OWLClass>();
individuals = new Hashtable<String, OWLIndividual>();
dataProperties = new Hashtable<String, OWLDataProperty>();
objectProperties = new Hashtable<String, OWLObjectProperty>();
_classes = new Hashtable<OntClass, OWLClass>();
_individuals = new Hashtable<Individual, OWLIndividual>();
_dataProperties = new Hashtable<OntProperty, OWLDataProperty>();
_objectProperties = new Hashtable<OntProperty, OWLObjectProperty>();
orderedClasses = new Vector<OWLClass>();
orderedIndividuals = new Vector<OWLIndividual>();
orderedDataProperties = new Vector<OWLDataProperty>();
orderedObjectProperties = new Vector<OWLObjectProperty>();
}
public static String findOntologyURI(File aFile) {
String returned = findOntologyURIWithOntologyAboutMethod(aFile);
if (StringUtils.isNotEmpty(returned) && returned.endsWith("#")) {
returned = returned.substring(0, returned.lastIndexOf("#"));
}
if (StringUtils.isEmpty(returned)) {
returned = findOntologyURIWithRDFBaseMethod(aFile);
}
if (StringUtils.isNotEmpty(returned) && returned.endsWith("#")) {
returned = returned.substring(0, returned.lastIndexOf("#"));
}
if (StringUtils.isEmpty(returned)) {
logger.warning("Could not find URI for ontology stored in file " + aFile.getAbsolutePath());
}
return returned;
}
private static String findOntologyURIWithRDFBaseMethod(File aFile) {
Document document;
try {
logger.fine("Try to find URI for " + aFile);
document = readXMLFile(aFile);
Element root = getElement(document, "RDF");
if (root != null) {
Iterator it = root.getAttributes().iterator();
while (it.hasNext()) {
Attribute at = (Attribute) it.next();
if (at.getName().equals("base")) {
logger.fine("Returned " + at.getValue());
return at.getValue();
}
}
}
} catch (JDOMException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
logger.fine("Returned null");
return null;
}
private static String findOntologyURIWithOntologyAboutMethod(File aFile) {
Document document;
try {
logger.fine("Try to find URI for " + aFile);
document = readXMLFile(aFile);
Element root = getElement(document, "Ontology");
if (root != null) {
Iterator it = root.getAttributes().iterator();
while (it.hasNext()) {
Attribute at = (Attribute) it.next();
if (at.getName().equals("about")) {
logger.fine("Returned " + at.getValue());
String returned = at.getValue();
if (StringUtils.isNotEmpty(returned)) {
return returned;
}
}
}
}
} catch (JDOMException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
logger.fine("Returned null");
return findOntologyURIWithRDFBaseMethod(aFile);
}
public static String findOntologyName(File aFile) {
if (aFile == null || !aFile.exists() || aFile.length() == 0) {
if (aFile != null && aFile.length() == 0) {
aFile.delete();
}
return null;
}
Document document;
try {
logger.fine("Try to find name for " + aFile);
document = readXMLFile(aFile);
Element root = getElement(document, "RDF");
if (root != null) {
Element ontology = getElement(root, "Ontology");
if (ontology != null) {
Element title = getElement(root, "title");
if (title != null) {
return title.getValue();
}
List<Attribute> l = ontology.getAttributes();
for (int i = 0; i < l.size(); i++) {
Attribute a = l.get(i);
if (a.getName().equals("title")) {
return a.getValue();
}
}
}
}
} catch (JDOMException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private static Document readXMLFile(File f) throws JDOMException, IOException {
FileInputStream fio = new FileInputStream(f);
SAXBuilder parser = new SAXBuilder();
Document reply = parser.build(fio);
return reply;
}
private static Element getElement(Document document, String name) {
Iterator it = document.getDescendants(new ElementFilter(name));
if (it.hasNext()) {
return (Element) it.next();
} else {
return null;
}
}
private static Element getElement(Element from, String name) {
Iterator it = from.getDescendants(new ElementFilter(name));
if (it.hasNext()) {
return (Element) it.next();
} else {
return null;
}
}
@Override
public String getClassNameKey() {
return "flexo_ontology";
}
@Override
public String getURI() {
return getOntologyURI();
}
@Override
public String getOntologyURI() {
return ontologyURI;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String aName) {
String newURI;
if (getURI().indexOf("#") > -1) {
newURI = getURI().substring(0, getURI().indexOf("#")) + aName;
} else {
newURI = aName;
}
logger.warning("Rename ontology " + getURI() + " to " + newURI + " not implemented yet");
}
@Override
protected void _setOntResource(OntResource r) {
// not relevant
}
public OntModel getOntModel() {
loadWhenUnloaded();
return ontModel;
}
public void setOntModel(OntModel ontModel) {
this.ontModel = ontModel;
}
public File getAlternativeLocalFile() {
return alternativeLocalFile;
}
/**
* Return a vector of all imported ontologies in the context of this ontology. This method is recursive. Ontologies are imported only
* once. This ontology is also appened to returned list.
*
* @return
*/
@Override
public Vector<OWLOntology> getAllImportedOntologies() {
Vector<OWLOntology> returned = new Vector<OWLOntology>();
appendToAllImportedOntologies(this, returned);
return returned;
}
private static void appendToAllImportedOntologies(OWLOntology o, Vector<OWLOntology> v) {
if (!v.contains(o)) {
v.add(o);
for (OWLOntology importedOntology : o.getImportedOntologies()) {
appendToAllImportedOntologies(importedOntology, v);
}
}
}
/**
* Return a vector of imported ontologies in the context of this ontology
*
* @return
*/
@Override
public Vector<OWLOntology> getImportedOntologies() {
loadWhenUnloaded();
if (getURI().equals(OWL2URIDefinitions.OWL_ONTOLOGY_URI)) {
// OWL ontology should at least import RDF and RDFS ontologies
if (!importedOntologies.contains(getOntologyLibrary().getRDFOntology())) {
importedOntologies.add(getOntologyLibrary().getRDFOntology());
}
if (!importedOntologies.contains(getOntologyLibrary().getRDFSOntology())) {
importedOntologies.add(getOntologyLibrary().getRDFSOntology());
}
} else if (getURI().equals(RDFURIDefinitions.RDF_ONTOLOGY_URI)) {
// RDF ontology should at least import RDFS ontology
if (!importedOntologies.contains(getOntologyLibrary().getRDFSOntology())) {
importedOntologies.add(getOntologyLibrary().getRDFSOntology());
}
} else if (getURI().equals(RDFSURIDefinitions.RDFS_ONTOLOGY_URI)) {
// RDFS ontology has no requirement
if (!importedOntologies.contains(getOntologyLibrary().getRDFOntology())) {
importedOntologies.add(getOntologyLibrary().getRDFOntology());
}
} else {
// All other ontologies should at least import OWL ontology
if (!importedOntologies.contains(getOntologyLibrary().getOWLOntology())) {
importedOntologies.add(getOntologyLibrary().getOWLOntology());
}
}
/*if (importedOntologies.size() == 0) {
if (getURI().equals(OntologyLibrary.OWL_ONTOLOGY_URI)) {
importedOntologies.add(getOntologyLibrary().getRDFOntology());
importedOntologies.add(getOntologyLibrary().getRDFSOntology());
} else if (getURI().equals(OntologyLibrary.RDF_ONTOLOGY_URI)) {
importedOntologies.add(getOntologyLibrary().getRDFSOntology());
} else if (!getURI().equals(OntologyLibrary.RDFS_ONTOLOGY_URI)) {
importedOntologies.add(getOntologyLibrary().getOWLOntology());
}
}*/
return importedOntologies;
}
/**
* Return the local vision of OWL Thing concept
*
* @return
*/
@Override
public OWLClass getThingConcept() {
return THING_CONCEPT;
}
/**
* Return the root concept class, which is the local vision of OWL Thing concept
*
* @return
*/
public OWLClass getRootClass() {
return getThingConcept();
}
@Override
public String toString() {
return "ImportedOntology:" + getOntologyURI();
}
@Override
public String getFullyQualifiedName() {
return getOntologyURI();
}
public boolean importOntology(String ontologyURI) throws OntologyNotFoundException {
if (_library.getOntology(ontologyURI) == null) {
throw new OntologyNotFoundException();
} else {
return importOntology(_library.getOntology(ontologyURI));
}
}
/**
* Import ontology if supplied ontology is not yet imported in this ontology.<br>
* Return a flag indicating if import was effective (otherwise, it was already done)
*
* @param anOntology
* @return
* @throws OntologyNotFoundException
*/
public boolean importOntology(FlexoOntology anOntology) throws OntologyNotFoundException {
if (anOntology instanceof OWLOntology == false) {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("Tried to import a non-owl ontology to an owl ontology, this is not yet supported.");
}
}
loadWhenUnloaded();
if (getAllImportedOntologies().contains(anOntology)) {
return false;
}
if (_library.getOntology(anOntology.getOntologyURI()) == null) {
throw new OntologyNotFoundException();
} else if (_library.getOntology(anOntology.getOntologyURI()) != anOntology) {
throw new OntologyNotFoundException();
}
String SOURCE = "@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.\n"
+ "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.\n"
+ "@prefix owl: <http://www.w3.org/2002/07/owl#>.\n" + "<" + getOntologyURI() + "> a owl:Ontology \n"
+ " ; owl:imports <" + anOntology.getOntologyURI() + ">.\n";
logger.fine("About to load source ontology:");
logger.fine(SOURCE);
ontModel.read(new StringReader(SOURCE), getOntologyURI(), "N3");
importedOntologies.add((OWLOntology) anOntology);
setChanged();
return true;
}
public static class OntologyNotFoundException extends Exception {
};
public static class DuplicatedOntologyException extends Exception {
};
private boolean isNamedClass(OntClass ontClass) {
return !ontClass.isComplementClass() && !ontClass.isUnionClass() && !ontClass.isIntersectionClass() && !ontClass.isRestriction()
&& !ontClass.isEnumeratedClass() && StringUtils.isNotEmpty(ontClass.getURI());
}
private boolean isNamedResourceOfThisOntology(OntResource ontResource) {
return StringUtils.isNotEmpty(ontResource.getURI()) && ontResource.getURI().startsWith(getURI());
}
private void createConceptsAndProperties() {
classes.clear();
individuals.clear();
dataProperties.clear();
objectProperties.clear();
_classes.clear();
_individuals.clear();
_dataProperties.clear();
_objectProperties.clear();
for (Iterator<OntClass> i = getOntModel().listClasses(); i.hasNext();) {
OntClass ontClass = i.next();
if (_classes.get(ontClass) == null && isNamedResourceOfThisOntology(ontClass)) {
// Only named classes will be appended
makeNewClass(ontClass);
if (logger.isLoggable(Level.FINE)) {
logger.fine("Made class " + ontClass.getURI());
}
}
}
for (Iterator<Individual> i = getOntModel().listIndividuals(); i.hasNext();) {
Individual individual = i.next();
if (_individuals.get(individual) == null && isNamedResourceOfThisOntology(individual)) {
OntologyIndividual newIndividual = makeNewIndividual(individual);
if (logger.isLoggable(Level.FINE)) {
logger.fine("Made individual " + individual.getURI());
}
}
}
for (Iterator<DatatypeProperty> i = getOntModel().listDatatypeProperties(); i.hasNext();) {
DatatypeProperty ontProperty = i.next();
if (_dataProperties.get(ontProperty) == null && isNamedResourceOfThisOntology(ontProperty)) {
makeNewDataProperty(ontProperty);
if (logger.isLoggable(Level.FINE)) {
logger.fine(getURI() + ": made DataProperty" + ontProperty.getURI() + " in " + getURI());
}
}
}
for (Iterator<ObjectProperty> i = getOntModel().listObjectProperties(); i.hasNext();) {
ObjectProperty ontProperty = i.next();
if (_objectProperties.get(ontProperty) == null && isNamedResourceOfThisOntology(ontProperty)) {
makeNewObjectProperty(ontProperty);
if (logger.isLoggable(Level.FINE)) {
logger.fine(getURI() + ": made ObjectProperty" + ontProperty.getURI() + " in " + getURI());
}
}
}
// I dont understand why, but on some ontologies (RDF, RDFS and OWL), this is the only way to obtain those properties
for (Iterator i = ontModel.listAllOntProperties(); i.hasNext();) {
OntProperty ontProperty = (OntProperty) i.next();
// Do it if and only if property is not yet existant
if (getOntologyObject(ontProperty.getURI()) == null) {
if (ontProperty.canAs(ObjectProperty.class)) {
makeNewObjectProperty(ontProperty.as(ObjectProperty.class));
} else if (ontProperty.canAs(DatatypeProperty.class)) {
makeNewDataProperty(ontProperty.as(DatatypeProperty.class));
} else if (ontProperty.canAs(AnnotationProperty.class)) {
AnnotationProperty ap = ontProperty.as(AnnotationProperty.class);
if (ap.getRange() != null && ap.getRange().getURI().equals(RDFSURIDefinitions.RDFS_LITERAL_URI)) {
makeNewDataProperty(ontProperty);
} else if (ap.getRange() != null && ap.getRange().getURI().equals(RDFSURIDefinitions.RDFS_RESOURCE_URI)) {
makeNewObjectProperty(ontProperty);
}
} else {
// default behaviour: create object property
makeNewObjectProperty(ontProperty);
}
}
}
// I dont understand why, but on some ontologies, this is the only way to obtain those classes
for (NodeIterator i = ontModel.listObjects(); i.hasNext();) {
RDFNode node = i.nextNode();
if (node instanceof Resource && ((Resource) node).canAs(OntClass.class)) {
OntClass ontClass = ((Resource) node).as(OntClass.class);
if (_classes.get(ontClass) == null && isNamedResourceOfThisOntology(ontClass)) {
// Only named classes will be appended)
makeNewClass(ontClass);
// logger.info("Made class (2)" + ontClass.getURI());
}
}
}
/*if (getURI().equals(OntologyLibrary.RDFS_ONTOLOGY_URI)) {
for (StmtIterator i = getOntModel().listStatements(); i.hasNext();) {
Statement s = i.nextStatement();
System.out.println("statement = " + s);
}
for (NodeIterator i = ontModel.listObjects(); i.hasNext();) {
RDFNode node = i.nextNode();
System.out.println("node = " + node);
}
for (NodeIterator i = ontModel.listObjects(); i.hasNext();) {
RDFNode node = i.nextNode();
if (node.canAs(Resource.class)) {
System.out.println("resource = " + node.as(Resource.class));
}
}
for (Iterator i = ontModel.listAllOntProperties(); i.hasNext();) {
OntProperty ontProperty = (OntProperty) i.next();
System.out.println("Property: " + ontProperty);
if (ontProperty.canAs(ObjectProperty.class)) {
System.out.println("ObjectProperty");
} else if (ontProperty.canAs(DatatypeProperty.class)) {
System.out.println("DataProperty");
} else if (ontProperty.canAs(AnnotationProperty.class)) {
AnnotationProperty ap = ontProperty.as(AnnotationProperty.class);
System.out.println("AnnotationProperty " + ap.getRange());
} else if (ontProperty.canAs(FunctionalProperty.class)) {
System.out.println("FunctionalProperty");
}
}
System.exit(-1);
}*/
if (!getURI().equals(OWL2URIDefinitions.OWL_ONTOLOGY_URI) && !getURI().equals(RDFURIDefinitions.RDF_ONTOLOGY_URI)
&& !getURI().equals(RDFSURIDefinitions.RDFS_ONTOLOGY_URI)) {
// Following will not apply to RDF, RDFS and OWL ontologies
handleRedefinitionOfConceptsAndProperties();
}
// Special case for OWL ontology, register THING
if (getURI().equals(OWL2URIDefinitions.OWL_ONTOLOGY_URI)) {
THING_CONCEPT = getClass(OWL2URIDefinitions.OWL_THING_URI);
}
if (!getURI().equals(OWL2URIDefinitions.OWL_ONTOLOGY_URI) && !getURI().equals(RDFURIDefinitions.RDF_ONTOLOGY_URI)
&& !getURI().equals(RDFSURIDefinitions.RDFS_ONTOLOGY_URI)) {
// Following will not apply to RDF, RDFS and OWL ontologies
if (getOntologyLibrary().getOWLOntology() != null) {
if (!importedOntologies.contains(getOntologyLibrary().getOWLOntology())) {
importedOntologies.add(getOntologyLibrary().getOWLOntology());
}
THING_CONCEPT = makeThingConcept();
} else {
logger.warning("Could not find OWL ontology");
}
}
// SGU / Warning: entering hacking area !!!
// I don't know what, but i found this way to get some more classes not discovered
// by classical exploration. This is not satisfying.
// Please investigate and find the RIGHT way to browse all classes !!!
for (OWLClass aClass : new ArrayList<OWLClass>(classes.values())) {
for (Iterator<OntClass> scI = aClass.getOntResource().listSubClasses(); scI.hasNext();) {
OntClass subClass = scI.next();
// retrieveOntologyClass(subClass);
if (_classes.get(subClass) == null && isNamedResourceOfThisOntology(subClass)) {
// Only named classes will be appended)
makeNewClass(subClass);
// logger.info("Made class (3)" + ontClass.getURI());
}
}
}
logger.info("Done created all concepts, now initialize them");
for (OWLClass aClass : new ArrayList<OWLClass>(classes.values())) {
aClass.init();
}
for (OWLIndividual anIndividual : new ArrayList<OWLIndividual>(individuals.values())) {
anIndividual.init();
}
for (OWLDataProperty property : new ArrayList<OWLDataProperty>(dataProperties.values())) {
property.init();
}
for (OWLObjectProperty property : new ArrayList<OWLObjectProperty>(objectProperties.values())) {
property.init();
}
}
private void handleRedefinitionOfConceptsAndProperties() {
Set<OntClass> redefinedClasses = new HashSet<OntClass>();
Set<Individual> redefinedIndividuals = new HashSet<Individual>();
Set<ObjectProperty> redefinedObjectProperties = new HashSet<ObjectProperty>();
Set<DatatypeProperty> redefinedDatatypeProperties = new HashSet<DatatypeProperty>();
for (StmtIterator i = getOntModel().listStatements(); i.hasNext();) {
Statement s = i.nextStatement();
if (getOntModel().isInBaseModel(s)) {
// This statement was asserted in this model, so may redefine an other concept defined in imported ontologies
RDFNode object = s.getObject();
RDFNode subject = s.getSubject();
if (object.canAs(OntClass.class)) {
redefinedClasses.add(object.as(OntClass.class));
}
if (subject.canAs(OntClass.class)) {
redefinedClasses.add(subject.as(OntClass.class));
}
if (object.canAs(Individual.class)) {
redefinedIndividuals.add(object.as(Individual.class));
// System.out.println("Redefine individual as object because of statement " + s);
}
if (subject.canAs(Individual.class)) {
redefinedIndividuals.add(subject.as(Individual.class));
// System.out.println("Redefine individual as subject because of statement " + s);
}
if (object.canAs(ObjectProperty.class)) {
redefinedObjectProperties.add(object.as(ObjectProperty.class));
}
if (subject.canAs(ObjectProperty.class)) {
redefinedObjectProperties.add(subject.as(ObjectProperty.class));
}
if (object.canAs(DatatypeProperty.class)) {
redefinedDatatypeProperties.add(object.as(DatatypeProperty.class));
}
if (subject.canAs(DatatypeProperty.class)) {
redefinedDatatypeProperties.add(subject.as(DatatypeProperty.class));
}
}
}
for (OntClass ontClass : redefinedClasses) {
// Thing and Class concepts are handled differently
if (StringUtils.isNotEmpty(ontClass.getURI()) && !OWL2URIDefinitions.OWL_THING_URI.equals(ontClass.getURI())
&& !OWL2URIDefinitions.OWL_CLASS_URI.equals(ontClass.getURI())
&& !ontClass.getURI().startsWith("http://www.w3.org/2001/XMLSchema#") && getDeclaredClass(ontClass.getURI()) == null) {
redefineClass(ontClass);
}
}
// TODO
/*for (Individual individual : redefinedIndividuals) {
System.out.println("Ontology " + getURI() + ", redefine individual " + individual);
redefineIndividual(individual);
}*/
for (ObjectProperty ontProperty : redefinedObjectProperties) {
if (StringUtils.isNotEmpty(ontProperty.getURI()) && getDeclaredObjectProperty(ontProperty.getURI()) == null) {
redefineObjectProperty(ontProperty);
}
}
for (DatatypeProperty ontProperty : redefinedDatatypeProperties) {
if (StringUtils.isNotEmpty(ontProperty.getURI()) && getDeclaredDataProperty(ontProperty.getURI()) == null) {
redefineDataProperty(ontProperty);
}
}
}
@Override
protected void update() {
updateConceptsAndProperties();
}
public void updateConceptsAndProperties() {
logger.info("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% " + ontologyURI);
logger.info("Update ontology " + ontologyURI);
for (OWLClass aClass : classes.values()) {
aClass.update();
}
for (OWLIndividual anIndividual : individuals.values()) {
anIndividual.update();
}
for (OWLDataProperty property : dataProperties.values()) {
property.update();
}
for (OWLObjectProperty property : objectProperties.values()) {
property.update();
}
}
private OWLClass makeThingConcept() {
logger.fine("makeThingConcept() in ontology " + this);
OWLOntology owlOntology = getOntologyLibrary().getOWLOntology();
OWLClass thingInOWLOntology = owlOntology.getClass(OWL2URIDefinitions.OWL_THING_URI);
THING_CONCEPT = makeNewClass(thingInOWLOntology.getOntResource());
THING_CONCEPT.setOriginalDefinition(thingInOWLOntology);
return THING_CONCEPT;
}
protected OWLClass makeNewClass(OntClass ontClass) {
if (StringUtils.isNotEmpty(ontClass.getURI())) {
OWLClass aClass = new OWLClass(ontClass, this);
classes.put(ontClass.getURI(), aClass);
_classes.put(ontClass, aClass);
if (logger.isLoggable(Level.FINE)) {
logger.fine("Made new class " + ontClass.getURI() + " in " + getOntologyURI());
}
// aClass.init();
needsReordering = true;
setChanged();
notifyObservers(new OntologyClassInserted(aClass));
return aClass;
} else {
logger.warning("Unexpected null URI for " + ontClass);
return null;
}
}
protected OWLClass redefineClass(OntClass ontClass) {
OWLClass originalDefinition = getClass(ontClass.getURI());
if (originalDefinition == null) {
logger.warning("Tried to redefine " + this + " with null originalDefinition");
return null;
}
logger.info("###### REDEFINE class " + ontClass.getURI() + " originalDefinition=" + originalDefinition);
OWLClass returned = makeNewClass(ontClass);
returned.setOriginalDefinition(originalDefinition);
logger.info("Declare class " + returned.getName() + " as a redefinition of class initially asserted in "
+ originalDefinition.getOntology());
return returned;
}
protected OWLClass removeClass(OWLClass aClass) {
classes.remove(aClass.getURI());
_classes.remove(aClass.getOntResource());
needsReordering = true;
setChanged();
notifyObservers(new OntologyClassRemoved(aClass));
return aClass;
}
protected void renameClass(OWLClass object, String oldURI, String newURI) {
if (classes.get(oldURI) == object) {
classes.remove(oldURI);
classes.put(newURI, object);
} else if (classes.get(oldURI) == null) {
logger.warning("Inconsistent data in Ontology: rename invoked for non previously-existant ontology class");
classes.put(newURI, object);
} else {
logger.severe("Inconsistent data in Ontology: rename invoked while found an other class than the one renamed");
}
needsReordering = true;
setChanged();
notifyObservers(new OntologyObjectRenamed(object, oldURI, newURI));
}
protected OWLIndividual makeNewIndividual(Individual individual) {
if (StringUtils.isNotEmpty(individual.getURI())) {
OWLIndividual anIndividual = new OWLIndividual(individual, this);
individuals.put(individual.getURI(), anIndividual);
_individuals.put(individual, anIndividual);
logger.fine("Made new individual for " + anIndividual.getName() + " in " + getOntologyURI());
// anIndividual.init();
needsReordering = true;
setChanged();
notifyObservers(new OntologyIndividualInserted(anIndividual));
return anIndividual;
} else {
logger.warning("Unexpected null URI for " + individual);
return null;
}
}
protected OWLIndividual redefineIndividual(Individual individual) {
OWLIndividual originalDefinition = getIndividual(individual.getURI());
if (originalDefinition == null) {
logger.warning("Tried to redefine " + this + " with null originalDefinition");
return null;
}
OWLIndividual returned = makeNewIndividual(individual);
returned.setOriginalDefinition(originalDefinition);
logger.info("Declare individual " + returned.getName() + " as a redefinition of individual initially asserted in "
+ originalDefinition.getOntology());
return returned;
}
protected OWLIndividual removeIndividual(OWLIndividual anIndividual) {
individuals.remove(anIndividual.getURI());
_individuals.remove(anIndividual.getOntResource());
needsReordering = true;
setChanged();
notifyObservers(new OntologyIndividualRemoved(anIndividual));
return anIndividual;
}
protected void renameIndividual(OWLIndividual object, String oldURI, String newURI) {
if (individuals.get(oldURI) == object) {
individuals.remove(oldURI);
individuals.put(newURI, object);
} else if (individuals.get(oldURI) == null) {
logger.warning("Inconsistent data in Ontology: rename invoked for non previously-existant ontology individual");
individuals.put(newURI, object);
} else {
logger.severe("Inconsistent data in Ontology: rename invoked while found an other individual than the one renamed");
}
needsReordering = true;
setChanged();
notifyObservers(new OntologyObjectRenamed(object, oldURI, newURI));
}
protected OWLDataProperty makeNewDataProperty(OntProperty ontProperty) {
if (StringUtils.isNotEmpty(ontProperty.getURI())) {
OWLDataProperty property = new OWLDataProperty(ontProperty, this);
dataProperties.put(ontProperty.getURI(), property);
_dataProperties.put(ontProperty, property);
logger.fine("Made new data property for " + property.getName() + " in " + getOntologyURI());
// property.init();
needsReordering = true;
setChanged();
notifyObservers(new OntologyDataPropertyInserted(property));
return property;
} else {
logger.warning("Unexpected null URI for " + ontProperty);
return null;
}
}
protected OWLDataProperty redefineDataProperty(OntProperty ontProperty) {
OWLDataProperty originalDefinition = getDataProperty(ontProperty.getURI());
if (originalDefinition == null) {
logger.warning("Tried to redefine " + this + " with null originalDefinition");
return null;
}
OWLDataProperty returned = makeNewDataProperty(ontProperty);
returned.setOriginalDefinition(originalDefinition);
logger.info("Declare data property " + returned.getName() + " as a redefinition of data property initially asserted in "
+ originalDefinition.getOntology());
return returned;
}
protected OWLDataProperty removeDataProperty(OWLDataProperty aProperty) {
dataProperties.remove(aProperty.getURI());
_dataProperties.remove(aProperty.getOntResource());
needsReordering = true;
setChanged();
notifyObservers(new OntologyDataPropertyRemoved(aProperty));
return aProperty;
}
protected void renameDataProperty(OWLDataProperty object, String oldURI, String newURI) {
if (dataProperties.get(oldURI) == object) {
dataProperties.remove(oldURI);
dataProperties.put(newURI, object);
} else if (dataProperties.get(oldURI) == null) {
logger.warning("Inconsistent data in Ontology: rename invoked for non previously-existant ontology data property");
dataProperties.put(newURI, object);
} else {
logger.severe("Inconsistent data in Ontology: rename invoked while found an other data property than the one renamed");
}
needsReordering = true;
setChanged();
notifyObservers(new OntologyObjectRenamed(object, oldURI, newURI));
}
protected OWLObjectProperty makeNewObjectProperty(OntProperty ontProperty) {
if (StringUtils.isNotEmpty(ontProperty.getURI())) {
OWLObjectProperty property = new OWLObjectProperty(ontProperty, this);
objectProperties.put(ontProperty.getURI(), property);
_objectProperties.put(ontProperty, property);
logger.fine("Made new object property for " + property.getName() + " in " + getOntologyURI());
// property.init();
needsReordering = true;
setChanged();
notifyObservers(new OntologyObjectPropertyInserted(property));
return property;
} else {
logger.warning("Unexpected null URI for " + ontProperty);
return null;
}
}
protected OWLObjectProperty redefineObjectProperty(OntProperty ontProperty) {
OWLObjectProperty originalDefinition = getObjectProperty(ontProperty.getURI());
if (originalDefinition == null) {
logger.warning("Tried to redefine " + this + " with null originalDefinition");
return null;
}
OWLObjectProperty returned = makeNewObjectProperty(ontProperty);
returned.setOriginalDefinition(originalDefinition);
logger.info("Declare object property " + returned.getName() + " as a redefinition of object property initially asserted in "
+ originalDefinition.getOntology());
return returned;
}
protected OWLObjectProperty removeObjectProperty(OWLObjectProperty aProperty) {
objectProperties.remove(aProperty.getURI());
_objectProperties.remove(aProperty.getOntResource());
needsReordering = true;
setChanged();
notifyObservers(new OntologyObjectPropertyRemoved(aProperty));
return aProperty;
}
protected void renameObjectProperty(OWLObjectProperty object, String oldURI, String newURI) {
if (objectProperties.get(oldURI) == object) {
objectProperties.remove(oldURI);
objectProperties.put(newURI, object);
} else if (objectProperties.get(oldURI) == null) {
logger.warning("Inconsistent data in Ontology: rename invoked for non previously-existant ontology object property");
objectProperties.put(newURI, object);
} else {
logger.severe("Inconsistent data in Ontology: rename invoked while found an other object property than the one renamed");
}
needsReordering = true;
setChanged();
notifyObservers(new OntologyObjectRenamed(object, oldURI, newURI));
}
protected void renameObject(OWLObject<?> object, String oldURI, String newURI) {
if (object instanceof OWLIndividual) {
renameIndividual((OWLIndividual) object, oldURI, newURI);
} else if (object instanceof OWLClass) {
renameClass((OWLClass) object, oldURI, newURI);
} else if (object instanceof OWLDataProperty) {
renameDataProperty((OWLDataProperty) object, oldURI, newURI);
} else if (object instanceof OWLObjectProperty) {
renameObjectProperty((OWLObjectProperty) object, oldURI, newURI);
} else {
logger.warning("Unexpected object " + object);
}
}
protected OWLObject<?> retrieveOntologyObject(Resource resource) {
// First try to lookup with resource URI
if (StringUtils.isNotEmpty(resource.getURI())) {
OWLObject<?> returned = getOntologyObject(resource.getURI());
if (returned != null) {
return returned;
}
}
// Not found, may be we have to create this new concept
if (resource.canAs(OntClass.class)) {
return retrieveOntologyClass(resource.as(OntClass.class));
} else if (resource.canAs(Individual.class)) {
return retrieveOntologyIndividual(resource.as(Individual.class));
} else if (resource.canAs(ObjectProperty.class)) {
return retrieveOntologyObjectProperty(resource.as(ObjectProperty.class));
} else if (resource.canAs(DatatypeProperty.class)) {
return retrieveOntologyDataProperty(resource.as(DatatypeProperty.class));
} else {
logger.warning("Unexpected resource: " + resource);
return null;
}
}
protected OWLProperty retrieveOntologyProperty(OntProperty property) {
if (property.canAs(ObjectProperty.class)) {
return retrieveOntologyObjectProperty(property.as(ObjectProperty.class));
} else if (property.canAs(DatatypeProperty.class)) {
return retrieveOntologyDataProperty(property.as(DatatypeProperty.class));
} else {
logger.warning("Unexpected property: " + property);
return null;
}
}
protected OWLObjectProperty retrieveOntologyObjectProperty(ObjectProperty ontProperty) {
OWLObjectProperty returned = _objectProperties.get(ontProperty);
if (returned != null) {
return returned;
}
returned = makeNewObjectProperty(ontProperty);
returned.init();
return returned;
}
protected OWLDataProperty retrieveOntologyDataProperty(DatatypeProperty ontProperty) {
OWLDataProperty returned = _dataProperties.get(ontProperty);
if (returned != null) {
return returned;
}
returned = makeNewDataProperty(ontProperty);
returned.init();
return returned;
}
protected OWLIndividual retrieveOntologyIndividual(Individual individual) {
OWLIndividual returned = _individuals.get(individual);
if (returned != null) {
return returned;
}
// Special case for OWL, RDF and RDFS ontologies, don't create individuals !!!
if (!getURI().equals(OWL2URIDefinitions.OWL_ONTOLOGY_URI) && !getURI().equals(RDFURIDefinitions.RDF_ONTOLOGY_URI)
&& !getURI().equals(RDFSURIDefinitions.RDFS_ONTOLOGY_URI)) {
// Following will not apply to RDF, RDFS and OWL ontologies
if (isNamedResourceOfThisOntology(individual)) {
returned = makeNewIndividual(individual);
returned.init();
return returned;
}
}
return null;
}
protected OWLClass retrieveOntologyClass(OntClass resource) {
OWLClass returned = _classes.get(resource);
if (returned != null) {
return returned;
}
if (isNamedClass(resource) && StringUtils.isNotEmpty(resource.getURI())) {
returned = getClass(resource.getURI());
if (returned != null) {
return returned;
}
}
if (isNamedResourceOfThisOntology(resource)) {
returned = makeNewClass(resource);
returned.init();
}
else if (resource.isRestriction()) {
return retrieveRestriction(resource.asRestriction());
}
else if (resource.canAs(ComplementClass.class)) {
returned = new OWLComplementClass(resource.asComplementClass(), getOntology());
} else if (resource.canAs(UnionClass.class)) {
returned = new OWLUnionClass(resource.asUnionClass(), getOntology());
} else if (resource.canAs(IntersectionClass.class)) {
returned = new OWLIntersectionClass(resource.asIntersectionClass(), getOntology());
} else {
// logger.warning("Unexpected class: " + resource);
return null;
}
_classes.put(resource, returned);
return returned;
}
private OntologyRestrictionClass retrieveRestriction(Restriction restriction) {
OntologyRestrictionClass returned = (OntologyRestrictionClass) _classes.get(restriction);
if (returned != null) {
return returned;
}
String OWL = getFlexoOntology().getOntModel().getNsPrefixURI("owl");
Property ON_CLASS = ResourceFactory.createProperty(OWL + OntologyRestrictionClass.ON_CLASS);
Property ON_DATA_RANGE = ResourceFactory.createProperty(OWL + OntologyRestrictionClass.ON_DATA_RANGE);
Property QUALIFIED_CARDINALITY = ResourceFactory.createProperty(OWL + OntologyRestrictionClass.QUALIFIED_CARDINALITY);
Property MIN_QUALIFIED_CARDINALITY = ResourceFactory.createProperty(OWL + OntologyRestrictionClass.MIN_QUALIFIED_CARDINALITY);
Property MAX_QUALIFIED_CARDINALITY = ResourceFactory.createProperty(OWL + OntologyRestrictionClass.MAX_QUALIFIED_CARDINALITY);
if (restriction.isSomeValuesFromRestriction()) {
returned = new SomeValuesFromRestrictionClass(restriction.asSomeValuesFromRestriction(), getOntology());
} else if (restriction.isAllValuesFromRestriction()) {
returned = new AllValuesFromRestrictionClass(restriction.asAllValuesFromRestriction(), getOntology());
} else if (restriction.isHasValueRestriction()) {
returned = new HasValueRestrictionClass(restriction.asHasValueRestriction(), getOntology());
} else if (restriction.isCardinalityRestriction()) {
returned = new CardinalityRestrictionClass(restriction.asCardinalityRestriction(), getOntology());
} else if (restriction.isMinCardinalityRestriction()) {
returned = new MinCardinalityRestrictionClass(restriction.asMinCardinalityRestriction(), getOntology());
} else if (restriction.isMaxCardinalityRestriction()) {
returned = new MaxCardinalityRestrictionClass(restriction.asMaxCardinalityRestriction(), getOntology());
} else if (restriction.getProperty(ON_CLASS) != null || restriction.getProperty(ON_DATA_RANGE) != null) {
if (restriction.getProperty(QUALIFIED_CARDINALITY) != null) {
returned = new CardinalityRestrictionClass(restriction, getOntology());
} else if (restriction.getProperty(MIN_QUALIFIED_CARDINALITY) != null) {
returned = new MinCardinalityRestrictionClass(restriction, getOntology());
} else if (restriction.getProperty(MAX_QUALIFIED_CARDINALITY) != null) {
returned = new MaxCardinalityRestrictionClass(restriction, getOntology());
}
}
if (returned != null) {
_classes.put(restriction, returned);
return returned;
} else {
logger.warning("Unexpected restriction: " + restriction);
return null;
}
}
/**
* Return all classes accessible in the context of this ontology.<br>
* This means that classes are also retrieved from imported ontologies (non-strict mode)
*
* @return
*/
@Override
public List<OWLClass> getAccessibleClasses() {
List<OWLClass> returned = new ArrayList<OWLClass>();
for (OWLOntology o : getAllImportedOntologies()) {
returned.addAll(o.getClasses());
}
removeOriginalFromRedefinedObjects(returned);
return returned;
}
/**
* Return all individuals accessible in the context of this ontology.<br>
* This means that individuals are also retrieved from imported ontologies (non-strict mode)
*
* @return
*/
@Override
public List<OWLIndividual> getAccessibleIndividuals() {
List<OWLIndividual> returned = new ArrayList<OWLIndividual>();
for (OWLOntology o : getAllImportedOntologies()) {
returned.addAll(o.getIndividuals());
}
removeOriginalFromRedefinedObjects(returned);
return returned;
}
/**
* Return all object properties accessible in the context of this ontology.<br>
* This means that properties are also retrieved from imported ontologies (non-strict mode)
*
* @return
*/
@Override
public List<OWLObjectProperty> getAccessibleObjectProperties() {
List<OWLObjectProperty> returned = new ArrayList<OWLObjectProperty>();
for (OWLOntology o : getAllImportedOntologies()) {
returned.addAll(o.getObjectProperties());
}
removeOriginalFromRedefinedObjects(returned);
return returned;
}
/**
* Return all data properties accessible in the context of this ontology.<br>
* This means that properties are also retrieved from imported ontologies (non-strict mode)
*
* @return
*/
@Override
public List<OWLDataProperty> getAccessibleDataProperties() {
List<OWLDataProperty> returned = new ArrayList<OWLDataProperty>();
for (OWLOntology o : getAllImportedOntologies()) {
returned.addAll(o.getDataProperties());
}
removeOriginalFromRedefinedObjects(returned);
return returned;
}
/**
* Remove originals from redefined classes<br>
* Special case: original Thing definition is kept and redefinitions are excluded
*
* @param list
*/
private void removeOriginalFromRedefinedObjects(List<? extends OWLObject<?>> list) {
for (OWLObject c : new ArrayList<OWLObject>(list)) {
if (c.redefinesOriginalDefinition()) {
if (c instanceof OWLClass && ((OWLClass) c).isThing()) {
list.remove(c);
} else {
list.remove(c.getOriginalDefinition());
}
}
}
}
@Override
public Vector<OWLClass> getClasses() {
if (needsReordering) {
reorderConceptAndProperties();
}
return orderedClasses;
}
@Override
public Vector<OWLIndividual> getIndividuals() {
if (needsReordering) {
reorderConceptAndProperties();
}
return orderedIndividuals;
}
@Override
public Vector<OWLDataProperty> getDataProperties() {
if (needsReordering) {
reorderConceptAndProperties();
}
return orderedDataProperties;
}
@Override
public Vector<OWLObjectProperty> getObjectProperties() {
if (needsReordering) {
reorderConceptAndProperties();
}
return orderedObjectProperties;
}
private boolean needsReordering = true;
private void reorderConceptAndProperties() {
orderedClasses.clear();
for (OWLClass aClass : classes.values()) {
aClass.updateDomainsAndRanges();
orderedClasses.add(aClass);
}
Collections.sort(orderedClasses);
orderedIndividuals.clear();
for (OWLIndividual anIndividual : individuals.values()) {
anIndividual.updateDomainsAndRanges();
orderedIndividuals.add(anIndividual);
}
Collections.sort(orderedIndividuals);
orderedDataProperties.clear();
for (OWLDataProperty property : dataProperties.values()) {
property.updateDomainsAndRanges();
orderedDataProperties.add(property);
}
Collections.sort(orderedDataProperties);
orderedObjectProperties.clear();
for (OWLObjectProperty property : objectProperties.values()) {
property.updateDomainsAndRanges();
orderedObjectProperties.add(property);
}
Collections.sort(orderedObjectProperties);
needsReordering = false;
}
@Override
public boolean loadWhenUnloaded() {
if (!isLoaded && !isLoading) {
isLoading = true;
// logger.info("Perform load "+getURI());
load();
isLoading = false;
return true;
} else {
// logger.info("Skip loading"+getURI());
return false;
}
}
/* (non-Javadoc)
* @see org.openflexo.foundation.ontology.IFlexoOntology#isLoaded()
*/
@Override
public boolean isLoaded() {
return isLoaded;
}
/* (non-Javadoc)
* @see org.openflexo.foundation.ontology.IFlexoOntology#isLoading()
*/
@Override
public boolean isLoading() {
return isLoading;
}
private static void handleResource(OntResource resource, Hashtable<OntResource, String> renamedResources,
Hashtable<String, OntResource> renamedURI) {
for (StmtIterator j = resource.listProperties(); j.hasNext();) {
Statement s = j.nextStatement();
Property predicate = s.getPredicate();
if (predicate.getURI().equals("http://www.w3.org/2000/01/rdf-schema#label")) {
String baseName = s.getString();
String newName = baseName;
int k = 2;
while (renamedURI.get(newName) != null) {
System.out.println("Duplicated URI " + newName);
newName = baseName + k;
k++;
}
renamedResources.put(resource, newName);
renamedURI.put(newName, resource);
}
}
}
protected void load() {
logger.info("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% " + ontologyURI);
logger.info("Try to load ontology " + ontologyURI);
ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, _library, null);
// FIXES add strict to FALSE (XtoF)
// FIXES OPENFLEXO-39, OPENFLEXO-40, OPENFLEXO-41, OPENFLEXO-42, OPENFLEXO-43, OPENFLEXO-44
// ontModel.setStrictMode(false);
// we have a local copy of flexo concept ontology
if (alternativeLocalFile != null) {
logger.fine("Alternative local file: " + alternativeLocalFile.getAbsolutePath());
try {
ontModel.getDocumentManager().addAltEntry(ontologyURI, alternativeLocalFile.toURL().toString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
// read the source document
try {
logger.info("BEGIN Read " + ontologyURI);
ontModel.read(ontologyURI);
logger.info("END read " + ontologyURI);
} catch (Exception e) {
logger.warning("Unexpected exception while reading ontology " + ontologyURI);
logger.warning("Exception " + e.getMessage() + ". See logs for details");
e.printStackTrace();
}
isLoaded = true;
for (Object o : ontModel.listImportedOntologyURIs()) {
OWLOntology importedOnt = (OWLOntology) _library.getOntology((String) o);
logger.info("importedOnt= " + importedOnt);
if (importedOnt != null) {
importedOnt.loadWhenUnloaded();
importedOntologies.add(importedOnt);
}
}
logger.info("For " + ontologyURI + " Imported ontologies = " + getImportedOntologies());
logger.info("Loaded ontology " + ontologyURI + " search for concepts and properties");
for (FlexoOntology o : getImportedOntologies()) {
logger.info("Imported ontology: " + o);
}
createConceptsAndProperties();
logger.info("Finished loading ontology " + ontologyURI);
}
public void describe() {
DescribeClass dc = new DescribeClass();
DescribeDatatypeProperty dp = new DescribeDatatypeProperty();
for (Iterator<OntClass> i = getOntModel().listClasses(); i.hasNext();) {
dc.describeClass(System.out, i.next());
}
for (Iterator<ObjectProperty> i = getOntModel().listObjectProperties(); i.hasNext();) {
ObjectProperty property = i.next();
System.out.println("Object Property: " + property.getLocalName());
}
for (Iterator<DatatypeProperty> i = getOntModel().listDatatypeProperties(); i.hasNext();) {
dp.describeProperty(System.out, i.next());
}
}
@Override
public OWLOntology getFlexoOntology() {
return this;
}
@Override
public void setDescription(String description) {
// TODO
}
@Override
public OntResource getOntResource() {
return null;
// return ontModel.createTypedLiteral(this, XSDDatatype.XSDanyURI);
}
@Override
public Resource getResource() {
return getOntModel().createResource(getURI());
}
@Override
public void saveToFile(File aFile) {
FileOutputStream out = null;
try {
out = new FileOutputStream(aFile);
RDFWriter writer = ontModel.getWriter("RDF/XML-ABBREV");
writer.setProperty("xmlbase", getOntologyURI());
writer.write(ontModel.getBaseModel(), out, getOntologyURI());
// getOntModel().setNsPrefix("base", getOntologyURI());
// getOntModel().write(out, "RDF/XML-ABBREV", getOntologyURI()); // "RDF/XML-ABBREV"
clearIsModified(true);
logger.info("Wrote " + aFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
logger.warning("FileNotFoundException: " + e.getMessage());
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
logger.warning("IOException: " + e.getMessage());
}
}
}
@Override
public void save() throws SaveResourceException {
saveToFile(getAlternativeLocalFile());
}
@Override
public OntologyLibrary getOntologyLibrary() {
return _library;
}
@Override
public boolean isSuperConceptOf(OntologyObject concept) {
return false;
}
/**
* Return a vector of Ontology class, which correspond to all classes necessary to see all classes and individuals belonging to current
* ontology
*
* @param context
* @return
*/
@Deprecated
public Vector<OWLClass> getRootClasses() {
Vector<OWLClass> topLevelClasses = new Vector<OWLClass>();
for (OWLClass aClass : getClasses()) {
addTopLevelClass(aClass, topLevelClasses);
}
for (OWLIndividual anIndividual : getIndividuals()) {
addTopLevelClass(anIndividual, topLevelClasses);
}
return topLevelClasses;
}
@Deprecated
private static void addTopLevelClass(OWLClass aClass, Vector<OWLClass> topLevelClasses) {
// System.out.println("addTopLevelClass " + aClass + " for " + topLevelClasses);
if (aClass.getSuperClasses().size() == 0) {
if (!topLevelClasses.contains(aClass)) {
topLevelClasses.add(aClass);
}
return;
}
for (OWLClass superClass : aClass.getSuperClasses()) {
if (superClass != aClass) {
addTopLevelClass(superClass, topLevelClasses);
}
}
}
@Deprecated
private static void addTopLevelClass(OWLIndividual anIndividual, Vector<OWLClass> topLevelClasses) {
for (OWLClass superClass : anIndividual.getSuperClasses()) {
addTopLevelClass(superClass, topLevelClasses);
}
}
/**
* Return a vector of Ontology properties, which correspond to all properties necessary to see all properties belonging to current
* ontology
*
* @param context
* @return
*/
@Deprecated
public Vector<OWLProperty> getRootProperties() {
Vector<OWLProperty> topLevelProperties = new Vector<OWLProperty>();
for (OWLProperty aProperty : getObjectProperties()) {
addTopLevelProperty(aProperty, topLevelProperties);
}
for (OWLProperty aProperty : getDataProperties()) {
addTopLevelProperty(aProperty, topLevelProperties);
}
return topLevelProperties;
}
@Deprecated
private void addTopLevelProperty(OWLProperty aProperty, Vector<OWLProperty> topLevelProperties) {
if (aProperty.getSuperProperties().size() == 0) {
if (!topLevelProperties.contains(aProperty)) {
topLevelProperties.add(aProperty);
}
return;
}
for (OWLProperty superProperty : aProperty.getSuperProperties()) {
addTopLevelProperty(superProperty, topLevelProperties);
}
}
@Override
public boolean getIsReadOnly() {
return readOnly;
}
public void setIsReadOnly(boolean readOnly) {
this.readOnly = readOnly;
}
/**
* Return true if URI is valid regarding its unicity (no one other object has same URI)
*
* @param uri
* @return
*/
public boolean testValidURI(String name) {
return getOntologyLibrary().testValidURI(getURI(), name);
}
public String makeURI(String name) {
return getURI() + "#" + name;
}
public void assumeOntologyImportForReference(OWLObject<?> object) {
if (!getImportedOntologies().contains(object.getFlexoOntology())) {
logger.info("Import ontology:" + object.getFlexoOntology());
try {
importOntology(object.getFlexoOntology());
} catch (OntologyNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* Creates an new individual with specified name, and with specified type
*
* @param name
* @param type
* @return
* @throws DuplicateURIException
*/
@Override
public OWLIndividual createOntologyIndividual(String name, OntologyClass type) throws DuplicateURIException {
if (type instanceof OWLClass) {
assumeOntologyImportForReference((OWLClass) type);
OntModel ontModel = getOntModel();
String uri = makeURI(name);
if (testValidURI(name)) {
Individual individual = ontModel.createIndividual(uri, ((OWLClass) type).getOntResource());
OWLIndividual returned = makeNewIndividual(individual);
returned.init();
return returned;
} else {
throw new DuplicateURIException(uri);
}
}
logger.warning("Type is not an OWLClass");
return null;
}
/**
* Creates a new class with specified name, and with specified superClass
*
* @param name
* @param father
* @return
* @throws DuplicateURIException
*/
@Override
public OWLClass createOntologyClass(String name) throws DuplicateURIException {
return createOntologyClass(name, null);
}
/**
* Creates a new class with specified name, and with specified superClass
*
* @param name
* @param father
* @return
* @throws DuplicateURIException
*/
@Override
public OWLClass createOntologyClass(String name, OntologyClass father) throws DuplicateURIException {
if (father instanceof OWLClass) {
assumeOntologyImportForReference((OWLClass) father);
OntModel ontModel = getOntModel();
String uri = makeURI(name);
if (testValidURI(name)) {
OntClass aClass = ontModel.createClass(uri);
if (father != null) {
aClass.addSuperClass(((OWLClass) father).getOntResource());
}
OWLClass returned = makeNewClass(aClass);
returned.init();
return returned;
} else {
throw new DuplicateURIException(uri);
}
}
logger.warning("Type is not an OWLClass");
return null;
}
/**
* Creates an new data property with specified name, super property, domain and range
*
* @param name
* @param father
* @return
* @throws DuplicateURIException
*/
@Override
public OntologyObjectProperty createObjectProperty(String name, OntologyObjectProperty superProperty, OntologyClass domain,
OntologyClass range) throws DuplicateURIException {
// TODO implement this
logger.warning("createObjectProperty() not implemented yet");
return null;
}
/**
* Creates an new data property with specified name, super property, domain and datatype
*
* @param name
* @param father
* @return
* @throws DuplicateURIException
*/
@Override
public OntologyDataProperty createDataProperty(String name, OntologyDataProperty superProperty, OntologyClass domain,
OntologicDataType dataType) throws DuplicateURIException {
// TODO implement this
logger.warning("createDataProperty() not implemented yet");
return null;
}
public OntologyRestrictionClass createRestriction(OWLClass subjectClass, OWLProperty property,
OntologyRestrictionClass.RestrictionType type, int cardinality, OWLClass objectClass) {
if (subjectClass != null) {
assumeOntologyImportForReference(subjectClass);
}
if (objectClass != null) {
assumeOntologyImportForReference(objectClass);
}
if (property != null) {
assumeOntologyImportForReference(property);
}
OntModel ontModel = getOntModel();
Restriction restriction = null;
String OWL = getFlexoOntology().getOntModel().getNsPrefixURI("owl");
Property ON_CLASS = ResourceFactory.createProperty(OWL + "onClass");
switch (type) {
case Some:
restriction = ontModel.createSomeValuesFromRestriction(null, property.getOntProperty(), objectClass.getOntResource());
break;
case Only:
restriction = ontModel.createAllValuesFromRestriction(null, property.getOntProperty(), objectClass.getOntResource());
break;
case Exact:
Property QUALIFIED_CARDINALITY = ResourceFactory.createProperty(OWL + "qualifiedCardinality");
restriction = ontModel.createRestriction(property.getOntProperty());
restriction.addProperty(ON_CLASS, objectClass.getOntResource());
restriction.addLiteral(QUALIFIED_CARDINALITY, cardinality);
break;
case Min:
Property MIN_QUALIFIED_CARDINALITY = ResourceFactory.createProperty(OWL + "minQualifiedCardinality");
restriction = ontModel.createRestriction(property.getOntProperty());
restriction.addProperty(ON_CLASS, objectClass.getOntResource());
restriction.addLiteral(MIN_QUALIFIED_CARDINALITY, cardinality);
break;
case Max:
Property MAX_QUALIFIED_CARDINALITY = ResourceFactory.createProperty(OWL + "maxQualifiedCardinality");
restriction = ontModel.createRestriction(property.getOntProperty());
restriction.addProperty(ON_CLASS, objectClass.getOntResource());
restriction.addLiteral(MAX_QUALIFIED_CARDINALITY, cardinality);
break;
default:
break;
}
if (restriction != null) {
return getOntology().retrieveRestriction(restriction);
}
setIsModified();
logger.warning("Could not create restriction for " + property.getURI());
return null;
}
public OntologyClass newOntologyClass(FlexoEditor editor) {
CreateOntologyClass action = CreateOntologyClass.actionType.makeNewAction(this, null, editor).doAction();
return action.getNewClass();
}
public OntologyIndividual newOntologyIndividual(FlexoEditor editor) {
CreateOntologyIndividual action = CreateOntologyIndividual.actionType.makeNewAction(this, null, editor).doAction();
return action.getNewIndividual();
}
public OntologyObjectProperty newOntologyObjectProperty(FlexoEditor editor) {
CreateObjectProperty action = CreateObjectProperty.actionType.makeNewAction(this, null, editor).doAction();
return action.getNewProperty();
}
public OntologyDataProperty newCreateDataProperty(FlexoEditor editor) {
CreateDataProperty action = CreateDataProperty.actionType.makeNewAction(this, null, editor).doAction();
return action.getNewProperty();
}
public OWLObject<?> deleteOntologyObject(OWLObject<?> o, FlexoEditor editor) {
DeleteOntologyObjects.actionType.makeNewAction(o, null, editor).doAction();
return o;
}
@Override
public boolean isOntology() {
return true;
}
/**
* Retrieve an ontology object from its URI, in the context of current ontology.<br>
* The current ontology defines the scope, in which to lookup returned object. This method does NOT try to lookup object from other
* ontologies. If you want to do this, try using method in OntologyLibrary.
*
* @param objectURI
* @return
*/
@Override
public OWLObject<?> getOntologyObject(String objectURI) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("retrieve OntologyObject " + objectURI);
}
if (objectURI == null) {
return null;
}
if (objectURI.endsWith("#")) {
String potentialOntologyURI = objectURI.substring(0, objectURI.lastIndexOf("#"));
OWLOntology returned = (OWLOntology) getOntologyLibrary().getOntology(ontologyURI);
if (returned != null) {
return returned;
}
}
if (objectURI.equals(getURI())) {
return this;
}
OWLObject<?> returned = null;
returned = getClass(objectURI);
if (returned != null) {
return returned;
}
returned = getIndividual(objectURI);
if (returned != null) {
return returned;
}
returned = getObjectProperty(objectURI);
if (returned != null) {
return returned;
}
returned = getDataProperty(objectURI);
if (returned != null) {
return returned;
}
// logger.warning("Cannot find OntologyObject " + objectURI);
return null;
}
@Override
public OWLClass getClass(String classURI) {
if (classURI == null) {
return null;
}
OWLClass returned = getDeclaredClass(classURI);
if (returned != null) {
return returned;
}
for (OWLOntology o : getAllImportedOntologies()) {
returned = o.getDeclaredClass(classURI);
if (returned != null) {
return returned;
}
}
return null;
}
public OWLClass getDeclaredClass(String classURI) {
if (classURI == null) {
return null;
}
return classes.get(classURI);
}
@Override
public OWLIndividual getIndividual(String individualURI) {
if (individualURI == null) {
return null;
}
OWLIndividual returned = getDeclaredIndividual(individualURI);
if (returned != null) {
return returned;
}
for (OWLOntology o : getAllImportedOntologies()) {
returned = o.getDeclaredIndividual(individualURI);
if (returned != null) {
return returned;
}
}
return null;
}
public OWLIndividual getDeclaredIndividual(String individualURI) {
if (individualURI == null) {
return null;
}
return individuals.get(individualURI);
}
@Override
public OWLObjectProperty getObjectProperty(String propertyURI) {
if (propertyURI == null) {
return null;
}
OWLObjectProperty returned = getDeclaredObjectProperty(propertyURI);
if (returned != null) {
return returned;
}
for (OWLOntology o : getAllImportedOntologies()) {
returned = o.getDeclaredObjectProperty(propertyURI);
if (returned != null) {
return returned;
}
}
return null;
}
public OWLObjectProperty getDeclaredObjectProperty(String propertyURI) {
if (propertyURI == null) {
return null;
}
return objectProperties.get(propertyURI);
}
/**
* Retrieve a data property from its URI, in the context of current ontology.<br>
* The current ontology defines the scope, in which to lookup returned object. This method does NOT try to lookup object from other
* ontologies. If you want to do this, try using method in OntologyLibrary.
*
* @param objectURI
* @return
*/
@Override
public OWLDataProperty getDataProperty(String propertyURI) {
if (propertyURI == null) {
return null;
}
OWLDataProperty returned = getDeclaredDataProperty(propertyURI);
if (returned != null) {
return returned;
}
for (OWLOntology o : getAllImportedOntologies()) {
returned = o.getDeclaredDataProperty(propertyURI);
if (returned != null) {
return returned;
}
}
return null;
}
public OWLDataProperty getDeclaredDataProperty(String propertyURI) {
if (propertyURI == null) {
return null;
}
return dataProperties.get(propertyURI);
}
@Override
public OWLProperty getProperty(String objectURI) {
OWLProperty returned = getObjectProperty(objectURI);
if (returned != null) {
return returned;
}
returned = getDataProperty(objectURI);
if (returned != null) {
return returned;
}
return null;
}
public static void main(String[] args) {
File f = new File("/Users/sylvain/Library/OpenFlexo/FlexoResourceCenter/Ontologies/www.bolton.ac.uk/Archimate_from_Ecore.owl");
String uri = findOntologyURI(f);
System.out.println("uri: " + uri);
System.out.println("uri: " + findOntologyName(f));
FlexoResourceCenter resourceCenter = LocalResourceCenterImplementation.instanciateTestLocalResourceCenterImplementation(new File(
"/Users/sylvain/Library/OpenFlexo/FlexoResourceCenter"));
resourceCenter.retrieveBaseOntologyLibrary();
// ImportedOntology o = ImportedOntology.createNewImportedOntology(uri, f, resourceCenter.retrieveBaseOntologyLibrary());
// o.load();
/*try {
o.save();
} catch (SaveResourceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
/*System.out.println("ontologies:" + o.getImportedOntologies());
System.out.println("classes:" + o.getClasses());
System.out.println("properties:" + o.getObjectProperties());*/
}
public static void main2(String[] args) {
Hashtable<OntResource, String> renamedResources = new Hashtable<OntResource, String>();
Hashtable<String, OntResource> renamedURI = new Hashtable<String, OntResource>();
OntModel ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
String ontologyURI = "file:/tmp/UML2.owl";
ontModel.read(ontologyURI);
for (Iterator<OntClass> i = ontModel.listClasses(); i.hasNext();) {
OntClass aClass = i.next();
handleResource(aClass, renamedResources, renamedURI);
}
for (Iterator<ObjectProperty> i = ontModel.listObjectProperties(); i.hasNext();) {
ObjectProperty aProperty = i.next();
handleResource(aProperty, renamedResources, renamedURI);
}
for (Iterator<DatatypeProperty> i = ontModel.listDatatypeProperties(); i.hasNext();) {
DatatypeProperty aProperty = i.next();
handleResource(aProperty, renamedResources, renamedURI);
}
for (OntResource r : renamedResources.keySet()) {
String oldURI = r.getURI();
String newURI = r.getURI().substring(0, r.getURI().indexOf("#")) + "#" + renamedResources.get(r);
System.out.println("Rename " + oldURI + " to " + newURI);
ResourceUtils.renameResource(r, newURI);
}
FileOutputStream out = null;
try {
out = new FileOutputStream(new File("/tmp/Prout.owl"));
ontModel.write(out);
logger.info("Wrote " + out);
} catch (FileNotFoundException e) {
e.printStackTrace();
logger.warning("FileNotFoundException: " + e.getMessage());
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
logger.warning("IOException: " + e.getMessage());
}
}
}
}