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

org.protege.editor.owl.model.hierarchy.AbstractOWLPropertyHierarchyProvider Maven / Gradle / Ivy

package org.protege.editor.owl.model.hierarchy;

import org.semanticweb.owlapi.model.*;
import org.semanticweb.owlapi.search.EntitySearcher;

import java.util.*;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;


/**
 * Author: Matthew Horridge
* The University Of Manchester
* Bio-Health Informatics Group
* Date: 23-Jan-2007

*/ public abstract class AbstractOWLPropertyHierarchyProvider extends AbstractOWLObjectHierarchyProvider

{ // private static final Logger logger = LoggerFactory.getLogger(AbstractOWLPropertyHierarchyProvider.class); private ReadLock ontologySetReadLock; private WriteLock ontologySetWriteLock; /* * The ontologies variable is protected by the ontologySetReadLock and the ontologySetWriteLock. * These locks are always taken and held inside of the getReadLock() and getWriteLock()'s for the * OWL Ontology Manager. This is necessary because when the set of ontologies changes, everything * about this class changes. So when the set of ontologies is changed we need to make sure that nothing * else is running. */ private Set ontologies; private Set

subPropertiesOfRoot; private OWLOntologyChangeListener listener; public AbstractOWLPropertyHierarchyProvider(OWLOntologyManager owlOntologyManager) { super(owlOntologyManager); this.subPropertiesOfRoot = new HashSet<>(); ontologies = new FakeSet<>(); ReentrantReadWriteLock locks = new ReentrantReadWriteLock(); ontologySetReadLock = locks.readLock(); ontologySetWriteLock = locks.writeLock(); listener = this::handleChanges; owlOntologyManager.addOntologyChangeListener(listener); } public void dispose() { super.dispose(); getManager().removeOntologyChangeListener(listener); } /* * This call holds the write lock so no other thread can hold the either the OWL ontology * manager read or write locks or the ontologies */ private void handleChanges(List changes) { Set

properties = new HashSet<>(getPropertiesReferencedInChange(changes)); for (P prop : properties) { if (isSubPropertyOfRoot(prop)) { subPropertiesOfRoot.add(prop); fireNodeChanged(getRoot()); } else { if (getAncestors(prop).contains(prop)) { subPropertiesOfRoot.add(prop); getAncestors(prop).stream() .filter(anc -> getAncestors(anc).contains(prop)) .forEach(anc -> { subPropertiesOfRoot.add(anc); fireNodeChanged(anc); }); } else { subPropertiesOfRoot.remove(prop); } } fireNodeChanged(prop); } fireNodeChanged(getRoot()); } protected abstract Set

getPropertiesReferencedInChange(List changes); private boolean isSubPropertyOfRoot(P prop) { if (prop.equals(getRoot())) { return false; } // We deem a property to be a sub of the top property if this is asserted // or if no named superproperties are asserted final Set

parents = getParents(prop); if (parents.isEmpty() || parents.contains(getRoot())) { for (OWLOntology ont : ontologies) { if (containsReference(ont, prop)) { return true; } } } // Additional condition: If we have P -> Q and Q -> P, then // there is no path to the root, so put P and Q as root properties // Collapse any cycles and force properties that are equivalent // through cycles to appear at the root. return getAncestors(prop).contains(prop); } private void rebuildRoots() { subPropertiesOfRoot.clear(); for (OWLOntology ontology : ontologies) { for (P prop : getReferencedProperties(ontology)) { if (isSubPropertyOfRoot(prop)) { subPropertiesOfRoot.add(prop); } } } } protected abstract boolean containsReference(OWLOntology ont, P prop); /** * Gets the relevant properties in the specified ontology that are contained * within the property hierarchy. For example, for an object property hierarchy * this would constitute the set of referenced object properties in the specified * ontology. * * @param ont The ontology */ protected abstract Set getReferencedProperties(OWLOntology ont); protected abstract Set getSubPropertyAxiomForRHS(P prop, OWLOntology ont); protected abstract P getRoot(); /** * Gets the objects that represent the roots of the hierarchy. */ public Set

getRoots() { return Collections.singleton(getRoot()); } /** * Sets the ontologies that this hierarchy provider should use * in order to determine the hierarchy. */ final public void setOntologies(Set ontologies) { // getReadLock().lock(); ontologySetWriteLock.lock(); try { this.ontologies.clear(); this.ontologies.addAll(ontologies); rebuildRoots(); fireHierarchyChanged(); } finally { ontologySetWriteLock.unlock(); // getReadLock().unlock(); } } public boolean containsReference(P object) { // getReadLock().lock(); ontologySetReadLock.lock(); try { for (OWLOntology ont : ontologies) { if (getReferencedProperties(ont).contains(object)) { return true; } } return false; } finally { ontologySetReadLock.unlock(); // getReadLock().unlock(); } } public Set

getUnfilteredChildren(P object) { // getReadLock().lock(); ontologySetReadLock.lock(); try { if (object.equals(getRoot())) { return Collections.unmodifiableSet(subPropertiesOfRoot); } final Set

result = new HashSet<>(); for (E subProp : getSubProperties(object, ontologies)) { // Don't add the sub property if it is a parent of // itself - i.e. prevent cycles if (!subProp.isAnonymous() && !getAncestors((P) subProp).contains(subProp)) { result.add((P) subProp); } } return result; } finally { ontologySetReadLock.unlock(); // getReadLock().unlock(); } } protected abstract Collection

getSubProperties(P object, Set ontologies); public Set

getEquivalents(P object) { // getReadLock().lock(); ontologySetReadLock.lock(); try { Set

result = new HashSet<>(); Set

ancestors = getAncestors(object); if (ancestors.contains(object)) { for (P anc : ancestors) { if (getAncestors(anc).contains(object)) { result.add(anc); } } } for (E prop : EntitySearcher.getEquivalentProperties(object, ontologies)) { if (!prop.isAnonymous()) { result.add((P) prop); } } result.remove(object); return result; } finally { ontologySetReadLock.unlock(); // getReadLock().unlock(); } } public Set

getParents(P object) { // getReadLock().lock(); ontologySetReadLock.lock(); try { if (object.equals(getRoot())) { return Collections.emptySet(); } Set

result = new HashSet<>(); for (E prop : getSuperProperties(object, ontologies)) { if (!prop.isAnonymous()) { result.add((P) prop); } } if (result.isEmpty() && isReferenced(object)) { result.add(getRoot()); } return result; } finally { ontologySetReadLock.unlock(); // getReadLock().unlock(); } } protected abstract Collection

getSuperProperties(P subProperty, Set ontologies); private boolean isReferenced(P e) { return e.accept(new IsReferencePropertyExpressionVisitor()); } private class IsReferencePropertyExpressionVisitor implements OWLPropertyExpressionVisitorEx { @Override public Boolean visit(OWLAnnotationProperty owlAnnotationProperty) { return isReferenced(owlAnnotationProperty); } public Boolean visit(OWLObjectProperty property) { return isReferenced(property); } public Boolean visit(OWLObjectInverseOf property) { return property.getInverse().accept(this); } public Boolean visit(OWLDataProperty property) { return isReferenced(property); } private boolean isReferenced(OWLEntity e) { for (OWLOntology ontology : ontologies) { if (ontology.containsEntityInSignature(e)) { return true; } } return false; } } private class FakeSet extends AbstractSet { private List elements = new ArrayList<>(); @Override public Iterator iterator() { return elements.iterator(); } @Override public int size() { return elements.size(); } @Override public boolean add(X e) { if (!elements.contains(e)) { elements.add(e); return true; } return false; } @Override public void clear() { elements.clear(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy