//The MIT License
//
// Copyright (c) 2004 Mindswap Research Group, University of Maryland, College Park
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
/*
* Author: Aditya Kalyanpur
*/
package org.mindswap.swoop.utils.owlapi;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.semanticweb.owl.model.OWLAnd;
import org.semanticweb.owl.model.OWLAnnotationInstance;
import org.semanticweb.owl.model.OWLClass;
import org.semanticweb.owl.model.OWLClassAxiom;
import org.semanticweb.owl.model.OWLDataAllRestriction;
import org.semanticweb.owl.model.OWLDataCardinalityRestriction;
import org.semanticweb.owl.model.OWLDataFactory;
import org.semanticweb.owl.model.OWLDataProperty;
import org.semanticweb.owl.model.OWLDataSomeRestriction;
import org.semanticweb.owl.model.OWLDataType;
import org.semanticweb.owl.model.OWLDataValue;
import org.semanticweb.owl.model.OWLDataValueRestriction;
import org.semanticweb.owl.model.OWLDescription;
import org.semanticweb.owl.model.OWLDifferentIndividualsAxiom;
import org.semanticweb.owl.model.OWLDisjointClassesAxiom;
import org.semanticweb.owl.model.OWLEntity;
import org.semanticweb.owl.model.OWLEnumeration;
import org.semanticweb.owl.model.OWLEquivalentClassesAxiom;
import org.semanticweb.owl.model.OWLEquivalentPropertiesAxiom;
import org.semanticweb.owl.model.OWLException;
import org.semanticweb.owl.model.OWLIndividual;
import org.semanticweb.owl.model.OWLIndividualAxiom;
import org.semanticweb.owl.model.OWLNot;
import org.semanticweb.owl.model.OWLObjectAllRestriction;
import org.semanticweb.owl.model.OWLObjectCardinalityRestriction;
import org.semanticweb.owl.model.OWLObjectProperty;
import org.semanticweb.owl.model.OWLObjectQuantifiedRestriction;
import org.semanticweb.owl.model.OWLObjectSomeRestriction;
import org.semanticweb.owl.model.OWLObjectValueRestriction;
import org.semanticweb.owl.model.OWLOntology;
import org.semanticweb.owl.model.OWLOr;
import org.semanticweb.owl.model.OWLProperty;
import org.semanticweb.owl.model.OWLPropertyAxiom;
import org.semanticweb.owl.model.OWLRestriction;
import org.semanticweb.owl.model.OWLSameIndividualsAxiom;
import org.semanticweb.owl.model.OWLSubClassAxiom;
import org.semanticweb.owl.model.OWLSubPropertyAxiom;
import org.semanticweb.owl.model.change.AddAnnotationInstance;
import org.semanticweb.owl.model.change.AddClassAxiom;
import org.semanticweb.owl.model.change.AddDataPropertyInstance;
import org.semanticweb.owl.model.change.AddDataPropertyRange;
import org.semanticweb.owl.model.change.AddDomain;
import org.semanticweb.owl.model.change.AddEnumeration;
import org.semanticweb.owl.model.change.AddEquivalentClass;
import org.semanticweb.owl.model.change.AddIndividualAxiom;
import org.semanticweb.owl.model.change.AddIndividualClass;
import org.semanticweb.owl.model.change.AddInverse;
import org.semanticweb.owl.model.change.AddObjectPropertyInstance;
import org.semanticweb.owl.model.change.AddObjectPropertyRange;
import org.semanticweb.owl.model.change.AddPropertyAxiom;
import org.semanticweb.owl.model.change.AddSuperClass;
import org.semanticweb.owl.model.change.AddSuperProperty;
import org.semanticweb.owl.model.change.ChangeVisitor;
import org.semanticweb.owl.model.change.OntologyChange;
import org.semanticweb.owl.model.change.RemoveClassAxiom;
import org.semanticweb.owl.model.change.RemoveDataPropertyInstance;
import org.semanticweb.owl.model.change.RemoveDomain;
import org.semanticweb.owl.model.change.RemoveEntity;
import org.semanticweb.owl.model.change.RemoveEnumeration;
import org.semanticweb.owl.model.change.RemoveEquivalentClass;
import org.semanticweb.owl.model.change.RemoveIndividualAxiom;
import org.semanticweb.owl.model.change.RemoveIndividualClass;
import org.semanticweb.owl.model.change.RemoveInverse;
import org.semanticweb.owl.model.change.RemoveObjectPropertyInstance;
import org.semanticweb.owl.model.change.RemoveObjectPropertyRange;
import org.semanticweb.owl.model.change.RemovePropertyAxiom;
import org.semanticweb.owl.model.change.RemoveSuperClass;
import org.semanticweb.owl.model.change.RemoveSuperProperty;
import org.semanticweb.owl.model.change.SetFunctional;
import org.semanticweb.owl.model.change.SetInverseFunctional;
import org.semanticweb.owl.model.change.SetSymmetric;
import org.semanticweb.owl.model.change.SetTransitive;
/**
* @author Aditya Kalyanpur
*
*/
public class OWLEntityRemover {
private OWLOntology ontology;
private OWLEntity remEntity;
private OWLEntity replEntity;
final static int ANNOTATION = -1;
final static int SUPERCLASS = 0;
final static int EQUIVALENTCLASS = 1;
final static int ENUMERATION = 2;
final static int SUBCLASSAXIOM = 3;
final static int EQUCLASSAXIOM = 4;
final static int DISJOINTAXIOM = 5;
final static int SUPERPROPERTY = 6;
final static int EQUIVALENTPROPERTY = 7;
final static int SUBPROPAXIOM = 8;
final static int EQUPROPAXIOM = 9;
final static int DOMAIN = 10;
final static int RANGE = 11; // object property range
final static int INVERSE = 12;
final static int INDIVIDUALCLASS = 13;
final static int INDDATAPROP = 14;
final static int INDOBJPROP = 15;
final static int SAMEAS = 16;
final static int DIFFFROM = 17;
final static String DISCARD = "DISCARD";
private List changes;
public OWLEntityRemover(OWLOntology ontology) {
this.ontology = ontology;
this.changes = new ArrayList();
}
/**
* Replace an OWL Entity with another OWL Entity of the same type
* @param removeEntity
* @param replaceEntity
*/
public void replaceEntity(OWLEntity removeEntity, OWLEntity replaceEntity) {
this.replEntity = replaceEntity; // set this field
this.removeEntity(removeEntity); // now call this method which will remove and replace when necessary
}
/**
* Removes all references of an entity from an ontology
* @param removeEntity
*/
public void removeEntity(OWLEntity removeEntity) {
this.remEntity = removeEntity;
try {
// check all classes
for (Iterator iter = ontology.getClasses().iterator(); iter.hasNext();) {
OWLClass cla = (OWLClass) iter.next();
// check all basic stuff that would get removed automatically
// by using RemoveEntity on class
if (cla.equals(remEntity) && replEntity!=null) {
// move superclasses, equivalentclasses, enumerations, annotations
for (Iterator iter2 = cla.getSuperClasses(ontology).iterator(); iter2.hasNext();) {
OWLDescription sup = (OWLDescription) iter2.next();
this.addChange(replEntity, sup, this.SUPERCLASS);
}
for (Iterator iter2 = cla.getEquivalentClasses(ontology).iterator(); iter2.hasNext();) {
OWLDescription equ = (OWLDescription) iter2.next();
this.addChange(replEntity, equ, this.EQUIVALENTCLASS);
}
for (Iterator iter2 = cla.getEnumerations(ontology).iterator(); iter2.hasNext();) {
OWLEnumeration enu = (OWLEnumeration) iter2.next();
this.addChange(replEntity, enu, this.ENUMERATION);
}
for (Iterator iter2 = cla.getAnnotations(ontology).iterator(); iter2.hasNext();) {
OWLAnnotationInstance oai = (OWLAnnotationInstance) iter2.next();
this.addChange(replEntity, oai, this.ANNOTATION);
}
}
// check super classes
Set sup = cla.getSuperClasses(ontology);
for (Iterator iter2= sup.iterator(); iter2.hasNext();) {
OWLDescription desc = (OWLDescription) iter2.next();
this.checkClassRelation(cla, desc, SUPERCLASS);
}
// check equivalent classes
Set equ = cla.getEquivalentClasses(ontology);
for (Iterator iter2= equ.iterator(); iter2.hasNext();) {
OWLDescription desc = (OWLDescription) iter2.next();
this.checkClassRelation(cla, desc, EQUIVALENTCLASS);
}
// check enumerations
Set enuSet = cla.getEnumerations(ontology);
for (Iterator iter2= enuSet.iterator(); iter2.hasNext();) {
OWLEnumeration enu = (OWLEnumeration) iter2.next();
Set ops = enu.getIndividuals();
boolean changed = false;
for (Iterator iter3=new HashSet(ops).iterator(); iter3.hasNext();) {
OWLIndividual ind = (OWLIndividual) iter3.next();
if (ind.equals(remEntity)) {
changed = true;
ops.remove(ind);
if (replEntity!=null) ops.add(replEntity);
}
}
if (changed) {
// remove current enumeration and add new enum
this.removeChange(cla, enu, ENUMERATION);
if (ops.size()>0) {
OWLEnumeration newEnu = ontology.getOWLDataFactory().getOWLEnumeration(ops);
this.addChange(cla, newEnu, ENUMERATION);
}
}
}
}
// check class axioms
for (Iterator iter = ontology.getClassAxioms().iterator(); iter.hasNext();) {
OWLClassAxiom axiom = (OWLClassAxiom) iter.next();
// check sub class axioms
if (axiom instanceof OWLSubClassAxiom) {
OWLSubClassAxiom subAxiom = (OWLSubClassAxiom) axiom;
this.checkClassRelation(subAxiom.getSubClass(), subAxiom.getSuperClass(), SUBCLASSAXIOM);
}
// check equivalent class axioms
else if (axiom instanceof OWLEquivalentClassesAxiom) {
OWLEquivalentClassesAxiom equAxiom = (OWLEquivalentClassesAxiom) axiom;
Set equOps = equAxiom.getEquivalentClasses();
boolean changed = false;
for (Iterator iter2 = new HashSet(equOps).iterator(); iter2.hasNext();) {
OWLDescription desc = (OWLDescription) iter2.next();
Object check = this.traceDescription(desc);
if (check!=null) {
changed = true;
equOps.remove(desc);
if (check instanceof OWLDescription) {
equOps.add((OWLDescription) check);
}
}
}
if (changed) {
this.removeChange(equAxiom.getEquivalentClasses(), null, EQUCLASSAXIOM);
this.addChange(equOps, null, EQUCLASSAXIOM);
}
}
// check disjoint class axioms
else if (axiom instanceof OWLDisjointClassesAxiom) {
OWLDisjointClassesAxiom disAxiom = (OWLDisjointClassesAxiom) axiom;
Set disOps = disAxiom.getDisjointClasses();
boolean changed = false;
for (Iterator iter2 = new HashSet(disOps).iterator(); iter2.hasNext();) {
OWLDescription desc = (OWLDescription) iter2.next();
Object check = this.traceDescription(desc);
if (check!=null) {
changed = true;
disOps.remove(desc);
if (check instanceof OWLDescription) {
disOps.add((OWLDescription) check);
}
}
}
if (changed) {
this.removeChange(disAxiom.getDisjointClasses(), null, DISJOINTAXIOM);
this.addChange(disOps, null, DISJOINTAXIOM);
}
}
}
// check all data/object properties (annotation?)
Set properties = ontology.getDataProperties();
properties.addAll(ontology.getObjectProperties());
for (Iterator iter = properties.iterator(); iter.hasNext();) {
OWLProperty prop = (OWLProperty) iter.next();
// check all basic stuff that would get removed automatically
// by using RemoveEntity on property
if (prop.equals(remEntity) && replEntity!=null) {
// add domain of remEntity to replEntity
for (Iterator iter2 = prop.getDomains(ontology).iterator(); iter2.hasNext();) {
OWLDescription dom = (OWLDescription) iter2.next();
this.addChange(replEntity, dom, this.DOMAIN);
}
// add super-props, functional and annotations
for (Iterator iter2 = prop.getSuperProperties(ontology).iterator(); iter2.hasNext();) {
OWLProperty sup = (OWLProperty) iter2.next();
this.addChange(replEntity, sup, this.SUPERPROPERTY);
}
if (prop.isFunctional(ontology)) {
SetFunctional sf = new SetFunctional(ontology, (OWLProperty) replEntity, true, null);
changes.add(sf);
}
for (Iterator iter2 = prop.getAnnotations(ontology).iterator(); iter2.hasNext();) {
OWLAnnotationInstance oai = (OWLAnnotationInstance) iter2.next();
this.addChange(replEntity, oai, this.ANNOTATION);
}
if (prop instanceof OWLDataProperty) {
OWLDataProperty dp = (OWLDataProperty) prop;
// add data property range
for (Iterator iter2 = dp.getRanges(ontology).iterator(); iter2.hasNext();) {
OWLDataType dt = (OWLDataType) iter2.next();
AddDataPropertyRange adpr = new AddDataPropertyRange(ontology, (OWLDataProperty) replEntity, dt, null);
changes.add(adpr);
}
}
else if (prop instanceof OWLObjectProperty) {
// check range, inverse-props, and prop attributes
for (Iterator iter2 = prop.getRanges(ontology).iterator(); iter2.hasNext();) {
OWLDescription ran = (OWLDescription) iter2.next();
this.addChange(replEntity, ran, this.RANGE);
}
for (Iterator iter2 = ((OWLObjectProperty) prop).getInverses(ontology).iterator(); iter2.hasNext();) {
OWLObjectProperty inv = (OWLObjectProperty) iter2.next();
this.addChange(replEntity, inv, this.INVERSE);
}
if (((OWLObjectProperty) prop).isInverseFunctional(ontology)) {
SetInverseFunctional sif = new SetInverseFunctional(ontology, (OWLObjectProperty) replEntity, true, null);
changes.add(sif);
}
if (((OWLObjectProperty) prop).isTransitive(ontology)) {
SetTransitive st = new SetTransitive(ontology, (OWLObjectProperty) replEntity, true, null);
changes.add(st);
}
if (((OWLObjectProperty) prop).isSymmetric(ontology)) {
SetSymmetric ss = new SetSymmetric(ontology, (OWLObjectProperty) replEntity, true, null);
changes.add(ss);
}
}
}
// check all super properties
// *** different from adding superprops *of* remProp as done above,
// *** below checks if superProp = remProp
for (Iterator iter2=prop.getSuperProperties(ontology).iterator(); iter2.hasNext();) {
OWLProperty sup = (OWLProperty) iter2.next();
if (sup.equals(remEntity)) {
this.removeChange(prop, sup, SUPERPROPERTY);
if (replEntity!=null) this.addChange(prop, replEntity, SUPERPROPERTY);
}
}
// check all property domains
for (Iterator iter2=prop.getDomains(ontology).iterator(); iter2.hasNext();) {
OWLDescription desc = (OWLDescription) iter2.next();
Object check = this.traceDescription(desc);
if (check!=null) {
this.removeChange(prop, desc, DOMAIN);
if (check instanceof OWLDescription) {
this.addChange(prop, check, DOMAIN);
}
}
}
// check for all object properties
if (prop instanceof OWLObjectProperty && !((OWLObjectProperty) prop).isLink()) {
// check property ranges
for (Iterator iter2=prop.getRanges(ontology).iterator(); iter2.hasNext();) {
OWLDescription desc = (OWLDescription) iter2.next();
Object check = this.traceDescription(desc);
if (check!=null) {
this.removeChange(prop, desc, RANGE);
if (check instanceof OWLDescription) {
this.addChange(prop, check, RANGE);
}
}
}
// check inverses
for (Iterator iter2=((OWLObjectProperty) prop).getInverses(ontology).iterator(); iter2.hasNext();) {
OWLObjectProperty invProp = (OWLObjectProperty) iter2.next();
if (invProp.equals(remEntity)) {
this.removeChange(prop, invProp, INVERSE);
if (replEntity!=null) this.addChange(prop, replEntity, INVERSE);
}
}
}
}
// check property axioms
for (Iterator iter = ontology.getPropertyAxioms().iterator(); iter.hasNext();) {
OWLPropertyAxiom axiom = (OWLPropertyAxiom) iter.next();
// check sub prop axioms
if (axiom instanceof OWLSubPropertyAxiom) {
OWLSubPropertyAxiom subAxiom = (OWLSubPropertyAxiom) axiom;
OWLProperty sub = subAxiom.getSubProperty();
OWLProperty sup = subAxiom.getSuperProperty();
if (sub.equals(remEntity) || sup.equals(remEntity)) {
this.removeChange(sub, sup, SUBPROPAXIOM);
if (replEntity!=null && !sub.equals(remEntity)) this.addChange(sub, replEntity, SUBPROPAXIOM);
if (replEntity!=null && !sup.equals(remEntity)) this.addChange(replEntity, sup, SUBPROPAXIOM);
}
}
// check equivalent property axioms
else if (axiom instanceof OWLEquivalentPropertiesAxiom) {
OWLEquivalentPropertiesAxiom equAxiom = (OWLEquivalentPropertiesAxiom) axiom;
Set equOps = equAxiom.getProperties();
boolean changed = false;
for (Iterator iter2=new HashSet(equOps).iterator(); iter2.hasNext();) {
OWLProperty prop = (OWLProperty) iter2.next();
if (prop.equals(remEntity)) {
changed = true;
equOps.remove(prop);
if (replEntity!=null) equOps.add(replEntity);
}
}
if (changed) {
this.removeChange(equAxiom.getProperties(), null, EQUPROPAXIOM);
this.addChange(equOps, null, EQUPROPAXIOM);
}
}
}
// check all individuals
for (Iterator iter = ontology.getIndividuals().iterator(); iter.hasNext();) {
OWLIndividual ind = (OWLIndividual) iter.next();
// check all basic stuff that would get removed automatically
// by using RemoveEntity on individual
if (ind.equals(remEntity) && replEntity!=null) {
// move types, obj/data prop-values, annotations
for (Iterator iter2=ind.getTypes(ontology).iterator(); iter2.hasNext();) {
OWLDescription desc = (OWLDescription) iter2.next();
this.addChange(replEntity, desc, this.INDIVIDUALCLASS);
}
Map dValues = ind.getDataPropertyValues(ontology);
for (Iterator iter2 = dValues.keySet().iterator(); iter2.hasNext();) {
OWLDataProperty prop = (OWLDataProperty) iter2.next();
Set vals = (HashSet) dValues.get(prop);
for (Iterator valIter = vals.iterator(); valIter.hasNext();) {
OWLDataValue value = (OWLDataValue) valIter.next();
OntologyChange change = new AddDataPropertyInstance(ontology, (OWLIndividual) replEntity, prop, value, null);
changes.add(change);
}
}
Map oValues = ind.getObjectPropertyValues(ontology);
for (Iterator iter2 = oValues.keySet().iterator(); iter2.hasNext();) {
OWLObjectProperty prop = (OWLObjectProperty) iter2.next();
Set vals = (HashSet) oValues.get(prop);
for (Iterator valIter = vals.iterator(); valIter.hasNext();) {
OWLIndividual value = (OWLIndividual) valIter.next();
OntologyChange change = new AddObjectPropertyInstance(ontology, (OWLIndividual) replEntity, prop, value, null);
changes.add(change);
}
}
for (Iterator iter2=ind.getAnnotations(ontology).iterator(); iter2.hasNext();) {
OWLAnnotationInstance oai = (OWLAnnotationInstance) iter2.next();
this.addChange(replEntity, oai, this.ANNOTATION);
}
}
// check all individual types
for (Iterator iter2=ind.getTypes(ontology).iterator(); iter2.hasNext();) {
OWLDescription desc = (OWLDescription) iter2.next();
Object check = this.traceDescription(desc);
if (check!=null) {
this.removeChange(ind, desc, INDIVIDUALCLASS);
if (check instanceof OWLDescription) {
this.addChange(ind, check, INDIVIDUALCLASS);
}
}
}
// check data property value instances
Map dValues = ind.getDataPropertyValues(ontology);
for (Iterator iter2 = dValues.keySet().iterator(); iter2.hasNext();) {
OWLDataProperty prop = (OWLDataProperty) iter2.next();
Set vals = (HashSet) dValues.get(prop);
for (Iterator valIter = vals.iterator(); valIter.hasNext();) {
OWLDataValue value = (OWLDataValue) valIter.next();
if (prop.equals(remEntity)) {
OntologyChange change = new RemoveDataPropertyInstance(ontology, ind, prop, value, null);
changes.add(change);
if (replEntity!=null) {
OntologyChange change2 = new AddDataPropertyInstance(ontology, ind, (OWLDataProperty) replEntity, value, null);
changes.add(change2);
}
}
}
}
// check object property value instances
Map oValues = ind.getObjectPropertyValues(ontology);
for (Iterator iter2 = oValues.keySet().iterator(); iter2.hasNext();) {
OWLObjectProperty prop = (OWLObjectProperty) iter2.next();
Set vals = (HashSet) oValues.get(prop);
for (Iterator valIter = vals.iterator(); valIter.hasNext();) {
OWLIndividual value = (OWLIndividual) valIter.next();
if (prop.equals(remEntity) || value.equals(remEntity)) {
OntologyChange change = new RemoveObjectPropertyInstance(ontology, ind, prop, value, null);
changes.add(change);
if (prop.equals(remEntity) && replEntity!=null) {
OntologyChange change2 = new AddObjectPropertyInstance(ontology, ind, (OWLObjectProperty) replEntity, value, null);
changes.add(change2);
}
if (value.equals(remEntity) && replEntity!=null) {
OntologyChange change2 = new AddObjectPropertyInstance(ontology, ind, prop, (OWLIndividual) replEntity, null);
changes.add(change2);
}
}
}
}
}
// check individual axioms
for (Iterator iter = ontology.getIndividualAxioms().iterator(); iter.hasNext();) {
OWLIndividualAxiom axiom = (OWLIndividualAxiom) iter.next();
// check sameAs b/w individuals
if (axiom instanceof OWLSameIndividualsAxiom) {
OWLSameIndividualsAxiom sameAxiom = (OWLSameIndividualsAxiom) axiom;
Set sameOps = sameAxiom.getIndividuals();
boolean changed = false;
for (Iterator iter2 = new HashSet(sameOps).iterator(); iter2.hasNext();) {
OWLIndividual ind = (OWLIndividual) iter2.next();
if (ind.equals(remEntity)) {
changed = true;
sameOps.remove(ind);
if (replEntity!=null) sameOps.add(replEntity);
}
}
if (changed) {
this.removeChange(sameAxiom.getIndividuals(), null, SAMEAS);
this.addChange(sameOps, null, SAMEAS);
}
}
// check differentFrom b/w individuals
if (axiom instanceof OWLDifferentIndividualsAxiom) {
OWLDifferentIndividualsAxiom diffAxiom = (OWLDifferentIndividualsAxiom) axiom;
Set diffOps = diffAxiom.getIndividuals();
boolean changed = false;
for (Iterator iter2 = new HashSet(diffOps).iterator(); iter2.hasNext();) {
OWLIndividual ind = (OWLIndividual) iter2.next();
if (ind.equals(remEntity)) {
changed = true;
diffOps.remove(ind);
if (replEntity!=null) diffOps.add(replEntity);
}
}
if (changed) {
this.removeChange(diffAxiom.getIndividuals(), null, DIFFFROM);
this.addChange(diffOps, null, DIFFFROM);
}
}
}
// add removeEntity change right at the end
OntologyChange change = new RemoveEntity(ontology, remEntity, null);
changes.add(change);
// finally apply changes
for (Iterator iter = changes.iterator(); iter.hasNext();) {
change = (OntologyChange) iter.next();
change.accept((ChangeVisitor) ontology);
}
}
catch (OWLException ex) {
ex.printStackTrace();
}
}
/**
* Updates class relation (type: subclass/equivalent..) as follows:
* Traces contents of desc1 to see if entity found inside
* and contents of desc2 to see if entity found inside
* Based on checks made, adds/removes changes based on relation type specified
* @param desc1
* @param desc2
* @param relType
* @throws OWLException
*/
public void checkClassRelation(OWLDescription desc1, OWLDescription desc2, int relType) throws OWLException {
boolean changed = false;
OWLDescription addDesc1 = null;
OWLDescription addDesc2 = null;
// verify contents of description 1
Object check = this.traceDescription(desc1);
if (check!=null) {
// match found for entity
changed = true;
// get updated desc if any
if (check instanceof OWLDescription) addDesc1 = (OWLDescription) check;
}
// verify contents of description 2
check = this.traceDescription(desc2);
if (check!=null) {
// match found for entity
changed = true;
// get updated desc if any
if (check instanceof OWLDescription) addDesc2 = (OWLDescription) check;
}
// make changes based on verification check above
if (changed || addDesc1!=null || addDesc2!=null) this.removeChange(desc1, desc2, relType);
if (addDesc1!=null && addDesc2!=null) this.addChange(addDesc1, addDesc2, relType);
else if (addDesc1!=null) this.addChange(addDesc1, desc2, relType);
else if (addDesc2!=null) this.addChange(desc1, addDesc2, relType);
}
/**
* Traces the contents of an OWLDescription (desc) as follows:
* - if desc matches entity [A, ~A, restr(P,*) or hasValue(*,I)], returns DISCARD
* - else if desc contains entity, returns newDesc (minus entity)
* In all other cases (no match for entity at all), returns Null
*
* @param desc
* @return
*/
public Object traceDescription(OWLDescription desc) {
try {
// // testing
// if (desc instanceof OWLClass) System.out.println("tracing: "+((OWLClass) desc).getURI());
if (desc instanceof OWLClass && ((OWLClass) desc).equals(remEntity)) {
if (replEntity!=null) return replEntity;
else return this.DISCARD;
}
else
if (desc instanceof OWLAnd) {
// if description is intersection, get operands
OWLAnd and = (OWLAnd) desc;
Set operands = and.getOperands();
boolean changed = false;
for (Iterator iter = new HashSet(operands).iterator(); iter.hasNext();) {
OWLDescription andOp = (OWLDescription) iter.next();
Object check = this.traceDescription(andOp);
if (check!=null) {
// match found for entity
changed = true;
operands.remove(andOp);
// add new (updated) description if any
if (check instanceof OWLDescription) operands.add((OWLDescription) check);
}
}
if (changed) {
return ontology.getOWLDataFactory().getOWLAnd(operands);
}
}
else
if (desc instanceof OWLOr) {
// if description is union, get operands
OWLOr or = (OWLOr) desc;
Set operands = or.getOperands();
boolean changed = false;
for (Iterator iter = new HashSet(operands).iterator(); iter.hasNext();) {
OWLDescription orOp = (OWLDescription) iter.next();
Object check = this.traceDescription(orOp);
if (check!=null) {
// match found for entity
changed = true;
operands.remove(orOp);
// add new (updated) description if any
if (check instanceof OWLDescription) operands.add((OWLDescription) check);
}
}
if (changed) {
return ontology.getOWLDataFactory().getOWLOr(operands);
}
}
else
if (desc instanceof OWLNot) {
OWLNot not = (OWLNot) desc;
Object check = traceDescription(not.getOperand());
if (check!=null) {
// match found for entity
// either return updated ~Desc or DISCARD
if (check instanceof OWLDescription) return ontology.getOWLDataFactory().getOWLNot((OWLDescription) check);
else {
if (replEntity!=null) return replEntity;
else return this.DISCARD; // e.g. ~A. where entity = A
}
}
}
else
if (desc instanceof OWLRestriction) {
// check property of restriction first to discard entire restriction
if (((OWLRestriction) desc).getProperty().equals(remEntity)) {
if (replEntity!=null) {
// create OWLRestriction replacing prop w/ replEntity
return replaceRestriction((OWLRestriction) desc, (OWLProperty) replEntity);
}
else return this.DISCARD;
}
// check some/all value restriction
if (desc instanceof OWLObjectQuantifiedRestriction) {
OWLObjectQuantifiedRestriction objRes = (OWLObjectQuantifiedRestriction) desc;
OWLObjectProperty oprop = objRes.getObjectProperty();
Object check = traceDescription(objRes.getDescription());
if (check!=null) {
if (check instanceof OWLDescription) {
// return new restriction
OWLObjectQuantifiedRestriction rest = null;
if (objRes instanceof OWLObjectAllRestriction) rest = ontology.getOWLDataFactory().getOWLObjectAllRestriction(oprop, (OWLDescription) check);
else rest = ontology.getOWLDataFactory().getOWLObjectSomeRestriction(oprop, (OWLDescription) check);
return rest;
}
else {
if (replEntity!=null) return replEntity;
else return this.DISCARD; // e.g exists(P,C), where entity = P;
}
}
}
// finally check hasValue restriction
if (desc instanceof OWLObjectValueRestriction) {
OWLObjectValueRestriction objRes = (OWLObjectValueRestriction) desc;
// discard if match found for individual
if (objRes.getIndividual().equals(remEntity)) {
if (replEntity!=null) return replEntity;
else return this.DISCARD;
}
}
}
else if (desc instanceof OWLEnumeration) {
// check contents of enum to see if entity found
boolean changed = false;
Set indOps = ((OWLEnumeration) desc).getIndividuals();
for (Iterator iter = new HashSet(indOps).iterator(); iter.hasNext();) {
OWLIndividual ind = (OWLIndividual) iter.next();
if (ind.equals(remEntity)) {
// match found
changed = true;
indOps.remove(ind);
if (replEntity!=null) indOps.add(replEntity);
}
}
if (changed) {
if (indOps.size()==0) {
if (replEntity!=null) return replEntity;
else return this.DISCARD;
}
else {
return ontology.getOWLDataFactory().getOWLEnumeration(indOps);
}
}
}
}
catch (OWLException ex) {
ex.printStackTrace();
}
return null;
}
public void removeChange(Object subj, Object obj, int relType) throws OWLException {
OntologyChange changed = null;
switch (relType) {
case SUPERCLASS:
changed = new RemoveSuperClass(ontology, (OWLClass) subj, (OWLDescription) obj, null);
changes.add(changed);
break;
case EQUIVALENTCLASS:
changed = new RemoveEquivalentClass(ontology, (OWLClass) subj, (OWLDescription) obj, null);
changes.add(changed);
break;
case ENUMERATION:
changed = new RemoveEnumeration(ontology, (OWLClass) subj, (OWLEnumeration) obj, null);
changes.add(changed);
break;
case SUBCLASSAXIOM:
OWLSubClassAxiom axiom = ontology.getOWLDataFactory().getOWLSubClassAxiom((OWLDescription) subj, (OWLDescription) obj);
changed = new RemoveClassAxiom(ontology, axiom, null);
changes.add(changed);
break;
case EQUCLASSAXIOM:
OWLEquivalentClassesAxiom equAxiom = ontology.getOWLDataFactory().getOWLEquivalentClassesAxiom((Set) subj);
changed = new RemoveClassAxiom(ontology, equAxiom, null);
changes.add(changed);
break;
case DISJOINTAXIOM:
OWLDisjointClassesAxiom disAxiom = ontology.getOWLDataFactory().getOWLDisjointClassesAxiom((Set) subj);
changed = new RemoveClassAxiom(ontology, disAxiom, null);
changes.add(changed);
break;
case SUPERPROPERTY:
changed = new RemoveSuperProperty(ontology, (OWLProperty) subj, (OWLProperty) obj, null);
changes.add(changed);
break;
case SUBPROPAXIOM:
OWLSubPropertyAxiom subPAxiom = ontology.getOWLDataFactory().getOWLSubPropertyAxiom((OWLProperty) subj, (OWLProperty) obj);
changed = new RemovePropertyAxiom(ontology, subPAxiom, null);
changes.add(changed);
break;
case EQUPROPAXIOM:
OWLEquivalentPropertiesAxiom equPAxiom = ontology.getOWLDataFactory().getOWLEquivalentPropertiesAxiom((Set) subj);
changed = new RemovePropertyAxiom(ontology, equPAxiom, null);
changes.add(changed);
break;
case DOMAIN:
changed = new RemoveDomain(ontology, (OWLProperty) subj, (OWLDescription) obj, null);
changes.add(changed);
break;
case RANGE:
changed = new RemoveObjectPropertyRange(ontology, (OWLObjectProperty) subj, (OWLDescription) obj, null);
changes.add(changed);
break;
case INVERSE:
changed = new RemoveInverse(ontology, (OWLObjectProperty) subj, (OWLObjectProperty) obj, null);
changes.add(changed);
break;
case INDIVIDUALCLASS:
changed = new RemoveIndividualClass(ontology, (OWLIndividual) subj, (OWLDescription) obj, null);
changes.add(changed);
break;
case SAMEAS:
OWLSameIndividualsAxiom same = ontology.getOWLDataFactory().getOWLSameIndividualsAxiom((Set) subj);
changed = new RemoveIndividualAxiom(ontology, same, null);
changes.add(changed);
break;
case DIFFFROM:
OWLDifferentIndividualsAxiom diff = ontology.getOWLDataFactory().getOWLDifferentIndividualsAxiom((Set) subj);
changed = new RemoveIndividualAxiom(ontology, diff, null);
changes.add(changed);
break;
}
}
public void addChange(Object subj, Object obj, int relType) throws OWLException {
OntologyChange changed = null;
switch (relType) {
case ANNOTATION:
changed = new AddAnnotationInstance(ontology, (OWLEntity) subj, ((OWLAnnotationInstance) obj).getProperty(), ((OWLAnnotationInstance) obj).getContent(), null);
changes.add(changed);
break;
case SUPERCLASS:
changed = new AddSuperClass(ontology, (OWLClass) subj, (OWLDescription) obj, null);
changes.add(changed);
break;
case EQUIVALENTCLASS:
changed = new AddEquivalentClass(ontology, (OWLClass) subj, (OWLDescription) obj, null);
changes.add(changed);
break;
case ENUMERATION:
changed = new AddEnumeration(ontology, (OWLClass) subj, (OWLEnumeration) obj, null);
changes.add(changed);
break;
case SUBCLASSAXIOM:
OWLSubClassAxiom axiom = ontology.getOWLDataFactory().getOWLSubClassAxiom((OWLDescription) subj, (OWLDescription) obj);
changed = new AddClassAxiom(ontology, axiom, null);
changes.add(changed);
break;
case EQUCLASSAXIOM:
OWLEquivalentClassesAxiom equAxiom = ontology.getOWLDataFactory().getOWLEquivalentClassesAxiom((Set) subj);
changed = new AddClassAxiom(ontology, equAxiom, null);
changes.add(changed);
break;
case DISJOINTAXIOM:
OWLDisjointClassesAxiom disAxiom = ontology.getOWLDataFactory().getOWLDisjointClassesAxiom((Set) subj);
changed = new AddClassAxiom(ontology, disAxiom, null);
changes.add(changed);
break;
case SUPERPROPERTY:
changed = new AddSuperProperty(ontology, (OWLProperty) subj, (OWLProperty) obj, null);
changes.add(changed);
break;
case EQUPROPAXIOM:
OWLEquivalentPropertiesAxiom equPAxiom = ontology.getOWLDataFactory().getOWLEquivalentPropertiesAxiom((Set) subj);
changed = new AddPropertyAxiom(ontology, equPAxiom, null);
changes.add(changed);
break;
case DOMAIN:
changed = new AddDomain(ontology, (OWLProperty) subj, (OWLDescription) obj, null);
changes.add(changed);
break;
case RANGE:
changed = new AddObjectPropertyRange(ontology, (OWLObjectProperty) subj, (OWLDescription) obj, null);
changes.add(changed);
break;
case INVERSE:
changed = new AddInverse(ontology, (OWLObjectProperty) subj, (OWLObjectProperty) obj, null);
changes.add(changed);
break;
case INDIVIDUALCLASS:
changed = new AddIndividualClass(ontology, (OWLIndividual) subj, (OWLDescription) obj, null);
changes.add(changed);
break;
case SAMEAS:
OWLSameIndividualsAxiom same = ontology.getOWLDataFactory().getOWLSameIndividualsAxiom((Set) subj);
changed = new AddIndividualAxiom(ontology, same, null);
changes.add(changed);
break;
case DIFFFROM:
OWLDifferentIndividualsAxiom diff = ontology.getOWLDataFactory().getOWLDifferentIndividualsAxiom((Set) subj);
changed = new AddIndividualAxiom(ontology, diff, null);
changes.add(changed);
break;
}
}
private OWLRestriction replaceRestriction(OWLRestriction res, OWLProperty prop) {
try {
OWLDataFactory df = res.getOWLDataFactory();
// object prop restrictions
if (res instanceof OWLObjectAllRestriction) {
return df.getOWLObjectAllRestriction((OWLObjectProperty) prop, ((OWLObjectAllRestriction) res).getDescription());
}
else if (res instanceof OWLObjectSomeRestriction) {
return df.getOWLObjectSomeRestriction((OWLObjectProperty) prop, ((OWLObjectSomeRestriction) res).getDescription());
}
else if (res instanceof OWLObjectValueRestriction) {
return df.getOWLObjectValueRestriction((OWLObjectProperty) prop, ((OWLObjectValueRestriction) res).getIndividual());
}
else if (res instanceof OWLObjectCardinalityRestriction) {
return df.getOWLObjectCardinalityRestriction((OWLObjectProperty) prop, ((OWLObjectCardinalityRestriction) res).getAtLeast(), ((OWLObjectCardinalityRestriction) res).getAtMost());
}
// dataprop restrictions
else if (res instanceof OWLDataAllRestriction) {
return df.getOWLDataAllRestriction((OWLDataProperty) prop, ((OWLDataAllRestriction) res).getDataType());
}
else if (res instanceof OWLDataSomeRestriction) {
return df.getOWLDataSomeRestriction((OWLDataProperty) prop, ((OWLDataSomeRestriction) res).getDataType());
}
else if (res instanceof OWLDataValueRestriction) {
return df.getOWLDataValueRestriction((OWLDataProperty) prop, ((OWLDataValueRestriction) res).getValue());
}
else if (res instanceof OWLDataCardinalityRestriction) {
return df.getOWLDataCardinalityRestriction((OWLDataProperty) prop, ((OWLDataCardinalityRestriction) res).getAtLeast(), ((OWLDataCardinalityRestriction) res).getAtMost());
}
}
catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
}