/* * Copyright (c) 1998-2009, The University of Sheffield. * * This file is part of GATE (see http://gate.ac.uk/), and is free * software, licenced under the GNU Library General Public License, * Version 2, June 1991 (in the distribution as file licence.html, * and also available at http://gate.ac.uk/gate/licence.html). * * Johann Petrak 2009-08-13 * * $Id: AbstractOntologyImpl.java 11760 2009-10-24 22:20:05Z johann_p $ */ package gate.creole.ontology.impl; import gate.Gate; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.Writer; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.openrdf.model.vocabulary.XMLSchema; import gate.creole.AbstractLanguageResource; import gate.creole.ResourceData; import gate.creole.ontology.AllValuesFromRestriction; import gate.creole.ontology.AnnotationProperty; import gate.creole.ontology.AnonymousClass; import gate.creole.ontology.CardinalityRestriction; import gate.creole.ontology.DataType; import gate.creole.ontology.DatatypeProperty; import gate.creole.ontology.GateOntologyException; import gate.creole.ontology.HasValueRestriction; import gate.creole.ontology.InvalidValueException; import gate.creole.ontology.Literal; import gate.creole.ontology.MaxCardinalityRestriction; import gate.creole.ontology.MinCardinalityRestriction; import gate.creole.ontology.OBNodeID; import gate.creole.ontology.OClass; import gate.creole.ontology.OConstants; import gate.creole.ontology.OConstants.Closure; import gate.creole.ontology.OConstants.OntologyFormat; import gate.creole.ontology.OInstance; import gate.creole.ontology.OResource; import gate.creole.ontology.OURI; import gate.creole.ontology.ONodeID; import gate.creole.ontology.ObjectProperty; import gate.creole.ontology.Ontology; import gate.creole.ontology.OntologyModificationListener; import gate.creole.ontology.RDFProperty; import gate.creole.ontology.SomeValuesFromRestriction; import gate.creole.ontology.SymmetricProperty; import gate.creole.ontology.TransitiveProperty; import gate.util.ClosableIterator; import java.io.InputStream; import java.net.URISyntaxException; import gate.util.GateRuntimeException; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.InputStreamReader; import java.util.Collections; import java.util.Comparator; import java.util.Random; import org.apache.log4j.Logger; /** * This class provides implementation of most of the methods of Ontology * interface. This implementation is based on the OntologyService (a SAIL) that stores * data in repository using SESAME. * * @author Niraj Aswani * @author Johann Petrak * */ public abstract class AbstractOntologyImpl extends AbstractLanguageResource implements Ontology { /** * The ontology import URIs that were already processed for this ontology. * NOTE: this contains both the URIs from imports and the ontology URIs * from loading ontology data in order to prevent that an ontology that * was loaded gets again loaded as an import. Having an ontology loaded * both normally and as an import will cause things to break in absurd * and unpredictable ways!!! */ protected Set<String> knownImportURIs = new HashSet<String>(); protected List<OURI> loadedOntologyURIs = new ArrayList<OURI>(); /** * instance of the OntologyService */ protected OntologyService ontologyService; /** * Main URL of the ontology. This is the URL that was used to load * the first ontology data. If not known, this is null. */ protected URL ontologyURL; /** * Default Namespace */ protected String defaultNameSpace; /** * Parameter that keeps track of if the ontology is modified */ protected boolean isModified; /** * A List of ontology modification listeners */ protected transient List<OntologyModificationListener> modificationListeners; /** * Map where the key is a resource name and value is a list of resources with * that name. */ //protected Map<String, List<OResource>> resourceNamesToOResourcesMap; protected static int anonymousNodeCounter = 0; protected static String restrictionPrefix = "Restriction"; /** * This field controls whether new ontology entities will have their * label set to the entity resource name automatically. * The behavior has changed from the old to the new implementation: the * old implementation always set the label, the new implementation does * not do that for the new LRs. However, to provide better temporary backwards * compatibility, the backwards compatibility LR sets this to true and * does create the labels automatically. */ protected boolean doSetAutoLabel = false; private Logger logger; protected Random randomGenerator; /** * Constructor */ public AbstractOntologyImpl() { logger = Logger.getLogger(this.getClass().getName()); //TODO: get rid of this! //urisToOResouceMap = new HashMap<String, OResource>(); //resourceNamesToOResourcesMap = new HashMap<String, List<OResource>>(); knownImportURIs.add("http://www.w3.org/2000/01/rdf-schema"); randomGenerator = new Random(); } // TODO: why does this look if the map for the generated name is // empty? If a global counter gets incremented, should it not always be // empty since that name has never been used before? public String getAutoGeneratedRestrictionName() { anonymousNodeCounter++; String toReturn = restrictionPrefix + anonymousNodeCounter; /* OLD CODE: String toReturn = null; while(true) { anonymousNodeCounter++; toReturn = restrictionPrefix + anonymousNodeCounter; List<OResource> resources = resourceNamesToOResourcesMap.get(toReturn); if(resources == null || resources.isEmpty()) break; } * */ return toReturn; } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#cleanOntology() */ public void cleanOntology() { ontologyService.cleanOntology(); // TODO: REMOVE //urisToOResouceMap.clear(); //resourceNamesToOResourcesMap.clear(); } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getOntologyData(byte) */ public String getOntologyData(byte format) { throw new UnsupportedOperationException("Method not supported in this implementation"); } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#writeOntologyData(java.io.OutputStream, * byte) */ public void writeOntologyData(OutputStream out, byte format) { throw new UnsupportedOperationException("Method not supported in this implementation"); } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#writeOntologyData(java.io.Writer, byte) */ public void writeOntologyData(Writer out, byte format) { throw new UnsupportedOperationException("Not supported any more in this implementation"); } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getURL() */ public URL getURL() { return ontologyURL; } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#setURL(java.net.URL) */ public void setURL(URL aUrl) { this.ontologyURL = aUrl; } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#setDefaultNameSpace(gate.creole.ontology.URI) */ public void setDefaultNameSpace(String theURI) { defaultNameSpace = theURI; if(defaultNameSpace != null && !defaultNameSpace.endsWith("#") && !defaultNameSpace.endsWith("/")) { throw new GateOntologyException( "The default name space (base URI) must end with '#' or '/': "+ theURI); } } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getDefaultNameSpace() */ public String getDefaultNameSpace() { return this.defaultNameSpace; } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#setVersion(java.lang.String) */ public void setVersion(String theVersion) { ontologyService.setVersion(theVersion); } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getVersion() */ public String getVersion() { return ontologyService.getVersion(); } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#addOClass(gate.creole.ontology.URI) */ public OClass addOClass(OURI aURI, byte classType) { // TODO: save to not use map? //OResource resource = null; // = getOResourceFromMap(aURI.toString()); // if(resource != null) { return (OClass)resource; } OClass existing = this.getOClass(aURI); if(existing != null) { Utils.warning(aURI + " already exists"); return existing; } ontologyService.addClass(aURI.toString(), classType); OClass oClass = Utils.createOClass(this, ontologyService, aURI.toString(), classType); fireOntologyResourceAdded(oClass); if(doSetAutoLabel) { oClass.setLabel(aURI.getResourceName(), null); } return oClass; } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#addOClass(gate.creole.ontology.URI, * byte) */ public OClass addOClass(OURI aURI) { return addOClass(aURI, OConstants.OWL_CLASS); } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getOClass(gate.creole.ontology.URI) */ // public OClass getOClass(OURI theClassURI) { // if(ontologyService.hasClass(theClassURI.toString())) { // byte classType = // ontologyService.getClassType(theClassURI.toString()); // return Utils.createOClass(this, ontologyService, // theClassURI.toString(), classType); // } // return null; // // } public OClass getOClass(ONodeID theClassURI) { //OResource resource = getOResourceFromMap(theClassURI.toString()); //if(resource != null) { return (OClass)resource; } if(ontologyService.hasClass(theClassURI.toString())) { byte classType = ontologyService.getClassType(theClassURI.toString()); return Utils.createOClass(this, ontologyService, theClassURI.toString(), classType); } return null; } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#removeOClass(gate.creole.ontology.OClass) */ public void removeOClass(OClass theClass) { if(!containsOClass(theClass.getONodeID())) { Utils.warning("Cannot remove the class "+theClass.getONodeID().toString() + " - does not exist"); return; } String[] deletedResources = ontologyService.removeClass(theClass.getONodeID().toString(), true); fireOntologyResourcesRemoved(deletedResources); } /** * * @param theURI * @return */ //public boolean containsOClass(OURI theURI) { // return ontologyService.hasClass(theURI.toString()); //} public boolean containsOClass(ONodeID theURI) { return ontologyService.hasClass(theURI.toString()); } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#containsOClass(gate.creole.ontology.OClass) */ public boolean containsOClass(OClass theClass) { return ontologyService.hasClass(theClass.getONodeID().toString()); } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getOClasses(boolean) */ public Set<OClass> getOClasses(boolean top) { return ontologyService.getClasses(top); } public ClosableIterator<OClass> getOClassesIterator(boolean top) { return ontologyService.getClassesIterator(top); } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getDistance(gate.creole.ontology.OClass, * gate.creole.ontology.OClass) */ public int getDistance(OClass class1, OClass class2) { if(!containsOClass(class1.getONodeID())) { Utils.warning(class1.getONodeID().toString() + " does not exist"); return -1; } if(!containsOClass(class2.getONodeID())) { Utils.warning(class2.getONodeID() + " does not exist"); return -1; } int result = 0; OClass c; ArrayList<Set<OClass>> supers1 = class1.getSuperClassesVSDistance(); ArrayList<Set<OClass>> supers2 = class2.getSuperClassesVSDistance(); for(int i1 = 0; i1 < supers1.size(); i1++) { if(supers1.get(i1).contains(class2)) { result = i1 + 1; break; } } for(int i2 = 0; i2 < supers2.size(); i2++) { if(supers2.get(i2).contains(class1)) { result = i2 + 1; break; } } if(0 == result) { for(int i1 = 0; i1 < supers1.size(); i1++) { for(int i2 = 0; i2 < supers2.size(); i2++) { Set<OClass> s1 = supers1.get(i1); Set<OClass> s2 = supers2.get(i2); Iterator<OClass> i3 = s1.iterator(); while(i3.hasNext()) { c = i3.next(); if(s2.contains(c)) { result = i1 + i2 + 2; i1 = supers1.size(); i2 = supers2.size(); break; } } } } } return result; } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#addOInstance(gate.creole.ontology.URI, * gate.creole.ontology.OClass) */ public OInstance addOInstance(OURI theInstanceURI, OClass theClass) { if(!containsOClass(theClass.getONodeID())) { Utils.error(theClass.getONodeID() + " does not exist"); return null; } // TODO: how to properly not use the map here? OResource anInst = null; //getOResourceFromMap(theInstanceURI.toString()); // if(anInst != null && !(anInst instanceof OInstance)) { // Utils.error(anInst.getURI().toString() + " already exists but " // + " is not an ontology instance!"); // return null; //} /* if(anInst != null && ((OInstance)anInst).getOClasses(OConstants.TRANSITIVE_CLOSURE) .contains(theClass)) { Utils.warning(theInstanceURI.toString() + " is already registered as an instanceof " + theClass.getURI().toString()); return (OInstance)anInst; } * */ OInstance existing = getOInstance(theInstanceURI); if(existing != null) { Utils.warning("instance "+theInstanceURI+" already exists"); return existing; } ontologyService.addIndividual(theClass.getONodeID().toString(), theInstanceURI.toString()); OInstance oInst = Utils.createOInstance(this, ontologyService, theInstanceURI.toString()); fireOntologyResourceAdded(oInst); if(doSetAutoLabel) { oInst.setLabel(theInstanceURI.getResourceName(), null); } return oInst; } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#removeOInstance(gate.creole.ontology.OInstance * ) */ public void removeOInstance(OInstance theInstance) { if(!containsOInstance((OURI)theInstance.getOURI())) { Utils.warning(theInstance.getOURI() + " does not exist"); return; } String[] deletedResources = ontologyService.removeIndividual(theInstance.getOURI().toString()); System.out.println("Deleted for "+theInstance+": "+deletedResources); fireOntologyResourcesRemoved(deletedResources); } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getOInstances() */ public Set<OInstance> getOInstances() { // String[] oInsts = ontologyService.getIndividuals(); // Set<OInstance> set = new HashSet<OInstance>(); // for(int i = 0; i < oInsts.length; i++) { // set.add(Utils.createOInstance(this, this.ontologyService, // oInsts[i])); // } // return set; Set<OInstance> theInstances = new HashSet<OInstance>(); ClosableIterator<OInstance> ii = ontologyService.getInstancesIterator(null, null); while(ii.hasNext()) { OInstance i = ii.next(); //System.out.println("Adding to result: "+i); theInstances.add(i); } return theInstances; } public ClosableIterator<OInstance> getOInstancesIterator() { return ontologyService.getInstancesIterator(null, null); } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#getOInstances(gate.creole.ontology.OClass, * boolean) */ public Set<OInstance> getOInstances(OClass theClass, byte closure) { //throw new UnsupportedOperationException("Method not supported any more with these parameters"); Closure theClosure = closure == OConstants.DIRECT_CLOSURE ? Closure.DIRECT_CLOSURE : Closure.TRANSITIVE_CLOSURE; return getOInstances(theClass,theClosure); } public Set<OInstance> getOInstances(OClass theClass, Closure closure) { // String[] oInsts = // ontologyService.getIndividuals(theClass.getONodeID() // .toString(), closure); // Set<OInstance> set = new HashSet<OInstance>(); // // if(!containsOClass(theClass.getONodeID())) { // Utils.warning("GetOInstances: "+theClass.getONodeID() + " does not exist"); // return set; // } // // for(int i = 0; i < oInsts.length; i++) { // set.add(Utils.createOInstance(this, this.ontologyService, // oInsts[i])); // } // return set; Set<OInstance> theInstances = new HashSet<OInstance>(); ClosableIterator<OInstance> ii = ontologyService.getInstancesIterator(theClass.getONodeID(), closure); while(ii.hasNext()) { OInstance i = ii.next(); //System.out.println("Adding to result: "+i); theInstances.add(i); } return theInstances; } public ClosableIterator<OInstance> getOInstancesIterator(OClass theClass, Closure closure) { return ontologyService.getInstancesIterator(theClass.getONodeID(), closure); } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getOInstance(gate.creole.ontology.URI) */ // TODO: extremely bad performance, do this differnetly! public OInstance getOInstance(OURI theInstanceURI) { // // TODO: properly remove map // OResource resource = null; //= getOResourceFromMap(theInstanceURI.toString()); // //if(resource != null) return (OInstance)resource; // List<String> individuals = // Arrays.asList(ontologyService.getIndividuals()); // if(individuals.contains(theInstanceURI.toString())) { return Utils // .createOInstance(this, ontologyService, theInstanceURI // .toString()); } // return null; if(ontologyService.hasInstance(theInstanceURI, null, null)) { return Utils.createOInstance(this, ontologyService, theInstanceURI.toString()); } else { return null; } } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#containsOInstance(gate.creole.ontology.OInstance * ) */ public boolean containsOInstance(OInstance theInstance) { return containsOInstance(theInstance.getOURI()); } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#containsOInstance(gate.creole.ontology.URI) */ // TODO: !!!! extremely bad performance, do this differently! public boolean containsOInstance(OURI theInstanceURI) { // List<String> individuals = // Arrays.asList(ontologyService.getIndividuals()); // return individuals.contains(theInstanceURI.toString()); return ontologyService.hasInstance(theInstanceURI, null, null); } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#addRDFProperty(gate.creole.ontology.URI, * java.util.Set, java.util.Set) */ // TODO: this should really take a set of OClasses instead of a set of // OResources ... public RDFProperty addRDFProperty(OURI aPropertyURI, Set<OResource> domain, Set<OResource> range) { // TODO: properly remove map // OResource res = null; //= getOResourceFromMap(aPropertyURI.toString()); /* if(res != null) { if(res instanceof RDFProperty) { Utils.warning(aPropertyURI.toString() + " already exists"); return (RDFProperty)res; } else { Utils.error(aPropertyURI.toString() + " already exists but it is not an RDFProperty"); return null; } } * */ if(domain == null) { domain = new HashSet<OResource>(); } if(range == null) { range = new HashSet<OResource>(); } String[] domainURIs = new String[domain.size()]; String[] rangeURIs = new String[range.size()]; Iterator<OResource> iter = domain.iterator(); int counter = 0; while(iter.hasNext()) { domainURIs[counter] = iter.next().getONodeID().toString(); } iter = range.iterator(); counter = 0; while(iter.hasNext()) { rangeURIs[counter] = iter.next().getONodeID().toString(); } ontologyService.addRDFProperty(aPropertyURI.toString(), domainURIs, rangeURIs); RDFProperty rp = Utils.createOProperty(this, ontologyService, aPropertyURI .toString(), OConstants.RDF_PROPERTY); fireOntologyResourceAdded(rp); return rp; } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getRDFProperties() */ public Set<RDFProperty> getRDFProperties() { Property[] properties = ontologyService.getRDFProperties(); Set<RDFProperty> set = new HashSet<RDFProperty>(); for(int i = 0; i < properties.length; i++) { set.add(Utils.createOProperty( this, ontologyService, properties[i].getUri(), properties[i].getType())); } return set; } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#isRDFProperty(gate.creole.ontology.URI) */ public boolean isRDFProperty(OURI thePropertyURI) { return ontologyService.isRDFProperty(thePropertyURI .toString()); } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#addAnnotationProperty(gate.creole.ontology * .URI) */ public AnnotationProperty addAnnotationProperty(OURI aPropertyURI) { // TODO: properly remove map /* OResource res = getOResourceFromMap(aPropertyURI.toString()); if(res != null) { if(res instanceof AnnotationProperty) { Utils.warning(aPropertyURI.toString() + " already exists"); return (AnnotationProperty)res; } else { Utils.error(aPropertyURI.toString() + " already exists but it is not an AnnotationProperty"); return null; } } * */ RDFProperty exists = getProperty(aPropertyURI); if(exists != null) { if(exists instanceof DatatypeProperty) { Utils.warning(aPropertyURI.toString() + " already exists"); return (AnnotationProperty)exists; } Utils.warning(aPropertyURI.toString() + " already exists but is not an annotation property"); return null; } ontologyService.addAnnotationProperty(aPropertyURI .toString()); AnnotationProperty ap = (AnnotationProperty)Utils.createOProperty(this, ontologyService, aPropertyURI.toString(), OConstants.ANNOTATION_PROPERTY); fireOntologyResourceAdded(ap); if(doSetAutoLabel) { ap.setLabel(aPropertyURI.getResourceName(), null); } return ap; } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getAnnotationProperties() */ public Set<AnnotationProperty> getAnnotationProperties() { Property[] properties = ontologyService.getAnnotationProperties(); Set<AnnotationProperty> set = new HashSet<AnnotationProperty>(); for(int i = 0; i < properties.length; i++) { set.add((AnnotationProperty)Utils.createOProperty( this, ontologyService, properties[i].getUri(), properties[i].getType())); } return set; } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#isAnnotationProperty(gate.creole.ontology * .URI) */ public boolean isAnnotationProperty(OURI thePropertyURI) { return ontologyService.isAnnotationProperty(thePropertyURI .toString()); } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#addDatatypeProperty(gate.creole.ontology.URI, * java.util.Set, gate.creole.ontology.DataType) */ public DatatypeProperty addDatatypeProperty(OURI aPropertyURI, Set<OClass> domain, DataType aDatatype) { // TODO: properly remove map /* OResource res = getOResourceFromMap(aPropertyURI.toString()); if(res != null) { if(res instanceof DatatypeProperty) { Utils.warning(aPropertyURI.toString() + " already exists"); return (DatatypeProperty)res; } else { Utils.error(aPropertyURI.toString() + " already exists but it is not a DatatypeProperty"); return null; } } * */ if(domain == null) { domain = new HashSet<OClass>(); } RDFProperty exists = getProperty(aPropertyURI); if(exists != null) { if(exists instanceof DatatypeProperty) { Utils.warning(aPropertyURI.toString() + " already exists"); return (DatatypeProperty)exists; } Utils.warning(aPropertyURI.toString() + " already exists but is not a datatype property"); return null; } String[] domainURIs = new String[domain.size()]; Iterator<OClass> iter = domain.iterator(); int counter = 0; while(iter.hasNext()) { domainURIs[counter] = iter.next().getONodeID().toString(); } ontologyService.addDataTypeProperty(aPropertyURI.toString(), domainURIs, aDatatype.getXmlSchemaURIString()); DatatypeProperty dp = (DatatypeProperty)Utils.createOProperty(this, ontologyService, aPropertyURI.toString(), OConstants.DATATYPE_PROPERTY); fireOntologyResourceAdded(dp); if(doSetAutoLabel) { dp.setLabel(aPropertyURI.getResourceName(), null); } return dp; } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getDatatypeProperties() */ public Set<DatatypeProperty> getDatatypeProperties() { Property[] properties = ontologyService.getDatatypeProperties(); Set<DatatypeProperty> set = new HashSet<DatatypeProperty>(); for(int i = 0; i < properties.length; i++) { set.add((DatatypeProperty)Utils.createOProperty( this, ontologyService, properties[i].getUri(), properties[i].getType())); } return set; } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#isDatatypeProperty(gate.creole.ontology.URI) */ public boolean isDatatypeProperty(OURI thePropertyURI) { return ontologyService.isDatatypeProperty(thePropertyURI .toString()); } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#addObjectProperty(gate.creole.ontology.URI, * java.util.Set, java.util.Set) */ public ObjectProperty addObjectProperty(OURI aPropertyURI, Set<OClass> domain, Set<OClass> range) { // TODO: properly not use map /* OResource res = getOResourceFromMap(aPropertyURI.toString()); if(res != null) { if(res instanceof ObjectProperty) { Utils.warning(aPropertyURI.toString() + " already exists"); return (ObjectProperty)res; } else { Utils.error(aPropertyURI.toString() + " already exists but it is not an ObjectProperty"); return null; } } * */ if(domain == null) { domain = new HashSet<OClass>(); } if(range == null) { range = new HashSet<OClass>(); } RDFProperty exists = getProperty(aPropertyURI); if(exists != null) { if(exists instanceof DatatypeProperty) { Utils.warning(aPropertyURI.toString() + " already exists"); return (ObjectProperty)exists; } Utils.warning(aPropertyURI.toString() + " already exists but is not an object property"); return null; } String[] domainURIs = new String[domain.size()]; String[] rangeURIs = new String[range.size()]; Iterator<OClass> iter = domain.iterator(); int counter = 0; while(iter.hasNext()) { domainURIs[counter] = iter.next().getONodeID().toString(); counter++; } iter = range.iterator(); counter = 0; while(iter.hasNext()) { rangeURIs[counter] = iter.next().getONodeID().toString(); counter++; } ontologyService.addObjectProperty(aPropertyURI.toString(), domainURIs, rangeURIs); ObjectProperty op = (ObjectProperty)Utils.createOProperty(this, ontologyService, aPropertyURI.toString(), OConstants.OBJECT_PROPERTY); fireOntologyResourceAdded(op); if(doSetAutoLabel) { op.setLabel(aPropertyURI.getResourceName(), null); } return op; } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getObjectProperties() */ public Set<ObjectProperty> getObjectProperties() { Property[] properties = ontologyService.getObjectProperties(); Set<ObjectProperty> set = new HashSet<ObjectProperty>(); for(int i = 0; i < properties.length; i++) { set.add((ObjectProperty)Utils.createOProperty( this, ontologyService, properties[i].getUri(), properties[i].getType())); } return set; } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#isObjectProperty(gate.creole.ontology.URI) */ public boolean isObjectProperty(OURI thePropertyURI) { return ontologyService.isObjectProperty(thePropertyURI .toString()); } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#addSymmetricProperty(gate.creole.ontology * .URI, java.util.Set) */ public SymmetricProperty addSymmetricProperty(OURI aPropertyURI, Set<OClass> domainAndRange) { // TODO: properly not use map /* OResource res = getOResourceFromMap(aPropertyURI.toString()); if(res != null) { if(res instanceof SymmetricProperty) { Utils.warning(aPropertyURI.toString() + " already exists"); return (SymmetricProperty)res; } else { Utils.error(aPropertyURI.toString() + " already exists but it is not an SymmetricProperty"); return null; } } */ if(domainAndRange == null) { domainAndRange = new HashSet<OClass>(); } RDFProperty exists = getProperty(aPropertyURI); if(exists != null) { if(exists instanceof DatatypeProperty) { Utils.warning(aPropertyURI.toString() + " already exists"); return (SymmetricProperty)exists; } Utils.warning(aPropertyURI.toString() + " already exists but is not as ymmetric property"); return null; } String[] domainURIs = new String[domainAndRange.size()]; Iterator<OClass> iter = domainAndRange.iterator(); int counter = 0; while(iter.hasNext()) { domainURIs[counter] = iter.next().getONodeID().toString(); counter++; } ontologyService.addSymmetricProperty( aPropertyURI.toString(), domainURIs); SymmetricProperty sp = (SymmetricProperty)Utils.createOProperty(this, ontologyService, aPropertyURI.toString(), OConstants.SYMMETRIC_PROPERTY); fireOntologyResourceAdded(sp); if(doSetAutoLabel) { sp.setLabel(aPropertyURI.getResourceName(), null); } return sp; } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getSymmetricProperties() */ public Set<SymmetricProperty> getSymmetricProperties() { Property[] properties = ontologyService.getSymmetricProperties(); Set<SymmetricProperty> set = new HashSet<SymmetricProperty>(); for(int i = 0; i < properties.length; i++) { set.add((SymmetricProperty)Utils.createOProperty( this, ontologyService, properties[i].getUri(), properties[i].getType())); } return set; } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#isSymmetricProperty(gate.creole.ontology.URI) */ public boolean isSymmetricProperty(OURI thePropertyURI) { return ontologyService.isSymmetricProperty(thePropertyURI .toString()); } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#addTransitiveProperty(gate.creole.ontology * .URI, java.util.Set, java.util.Set) */ public TransitiveProperty addTransitiveProperty(OURI aPropertyURI, Set<OClass> domain, Set<OClass> range) { // TODO: properly remove map /* OResource res = getOResourceFromMap(aPropertyURI.toString()); if(res != null) { if(res instanceof TransitiveProperty) { Utils.warning(aPropertyURI.toString() + " already exists"); return (TransitiveProperty)res; } else { Utils.error(aPropertyURI.toString() + " already exists but it is not a TransitiveProperty"); return null; } } * */ if(domain == null) { domain = new HashSet<OClass>(); } if(range == null) { range = new HashSet<OClass>(); } RDFProperty exists = getProperty(aPropertyURI); if(exists != null) { if(exists instanceof DatatypeProperty) { Utils.warning(aPropertyURI.toString() + " already exists"); return (TransitiveProperty)exists; } Utils.warning(aPropertyURI.toString() + " already exists but is not as transitive property"); return null; } String[] domainURIs = new String[domain.size()]; String[] rangeURIs = new String[range.size()]; Iterator<OClass> iter = domain.iterator(); int counter = 0; while(iter.hasNext()) { domainURIs[counter] = iter.next().getONodeID().toString(); counter++; } iter = range.iterator(); counter = 0; while(iter.hasNext()) { rangeURIs[counter] = iter.next().getONodeID().toString(); counter++; } ontologyService.addTransitiveProperty(aPropertyURI .toString(), domainURIs, rangeURIs); TransitiveProperty tp = (TransitiveProperty)Utils.createOProperty(this, ontologyService, aPropertyURI.toString(), OConstants.TRANSITIVE_PROPERTY); fireOntologyResourceAdded(tp); if(doSetAutoLabel) { tp.setLabel(aPropertyURI.getResourceName(), null); } return tp; } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getTransitiveProperties() */ public Set<TransitiveProperty> getTransitiveProperties() { Property[] properties = ontologyService.getTransitiveProperties(); Set<TransitiveProperty> set = new HashSet<TransitiveProperty>(); for(int i = 0; i < properties.length; i++) { set.add((TransitiveProperty)Utils.createOProperty( this, ontologyService, properties[i].getUri(), properties[i].getType())); } return set; } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#isTransitiveProperty(gate.creole.ontology * .URI) */ public boolean isTransitiveProperty(OURI thePropertyURI) { return ontologyService.isTransitiveProperty(thePropertyURI .toString()); } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getPropertyDefinitions() */ public Set<RDFProperty> getPropertyDefinitions() { Set<RDFProperty> set = new HashSet<RDFProperty>(); set.addAll(getAnnotationProperties()); set.addAll(getDatatypeProperties()); set.addAll(getObjectProperties()); set.addAll(getRDFProperties()); return set; } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getProperty(gate.creole.ontology.URI) */ public RDFProperty getProperty(OURI thePropertyURI) { Property property = ontologyService.getPropertyFromOntology(thePropertyURI .toString()); if(property == null) return null; return Utils.createOProperty(this, ontologyService, thePropertyURI.toString(), property.getType()); } public AnnotationProperty getAnnotationProperty(OURI theURI) { if(ontologyService.isAnnotationProperty(theURI.toString())) { return (AnnotationProperty) Utils.createOProperty(this,ontologyService, theURI.toString(), OConstants.ANNOTATION_PROPERTY); } else { return null; } } public DatatypeProperty getDatatypeProperty(OURI theURI) { if(ontologyService.isDatatypeProperty(theURI.toString())) { return (DatatypeProperty) Utils.createOProperty(this,ontologyService, theURI.toString(), OConstants.DATATYPE_PROPERTY); } else { return null; } } public ObjectProperty getObjectProperty(OURI theURI) { if(ontologyService.isObjectProperty(theURI.toString())) { return (ObjectProperty) Utils.createOProperty(this,ontologyService, theURI.toString(), OConstants.OBJECT_PROPERTY); } else { return null; } } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#removeProperty(gate.creole.ontology.RDFProperty * ) */ public void removeProperty(RDFProperty theProperty) { // TODO: properly remove map /* OResource res = getOResourceFromMap(theProperty.getURI().toString()); if(res == null) { Utils.warning(theProperty.getURI().toString() + " does not exist"); return; } * */ String[] deletedResources = ontologyService.removePropertyFromOntology(theProperty .getOURI().toString(), true); fireOntologyResourcesRemoved(deletedResources); } /** * Adds a new MinCardinality Restriction to the ontology. It automatically * creates a randon anonymous class, which it uses to denote the restriction. * The default datatype is set to NonNegativeIntegerNumber * * @param onProperty * - Specifies the property for which the restriction is being set. * @param minCardinalityValue * - generally a numeric number. * @return * @throws InvalidValueException * - if a value is not compatible with the nonNegativeIntegerNumber * datatype. */ public MinCardinalityRestriction addMinCardinalityRestriction( RDFProperty onProperty, String minCardinalityValue) throws InvalidValueException { String restId = getAutoGeneratedRestrictionName(); DataType datatype = OntologyUtilities.getDataType(XMLSchema.NON_NEGATIVE_INTEGER.toString()); ontologyService.addClass(restId, OConstants.MIN_CARDINALITY_RESTRICTION); ontologyService.setOnPropertyValue(restId, onProperty .getOURI().toString()); if(!datatype.isValidValue(minCardinalityValue)) { throw new InvalidValueException(minCardinalityValue + " is not valid for datatype " + datatype.getXmlSchemaURIString()); } ontologyService.setPropertyValue(restId, OConstants.MIN_CARDINALITY_RESTRICTION, minCardinalityValue, datatype .getXmlSchemaURIString()); MinCardinalityRestriction mcr = (MinCardinalityRestriction)Utils.createOClass( this, ontologyService, restId, OConstants.MIN_CARDINALITY_RESTRICTION); fireOntologyResourceAdded(mcr); return mcr; } /** * Adds a new MaxCardinality Restriction to the ontology. It automatically * creates a randon anonymous class, which it uses to denote the restriction. * The default datatype is set to NonNegativeIntegerNumber * * @param onProperty * - Specifies the property for which the restriction is being set. * @param maxCardinalityValue * - generally a numeric number. * @return * @throws InvalidValueException * - if a value is not compatible with the nonNegativeIntegerNumber * datatype. */ public MaxCardinalityRestriction addMaxCardinalityRestriction( RDFProperty onProperty, String maxCardinalityValue) throws InvalidValueException { String restId = getAutoGeneratedRestrictionName(); DataType datatype = OntologyUtilities.getDataType(XMLSchema.NON_NEGATIVE_INTEGER.toString()); ontologyService.addClass(restId, OConstants.MAX_CARDINALITY_RESTRICTION); ontologyService.setOnPropertyValue(restId, onProperty .getOURI().toString()); if(!datatype.isValidValue(maxCardinalityValue)) { throw new InvalidValueException(maxCardinalityValue + " is not valid for datatype " + datatype.getXmlSchemaURIString()); } ontologyService.setPropertyValue(restId, OConstants.MAX_CARDINALITY_RESTRICTION, maxCardinalityValue, datatype .getXmlSchemaURIString()); MaxCardinalityRestriction mcr = (MaxCardinalityRestriction)Utils.createOClass( this, ontologyService, restId, OConstants.MAX_CARDINALITY_RESTRICTION); fireOntologyResourceAdded(mcr); return mcr; } /** * Adds a new Cardinality Restriction to the ontology. It automatically * creates a randon anonymous class, which it uses to denote the restriction. * The default datatype is set to NonNegativeIntegerNumber * * @param onProperty * - Specifies the property for which the restriction is being set. * @param cardinalityValue * - generally a numeric number. * @return * @throws InvalidValueException * - if a value is not compatible with the nonNegativeIntegerNumber * datatype. */ public CardinalityRestriction addCardinalityRestriction( RDFProperty onProperty, String cardinalityValue) throws InvalidValueException { String restId = getAutoGeneratedRestrictionName(); DataType datatype = OntologyUtilities.getDataType(XMLSchema.NON_NEGATIVE_INTEGER.toString()); ontologyService.addClass(restId, OConstants.CARDINALITY_RESTRICTION); ontologyService.setOnPropertyValue(restId, onProperty .getOURI().toString()); if(!datatype.isValidValue(cardinalityValue)) throw new InvalidValueException(cardinalityValue + " is not valid for datatype " + datatype.getXmlSchemaURIString()); ontologyService.setPropertyValue(restId, OConstants.CARDINALITY_RESTRICTION, cardinalityValue, datatype .getXmlSchemaURIString()); CardinalityRestriction cr = (CardinalityRestriction)Utils.createOClass(this, ontologyService, restId, OConstants.CARDINALITY_RESTRICTION); fireOntologyResourceAdded(cr); return cr; } /** * Adds a new HasValue Restriction to the ontology. It automatically creates a * randon anonymous class, which it uses to denote the restriction. * * @param onProperty * - Specifies the property for which the restriction is being set. * @param hasValue * - a resource or a literal used as a value for hasValue element of * the restriction. * @return */ public HasValueRestriction addHasValueRestriction(RDFProperty onProperty, OResource hasValue) { String restId = getAutoGeneratedRestrictionName(); ontologyService.addClass(restId, OConstants.HAS_VALUE_RESTRICTION); ontologyService.setOnPropertyValue(restId, onProperty .getOURI().toString()); String valueString = hasValue instanceof Literal ? ((Literal)hasValue).getValue() : ((OResource)hasValue).getONodeID().toString(); ontologyService.setRestrictionValue(restId, OConstants.HAS_VALUE_RESTRICTION, valueString); HasValueRestriction hvr = (HasValueRestriction)Utils.createOClass(this, ontologyService, restId, OConstants.HAS_VALUE_RESTRICTION); fireOntologyResourceAdded(hvr); return hvr; } /** * Adds a new AllValuesFrom Restriction to the ontology. It automatically * creates a randon anonymous class, which it uses to denote the restriction. * * @param onProperty * - Specifies the property for which the restriction is being set. * @param hasValue * - a resource used as a value for hasValue element of the * restriction. * @return */ public AllValuesFromRestriction addAllValuesFromRestriction( RDFProperty onProperty, OResource hasValue) { String restId = getAutoGeneratedRestrictionName(); ontologyService.addClass(restId, OConstants.ALL_VALUES_FROM_RESTRICTION); ontologyService.setOnPropertyValue(restId, onProperty .getOURI().toString()); ontologyService.setRestrictionValue(restId, OConstants.ALL_VALUES_FROM_RESTRICTION, hasValue.getONodeID().toString()); AllValuesFromRestriction avfr = (AllValuesFromRestriction)Utils.createOClass( this, ontologyService, restId, OConstants.ALL_VALUES_FROM_RESTRICTION); fireOntologyResourceAdded(avfr); return avfr; } public AllValuesFromRestriction addAllValuesFromRestriction( ObjectProperty onProperty, OClass hasValue) { String restId = getAutoGeneratedRestrictionName(); ontologyService.addClass(restId, OConstants.ALL_VALUES_FROM_RESTRICTION); ontologyService.setOnPropertyValue(restId, onProperty .getOURI().toString()); ontologyService.setRestrictionValue(restId, OConstants.ALL_VALUES_FROM_RESTRICTION, hasValue.getONodeID().toString()); AllValuesFromRestriction avfr = (AllValuesFromRestriction)Utils.createOClass( this, ontologyService, restId, OConstants.ALL_VALUES_FROM_RESTRICTION); fireOntologyResourceAdded(avfr); return avfr; } /** * Adds a new AllValuesFrom Restriction to the ontology. It automatically * creates a randon anonymous class, which it uses to denote the restriction. * * @param onProperty * - Specifies the property for which the restriction is being set. * @param hasValue * - a resource used as a value for hasValue element of the * restriction. * @return */ public SomeValuesFromRestriction addSomeValuesFromRestriction( RDFProperty onProperty, OResource hasValue) { String restId = getAutoGeneratedRestrictionName(); ontologyService.addClass(restId, OConstants.SOME_VALUES_FROM_RESTRICTION); ontologyService.setOnPropertyValue(restId, onProperty .getOURI().toString()); ontologyService.setRestrictionValue(restId, OConstants.SOME_VALUES_FROM_RESTRICTION, hasValue.getONodeID().toString()); SomeValuesFromRestriction svfr = (SomeValuesFromRestriction)Utils.createOClass( this, ontologyService, restId, OConstants.SOME_VALUES_FROM_RESTRICTION); fireOntologyResourceAdded(svfr); return svfr; } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#setModified(boolean) */ public void setModified(boolean isModified) { this.isModified = isModified; } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#isModified() */ @Override public boolean isModified() { return this.isModified; } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#addOntologyModificationListener(gate.creole * .ontology.OntologyModificationListener) */ public synchronized void addOntologyModificationListener( OntologyModificationListener oml) { List<OntologyModificationListener> newListeners = new ArrayList<OntologyModificationListener>(); if(this.modificationListeners != null) { newListeners.addAll(this.modificationListeners); } newListeners.add(oml); this.modificationListeners = newListeners; } /* * (non-Javadoc) * * @see * gate.creole.ontology.Ontology#removeOntologyModificationListener(gate.creole * .ontology.OntologyModificationListener) */ public synchronized void removeOntologyModificationListener( OntologyModificationListener oml) { if(this.modificationListeners == null || !this.modificationListeners.contains(oml)) { return; } else { List<OntologyModificationListener> newListeners = new ArrayList<OntologyModificationListener>(); for(OntologyModificationListener l : this.modificationListeners) { if(l != oml) { newListeners.add(l); } } this.modificationListeners = newListeners; } } /** * A method to invoke when a resource's property value is changed * * @param resource * @param eventType */ public void fireResourcePropertyValueChanged(OResource resource, RDFProperty property, Object value, int eventType) { List<OntologyModificationListener> listeners = this.modificationListeners; if(listeners != null) { for(OntologyModificationListener l : listeners) { l.resourcePropertyValueChanged(this, resource, property, value, eventType); } } } /** * A method to invoke when a resource's property value is changed * * @param resource * @param eventType */ public void fireResourceRelationChanged(OResource resource1, OResource resource2, int eventType) { List<OntologyModificationListener> listeners = this.modificationListeners; if(listeners != null) { for(OntologyModificationListener l : listeners) { l.resourceRelationChanged(this, resource1, resource2, eventType); } } } public void fireOntologyReset() { List<OntologyModificationListener> listeners = this.modificationListeners; if(listeners != null) { for(OntologyModificationListener l : listeners) { l.ontologyReset(this); } } } /** * A Method to invoke an event for newly added ontology resource * * @param resource */ public void fireOntologyResourceAdded(OResource resource) { List<OntologyModificationListener> listeners = this.modificationListeners; if(listeners != null) { for(OntologyModificationListener l : listeners) { l.resourceAdded(this, resource); } } } /** * A Method to invoke an event for a removed ontology resource * * @param resource */ public void fireOntologyResourcesRemoved(String[] resources) { // we need to delete this resource from our maps //for(int i = 0; i < resources.length; i++) { // removeOResourceFromMap(resources[i]); //} List<OntologyModificationListener> listeners = this.modificationListeners; if(listeners != null) { for(OntologyModificationListener l : listeners) { l.resourcesRemoved(this, resources); } } } public boolean transationStarted() { throw new UnsupportedOperationException("Not supported any more in this implementation"); } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getSesameRepository() */ public Object getSesameRepository() { throw new UnsupportedOperationException("Not supported any more in this implementation"); } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getSesameRepositoryID() */ public String getSesameRepositoryID() { throw new UnsupportedOperationException("Not supported in this implementation"); } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#getOResourceFromMap(java.lang.String) */ public OResource getOResourceFromMap(String uri) { //Utils.warnDeprecation("getOResourceFromMap"); // TODO: this tries to provide a replacement without the map for // backwards compatibility but this should really be dropped entirely! OURI ouri = this.createOURI(uri); List<OResource> toReturn = new ArrayList<OResource>(); OClass c = getOClass(ouri); if(c != null) { return c; } OInstance i = getOInstance(ouri); if(i != null) { return i; } RDFProperty r = getProperty(ouri); if(r != null) { return r; } return null; //throw new UnsupportedOperationException("getResourceFromMap not supported any more"); } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#addOResourceToMap(java.lang.String, * gate.creole.ontology.OResource) */ public void addOResourceToMap(String uri, OResource resource) { throw new UnsupportedOperationException("addOResourceToMap not supported any more"); } /* * (non-Javadoc) * * @see gate.creole.ontology.Ontology#removeOResourceFromMap(java.lang.String) */ public void removeOResourceFromMap(String uri) { throw new UnsupportedOperationException("rremoveOResourceFromMap not supported any more"); } public void cleanup() { } /** * This method checks in its cache find out the URI for the given resource * name. However, doesn't guranttee that it will be able to return the URI. It * is also possible for two resources to have a same name but different name * spaces. This method returns a List containing all such URIs. * * @param resourceName * @return */ public OResource getOResourceByName(String resourceName) { //System.err.println("getOResourceByName called"); //new GateOntologyException("NO USE").printStackTrace(); List<OResource> resources = getOResourcesByName(resourceName); if(resources != null) { if(resources.size() > 1) { System.err .print("Warning : there are more than one resources matching with the name " + resourceName); } if(resources.size() == 1) { return resources.get(0); } } return null; } /** * This method checks in its cache to find out the OResources for the given * resource name. It is possible for two resources to have a same name but * different name spaces. This method returns a list of resources with the * common name. Please note that deleting an instance from this list (e.g. * list.remove(int/Object)) does not delete the resource from an ontology. One * must use appropriate method from the Ontology interface to delete such * resources. * * @param resourceName * @return */ // TODO: replace by actual lookup! public List<OResource> getOResourcesByName(String resourceName) { //Utils.warnDeprecation("getOResourcesByName"); //System.err.println("getOResourcesByName called"); //new GateOntologyException("NO USE").printStackTrace(); List<OResource> toReturn = new ArrayList<OResource>(); Set<OClass> classes = getOClassesByName(resourceName); toReturn.addAll(classes); classes = null; Set<OInstance> instances = getOInstancesByName(resourceName); toReturn.addAll(instances); instances = null; Set<RDFProperty> properties = getPropertiesByName(resourceName); toReturn.addAll(properties); properties = null; //List<OResource> resources = resourceNamesToOResourcesMap.get(resourceName); //if(resources == null) { return null; } //List<OResource> toReturn = new ArrayList<OResource>(); //toReturn.addAll(resources); return toReturn; } public Set<OClass> getOClassesByName(String resourceName) { // TODO: normalize/check resourceName: quotes, spaces etc must be escaped! return ontologyService.getClassesByName(encodeResourceName(resourceName)); } public Set<OInstance> getOInstancesByName(String resourceName) { // TODO: normalize/check resourceName: quotes, spaces etc must be escaped! return ontologyService.getInstancesByName(encodeResourceName(resourceName)); } public Set<RDFProperty> getPropertiesByName(String resourceName) { // TODO: normalize/check resourceName: quotes, spaces etc must be escaped! return ontologyService.getPropertiesByName(encodeResourceName(resourceName)); } protected String encodeResourceName(String resourceName) { // TODO: replace blanks by %20, quotes, <, >, #(?), ampersand? return resourceName; } /** * This method returns a list of OResources from the ontology. Please note * that deleting an instance from this list (e.g. list.remove(int/Object)) * does not delete the resource from an ontology. One must use appropriate * method from the Ontology interface to delete such resources. * * @return */ public List<OResource> getAllResources() { //Utils.warnDeprecation("getAllResources"); // TODO: would love to make this Unsupported but at the moment // it is still used by the ontology editor. Set<OClass> cs = getOClasses(false); Set<OInstance> is = getOInstances(); Set<RDFProperty> rs = getPropertyDefinitions(); List<OResource> toReturn = new ArrayList<OResource>(); for(OClass c : cs) { toReturn.add(c); } for(OInstance i : is) { toReturn.add(i); } for(RDFProperty r : rs) { toReturn.add(r); } //Iterator<String> keys = resourceNamesToOResourcesMap.keySet().iterator(); //while(keys.hasNext()) { // toReturn.addAll(resourceNamesToOResourcesMap.get(keys.next())); //} return toReturn; //throw new UnsupportedOperationException("getAllResources not supported any more"); } /** * Tries to save the ontology at the provided File */ public void store(File newOntology) throws IOException { throw new UnsupportedOperationException("Method not supported in this implementation"); } /** * This method given a property (either an annotation or datatype), retrieves * a list of resources which have the provided literal set as a value. * * @param aProperty * @param aValue * @return */ public List<OResource> getOResourcesWith(RDFProperty aProperty, Literal aValue) { List<OResource> toReturn = new ArrayList<OResource>(); int propType = 1; if(aProperty instanceof AnnotationProperty) { propType = 1; } else if(aProperty instanceof DatatypeProperty) { propType = 2; } else { return toReturn; } // here the first thing is to obtain all the resources List<OResource> resources = getAllResources(); // and on each resource we need to check if it has the above // property set on it for(OResource aResource : resources) { switch(propType){ case 1: if(aResource.hasAnnotationPropertyWithValue( (AnnotationProperty)aProperty, aValue)) { toReturn.add(aResource); } break; case 2: if(aResource instanceof OInstance && ((OInstance)aResource).hasDatatypePropertyWithValue( (DatatypeProperty)aProperty, aValue)) { toReturn.add(aResource); } break; } } return toReturn; } /** * This method given a property (either object, transitive, symmetric or rdf), * retrieves a list of resources which have the provided resource set as a * value. * * @param aProperty * @param aValue * @return */ public List<OResource> getOResourcesWith(RDFProperty aProperty, OResource aValue) { List<OResource> toReturn = new ArrayList<OResource>(); int propType = 1; if(aProperty instanceof ObjectProperty) { propType = 1; } else if(!(aProperty instanceof DatatypeProperty)) { propType = 2; } else { return toReturn; } // here the first thing is to obtain all the resources List<OResource> resources = getAllResources(); // and on each resource we need to check if it has the above // property set on it for(OResource aResource : resources) { switch(propType){ case 1: if(aResource instanceof OInstance && aValue instanceof OInstance && ((OInstance)aResource).hasObjectPropertyWithValue( (ObjectProperty)aProperty, (OInstance)aValue)) { toReturn.add(aResource); } break; case 2: if(aResource instanceof OInstance && ((OInstance)aResource) .hasRDFPropertyWithValue(aProperty, aValue)) { toReturn.add(aResource); } break; } } return toReturn; } // NOTE: we provide an implementation for this in the sesame implementation // package that overwrites this method @Deprecated public String executeQuery(String serqlQuery) { throw new UnsupportedOperationException("Not supported in this implementation"); } public void resolveImports(Map<String, String> importMappings) { boolean haveUnresolvedImports = true; // make sure we have a map, even if empty if (importMappings == null) { importMappings = new HashMap<String, String>(); } // get the global substitution patterns from the map: everything that // starts with "*" will be replaced in any import URI that starts with // this. List<String> patterns = new ArrayList<String>(); for (String from : importMappings.keySet()) { if (from.startsWith("*")) { //System.out.println("Adding pattern: " + from); patterns.add(from.substring(1)); } } // now sort by decreasing length of the replacement patter Collections.sort(patterns, new Comparator<String>() { public int compare(String s1, String s2) { if (s1.length() == s2.length()) { return s1.compareTo(s2); } else if (s1.length() < s2.length()) { return 1; } else { return -1; } } }); // Go through all the import URIs and if we have not seen the URI yet, // load or ignore according to the map. Repeat until no more unseen // import URIs are left while (haveUnresolvedImports) { // get all the imports mentioned in the ontology repository // this includes the ones we already have processed Set<OURI> importURIs = getImportURIs(); // lets see if we find anything new to load in this iteration int loaded = 0; OUTER: for (OURI anURI : importURIs) { String URIString = anURI.toString(); // if we find an URI that we have not processed yet if (!this.knownImportURIs.contains(URIString)) { // lets see if we have a specific mapping for it if (importMappings.containsKey(URIString)) { String mapped = importMappings.get(URIString); // if the mapping contains something, try to interpret that // as an URL and load from there, otherwise do not actually // import anything if (mapped != null && // !mapped.isEmpty() - does not work in Java 1.5 (mapped.length() != 0)) { URL location; try { location = new URL(mapped); } catch (MalformedURLException ex) { throw new GateOntologyException( "Problem creating an URL from the mapping " + mapped + " for ontology import " + anURI, ex); } InputStream is; try { is = location.openStream(); } catch (IOException ex) { throw new GateOntologyException( "Problem opening the URL " + location + " from the mapping " + mapped + " for ontology import " + anURI, ex); } try { System.out.println("Loading import for " + URIString + " from " + location); readOntologyData(is, anURI.toString(), OntologyFormat.RDFXML, true); } catch (Exception ex) { throw new GateOntologyException( "Problem loading ontology from URL " + location, ex); } try { is.close(); } catch (IOException ex) { throw new GateOntologyException("Problem closing the stream for URL " + location + " from the mapping " + mapped + " for ontology import " + anURI, ex); } loaded++; } else { System.out.println("Ignoring import for " + URIString); } knownImportURIs.add(anURI.toString()); continue OUTER; } // we get here only if we did not find a specific mapping // lets see if we have a pattern that matches for (String pattern : patterns) { if (URIString.startsWith(pattern)) { //System.out.println("Processing URI: " + URIString); //System.out.println("Found matching pattern: " + pattern); // substitute the pattern in the uri with the mapping, or // ignore the URI if the mapping is empty String subst = importMappings.get("*" + pattern); //System.out.println("Found replacement " + subst); if (subst.length() == 0) { knownImportURIs.add(anURI.toString()); continue OUTER; } else { // substitute the part of the URI that matches with // the replacement part knownImportURIs.add(anURI.toString()); URIString = URIString.replaceFirst("\\Q" + pattern + "\\E", subst); //System.out.println("URI String after replacement: " + URIString); anURI = createOURI(URIString); //System.out.println("Replaced, new URI is: " + anURI.toString()); } } } // no process either the original URI or the one we got after // making the substitution URL location; try { location = new URL(anURI.toString()); } catch (MalformedURLException ex) { throw new GateOntologyException( "Problem creating an URL from the ontology import URI " + anURI, ex); } InputStream is; try { is = location.openStream(); } catch (IOException ex) { throw new GateOntologyException( "Problem opening the URL " + location + " from the ontology import URI " + anURI, ex); } try { System.out.println("Loading import for " + URIString + " from " + location); readOntologyData(is, anURI.toString(), OntologyFormat.RDFXML, true); } catch (Exception ex) { throw new GateOntologyException( "Problem loading ontology from URL " + location, ex); } try { is.close(); } catch (IOException ex) { throw new GateOntologyException( "Problem closing the stream for URL " + location + " for ontology import URI " + anURI, ex); } loaded++; // remember that we have already processed this URI knownImportURIs.add(anURI.toString()); } } // if nothing was loaded, there will be no more import URIs to process if (loaded == 0) { haveUnresolvedImports = false; } } } public Set<OURI> getImportURIs() { Set<OURI> set = new HashSet<OURI>(); Set<String> ss = ontologyService.getImportURIStrings(); for (String s : ss) { OURI theOURI = createOURI(s); set.add(theOURI); //System.out.println("Converted import URI string "+s+" to OURI "+theOURI.toString()); } return set; } // TODO: maybe we implement this at a later time if it is needed and // useful, at the moment, only the first URL loaded is returned by getURL //public List<URL> getURLs(boolean includeImports) { // throw new UnsupportedOperationException("Needs to get implemented in AbstractOntologyImpl.getURLs"); //} public void startTransaction() { throw new UnsupportedOperationException("Not supported in this implementation"); } public void commitTransaction() { throw new UnsupportedOperationException("Not supported in this implementation"); } /** * Return an URL that is related to the source of the ontology. * This needs to be implemented by all implementing LRs so the factory * can determine a name based on the source of the ontology. If the ontology * is empty or the source otherwise unknown, null can be returned. * This is not part of the public ontology API but used internally by * the GATE Factory. * * @return a URL of the source of the ontology */ public abstract java.net.URL getSourceURL(); protected File pluginDir = null; public File getPluginDir() { if (pluginDir == null) { ResourceData myResourceData = Gate.getCreoleRegister().get("gate.creole.ontology.impl.sesame.OWLIMOntology"); java.net.URL creoleXml = myResourceData.getXmlFileUrl(); try { pluginDir = new File(creoleXml.toURI()).getParentFile(); } catch (URISyntaxException ex) { throw new GateRuntimeException("Problem finding plugin location", ex); } } return pluginDir; } public Map<String, String> loadImportMappingsFile(java.net.URL mappingsURL) { Map<String, String> mappings = new HashMap<String, String>(); try { // open file and read line by line, each line should have // two tab-separated strings, which will be trimmed and added // to the map InputStream is = mappingsURL.openStream(); DataInputStream dis = new DataInputStream(is); BufferedReader br = new BufferedReader(new InputStreamReader(dis)); String strLine; while ((strLine = br.readLine()) != null) { if(strLine.matches("^\\s*#.*") || strLine.matches("^\\s*$")) { continue; } String[] s = strLine.split("[\\t\\s]+", 2); if (s.length == 2) { String theMapping = s[1]; if(!theMapping.startsWith("http:") && !theMapping.startsWith("file:") && !theMapping.startsWith("/")) { String mappingsDir = mappingsURL.toString(); // remove everything after the last "/" and append the relative name mappingsDir = mappingsDir.substring(0,mappingsDir.lastIndexOf("/")); theMapping = mappingsDir+"/"+theMapping; } else if(theMapping.startsWith("/")) { String mappingsURIString = "file://"+theMapping; } mappings.put(s[0].trim(), theMapping); } else { mappings.put(strLine.trim(),""); } } is.close(); } catch (IOException ex) { throw new GateRuntimeException("Error reading mappings file ", ex); } return mappings; } // ************************* helper methods and utilities // add the ontology URI of an ontology just loaded to the known imports // this should get called by any method that LOADS an ontology and // it should find exactly one new ontology URI // If more than one URI has been found they will all get added to the known // import URIs and to the loaded ontology URIs for now ... // the method returns the new URIs actually found. protected Set<OURI> addOntologyURIs() { Set<OURI> ouris = ontologyService.getOntologyURIs(); Set<OURI> newuris = new HashSet<OURI>(); for (OURI u : ouris) { if(!loadedOntologyURIs.contains(u)) { loadedOntologyURIs.add(u); knownImportURIs.add(u.toString()); newuris.add(u); } } return newuris; } public List<OURI> getOntologyURIs() { return loadedOntologyURIs; } public AnonymousClass addAnonymousClass() { throw new UnsupportedOperationException("Still to be implemented!"); } public abstract OBNodeID createOBNodeID(String id); public List<Literal> getOntologyAnnotationValues(AnnotationProperty ann) { Set<OURI> ontouris = ontologyService.getOntologyURIs(); if(ontouris.size() != 1) { throw new GateOntologyException( "Can only get ontology annotation values if there is a single ontology uri but there are "+ ontouris.size()+": "+ontouris); } OURI ouri = ontouris.iterator().next(); PropertyValue[] propValues = ontologyService.getAnnotationPropertyValues( ouri.toString(), ann .getOURI().toString()); List<Literal> list = new ArrayList<Literal>(); for(int i = 0; i < propValues.length; i++) { Literal l = new Literal(propValues[i].getValue(), OntologyUtilities .getLocale(propValues[i].getDatatype())); list.add(l); } return list; } public void setOntologyAnnotation(AnnotationProperty ann, Literal val) { Set<OURI> ontouris = ontologyService.getOntologyURIs(); if(ontouris.size() != 1) { throw new GateOntologyException( "Can only set ontology annotation values if there is a single ontology uri but there are "+ ontouris.size()+": "+ontouris); } OURI ouri = ontouris.iterator().next(); RDFProperty res = getProperty(ann.getOURI()); if(res == null) { Utils .error(ann.getOURI().toTurtle() + " does not exist"); return; } if(!(res instanceof AnnotationProperty)) { Utils.error(ann.getOURI().toTurtle() + " is not an annotation property"); return; } ontologyService.addAnnotationPropertyValue(ouri.toString(), ann.getOURI().toString(), val.getValue(), val.getLanguage() != null ? val.getLanguage().getLanguage() : null); } public void setOntologyURI(OURI theURI) { // TODO: check if already have one or more URIs, if yes, remove them(?) Set<OURI> uris = ontologyService.getOntologyURIs(); if(uris.size() == 0) { ontologyService.setOntologyURI(theURI); } else if(uris.size() == 1) { OURI existing = uris.iterator().next(); if(existing.equals(theURI)) { throw new GateOntologyException("Ontology URI already set to "+existing.toTurtle()); } } else { throw new GateOntologyException("Ontology has already several URIS: "+uris); } } public OURI getOntologyURI() { Set<OURI> uris = ontologyService.getOntologyURIs(); if(uris.size() == 0) { return null; } else if(uris.size() == 1) { return uris.iterator().next(); } else { throw new GateOntologyException("More than one ontology URI found: "+uris); } } }