/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.stanbol.ontologymanager.multiplexer.clerezza.impl; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.TreeSet; import org.apache.clerezza.commons.rdf.ImmutableGraph; import org.apache.clerezza.commons.rdf.Literal; import org.apache.clerezza.commons.rdf.Graph; import org.apache.clerezza.commons.rdf.BlankNodeOrIRI; import org.apache.clerezza.commons.rdf.RDFTerm; import org.apache.clerezza.commons.rdf.Triple; import org.apache.clerezza.commons.rdf.Graph; import org.apache.clerezza.commons.rdf.IRI; import org.apache.clerezza.commons.rdf.impl.utils.simple.SimpleGraph; import org.apache.clerezza.commons.rdf.impl.utils.TripleImpl; import org.apache.clerezza.rdf.ontologies.OWL; import org.apache.clerezza.rdf.ontologies.RDF; import org.apache.stanbol.commons.indexedgraph.IndexedGraph; import org.apache.stanbol.commons.owl.util.URIUtils; import org.apache.stanbol.ontologymanager.servicesapi.collector.Lockable; import org.apache.stanbol.ontologymanager.servicesapi.collector.MissingOntologyException; import org.apache.stanbol.ontologymanager.servicesapi.collector.OntologyCollector; import org.apache.stanbol.ontologymanager.servicesapi.collector.OntologyCollectorListener; import org.apache.stanbol.ontologymanager.servicesapi.collector.OntologyCollectorModificationException; import org.apache.stanbol.ontologymanager.servicesapi.collector.UnmodifiableOntologyCollectorException; import org.apache.stanbol.ontologymanager.servicesapi.io.OntologyInputSource; import org.apache.stanbol.ontologymanager.servicesapi.io.OntologyInputSourceHandler; import org.apache.stanbol.ontologymanager.servicesapi.io.Origin; import org.apache.stanbol.ontologymanager.servicesapi.ontology.OWLExportable; import org.apache.stanbol.ontologymanager.servicesapi.ontology.OntologyProvider; import org.apache.stanbol.ontologymanager.servicesapi.util.OntologyUtils; import org.apache.stanbol.ontologymanager.sources.clerezza.GraphSource; import org.apache.stanbol.ontologymanager.sources.owlapi.RootOntologySource; import org.semanticweb.owlapi.apibinding.OWLManager; import org.semanticweb.owlapi.model.AddImport; import org.semanticweb.owlapi.model.OWLDataFactory; import org.semanticweb.owlapi.model.OWLImportsDeclaration; import org.semanticweb.owlapi.model.OWLOntology; import org.semanticweb.owlapi.model.OWLOntologyAlreadyExistsException; import org.semanticweb.owlapi.model.OWLOntologyChange; import org.semanticweb.owlapi.model.OWLOntologyCreationException; import org.semanticweb.owlapi.model.OWLOntologyID; import org.semanticweb.owlapi.model.OWLOntologyManager; import org.semanticweb.owlapi.model.OWLOntologySetProvider; import org.semanticweb.owlapi.model.RemoveImport; import org.semanticweb.owlapi.util.OWLOntologyMerger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A basic Clerezza-native implementation of an ontology collector. * * @author alexdma * */ public abstract class AbstractOntologyCollectorImpl implements OntologyCollector, Lockable, OntologyInputSourceHandler, OWLExportable { protected String _id = null; /** * How many levels back to go in the namespace+id concatenation in order to write resolvable import * statements. */ protected int backwardPathLength = 0; protected ConnectivityPolicy connectivityPolicy; private Set<OntologyCollectorListener> listeners = new HashSet<OntologyCollectorListener>(); /** * Indicates whether this ontology space is marked as read-only. Default value is false. */ protected volatile boolean locked = false; protected Logger log = LoggerFactory.getLogger(getClass()); /** * The identifier of the ontologies directly managed by this collector (i.e. that were directly added to * this space, hence not including those just pulled in via import statements).<br> * <br> * XXX depending on whether we want to support multiple versionIRIs in the same collector, we may want to * turn this one into a set of {@link OWLOntologyID}. */ protected Set<OWLOntologyID> managedOntologies; protected org.semanticweb.owlapi.model.IRI namespace = null; protected OntologyProvider<?> ontologyProvider; protected Set<Class<?>> supportedTypes; public AbstractOntologyCollectorImpl(String id, org.semanticweb.owlapi.model.IRI namespace, OntologyProvider<?> ontologyProvider) { // Supports OWL API and Clerezza supportedTypes = new HashSet<Class<?>>(); supportedTypes.add(OWLOntology.class); supportedTypes.add(Graph.class); setID(id); setDefaultNamespace(namespace); this.ontologyProvider = ontologyProvider; this.managedOntologies = new HashSet<OWLOntologyID>(); } @Override public synchronized OWLOntologyID addOntology(OntologyInputSource<?> ontologySource) throws UnmodifiableOntologyCollectorException { // Check for error conditions. if (locked) throw new UnmodifiableOntologyCollectorException(this); if (ontologySource == null) throw new IllegalArgumentException("Ontology source cannot be null."); log.debug("Adding ontology to collector {}", getID()); OWLOntologyID key = null; if (ontologySource.hasRootOntology()) { long before = System.currentTimeMillis(); Object o = ontologySource.getRootOntology(); // // FIXME restore ownership management, but maybe not by directly setting the versionIRI // if (ontologyProvider.hasOntology(id.getOntologyIRI())) if (o instanceof Graph) // claimOwnership((Graph) o); // else if (o instanceof OWLOntology) claimOwnership((OWLOntology) o); // Check the origin anyhow, as it may be useful for setting aliases with physical locations etc. if (ontologySource.hasOrigin()) key = ontologyProvider.loadInStore(o, false, ontologySource.getOrigin()); else key = ontologyProvider.loadInStore(o, false); if (key != null) { managedOntologies.add(key); // Note that imported ontologies are not considered as managed! TODO should we change this? log.info("Add ontology completed in {} ms.", (System.currentTimeMillis() - before)); // Fire the event fireOntologyAdded(key); } } else if (ontologySource.hasOrigin()) { // Just the origin : see if it is satisfiable log.debug("Checking origin satisfiability..."); Origin<?> origin = ontologySource.getOrigin(); Object ref = origin.getReference(); log.debug("Origin wraps a {}", ref.getClass().getCanonicalName()); if (ref instanceof org.semanticweb.owlapi.model.IRI) try { log.debug("Deferring addition to physical IRI {} (if available).", ref); key = addOntology(new RootOntologySource((org.semanticweb.owlapi.model.IRI) ref)); } catch (OWLOntologyCreationException e) { throw new RuntimeException(e); } else if (ref instanceof IRI) { log.debug("Deferring addition to stored Clerezza graph {} (if available).", ref); key = addOntology(new GraphSource((IRI) ref)); } else if (ref instanceof OWLOntologyID) { OWLOntologyID idref = (OWLOntologyID) ref; log.debug("Deferring addition to stored ontology with public key {} (if available).", ref); if (!ontologyProvider.hasOntology(idref)) throw new MissingOntologyException(this, idref); key = idref; if (managedOntologies.add(idref)) fireOntologyAdded(idref); } else throw new IllegalArgumentException("Invalid origin " + origin); } else throw new IllegalArgumentException( "Ontology source must provide either an ontology object, or a way to reference one (i.e. an origin)."); log.info("Public key : {}", key); return key; } @Override public void addOntologyCollectorListener(OntologyCollectorListener listener) { listeners.add(listener); } protected void claimOwnership(OWLOntologyID publicKey) { throw new UnsupportedOperationException("Not implemented yet."); } @Override public void clearOntologyCollectorListeners() { listeners.clear(); } @Override public boolean equals(Object arg0) { if (arg0 == null) return false; if (!(arg0 instanceof OntologyCollector)) return false; if (this == arg0) return true; log.warn( "{} only implements weak equality, i.e. managed ontologies are only checked by public key, not by content.", getClass()); OntologyCollector coll = (OntologyCollector) arg0; return this.getID().equals(coll.getID()) && this.getDefaultNamespace().equals(coll.getDefaultNamespace()) && this.listManagedOntologies().equals(coll.listManagedOntologies()) && this.getSupportedOntologyTypes().equals(coll.getSupportedOntologyTypes()); } @Override public <O> O export(Class<O> returnType, boolean merge) { return export(returnType, merge, getDefaultNamespace()); } @SuppressWarnings("unchecked") @Override public <O> O export(Class<O> returnType, boolean merge, org.semanticweb.owlapi.model.IRI universalPrefix) { if (OWLOntology.class.isAssignableFrom(returnType)) { return (O) exportToOWLOntology(merge, universalPrefix); } if (Graph.class.isAssignableFrom(returnType)) { Graph root = exportToGraph(merge, universalPrefix); // A Clerezza graph has to be cast properly. if (returnType == ImmutableGraph.class) root = ((Graph) root).getImmutableGraph(); else if (returnType == Graph.class) {} return (O) root; } throw new UnsupportedOperationException("Cannot export ontology collector " + getID() + " to a " + returnType); } /** * This method has no conversion calls, to it can be invoked by subclasses that wish to modify it * afterwards. * * @param merge * @return */ protected Graph exportToGraph(boolean merge, org.semanticweb.owlapi.model.IRI prefix) { // if (merge) throw new UnsupportedOperationException( // "Merge not implemented yet for Clerezza triple collections."); long before = System.currentTimeMillis(); // No need to store, give it a name, or anything. Graph root = new SimpleGraph(); IRI iri = new IRI(prefix + _id); // Add the import declarations for directly managed ontologies. if (root != null) { // Set the ontology ID root.add(new TripleImpl(iri, RDF.type, OWL.Ontology)); if (merge) { log.warn("Merging of Clerezza triple collections is only implemented one level down. Import statements will be preserved for further levels."); Iterator<Triple> it; Set<RDFTerm> importTargets = new HashSet<RDFTerm>(); for (OWLOntologyID ontologyId : managedOntologies) { ImmutableGraph g = getOntology(ontologyId, ImmutableGraph.class, false); root.addAll(g); it = g.filter(null, OWL.imports, null); while (it.hasNext()) { org.semanticweb.owlapi.model.IRI tgt; RDFTerm r = it.next().getObject(); try { if (r instanceof IRI) tgt = org.semanticweb.owlapi.model.IRI.create(((IRI) r).getUnicodeString()); else if (r instanceof Literal) tgt = org.semanticweb.owlapi.model.IRI.create(((Literal) r).getLexicalForm()); else tgt = org.semanticweb.owlapi.model.IRI.create(r.toString()); tgt = URIUtils.sanitize(tgt); importTargets.add(new IRI(tgt.toString())); } catch (Exception ex) { log.error("FAILED to obtain import target from resource {}", r); continue; } } it = g.filter(null, RDF.type, OWL.Ontology); while (it.hasNext()) { BlankNodeOrIRI ontology = it.next().getSubject(); log.debug("Removing all triples related to {} from {}", ontology, iri); Iterator<Triple> it2 = g.filter(ontology, null, null); while (it2.hasNext()) root.remove(it2.next()); } /* * Reinstate import statements, though. If imported ontologies were not merged earlier, we * are not doing it now anyway. */ for (RDFTerm target : importTargets) root.add(new TripleImpl(iri, OWL.imports, target)); } } else { String base = prefix + getID(); for (int i = 0; i < backwardPathLength; i++) base = URIUtils.upOne(URI.create(base)).toString(); base += "/"; // The key set of managedOntologies contains the ontology IRIs, not their storage keys. for (OWLOntologyID ontologyId : managedOntologies) { org.semanticweb.owlapi.model.IRI physIRI = // ontologyId.getVersionIRI() == null ? URIUtils.sanitize(IRI // .create(base + ontologyId.getOntologyIRI())) : URIUtils.sanitize(IRI // .create(base + ontologyId.getVersionIRI())); org.semanticweb.owlapi.model.IRI.create(base + OntologyUtils.encode(ontologyId)); root.add(new TripleImpl(iri, OWL.imports, new IRI(physIRI.toString()))); } } log.debug("Clerezza export of {} completed in {} ms.", getID(), System.currentTimeMillis() - before); } return root; } private Graph getMergedTc() { Graph result = new SimpleGraph(); // Takes less memory than the Indexed one for (OWLOntologyID key : listManagedOntologies()) { // TODO when implemented, switch to true. Graph managed = getOntology(key, Graph.class, false); Set<RDFTerm> exclusions = new HashSet<RDFTerm>(); Iterator<Triple> it = managed.filter(null, RDF.type, OWL.Ontology); while (it.hasNext()) exclusions.add(it.next().getSubject()); for (Triple t : managed) if (!exclusions.contains(t.getSubject())) result.add(t); } // TODO Purge property usage return result; } /** * This method has no conversion calls, to it can be invoked by subclasses that wish to modify it * afterwards. * * FIXME not merging yet FIXME not including imported ontologies unless they are merged *before* storage. * * @param merge * @return */ protected OWLOntology exportToOWLOntology(boolean merge, org.semanticweb.owlapi.model.IRI prefix) { long before = System.currentTimeMillis(); // Create a new ontology OWLOntology root; OWLOntologyManager ontologyManager = OWLManager.createOWLOntologyManager(); org.semanticweb.owlapi.model.IRI iri = org.semanticweb.owlapi.model.IRI.create(prefix + _id); try { root = ontologyManager.createOntology(iri); } catch (OWLOntologyAlreadyExistsException e) { // It should be impossible, but just in case. ontologyManager.removeOntology(ontologyManager.getOntology(iri)); try { root = ontologyManager.createOntology(iri); } catch (OWLOntologyAlreadyExistsException e1) { root = ontologyManager.getOntology(iri); } catch (OWLOntologyCreationException e1) { log.error("Failed to assemble root ontology for scope " + iri, e); root = null; } } catch (OWLOntologyCreationException e) { log.error("Failed to assemble root ontology for scope " + _id, e); root = null; } // Add the import declarations for directly managed ontologies. if (root != null) { if (merge) { final Set<OWLOntology> set = new HashSet<OWLOntology>(); log.debug("Merging {} with its imports.", root); set.add(root); for (OWLOntologyID ontologyId : managedOntologies) { log.debug("Merging {} with {}.", ontologyId, root); set.add(getOntology(ontologyId, OWLOntology.class, true)); } OWLOntologySetProvider provider = new OWLOntologySetProvider() { @Override public Set<OWLOntology> getOntologies() { return set; } }; OWLOntologyMerger merger = new OWLOntologyMerger(provider); try { root = merger.createMergedOntology(OWLManager.createOWLOntologyManager(), iri); } catch (OWLOntologyCreationException e) { log.error("Failed to merge imports for ontology " + iri, e); root = null; } } else { // Add the import declarations for directly managed ontologies. List<OWLOntologyChange> changes = new LinkedList<OWLOntologyChange>(); OWLDataFactory df = ontologyManager.getOWLDataFactory(); String base = prefix + getID(); for (int i = 0; i < backwardPathLength; i++) base = URIUtils.upOne(URI.create(base)).toString(); base += "/"; // The key set of managedOntologies contains the ontology IRIs, not their storage keys. for (OWLOntologyID ontologyId : managedOntologies) { // XXX some day the versionIRI will be the only physical reference for the ontology org.semanticweb.owlapi.model.IRI physIRI = org.semanticweb.owlapi.model.IRI.create(base + OntologyUtils.encode(ontologyId)); changes.add(new AddImport(root, df.getOWLImportsDeclaration(physIRI))); } ontologyManager.applyChanges(changes); } } log.debug("OWL export of {} completed in {} ms.", getID(), System.currentTimeMillis() - before); return root; } /** * Notifies all ontology space listeners that an ontology has been added to this space. * * @param ontologyIri * the identifier of the ontology that was added to this space. */ protected void fireOntologyAdded(OWLOntologyID ontologyId) { for (OntologyCollectorListener listener : listeners) listener.onOntologyAdded(this, ontologyId); } /** * Notifies all ontology space listeners that an ontology has been removed from this space. * * @param ontologyIri * the identifier of the ontology that was removed from this space. */ protected void fireOntologyRemoved(OWLOntologyID ontologyId) { for (OntologyCollectorListener listener : listeners) listener.onOntologyRemoved(this, ontologyId); } @Override public ConnectivityPolicy getConnectivityPolicy() { return this.connectivityPolicy; } @Override public org.semanticweb.owlapi.model.IRI getDefaultNamespace() { return this.namespace; } @Override public String getID() { return _id; } @Override public <O> Set<O> getManagedOntologies(Class<O> returnType, boolean withClosure) { if (withClosure) log.warn("Closure support not implemented yet. Will merge instead."); Set<O> ontologies = new HashSet<O>(); for (OWLOntologyID id : managedOntologies) // FIXME temporary fix is to merge instead of including closure ontologies.add(getOntology(id, returnType, withClosure)); return Collections.unmodifiableSet(ontologies); } @Override public org.semanticweb.owlapi.model.IRI getNamespace() { return getDefaultNamespace(); } @Override public <O> O getOntology(org.semanticweb.owlapi.model.IRI ontologyIri, Class<O> returnType) { return getOntology(new OWLOntologyID(ontologyIri), returnType); } @Override public <O> O getOntology(org.semanticweb.owlapi.model.IRI ontologyIri, Class<O> returnType, boolean merge) { return getOntology(new OWLOntologyID(ontologyIri), returnType, merge); } @Override public <O> O getOntology(org.semanticweb.owlapi.model.IRI ontologyIri, Class<O> returnType, boolean merge, org.semanticweb.owlapi.model.IRI universalPrefix) { return getOntology(new OWLOntologyID(ontologyIri), returnType, merge, universalPrefix); } @Override public <O> O getOntology(org.semanticweb.owlapi.model.IRI ontologyIri, Class<O> returnType, org.semanticweb.owlapi.model.IRI universalPrefix) { return getOntology(new OWLOntologyID(ontologyIri), returnType, universalPrefix); } @Override public <O> O getOntology(OWLOntologyID ontologyId, Class<O> returnType) { return getOntology(ontologyId, returnType, false); } @Override public <O> O getOntology(OWLOntologyID ontologyId, Class<O> returnType, boolean merge) { return getOntology(ontologyId, returnType, merge, getDefaultNamespace()); } @SuppressWarnings("unchecked") @Override public <O> O getOntology(OWLOntologyID ontologyId, Class<O> returnType, boolean merge, org.semanticweb.owlapi.model.IRI universalPrefix) { if (OWLOntology.class.isAssignableFrom(returnType)) return (O) getOntologyAsOWLOntology(ontologyId, merge, universalPrefix); if (Graph.class.isAssignableFrom(returnType)) { Graph root = getOntologyAsGraph(ontologyId, merge, universalPrefix); // A Clerezza graph has to be cast properly. if (returnType == ImmutableGraph.class) root = ((Graph) root).getImmutableGraph(); else if (returnType == Graph.class) {} // We don't know of other Graph subclasses: just try to cast the Graph. return (O) root; } throw new UnsupportedOperationException("Cannot export ontology collector " + getID() + " to a " + returnType); } @Override public <O> O getOntology(OWLOntologyID ontologyId, Class<O> returnType, org.semanticweb.owlapi.model.IRI universalPrefix) { return getOntology(ontologyId, returnType, false, universalPrefix); } protected Graph getOntologyAsGraph(OWLOntologyID ontologyId, boolean merge, org.semanticweb.owlapi.model.IRI universalPrefix) { if (merge) throw new UnsupportedOperationException( "Merge not implemented yet for Clerezza triple collections."); /* * TODO manage import rewrites better once the container ID is fully configurable (i.e. instead of * going upOne() add "session" or "ontology" if needed). But only do this if we keep considering * imported ontologies as *not* managed. */ // if (!merge) { // TODO Graph o = new IndexedGraph(ontologyProvider.getStoredOntology(ontologyId, Graph.class, merge)); // Now rewrite import statements // Scan import statements for each owl:Ontology instance (hopefully one). String tid = getID(); // Bit of a hack : since ontology spaces are named like {scopeid}/{core|custom}, in that particular // case we go back to {scopeid}, whereas for sessions we maintain their original id. if (backwardPathLength > 0) tid = tid.split("/")[0]; Iterator<Triple> it; List<Triple> newImports = new LinkedList<Triple>(); synchronized (o) { it = o.filter(null, OWL.imports, null); // We use this list to avoid concurrent modification exceptions. List<Triple> replaceUs = new LinkedList<Triple>(); while (it.hasNext()) replaceUs.add(it.next()); for (Triple t : replaceUs) { String s = ((IRI) (t.getObject())).getUnicodeString(); // FIXME note the different import targets in the OWLOntology and TripleColllection objects! // s = s.substring(s.indexOf("::") + 2, s.length()); boolean managed = managedOntologies.contains(org.semanticweb.owlapi.model.IRI.create(s)); IRI target = new IRI((managed ? universalPrefix + "/" + tid + "/" : URIUtils.upOne(universalPrefix) + "/") + s); o.remove(t); newImports.add(new TripleImpl(t.getSubject(), OWL.imports, target)); } } for (Triple t : newImports) o.add(t); // } // TODO else if (merge) return o; } protected OWLOntology getOntologyAsOWLOntology(OWLOntologyID ontologyId, boolean merge, org.semanticweb.owlapi.model.IRI universalPrefix) { // if (merge) throw new UnsupportedOperationException("Merge not implemented yet for OWLOntology."); // Remove the check below. It might be an unmanaged dependency (TODO remove from collector and // reintroduce check?). // if (!hasOntology(ontologyIri)) return null; OWLOntology o; o = ontologyProvider.getStoredOntology(ontologyId, OWLOntology.class, merge); if (merge) { final Set<OWLOntology> set = new HashSet<OWLOntology>(); log.debug("Merging {} with its imports, if any.", o); set.add(o); // Actually, if the provider already performed the merge, this won't happen for (OWLOntology impo : o.getImportsClosure()) { log.debug("Imported ontology {} will be merged with {}.", impo, o); set.add(impo); } OWLOntologySetProvider provider = new OWLOntologySetProvider() { @Override public Set<OWLOntology> getOntologies() { return set; } }; OWLOntologyMerger merger = new OWLOntologyMerger(provider); try { o = merger.createMergedOntology(OWLManager.createOWLOntologyManager(), ontologyId.getOntologyIRI()); } catch (OWLOntologyCreationException e) { log.error("Failed to merge imports for ontology " + ontologyId, e); // do not reassign the root ontology } } else { // Rewrite import statements List<OWLOntologyChange> changes = new ArrayList<OWLOntologyChange>(); OWLDataFactory df = OWLManager.getOWLDataFactory(); /* * TODO manage import rewrites better once the container ID is fully configurable (i.e. instead of * going upOne() add "session" or "ontology" if needed). But only do this if we keep considering * imported ontologies as *not* managed. */ for (OWLImportsDeclaration oldImp : o.getImportsDeclarations()) { changes.add(new RemoveImport(o, oldImp)); String s = oldImp.getIRI().toString(); // FIXME Ugly way to check, but we'll get through with it if (s.contains("::")) s = s.substring(s.indexOf("::") + 2, s.length()); boolean managed = managedOntologies.contains(oldImp.getIRI()); // For space, always go up at least one String tid = getID(); if (backwardPathLength > 0) tid = tid.split("/")[0]; org.semanticweb.owlapi.model.IRI target = org.semanticweb.owlapi.model.IRI.create((managed ? universalPrefix + "/" + tid + "/" : URIUtils .upOne(universalPrefix) + "/") + s); changes.add(new AddImport(o, df.getOWLImportsDeclaration(target))); } o.getOWLOntologyManager().applyChanges(changes); } return o; } @Override public Collection<OntologyCollectorListener> getOntologyCollectorListeners() { return listeners; } @Override public Set<Class<?>> getSupportedOntologyTypes() { return Collections.unmodifiableSet(supportedTypes); } @Override public boolean hasOntology(org.semanticweb.owlapi.model.IRI ontologyIri) { return hasOntology(new OWLOntologyID(ontologyIri)); } @Override public boolean hasOntology(OWLOntologyID ontologyId) { Set<OWLOntologyID> aliases = ontologyProvider.listAliases(ontologyId); if (managedOntologies.contains(ontologyId)) return true; for (OWLOntologyID alias : aliases) if (managedOntologies.contains(alias)) return true; return false; } @Override public boolean isLocked() { return locked; } @Override public Set<OWLOntologyID> listManagedOntologies() { return new TreeSet<OWLOntologyID>(managedOntologies); } @Override public void removeOntology(org.semanticweb.owlapi.model.IRI ontologyId) throws OntologyCollectorModificationException { removeOntology(new OWLOntologyID(ontologyId)); } @Override public void removeOntology(OWLOntologyID publicKey) throws OntologyCollectorModificationException { if (publicKey == null) throw new IllegalArgumentException( "Cannot remove an ontology by providing a null public key."); if (publicKey.getOntologyIRI() == null) throw new IllegalArgumentException( "Cannot remove an ontology whose public key has a null ontology IRI."); if (locked) throw new UnmodifiableOntologyCollectorException(this); Set<OWLOntologyID> aliases = ontologyProvider.listAliases(publicKey); aliases.add(publicKey); boolean removed = false; for (OWLOntologyID alias : aliases) removed |= managedOntologies.remove(alias); // Don't fire if the ontology wasn't there in the first place. if (removed) fireOntologyRemoved(publicKey); else throw new MissingOntologyException(this, publicKey); } @Override public void removeOntologyCollectorListener(OntologyCollectorListener listener) { listeners.remove(listener); } @Override public void setConnectivityPolicy(ConnectivityPolicy policy) { this.connectivityPolicy = policy; } /** * @param namespace * The OntoNet namespace that will prefix the space ID in Web references. This implementation * only allows non-null and non-empty IRIs, with no query or fragment. Hash URIs are not * allowed, slash URIs are preferred. If neither, a slash will be concatenated and a warning * will be logged. */ @Override public void setDefaultNamespace(org.semanticweb.owlapi.model.IRI namespace) { if (namespace == null) throw new IllegalArgumentException( "Stanbol ontology namespace cannot be null."); if (namespace.toURI().getQuery() != null) throw new IllegalArgumentException( "URI Query is not allowed in Stanbol ontology namespaces."); if (namespace.toURI().getFragment() != null) throw new IllegalArgumentException( "URI Fragment is not allowed in Stanbol ontology namespaces."); if (namespace.toString().endsWith("#")) throw new IllegalArgumentException( "Stanbol ontology namespaces must not end with a hash ('#') character."); if (!namespace.toString().endsWith("/")) { log.warn("Namespace {} does not end with a slash ('/') character. It be added automatically.", namespace); namespace = org.semanticweb.owlapi.model.IRI.create(namespace + "/"); } this.namespace = namespace; } protected abstract void setID(String id); @Override public void setNamespace(org.semanticweb.owlapi.model.IRI namespace) { setDefaultNamespace(namespace); } @Override public void setUp() { this.locked = true; } @Override public void tearDown() { this.locked = false; } }