/**
* Copyright (c) 2013/2014 Verein zur Foerderung der IT-Sicherheit in Oesterreich (SBA).
* The work has been developed in the TIMBUS Project and the above-mentioned are Members of the TIMBUS Consortium.
* TIMBUS is supported by the European Union under the 7th Framework Programme for research and technological
* development and demonstration activities (FP7/2007-2013) under grant agreement no. 269940.
*
* Licensed 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, including without
* limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTIBITLY, or FITNESS FOR A PARTICULAR
* PURPOSE. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise,
* unless required by applicable law or agreed to in writing, shall any Contributor be liable for damages, including
* any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this
* License or out of the use or inability to use the Work.
* See the License for the specific language governing permissions and limitation under the License.
*/
package org.sbaresearch.owl;
import ch.lambdaj.function.convert.Converter;
import com.hp.hpl.jena.ontology.OntDocumentManager;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import net.sf.oval.constraint.NotNull;
import net.sf.oval.guard.Guarded;
import net.sf.oval.guard.Pre;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.io.*;
import org.semanticweb.owlapi.model.*;
import org.semanticweb.owlapi.util.OWLEntityRemover;
import org.semanticweb.owlapi.vocab.OWLRDFVocabulary;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.ac.manchester.cs.owl.owlapi.OWLClassImpl;
import java.io.*;
import java.util.*;
import static ch.lambdaj.Lambda.convert;
import static ch.lambdaj.Lambda.filter;
import static org.hamcrest.CoreMatchers.notNullValue;
/**
* This class wraps commonly used functions of the API to provide a simpler interface.
*
* @see <a href="http://owlapi.sourceforge.net/">The OWL API</a>
*/
@Guarded
public class OwlApiFacade {
private static final Logger LOG = LoggerFactory.getLogger(OwlApiFacade.class);
private OWLOntologyManager manager;
private OWLOntology ontology;
private OWLDataFactory dataFactory;
private OWLOntologyIRIMapper iriMapper;
/**
* Wraps an existing ontology.
*
* @param ontology An existing ontology.
*/
public OwlApiFacade(OWLOntology ontology) {
this.ontology = ontology;
this.manager = ontology.getOWLOntologyManager();
this.dataFactory = manager.getOWLDataFactory();
}
/**
* Use OWLManager.createOWLOntologyManager() and OWLManager.getOWLDataFactory()) per default.
*
* @param manager @see org.semanticweb.owlapi.model.OWLOntologyManager
* @param dataFactory @see org.semanticweb.owlapi.model.OWLDataFactory
*/
public OwlApiFacade(OWLOntologyManager manager, OWLDataFactory dataFactory) {
this.manager = manager;
this.dataFactory = dataFactory;
}
@SuppressWarnings("unused")
public OWLOntology getOntology() {
return ontology;
}
@SuppressWarnings("unused")
public OWLDataFactory getDataFactory() {
return dataFactory;
}
@SuppressWarnings("unused")
public OWLOntologyManager getManager() {
return manager;
}
public OWLOntologyIRIMapper getIriMapper() {
return iriMapper;
}
@Pre(expr = "_this.manager!=null", lang = "js")
public void setIRIMapping(final Map<String, String> iriMapping) {
iriMapper = new OWLOntologyIRIMapper() {
@Override
public IRI getDocumentIRI(IRI iri) {
if (!iriMapping.containsKey(iri.toString())) return iri;
return IRI.create(iriMapping.get(iri.toString()));
}
};
manager.addIRIMapper(iriMapper);
}
/**
* Load ontology from an URI. Does not throw exceptions if resolving any import fails.
*
* @param owlUri The ontology to load. This can be either an URL ("http://*") or local path ("file:*").
*/
@Pre(expr = "_this.manager!=null", lang = "js")
public void load(String owlUri) throws OWLOntologyCreationException {
ontology = manager.loadOntologyFromOntologyDocument(
new IRIDocumentSource(IRI.create(owlUri)),
new OWLOntologyLoaderConfiguration().setMissingImportHandlingStrategy(MissingImportHandlingStrategy.SILENT));
if (ontology.getOntologyID().getOntologyIRI() == null) {
LOG.info("Ontology IRI not found, using url...");
// manager.setOntologyDocumentIRI(ontology, IRI.create(owlUri)); // FIXME: does not seem to work @#%!$%
// FIXME: megahack to force using a valid ontology IRI...
manager = OWLManager.createOWLOntologyManager();
ontology = manager.createOntology(IRI.create(owlUri), new HashSet<OWLOntology>() {{
add(ontology);
}});
}
}
/**
* Load ontology from an URI, resolves missing imports by looking up the alternative locations mapping.
* This is useful for unpublished ontologies.
*
* @param owlUri The ontology to load. This can be either an URL ("http://*") or local path ("file:*").
* @param iriMapping The mapping of import to actual ontology locations.
* @throws OWLOntologyCreationException
* @see OwlApiFacade::load
*/
@Pre(expr = "_this.manager!=null", lang = "js")
public void load(String owlUri, final Map<String, String> iriMapping) throws OWLOntologyCreationException {
setIRIMapping(iriMapping);
load(owlUri);
}
/**
* Loads an ontology from a stream. Does not resolve missing imports but throws an exception.
*
* @param owlContent The ontology to load.
* @throws OWLOntologyCreationException
*/
@Pre(expr = "_this.manager!=null", lang = "js")
public void load(InputStream owlContent) throws OWLOntologyCreationException {
ontology = manager.loadOntologyFromOntologyDocument(owlContent);
}
/**
* Creates an empty ontology. This is useful for testing purposes.
*
* @param iri The IRI of the new ontology.
* @throws OWLOntologyCreationException
*/
@Pre(expr = "_this.manager!=null", lang = "js")
public void create(String iri) throws OWLOntologyCreationException {
ontology = manager.createOntology(IRI.create(iri));
}
/**
* Adds an individual to the ontology.
* No white spaces are allowed as individual name!
* Returns the new created individual.
*/
@Pre(expr = "_this.ontology!=null && _this.manager!=null && _this.dataFactory!=null", lang = "js")
public OWLNamedIndividual addIndividual(String name) {
OWLNamedIndividual indiv = dataFactory.getOWLNamedIndividual(createIri(name));
OWLDeclarationAxiom indivDeclaration = dataFactory.getOWLDeclarationAxiom(indiv);
manager.applyChange(new AddAxiom(ontology, indivDeclaration));
return indiv;
}
/**
* Adds an individual to the ontology that is instance of a specified class.
*
* @see #addIndividual
* @see #makeInstanceOf
*/
@Pre(expr = "_this.ontology!=null && _this.manager!=null && _this.dataFactory!=null", lang = "js")
public OWLNamedIndividual addIndividual(String indivName, String className) {
OWLNamedIndividual owlNamedIndividual = addIndividual(indivName);
makeInstanceOf(owlNamedIndividual, className);
return owlNamedIndividual;
}
/**
* Adds an individual to the ontology with its name generated using the provided label.
*
* @see #addIndividual(String, String)
*/
public OWLNamedIndividual addIndividualByLabel(String label, String className) {
String indivName = UUID.randomUUID().toString();
OWLNamedIndividual indiv = addIndividual(indivName, className);
addAnnotation(label, OWLRDFVocabulary.RDFS_LABEL, indiv);
return indiv;
}
/**
* Adds an individual to the ontology using the provided label and name.
*
* @see #addIndividual(String, String)
*/
public OWLNamedIndividual addIndividualByLabel(String label, String indivName, String className) {
OWLNamedIndividual indiv = addIndividual(indivName, className);
addAnnotation(label, OWLRDFVocabulary.RDFS_LABEL, indiv);
return indiv;
}
@Pre(expr = "_this.ontology!=null && _this.manager!=null", lang = "js")
public void removeIndividual(String indivName) throws OwlElementNotFoundException {
OWLEntityRemover remover = new OWLEntityRemover(manager, Collections.singleton(ontology));
OWLNamedIndividual indiv = getIndividual(indivName);
indiv.accept(remover);
manager.applyChanges(remover.getChanges());
}
public void addComment(OWLNamedIndividual indiv, String comment) {
addAnnotation(comment, OWLRDFVocabulary.RDFS_COMMENT, indiv);
}
public String getComment(OWLNamedIndividual indiv) throws AnnotationNotFoundException {
return getAnnotation(indiv, ontology.getOWLOntologyManager().getOWLDataFactory().getRDFSComment());
}
public String getLabel(OWLNamedIndividual indiv) throws AnnotationNotFoundException {
return getAnnotation(indiv, ontology.getOWLOntologyManager().getOWLDataFactory().getRDFSLabel());
}
public boolean hasLabel(OWLNamedIndividual indiv) {
return hasAnnotation(indiv, ontology.getOWLOntologyManager().getOWLDataFactory().getRDFSLabel());
}
public void addLabel(OWLNamedIndividual indiv, String label) {
addAnnotation(label, OWLRDFVocabulary.RDFS_LABEL, indiv);
}
public void deleteLabels(OWLNamedIndividual indiv) {
deleteAnnotations(indiv, ontology.getOWLOntologyManager().getOWLDataFactory().getRDFSLabel());
}
private boolean hasAnnotation(OWLNamedIndividual indiv, OWLAnnotationProperty property) {
for (OWLAnnotation annotation : indiv.getAnnotations(ontology)) {
if (!annotation.getProperty().equals(property)) {
continue;
}
return true;
}
for (OWLOntology o : ontology.getImports()) {
for (OWLAnnotation annotation : indiv.getAnnotations(o)) {
if (!annotation.getProperty().equals(property)) {
continue;
}
return true;
}
}
return false;
}
private String getAnnotation(OWLNamedIndividual indiv, OWLAnnotationProperty property) throws AnnotationNotFoundException {
for (OWLAnnotation annotation : indiv.getAnnotations(ontology)) {
if (!annotation.getProperty().equals(property)) {
continue;
}
return ((OWLLiteral) annotation.getValue()).getLiteral();
}
for (OWLOntology o : ontology.getImports()) {
for (OWLAnnotation annotation : indiv.getAnnotations(o)) {
if (!annotation.getProperty().equals(property)) {
continue;
}
return ((OWLLiteral) annotation.getValue()).getLiteral();
}
}
throw new AnnotationNotFoundException("No annotation found for this individual.");
}
private void deleteAnnotations(OWLNamedIndividual indiv, OWLAnnotationProperty property) {
for (OWLAnnotation annotation : indiv.getAnnotations(ontology)) {
if (!annotation.getProperty().equals(property)) {
continue;
}
ontology.getOWLOntologyManager().applyChange(new RemoveOntologyAnnotation(ontology, annotation)); // not sufficient
OWLAxiom axiom = dataFactory.getOWLAnnotationAssertionAxiom(indiv.getIRI(), annotation);
manager.applyChange(new RemoveAxiom(ontology, axiom));
}
for (OWLOntology o : ontology.getImports()) {
for (OWLAnnotation annotation : indiv.getAnnotations(o)) {
if (!annotation.getProperty().equals(property)) {
continue;
}
o.getOWLOntologyManager().applyChange(new RemoveOntologyAnnotation(o, annotation)); // not sufficient
OWLAxiom axiom = dataFactory.getOWLAnnotationAssertionAxiom(indiv.getIRI(), annotation);
manager.applyChange(new RemoveAxiom(o, axiom));
}
}
}
private void addAnnotation(String label, OWLRDFVocabulary type, OWLNamedIndividual indiv) {
addAnnotation(label, indiv, type.getIRI());
}
public void addAnnotation(String label, OWLNamedIndividual indiv, IRI iri) {
OWLLiteral literal = dataFactory.getOWLLiteral(label);
OWLAnnotation annotation = dataFactory.getOWLAnnotation(
dataFactory.getOWLAnnotationProperty(iri), literal);
OWLAxiom axiom = dataFactory.getOWLAnnotationAssertionAxiom(
indiv.getIRI(), annotation);
manager.applyChange(new AddAxiom(ontology, axiom));
}
/**
* Checks if an individual exists. If provided with the fragment only searches in all imports also.
*
* @param indivName The individual to search for, given by fragment or namespace and fragment.
* @return True if found (possibly in an imported ontology), false else.
*/
@Pre(expr = "_this.ontology!=null", lang = "js")
public boolean containsIndividual(String indivName) {
if (ontology.containsIndividualInSignature(createIri(indivName), true)) return true;
if (createIri(indivName).toString().equals(indivName)) return false;
for (OWLOntology importedOntology : ontology.getImports()) {
String qualifiedIndivName = importedOntology.getOntologyID().getOntologyIRI() + "#" + indivName;
if (ontology.containsIndividualInSignature(IRI.create(qualifiedIndivName), true)) return true;
}
for (OWLImportsDeclaration importDeclaration : ontology.getImportsDeclarations()) {
String qualifiedIndivName = importDeclaration.getIRI().toString() + "#" + indivName;
if (ontology.containsIndividualInSignature(IRI.create(qualifiedIndivName), true)) return true;
}
return false;
}
/**
* Checks if an individual exists using the label annotation. Also looks in all imports.
*
* @param label The label to search for.
* @return True if an individual with the specified label does exist, false else.
*/
@Pre(expr = "_this.ontology!=null && label!=null", lang = "js")
public boolean containsIndividualByLabel(String label) {
return containsIndividualByLabel(ontology, label);
}
public boolean containsIndividualByIRIOrLabel(String iriOrLabel) {
return containsIndividual(iriOrLabel) || containsIndividualByLabel(iriOrLabel);
}
private boolean containsIndividualByLabel(OWLOntology ontology, String label) {
for (OWLNamedIndividual individual : ontology.getIndividualsInSignature(true)) {
for (OWLAnnotation annotation : individual.getAnnotations(ontology)) {
if (!annotation.getProperty().equals(ontology.getOWLOntologyManager().getOWLDataFactory().getRDFSLabel())) {
continue;
}
if (((OWLLiteral) annotation.getValue()).getLiteral().equals(label)) {
return true;
}
}
}
for (OWLOntology model : ontology.getImports()) {
if (containsIndividualByLabel(model, label)) return true;
}
return false;
}
@Pre(expr = "_this.ontology!=null && _this.dataFactory!=null", lang = "js")
public OWLNamedIndividual getIndividual(String indivName) throws OwlElementNotFoundException {
IRI indivIri = createIri(indivName);
if (!ontology.containsIndividualInSignature(indivIri, true)) {
LOG.error(indivIri.toString());
LOG.error(indivName);
throw new OwlElementNotFoundException();
}
return dataFactory.getOWLNamedIndividual(indivIri);
}
public OWLNamedIndividual getIndividualByIRIOrLabel(String indivNameOrLabel) throws OwlElementNotFoundException {
try {
return getIndividual(indivNameOrLabel);
} catch (OwlElementNotFoundException e) {
return getIndividualByLabel(indivNameOrLabel);
}
}
/**
* This method expects an unqualified name and tries to find it using the base IRI of the ontology but optionally also
* using the base IRIs of all imported ontologies.
* This is useful to get an individual without knowing the exact ontology it has been defined.
*
* @param indivName The unqualified individual name.
* @param searchInImportedOntologiesAlso Specifies whether the search should be extended to all imported ontologies.
* @throws OwlElementNotFoundException If no matching individual can be found.
*/
public OWLNamedIndividual getIndividualByUnqualifiedName(String indivName, boolean searchInImportedOntologiesAlso) throws OwlElementNotFoundException {
if (containsIndividual(createIri(indivName).toString())) return getIndividual(indivName);
if (!searchInImportedOntologiesAlso)
throw new OwlElementNotFoundException(String.format("Individual with name %s not found, consider setting searchInImportedOntologiesAlso to true.", indivName));
for (OWLOntology importedOntology : ontology.getImports()) {
String qualifiedIndivName = importedOntology.getOntologyID().getOntologyIRI() + "#" + indivName;
if (containsIndividual(qualifiedIndivName)) return getIndividual(qualifiedIndivName);
}
for (OWLImportsDeclaration importDeclaration : ontology.getImportsDeclarations()) {
String qualifiedIndivName = importDeclaration.getIRI().toString() + "#" + indivName;
if (containsIndividual(qualifiedIndivName)) return getIndividual(qualifiedIndivName);
}
throw new OwlElementNotFoundException();
}
/**
* Retrieves an individual by matching label. This method also considers imported ontologies.
*
* @param label The label to search for (RDFS label).
* @return The individual if it could be found.
* @throws OwlElementNotFoundException If the individual could not be found.
*/
@Pre(expr = "_this.ontology!=null && label!=null", lang = "js")
public OWLNamedIndividual getIndividualByLabel(String label) throws OwlElementNotFoundException {
if (!containsIndividualByLabel(label)) {
throw new OwlElementNotFoundException(String.format("Individual with label %s not found, consider setting searchInImportedOntologiesAlso to true.", label));
}
OWLNamedIndividual individual = getIndividualByLabel(ontology, label);
if (individual == null) {
throw new OwlElementNotFoundException(String.format("Individual with label %s not found, consider setting searchInImportedOntologiesAlso to true.", label));
}
return individual;
}
public HashSet<OWLNamedIndividual> getIndividualsByClass(String classIRI) {
return getIndividualsByClass(ontology, IRI.create(classIRI));
}
public HashSet<OWLNamedIndividual> getIndividualsByClass(IRI classIRI) {
return getIndividualsByClass(ontology, classIRI);
}
private OWLNamedIndividual getIndividualByLabel(OWLOntology ontology, String label) {
for (OWLNamedIndividual individual : ontology.getIndividualsInSignature(true)) {
for (OWLAnnotation annotation : individual.getAnnotations(ontology)) {
if (!annotation.getProperty().equals(ontology.getOWLOntologyManager().getOWLDataFactory().getRDFSLabel())) {
continue;
}
if (((OWLLiteral) annotation.getValue()).getLiteral().equals(label)) {
return individual;
}
}
}
for (OWLOntology model : ontology.getImports()) {
OWLNamedIndividual result = getIndividualByLabel(model, label);
if (result != null) return result;
}
return null;
}
private HashSet<OWLNamedIndividual> getIndividualsByClass(OWLOntology ontology, IRI classIRI) {
HashSet<OWLNamedIndividual> result = new HashSet<OWLNamedIndividual>();
OWLClass owlClass = getDataFactory().getOWLClass(classIRI);
for (OWLIndividual owlIndividual : owlClass.getIndividuals(getOntology())) {
if (owlIndividual instanceof OWLNamedIndividual) {
result.add((OWLNamedIndividual) owlIndividual);
}
}
return result;
}
public IRI findIndividualByFragmentAndLabel(String indivName) {
try {
if (containsIndividual(indivName)) return getIndividualByUnqualifiedName(indivName, true).getIRI();
if (containsIndividualByLabel(indivName)) return getIndividualByLabel(indivName).getIRI();
} catch (OwlElementNotFoundException e) {
// ignore
}
return null;
}
/**
* Note: This method can be used for individuals only.
*/
@Pre(expr = "_this.ontology!=null && name!=null && name!=''", lang = "js")
public IRI createIri(String name) {
if (name.contains("#") || name.contains("://")) {
return IRI.create(name); // TODO: OwlAPI does not recognize numeric-only fragments, so just split manually
}
return IRI.create(ontology.getOntologyID().getOntologyIRI() + "#", name);
}
/**
* IRI.create does not seem to split numeric fragments correctly, this method tries to.
*/
public static String getFragment(IRI iri) {
// does not work for i.e. "http://timbus.teco.edu/ontologies/Scenarios/MusicClassification.owl#7cb4eeb2", split incorrectly by IRI.create
// if (iri.getFragment() != null) return iri.getFragment();
int prefixEndIndex = iri.toString().lastIndexOf('#') + 1;
return iri.toString().substring(prefixEndIndex);
}
/**
* IRI.create does not seem to split numeric fragments correctly, this method tries to.
*/
public static String getNamespace(IRI iri) {
int prefixEndIndex = iri.toString().lastIndexOf('#') + 1;
return iri.toString().substring(0, prefixEndIndex - 1) + "#";
}
/**
* Add an individual to s specific class.
*/
@Pre(expr = "_this.ontology!=null && _this.manager!=null && _this.dataFactory!=null", lang = "js")
public void makeInstanceOf(OWLNamedIndividual individual, String baseClass) {
OWLClass classExpression = dataFactory.getOWLClass(createIri(baseClass));
OWLClassAssertionAxiom classAssertion = dataFactory.getOWLClassAssertionAxiom(classExpression, individual);
manager.applyChange(new AddAxiom(ontology, classAssertion));
}
/**
* Remove an individual from a specific class.
*/
@Pre(expr = "_this.ontology!=null && _this.manager!=null && _this.dataFactory!=null", lang = "js")
public void unmakeInstanceOf(OWLNamedIndividual individual, String baseClass) {
OWLClass classExpression = dataFactory.getOWLClass(createIri(baseClass));
OWLClassAssertionAxiom classAssertion = dataFactory.getOWLClassAssertionAxiom(classExpression, individual);
manager.applyChange(new RemoveAxiom(ontology, classAssertion));
}
@Pre(expr = "_this.ontology!=null && _this.manager!=null && _this.dataFactory!=null", lang = "js")
public void addObjectProperty(OWLNamedIndividual individual1, String propertyName, OWLNamedIndividual individual2) {
OWLObjectProperty objectProperty = dataFactory.getOWLObjectProperty(createIri(propertyName));
OWLObjectPropertyAssertionAxiom objectPropertyAssertionAxiom = dataFactory.getOWLObjectPropertyAssertionAxiom(objectProperty, individual1, individual2);
manager.applyChange(new AddAxiom(ontology, objectPropertyAssertionAxiom));
}
@Pre(expr = "_this.ontology!=null && _this.manager!=null && _this.dataFactory!=null", lang = "js")
public void removeObjectProperty(OWLNamedIndividual individual1, String propertyName, OWLNamedIndividual individual2) {
OWLObjectProperty objectProperty = dataFactory.getOWLObjectProperty(createIri(propertyName));
OWLObjectPropertyAssertionAxiom objectPropertyAssertionAxiom = dataFactory.getOWLObjectPropertyAssertionAxiom(objectProperty, individual1, individual2);
manager.applyChange(new RemoveAxiom(ontology, objectPropertyAssertionAxiom));
}
/**
* Removes all object relations of a specified property (including reverse properties) of an individual.
* @return The affected individuals.
*/
@Pre(expr = "_this.ontology!=null && _this.manager!=null && _this.dataFactory!=null", lang = "js")
public List<OWLNamedIndividual> removeAllObjectProperties(OWLNamedIndividual individual1, String propertyName) {
OWLObjectProperty objectProperty = dataFactory.getOWLObjectProperty(createIri(propertyName));
List<OWLNamedIndividual> relatedIndivs = getObjectPropertyValues(individual1, propertyName);
relatedIndivs.addAll(getInverseObjectPropertyValues(individual1, propertyName));
for (OWLNamedIndividual relatedIndiv : relatedIndivs) {
OWLObjectPropertyAssertionAxiom objectPropertyAssertionAxiom = dataFactory.getOWLObjectPropertyAssertionAxiom(objectProperty, individual1, relatedIndiv);
manager.applyChange(new RemoveAxiom(ontology, objectPropertyAssertionAxiom));
objectPropertyAssertionAxiom = dataFactory.getOWLObjectPropertyAssertionAxiom(objectProperty, relatedIndiv, individual1);
manager.applyChange(new RemoveAxiom(ontology, objectPropertyAssertionAxiom));
}
return relatedIndivs;
}
@Pre(expr = "_this.ontology!=null && propertyIRI!=null", lang = "js")
public List<OWLNamedIndividual> getObjectPropertyValues(OWLNamedIndividual individual, String propertyIRI) {
Map<OWLObjectPropertyExpression, Set<OWLIndividual>> objectProperties = individual.getObjectPropertyValues(ontology);
Set<OWLIndividual> matchingProperties = new HashSet<>();
for (Map.Entry<OWLObjectPropertyExpression, Set<OWLIndividual>> entry : objectProperties.entrySet()) {
if (!entry.getKey().getNamedProperty().getIRI().toString().equals(propertyIRI)) continue;
matchingProperties.addAll(entry.getValue());
}
return filter(notNullValue(), convert(matchingProperties, new Converter<OWLIndividual, OWLNamedIndividual>() {
@Override
public OWLNamedIndividual convert(OWLIndividual owlIndividual) {
return (OWLNamedIndividual) owlIndividual;
}
}));
}
@Pre(expr = "_this.ontology!=null && propertyIRI!=null", lang = "js")
public List<OWLNamedIndividual> getInverseObjectPropertyValues(OWLNamedIndividual individual, String propertyIRI) {
List<OWLNamedIndividual> matchingProperties = new ArrayList<>();
// maybe a reasoner should be used to improve performance
for (OWLNamedIndividual other : ontology.getIndividualsInSignature()) {
Map<OWLObjectPropertyExpression, Set<OWLIndividual>> objectProperties = other.getObjectPropertyValues(ontology);
for (Map.Entry<OWLObjectPropertyExpression, Set<OWLIndividual>> entry : objectProperties.entrySet()) {
if (!entry.getKey().getNamedProperty().getIRI().toString().equals(propertyIRI)) continue;
if (!entry.getValue().contains(individual)) continue;
matchingProperties.add(other);
}
}
return matchingProperties;
}
@Pre(expr = "_this.ontology!=null && _this.manager!=null && _this.dataFactory!=null", lang = "js")
public void addDataProperty(OWLNamedIndividual individual, String propertyName, OWLLiteral owlLiteral) {
OWLDataProperty dataProperty = dataFactory.getOWLDataProperty(createIri(propertyName));
OWLDataPropertyAssertionAxiom dataPropertyAssertion = dataFactory
.getOWLDataPropertyAssertionAxiom(dataProperty, individual, owlLiteral);
manager.applyChange(new AddAxiom(ontology, dataPropertyAssertion));
}
@Pre(expr = "_this.ontology!=null && _this.dataFactory!=null", lang = "js")
public Set<OWLLiteral> getDataProperty(OWLNamedIndividual individual, String propertyName) {
OWLDataProperty dataProperty = dataFactory.getOWLDataProperty(createIri(propertyName));
return individual.getDataPropertyValues(dataProperty, ontology);
}
@Pre(expr = "_this.ontology!=null && _this.manager!=null && _this.dataFactory!=null", lang = "js")
public void removeDataProperty(OWLNamedIndividual individual, String propertyName) {
OWLDataProperty dataProperty = dataFactory.getOWLDataProperty(createIri(propertyName));
for (OWLLiteral owlLiteral : getDataProperty(individual, propertyName)) {
OWLDataPropertyAssertionAxiom objectPropertyAssertionAxiom = dataFactory.getOWLDataPropertyAssertionAxiom(dataProperty, individual, owlLiteral);
manager.applyChange(new RemoveAxiom(ontology, objectPropertyAssertionAxiom));
}
}
@Pre(expr = "_this.dataFactory!=null", lang = "js")
public OWLLiteral getOWLLiteral(String data, OWLDatatype datatype) {
return dataFactory.getOWLLiteral(data, datatype);
}
@Pre(expr = "_this.dataFactory!=null", lang = "js")
public OWLLiteral getOWLLiteralString(String data) {
return dataFactory.getOWLLiteral(data);
}
@Pre(expr = "_this.ontology!=null && _this.manager!=null", lang = "js")
public void save(String filename) throws OWLOntologyStorageException {
manager.saveOntology(ontology, new RDFXMLOntologyFormat(), new FileDocumentTarget(new File(filename)));
}
@Pre(expr = "_this.ontology!=null && _this.manager!=null && _this.dataFactory!=null", lang = "js")
public void addOntology(String owlUri) {
OWLImportsDeclaration importsDeclaration = dataFactory.getOWLImportsDeclaration(IRI.create(owlUri));
manager.applyChange(new AddImport(ontology, importsDeclaration));
}
@Pre(expr = "_this.ontology!=null && _this.manager!=null", lang = "js")
public Model getJenaModel(final boolean ignoreMissingImports) throws OWLOntologyStorageException, OWLOntologyCreationException, IOException {
// TODO: cache and make more performant
OntModel ontologyModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
ontologyModel.getDocumentManager().setProcessImports(true);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
manager.saveOntology(ontology, new RDFXMLOntologyFormat(), outputStream);
ontologyModel.setDynamicImports(true);
ontologyModel.getDocumentManager().setReadFailureHandler(new OntDocumentManager.ReadFailureHandler() {
@Override
public void handleFailedRead(String url, Model model, Exception e) {
LOG.info("Loading imported model: " + url);
OwlApiFacade api = new OwlApiFacade(OWLManager.createOWLOntologyManager(), OWLManager.getOWLDataFactory());
try {
api.load(url);
model.add(api.getJenaModel(false));
} catch (OWLOntologyCreationException | IOException | OWLOntologyStorageException f) {
if (ignoreMissingImports) return;
throw new ModelConversionException(f);
}
}
});
ontologyModel.read(new ByteArrayInputStream(outputStream.toByteArray()), ontology.getOntologyID().getOntologyIRI().toString(), "RDF/XML");
ontologyModel.loadImports();
return ontologyModel;
}
@Pre(expr = "_this.ontology!=null && owlNamedIndividual!=null", lang = "js")
public List<IRI> getClassesOfIndividual(OWLNamedIndividual owlNamedIndividual) {
Set<OWLClassExpression> types = owlNamedIndividual.getTypes(ontology.getOWLOntologyManager().getOntologies());
return filter(notNullValue(), convert(types, new Converter<OWLClassExpression, IRI>() {
@Override
public IRI convert(OWLClassExpression owlClassExpression) {
if (!(owlClassExpression instanceof OWLClassImpl)) return null;
return ((OWLClassImpl) owlClassExpression).getIRI();
}
}));
}
@Pre(expr = "_this.ontology!=null && individual!=null && classIRI!=null", lang = "js")
public boolean isIndividualOfClass(OWLNamedIndividual individual, IRI classIRI) {
return getClassesOfIndividual(individual).contains(classIRI);
}
/**
* Creates a new instance using a new OWLOntologyManager.
*/
public static OwlApiFacade create() {
return new OwlApiFacade(OWLManager.createOWLOntologyManager(), OWLManager.getOWLDataFactory());
}
/**
* Converts a given ontology to RDF/XML.
*/
public static String toRdfXml(@NotNull OWLOntology ontology) throws OWLOntologyStorageException {
return toFormat(ontology, new RDFXMLOntologyFormat());
}
/**
* Returns a representation of the ontology as RDF/XML.
*
* @see #toRdfXml(org.semanticweb.owlapi.model.OWLOntology)
*/
@Pre(expr = "_this.ontology!=null", lang = "js")
public String toRdfXml() throws OWLOntologyStorageException {
return toRdfXml(ontology);
}
/**
* Converts a given ontology to OWL/XML.
*/
public static String toOwlXml(@NotNull OWLOntology ontology) throws OWLOntologyStorageException {
return toFormat(ontology, new OWLXMLOntologyFormat());
}
/**
* Returns a representation of the ontology as OWL/XML.
*
* @see #toOwlXml(org.semanticweb.owlapi.model.OWLOntology)
*/
public String toOwlXml() throws OWLOntologyStorageException {
return toOwlXml(ontology);
}
private static String toFormat(OWLOntology ontology, OWLOntologyFormat ontologyFormat) throws OWLOntologyStorageException {
StringDocumentTarget stringDocumentTarget = new StringDocumentTarget();
ontology.getOWLOntologyManager().saveOntology(ontology, ontologyFormat, stringDocumentTarget);
return stringDocumentTarget.toString();
}
/**
* Returns an encoded version of a string that can be used as individual name.
*/
public static String cleanName(String name) {
return name.replaceAll(" |/|:", "-").replaceAll("[^a-zA-Z0-9_-]", "");
}
}