/* * Copyright (c) 2013-2015 Josef Hardi <josef.hardi@gmail.com> * * 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. * See the License for the specific language governing permissions and * limitations under the License. */ package com.obidea.semantika.ontology.owlapi; import java.util.HashSet; import java.util.Set; import org.semanticweb.owlapi.model.AxiomType; import org.semanticweb.owlapi.model.OWLAxiom; import org.semanticweb.owlapi.model.OWLClassExpression; import org.semanticweb.owlapi.model.OWLDataFactory; import org.semanticweb.owlapi.model.OWLDataPropertyDomainAxiom; import org.semanticweb.owlapi.model.OWLDataPropertyExpression; import org.semanticweb.owlapi.model.OWLObjectInverseOf; import org.semanticweb.owlapi.model.OWLObjectPropertyDomainAxiom; import org.semanticweb.owlapi.model.OWLObjectPropertyExpression; import org.semanticweb.owlapi.model.OWLObjectPropertyRangeAxiom; import org.semanticweb.owlapi.model.OWLOntology; import org.semanticweb.owlapi.model.OWLPropertyExpression; import org.semanticweb.owlapi.model.OWLSubClassOfAxiom; import org.semanticweb.owlapi.util.OWLAxiomVisitorAdapter; /* package */class OwlClassStructureHandler extends OWLAxiomVisitorAdapter implements IOwlStructureHandler<OWLClassExpression> { private OwlNode<OWLClassExpression> mRoot = new OwlNode<OWLClassExpression>(); private Set<OWLClassExpression> mClassCache = new HashSet<OWLClassExpression>(); private OwlPropertyStructureHandler mPropertyStructureHandler; private OWLDataFactory mOwlDataFactory; public OwlClassStructureHandler(AbstractOwlOntology ontology) { mPropertyStructureHandler = ontology.getPropertyStructureHandler(); mOwlDataFactory = ontology.getOwlDataFactory(); OWLOntology ont = ontology.asOwlOntology(); for (AxiomType<?> type : AxiomType.TBoxAxiomTypes) { for (OWLAxiom axiom : ont.getAxioms(type, true)) { axiom.accept(this); } } } @Override public void visit(OWLSubClassOfAxiom axiom) { addSubClassAxiom(axiom); } @Override public void visit(OWLObjectPropertyDomainAxiom axiom) { addSubClassAxiom(axiom.asOWLSubClassOfAxiom()); OWLObjectPropertyExpression op = axiom.getProperty(); OwlNodeSet<OWLPropertyExpression<?,?>> descendants = mPropertyStructureHandler.getDescendants(op, false); for (OwlNode<OWLPropertyExpression<?,?>> node : descendants.getNodes()) { op = (OWLObjectPropertyExpression) node.getEntity(); axiom = mOwlDataFactory.getOWLObjectPropertyDomainAxiom(op, axiom.getDomain()); addSubClassAxiom(axiom.asOWLSubClassOfAxiom()); } } @Override public void visit(OWLObjectPropertyRangeAxiom axiom) { addSubClassAxiom(asSubClassOfAxiom(axiom)); OWLObjectPropertyExpression op = axiom.getProperty(); OwlNodeSet<OWLPropertyExpression<?,?>> descendants = mPropertyStructureHandler.getDescendants(op, false); for (OwlNode<OWLPropertyExpression<?,?>> node : descendants.getNodes()) { op = (OWLObjectPropertyExpression) node.getEntity(); axiom = mOwlDataFactory.getOWLObjectPropertyRangeAxiom(op, axiom.getRange()); addSubClassAxiom(asSubClassOfAxiom(axiom)); } } @Override public void visit(OWLDataPropertyDomainAxiom axiom) { addSubClassAxiom(axiom.asOWLSubClassOfAxiom()); OWLDataPropertyExpression op = axiom.getProperty(); OwlNodeSet<OWLPropertyExpression<?,?>> descendants = mPropertyStructureHandler.getDescendants(op, false); for (OwlNode<OWLPropertyExpression<?,?>> node : descendants.getNodes()) { op = (OWLDataPropertyExpression) node.getEntity(); axiom = mOwlDataFactory.getOWLDataPropertyDomainAxiom(op, axiom.getDomain()); addSubClassAxiom(axiom.asOWLSubClassOfAxiom()); } } private void addSubClassAxiom(OWLSubClassOfAxiom axiom) { OWLClassExpression subClass = axiom.getSubClass(); OWLClassExpression superClass = axiom.getSuperClass(); OwlNode<OWLClassExpression> subClassNode = createNode(subClass); OwlNode<OWLClassExpression> superClassNode = createNode(superClass); if (mClassCache.contains(subClass)) { subClassNode = findNode(subClass); superClassNode.setParent(subClassNode.getParent()); subClassNode.setParent(superClassNode); } else if (mClassCache.contains(superClass)) { superClassNode = findNode(superClass); subClassNode.setParent(superClassNode); } else { superClassNode.setParent(mRoot); subClassNode.setParent(superClassNode); } mClassCache.add(subClass); mClassCache.add(superClass); } @Override public OwlNode<OWLClassExpression> findNode(OWLClassExpression entity) { return mRoot.findNode(entity); } @Override public OwlNodeSet<OWLClassExpression> getAncestors(OWLClassExpression entity, boolean direct) { OwlNodeSet<OWLClassExpression> ancestors = new OwlNodeSet<OWLClassExpression>(); OwlNode<OWLClassExpression> node = mRoot.findNode(entity); if (node != null) { OwlNode<OWLClassExpression> parent = node.getParent(); while (!parent.isRoot()) { ancestors.addNode(parent); if (direct) { break; } parent = parent.getParent(); } } return ancestors; } @Override public OwlNodeSet<OWLClassExpression> getDescendants(OWLClassExpression entity, boolean direct) { OwlNodeSet<OWLClassExpression> descendants = new OwlNodeSet<OWLClassExpression>(); OwlNode<OWLClassExpression> node = mRoot.findNode(entity); if (node != null) { OwlNodeSet<OWLClassExpression> children = node.getChildren(); if (direct) { descendants.addNodeSet(children); } else { collectChildren(children, descendants); } } return descendants; } private static void collectChildren(OwlNodeSet<OWLClassExpression> children, OwlNodeSet<OWLClassExpression> descendants) { if (children.isEmpty()) { return; } descendants.addNodeSet(children); OwlNodeSet<OWLClassExpression> newChildren = new OwlNodeSet<OWLClassExpression>(); for (OwlNode<OWLClassExpression> node : children.getNodes()) { newChildren.addNodeSet(node.getChildren()); } collectChildren(newChildren, descendants); } private static OwlNode<OWLClassExpression> createNode(OWLClassExpression entity) { return new OwlNode<OWLClassExpression>(entity); } private OWLSubClassOfAxiom asSubClassOfAxiom(OWLObjectPropertyRangeAxiom axiom) { OWLObjectInverseOf inverseExpression = mOwlDataFactory.getOWLObjectInverseOf(axiom.getProperty()); OWLClassExpression classExpression = axiom.getRange(); OWLClassExpression sub = mOwlDataFactory.getOWLObjectSomeValuesFrom(inverseExpression, mOwlDataFactory.getOWLThing()); return mOwlDataFactory.getOWLSubClassOfAxiom(sub, classExpression); } }