org.obolibrary.macro.ManchesterSyntaxTool Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of owlapi-oboformat Show documentation
Show all versions of owlapi-oboformat Show documentation
A java library for converting obo format documents to OWL, and for converting (a subset of) OWL to obo format. This version has been slightly modified to be included directly in the OWL API.
The upstream code for this module and its authors can be found at https://code.google.com/p/oboformat/.
The newest version!
package org.obolibrary.macro;
import static org.semanticweb.owlapi.util.OWLAPIStreamUtils.add;
import static org.semanticweb.owlapi.util.OWLAPIStreamUtils.asList;
import static org.semanticweb.owlapi.util.OWLAPIStreamUtils.asUnorderedSet;
import java.util.Collection;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.Nullable;
import org.obolibrary.obo2owl.OWLAPIObo2Owl;
import org.obolibrary.oboformat.model.OBODoc;
import org.semanticweb.owlapi.expression.OWLEntityChecker;
import org.semanticweb.owlapi.expression.ShortFormEntityChecker;
import org.semanticweb.owlapi.manchestersyntax.parser.ManchesterOWLSyntaxParserImpl;
import org.semanticweb.owlapi.manchestersyntax.renderer.ParserException;
import org.semanticweb.owlapi.model.AxiomType;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom;
import org.semanticweb.owlapi.model.OWLAnnotationProperty;
import org.semanticweb.owlapi.model.OWLAnnotationValue;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLClassExpression;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLDataProperty;
import org.semanticweb.owlapi.model.OWLDatatype;
import org.semanticweb.owlapi.model.OWLDeclarationAxiom;
import org.semanticweb.owlapi.model.OWLEntity;
import org.semanticweb.owlapi.model.OWLLiteral;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.model.OWLRuntimeException;
import org.semanticweb.owlapi.model.OntologyConfigurator;
import org.semanticweb.owlapi.util.BidirectionalShortFormProviderAdapter;
import org.semanticweb.owlapi.util.IRIShortFormProvider;
import org.semanticweb.owlapi.util.OntologyAxiomPair;
import org.semanticweb.owlapi.util.ShortFormProvider;
import org.semanticweb.owlapi.util.SimpleIRIShortFormProvider;
import org.semanticweb.owlapi.util.mansyntax.ManchesterOWLSyntaxParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* wrapper for parsing Manchester Syntax.
*
* @author heiko
*/
public class ManchesterSyntaxTool {
private static final Logger LOG = LoggerFactory.getLogger(ManchesterSyntaxTool.class);
protected final IRIShortFormProvider iriShortFormProvider = new SimpleIRIShortFormProvider();
private final OWLDataFactory dataFactory;
private final AdvancedEntityChecker entityChecker;
private final ShortFormProvider shortFormProvider =
e -> iriShortFormProvider.getShortForm(e.getIRI());
private final AtomicBoolean disposed = new AtomicBoolean(false);
/**
* Create a new parser instance for the given ontology. By default, this parser will also try to
* resolve {@code OWLObject} instances via their identifier or rdfs:label.
*
* @param inputOntology input ontology
*/
public ManchesterSyntaxTool(OWLOntology inputOntology) {
this(inputOntology, null);
}
/**
* Create a new parser instance for the given ontologies. By default, this parser will also try
* to resolve {@code OWLObject} instances via their identifier or rdfs:label.
*
* @param inputOntology input ontology
* @param auxiliaryOntologies set of additional ontologies or null
*/
public ManchesterSyntaxTool(OWLOntology inputOntology,
@Nullable Collection auxiliaryOntologies) {
OWLOntologyManager manager = inputOntology.getOWLOntologyManager();
dataFactory = manager.getOWLDataFactory();
Set ontologies = asUnorderedSet(inputOntology.importsClosure());
if (auxiliaryOntologies != null) {
auxiliaryOntologies.forEach(o -> add(ontologies, o.importsClosure()));
}
ShortFormEntityChecker defaultInstance = new ShortFormEntityChecker(
new BidirectionalShortFormProviderAdapter(manager, ontologies, shortFormProvider));
entityChecker = new AdvancedEntityChecker(defaultInstance, ontologies,
inputOntology.getOWLOntologyManager());
}
/**
* Parse frame expressions in Manchester syntax.
*
* @param expression expression
* @return set of {@link OntologyAxiomPair}
* @throws ParserException parser exception
*/
public Set parseManchesterExpressionFrames(String expression) {
ManchesterOWLSyntaxParser parser = createParser(expression);
return parser.parseFrames();
}
/**
* Parse a class expression in Manchester syntax.
*
* @param expression expression
* @return {@link OWLClassExpression}
* @throws ParserException parser exception
*/
public OWLClassExpression parseManchesterExpression(String expression) {
ManchesterOWLSyntaxParser parser = createParser(expression);
return parser.parseClassExpression();
}
private ManchesterOWLSyntaxParser createParser(String expression) {
if (disposed.get()) {
throw new OWLRuntimeException("Illegal State: Trying to use an disposed instance.");
}
ManchesterOWLSyntaxParser parser =
new ManchesterOWLSyntaxParserImpl(new OntologyConfigurator(), dataFactory);
parser.setStringToParse(expression);
parser.setOWLEntityChecker(entityChecker);
LOG.info("parsing: {}", expression);
return parser;
}
/**
* Translate the {@link IRI} into the short form as expected by the parser.
*
* @param iri iri
* @return short form
*/
public String getId(IRI iri) {
if (disposed.get()) {
throw new OWLRuntimeException("Illegal State: Trying to use an disposed instance.");
}
return iriShortFormProvider.getShortForm(iri);
}
/**
* Translate the {@link OWLEntity} identifier into the short form as expected by the parser.
*
* @param entity entity
* @return short form
*/
public String getId(OWLEntity entity) {
if (disposed.get()) {
throw new OWLRuntimeException("Illegal State: Trying to use an disposed instance.");
}
return shortFormProvider.getShortForm(entity);
}
/**
* Call this method to dispose the internal data structures. This will remove also the listeners
* registered with the ontology manager.
*/
public void dispose() {
if (!disposed.getAndSet(true)) {
shortFormProvider.dispose();
}
}
/**
* {@link OWLEntityChecker} which additionally checks for corresponding identifiers and labels
* to retrieve entities. The intended behavior is specified as follows:
*
* - If the string is enclosed with matching single quotes, try to resolve as label
* - Otherwise, try to resolve as identifier
*
*/
static class AdvancedEntityChecker implements OWLEntityChecker {
private final OWLEntityChecker defaultInstance;
private final Set ontologies;
private final OWLOntologyManager manager;
/**
* @param defaultInstance default instance
* @param ontologies ontologies
* @param manager manager
*/
AdvancedEntityChecker(OWLEntityChecker defaultInstance, Set ontologies,
OWLOntologyManager manager) {
this.defaultInstance = defaultInstance;
this.ontologies = ontologies;
this.manager = manager;
}
private static boolean isQuoted(String s) {
int length = s.length();
if (length >= 2) {
return s.charAt(0) == '\'' && s.charAt(length - 1) == '\'';
}
return false;
}
@Override
@Nullable
public OWLClass getOWLClass(String name) {
OWLClass owlClass = defaultInstance.getOWLClass(name);
if (owlClass == null) {
IRI iri = getIRI(name);
if (iri != null) {
owlClass = getOWLClass(iri);
}
}
return owlClass;
}
@Override
@Nullable
public OWLObjectProperty getOWLObjectProperty(String name) {
OWLObjectProperty owlObjectProperty = defaultInstance.getOWLObjectProperty(name);
if (owlObjectProperty == null) {
IRI iri = getIRI(name);
if (iri != null) {
owlObjectProperty = getOWLObjectProperty(iri);
}
}
return owlObjectProperty;
}
@Override
@Nullable
public OWLDataProperty getOWLDataProperty(String name) {
return defaultInstance.getOWLDataProperty(name);
}
@Override
@Nullable
public OWLNamedIndividual getOWLIndividual(String name) {
OWLNamedIndividual owlIndividual = defaultInstance.getOWLIndividual(name);
if (owlIndividual == null) {
IRI iri = getIRI(name);
if (iri != null) {
owlIndividual = getOWLIndividual(iri);
}
}
return owlIndividual;
}
@Override
@Nullable
public OWLDatatype getOWLDatatype(String name) {
return defaultInstance.getOWLDatatype(name);
}
@Override
@Nullable
public OWLAnnotationProperty getOWLAnnotationProperty(String name) {
return defaultInstance.getOWLAnnotationProperty(name);
}
@Nullable
protected IRI getIRI(String name) {
if (isQuoted(name)) {
// anything in '....' quotes is a label
return getIRIByLabel(name.substring(1, name.length() - 1));
}
if (name.length() > 2 && name.charAt(0) == '<'
&& name.charAt(name.length() - 1) == '>') {
// anything between <...> brackets is a complete IRI
return IRI.create(name.substring(1, name.length() - 1));
}
return getIRIByIdentifier(name);
}
@Nullable
protected IRI getIRIByIdentifier(String id) {
OWLAPIObo2Owl b = new OWLAPIObo2Owl(manager);
b.setObodoc(new OBODoc());
return b.oboIdToIRI(id);
}
/**
* Retrieve an {@link IRI} by rdfs:label.
*
* @param label label
* @return {@link IRI} or null
*/
@Nullable
protected IRI getIRIByLabel(String label) {
for (OWLOntology o : ontologies) {
Optional anyMatch =
o.axioms(AxiomType.ANNOTATION_ASSERTION)
.filter(aa -> isMatchingLabel(label, aa.getValue(), aa.getProperty())
&& aa.getSubject().isIRI())
.findAny();
if (anyMatch.isPresent()) {
return (IRI) anyMatch.get().getSubject();
}
}
return null;
}
/**
* @param label label to match
* @param v annotation value
* @param property property to check
* @return true if property is a label, v is a literal and v matches label
*/
protected boolean isMatchingLabel(String label, OWLAnnotationValue v,
OWLAnnotationProperty property) {
return property.isLabel() && v instanceof OWLLiteral
&& label.equals(((OWLLiteral) v).getLiteral());
}
/**
* Retrieve the {@link OWLClass} for a given {@link IRI}, if it has at least one
* {@link OWLDeclarationAxiom}.
*
* @param iri iri
* @return {@link OWLClass} or null
*/
@Nullable
protected OWLClass getOWLClass(IRI iri) {
for (OWLOntology o : ontologies) {
OWLClass c = o.getOWLOntologyManager().getOWLDataFactory().getOWLClass(iri);
if (!asList(o.declarationAxioms(c)).isEmpty()) {
return c;
}
if (o.getOWLOntologyManager().getOWLDataFactory().getOWLNothing().equals(c)) {
return c;
}
}
return null;
}
/**
* Retrieve the {@link OWLNamedIndividual} for a given {@link IRI}, if it has at least one
* corresponding {@link OWLDeclarationAxiom}.
*
* @param iri iri
* @return {@link OWLNamedIndividual} or null
*/
@Nullable
protected OWLNamedIndividual getOWLIndividual(IRI iri) {
for (OWLOntology o : ontologies) {
OWLNamedIndividual c =
o.getOWLOntologyManager().getOWLDataFactory().getOWLNamedIndividual(iri);
Optional found = o.declarationAxioms(c)
.filter(da -> da.getEntity().isOWLNamedIndividual()).findAny();
if (found.isPresent()) {
return found.get().getEntity().asOWLNamedIndividual();
}
}
return null;
}
/**
* Retrieve the {@link OWLObjectProperty} for a given {@link IRI}, if it has at least one
* {@link OWLDeclarationAxiom}.
*
* @param iri iri
* @return {@link OWLObjectProperty} or null
*/
@Nullable
protected OWLObjectProperty getOWLObjectProperty(IRI iri) {
for (OWLOntology o : ontologies) {
OWLObjectProperty p =
o.getOWLOntologyManager().getOWLDataFactory().getOWLObjectProperty(iri);
if (!asList(o.declarationAxioms(p)).isEmpty()) {
return p;
}
}
return null;
}
}
}