All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.obolibrary.macro.ManchesterSyntaxTool Maven / Gradle / Ivy

There is a newer version: 5.5.1
Show 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; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy