/*******************************************************************************
* This file is part of the Coporate Semantic Web Project.
*
* This work has been partially supported by the ``InnoProfile-Corporate Semantic Web" project funded by the German Federal
* Ministry of Education and Research (BMBF) and the BMBF Innovation Initiative for the New German Laender - Entrepreneurial Regions.
*
* http://www.corporate-semantic-web.de/
*
*
* Freie Universitaet Berlin
* Copyright (c) 2007-2013
*
*
* Institut fuer Informatik
* Working Group Coporate Semantic Web
* Koenigin-Luise-Strasse 24-26
* 14195 Berlin
*
* http://www.mi.fu-berlin.de/en/inf/groups/ag-csw/
*
*
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or see <http://www.gnu.org/licenses/>
******************************************************************************/
package de.fuberlin.agcsw.svont.changedetection;
import java.net.URI;
import java.util.Collections;
import java.util.Set;
import org.apache.log4j.Logger;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLDataProperty;
import org.semanticweb.owlapi.model.OWLIndividual;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyChangeException;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.util.OWLEntityRemover;
import cz.cvut.kbss.owldiff.diff.cex.impl.Diff;
/**
* Implementation of the CEX Diff from OWLdiff
* All DiffL and DiffR Results from the CEX Diff are semantical Changed Classes
*
* http://krizik.felk.cvut.cz/km/owldiff/
*
* @author mario
*
*/
public class CEXDiffAlgorithm implements DiffExecutor {
final Logger log = Logger.getLogger(CEXDiffAlgorithm.class);
private Diff cexDiffForward, cexDiffReverse;
private OWLOntology baseOnt;
private OWLOntology updateOnt;
private DiffResult diffResult;
/* (non-Javadoc)
* @see de.fuberlin.agcsw.svont.changedetection.DiffExecutor#executeDiff(java.net.URI, java.net.URI)
*/
public DiffResult executeDiff(URI baseOntologyURI, URI updateOntologyURI)
throws Exception {
//inits the OntologyManager
OWLOntologyManager baseM = OWLManager.createOWLOntologyManager();
OWLOntologyManager updateM = OWLManager.createOWLOntologyManager();
//loads the Ontologies
baseOnt = baseM.loadOntologyFromOntologyDocument(IRI.create(baseOntologyURI));
updateOnt = updateM.loadOntologyFromOntologyDocument(IRI.create(updateOntologyURI));
// first we execute the BaseDiff and use its results
diffResult = new BaseDiffAlgorithm().executeDiff(baseOntologyURI,
updateOntologyURI);
cexDiffForward = new Diff(null);
cexDiffReverse = new Diff(null);
//clean all except classes out of the ontologies, cause CEX-Diff will fail with "ontologie is no EL" else
prepareOntologyForCEX(baseM,baseOnt);
prepareOntologyForCEX(updateM,updateOnt);
//then we execute the CEX Diff from of the OWLdiff implementation
cexDiffForward.diff(baseM, baseOnt, updateM, updateOnt);
cexDiffReverse.diff(updateM, updateOnt, baseM, baseOnt);
//all classes that are in the sets of DiffL and DiffR has been changed and gets added to the diffResult
processChangedClasses(cexDiffForward.getDiffL());
processChangedClasses(cexDiffForward.getDiffR());
processChangedClasses(cexDiffReverse.getDiffL());
processChangedClasses(cexDiffReverse.getDiffR());
if (log.isDebugEnabled()) {
showDiffClasses(cexDiffForward.getDiffL(),"ForwardDiff Left Classes:");
showDiffClasses(cexDiffForward.getDiffR(),"ForwardDiff Right Classes:");
showDiffClasses(cexDiffReverse.getDiffL(),"ReverseDiff Left Classes:");
showDiffClasses(cexDiffReverse.getDiffR(),"ReverseDiff Right Classes:");
}
return diffResult;
}
/**
* Adds Set of Changed Classes to the DiffResult
*
* @param classes Set of Classes to add
*/
private void processChangedClasses(Set<OWLClass> classes) {
for (OWLClass c : classes) {
if (!diffResult.getChangedClasses().contains(c)) {
diffResult.getChangedClasses().add(c);
}
}
}
/**
* Preparing an Ontology for the EL Description Logic Language used for OWLdiff.
* It removes Individuals, DataProperties and ObjectProperties
*
* @param man OntologyManager of the Ontology
* @param ont The Ontology to Prepare
* @throws OWLOntologyChangeException
*/
private void prepareOntologyForCEX(OWLOntologyManager man, OWLOntology ont) throws OWLOntologyChangeException {
if (log.isDebugEnabled())
log.debug("Preparing Ontology for CEX Diff");
OWLEntityRemover remover = new OWLEntityRemover(man, Collections.singleton(ont));
// TODO check if this means the same thing as ont.getReferencedIndividuals()
Set<OWLNamedIndividual> individuals = ont.getIndividualsInSignature();
if (log.isDebugEnabled())
log.debug("Removing "+individuals.size()+" Individuals from Ontology");
for(OWLIndividual ind : individuals) {
if (ind.isNamed()) {
((OWLNamedIndividual)ind).accept(remover);
} else {
log.warn("Cannot remove anoynmous individual: " + ind);
}
}
Set<OWLDataProperty> dataProperties = ont.getDataPropertiesInSignature();
if (log.isDebugEnabled())
log.debug("Removing "+dataProperties.size()+" DataProperties from Ontology");
for (OWLDataProperty dp : dataProperties) {
dp.accept(remover);
}
Set<OWLObjectProperty> objectProperties = ont.getObjectPropertiesInSignature();
if (log.isDebugEnabled())
log.debug("Removing "+objectProperties.size()+" ObjectProperties from Ontology");
for (OWLObjectProperty op : objectProperties) {
op.accept(remover);
}
man.applyChanges(remover.getChanges());
log.debug("Ontology Prepared for CEX");
}
/**
* Logs the CEX Result
*
* @param classes
* @param type
*/
private void showDiffClasses(Set<OWLClass> classes, String type) {
log.debug(type);
for (OWLClass c : classes) {
log.debug(c);
}
log.debug("---------------");
}
}