/*******************************************************************************
* 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.changelog;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import org.apache.log4j.Logger;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.AddAxiom;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLDataProperty;
import org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom;
import org.semanticweb.owlapi.model.OWLIndividual;
import org.semanticweb.owlapi.model.OWLLiteral;
import org.semanticweb.owlapi.model.OWLNamedObject;
import org.semanticweb.owlapi.model.OWLObject;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyChange;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.vocab.OWL2Datatype;
import de.fuberlin.agcsw.svont.changedetection.DiffResult;
import de.fuberlin.agcsw.svont.preprocessing.CommitInfo;
/**
* OWLAPI Implementation of the Change Log Writer Interface
*
* It appends a ChangeLog owl File to the Change Log Directory with OMV-Changes Individuals
*
* @author mario
*
*/
public class OWLAPIChangeLogWriter implements ChangeLogWriter {
final Logger log = Logger.getLogger(OWLAPIChangeLogWriter.class);
/**
* URI of this part of ChangeLog
*/
private String changeLogURI;
/**
* Directory of Changelog
*/
private String chgLogDir;
/**
* DataManager of OMV-Change Ontology Manager
*/
private OWLDataFactory OMVChangeFactory;
/**
* Commit Info
*/
private CommitInfo ci;
/**
* Counter for ChangesURIS in ChangeLog
*/
private int chgCounter = 1;
/**
* Filename of ChangeLog owl File
*/
private String outputFilename;
/**
* List of changes for the ChangeLog
*/
private List<OWLOntologyChange> changes = new ArrayList<OWLOntologyChange>();
/**
* Creats the Writer Object
*
* @param props Properties from Configuration File
* @param ci CommitInfo Object
*/
public OWLAPIChangeLogWriter(Properties props, CommitInfo ci) {
this.ci = ci;
String newRev = String.valueOf((Integer.parseInt(ci.getRevision())+1));
this.chgLogDir = getChangeLogDirectory(props, ci);
this.outputFilename = newRev + ".owl";
// create URI for Change Log
changeLogURI = props.getProperty("changeLogBaseURI")
+ ci.getRepositoryName() + "/" + outputFilename + "#";
}
/**
* Get Directory for ChangeLog
*
* @param props Properties
* @param ci CommitInfo Container
* @return String of Directory
*/
private String getChangeLogDirectory(Properties props, CommitInfo ci) {
boolean inSVNRepo = props.getProperty("changeLogInSVNRepo") == "true";
if (inSVNRepo) {
return ci.getRepository() + "/" + props.getProperty("changeLogDir");
} else {
String svontRoot = props.getProperty("svontBase");
return svontRoot + "/" + props.getProperty("changeLogDir")
+ ci.getRepositoryName() + "/";
}
}
/**
* Initalize the Writer
* It Creates the Change Log Directory if it doesnt exist and loads the OMV-Change Ontology
*
* @throws Exception if creating of changeLogDirectory failed
*/
private void initWriter() throws Exception {
log.debug("ChangeLog URI: " + changeLogURI);
// test if changeLog Directory exists
File dir = new File(chgLogDir);
if (!dir.exists()) {
// newChangeLog = true;
log.debug("ChangeLog Directory doesn't exist..." + dir);
boolean success = dir.mkdir();
if (success) {
log.debug("Directory: " + dir + " created");
} else {
throw new Exception("Creating of ChangeLog Directory Failed");
}
}
// load OMVChange Ontology as schema
log.debug("Loading OMVChange Schema from uri:" + OMVChangesURI);
OWLOntologyManager man = OWLManager.createOWLOntologyManager();
OMVChangeFactory = man.getOWLDataFactory();
log.debug("ChangeLog initialization done");
}
/* (non-Javadoc)
* @see de.fuberlin.agcsw.svont.changelog.ChangeLogWriter#writeToChangeLog(de.fuberlin.agcsw.svont.changedetection.DiffResult)
*/
public void writeToChangeLog(DiffResult dr) throws Exception {
initWriter();
log.debug("Appending DiffResult to ChangeLog");
OWLOntologyManager man = OWLManager.createOWLOntologyManager();
OWLOntology ont = man.createOntology(IRI.create(changeLogURI));
// Create Added Concept Changes
log.debug("processing added Concepts in ChangeLog");
OWLClass changeTypeClass = OMVChangeFactory.getOWLClass(IRI
.create(OMVChangesURI2 + "AddClass"));
processConcepts(changeTypeClass, dr.getAddedClasses(), man, ont);
changeTypeClass = OMVChangeFactory.getOWLClass(IRI.create(OMVChangesURI
+ "AddDataProperty"));
processConcepts(changeTypeClass, dr.getAddedDataProperties(), man, ont);
changeTypeClass = OMVChangeFactory.getOWLClass(IRI.create(OMVChangesURI
+ "AddObjectProperty"));
processConcepts(changeTypeClass, dr.getAddedObjectProperties(), man,
ont);
changeTypeClass = OMVChangeFactory.getOWLClass(IRI.create(OMVChangesURI
+ "AddDatatype"));
processConcepts(changeTypeClass, dr.getAddedDataTypes(), man, ont);
changeTypeClass = OMVChangeFactory.getOWLClass(IRI
.create(OMVChangesURI2 + "AddIndividual"));
processConcepts(changeTypeClass, dr.getAddedIndividuals(), man, ont);
// Create Removed Concept Changes
log.debug("processing removed Concepts in ChangeLog");
changeTypeClass = OMVChangeFactory.getOWLClass(IRI
.create(OMVChangesURI2 + "RemoveClass"));
processConcepts(changeTypeClass, dr.getRemovedClasses(), man, ont);
changeTypeClass = OMVChangeFactory.getOWLClass(IRI.create(OMVChangesURI
+ "RemoveDataProperty"));
processConcepts(changeTypeClass, dr.getRemovedDataProperties(), man,
ont);
changeTypeClass = OMVChangeFactory.getOWLClass(IRI.create(OMVChangesURI
+ "RemoveObjectProperty"));
processConcepts(changeTypeClass, dr.getRemovedObjectProperties(), man,
ont);
changeTypeClass = OMVChangeFactory.getOWLClass(IRI.create(OMVChangesURI
+ "RemoveDatatype"));
processConcepts(changeTypeClass, dr.getRemovedDataTypes(), man, ont);
changeTypeClass = OMVChangeFactory.getOWLClass(IRI
.create(OMVChangesURI2 + "RemoveIndividual"));
processConcepts(changeTypeClass, dr.getRemovedIndividuals(), man, ont);
// Create Changed Concept Changes
log.debug("processing changed Concepts in ChangeLog");
changeTypeClass = OMVChangeFactory.getOWLClass(IRI
.create(OMVChangesURI2 + "ClassChange"));
processConcepts(changeTypeClass, dr.getChangedClasses(), man, ont);
changeTypeClass = OMVChangeFactory.getOWLClass(IRI.create(OMVChangesURI
+ "DataPropertyChange"));
processConcepts(changeTypeClass, dr.getChangedDataProperties(), man,
ont);
changeTypeClass = OMVChangeFactory.getOWLClass(IRI.create(OMVChangesURI
+ "ObjectPropertyChange"));
processConcepts(changeTypeClass, dr.getChangedObjectProperties(), man,
ont);
// FIXME: not in omv???
// changeTypeClass =
// OMVChangeFactory.getOWLClass(IRI.create(OMVChanges2URI +
// "RemoveDatatype"));
// processConcepts(changeTypeClass, dr.getChangedDataTypes(),man,ont);
changeTypeClass = OMVChangeFactory.getOWLClass(IRI.create(OMVChangesURI
+ "IndividualChange"));
processConcepts(changeTypeClass, dr.getChangedIndividuals(), man, ont);
// apply changes to change log ontology
man.applyChanges(changes);
// OS URI Fixing ... Windows file:/D:/<dir> Unix file:/<dir>
String prefix = (!chgLogDir.startsWith("/")) ? "/" : "";
IRI outFileIRI = IRI.create("file:" + prefix + chgLogDir
+ outputFilename);
// log.debug(outFileURI);
man.saveOntology(ont, outFileIRI);
log.debug("DiffResult successfully appended to ChangeLog: "
+ outFileIRI);
}
/**
* Creates OMVChanges Individuals for a specific Change Type Class
*
* @param changeTypeClass The Class the individuals belongs to
* @param set Set of Entities to process
* @param man OWLManager for the ChangeLog
* @param ont OWLOntology for the ChangeLog
*/
private void processConcepts(OWLClass changeTypeClass,
Set<? extends OWLObject> set, OWLOntologyManager man,
OWLOntology ont) {
// TODO: Check spec if we want to capture anonymous entities too
OWLDataFactory factory = man.getOWLDataFactory();
String date = getDateTime();
for (OWLObject o : set) {
// only take into account named objects with an IRI
// TODO handle anonymous entities
if (o instanceof OWLNamedObject) {
OWLNamedObject c = (OWLNamedObject)o;
log.debug("adding to changeLog:" + c.getIRI());
OWLIndividual in = factory.getOWLNamedIndividual(IRI
.create(changeLogURI + "change" + chgCounter));
// Create pure Change Class
OWLAxiom axiom = factory.getOWLClassAssertionAxiom(
changeTypeClass, in);
changes.add(new AddAxiom(ont, axiom));
// Create connection to changed Entity ("hasRelatedEntity");
OWLObjectProperty hasRE = OMVChangeFactory
.getOWLObjectProperty(IRI.create(OMVChangesURI
+ "hasRelatedEntity"));
OWLIndividual cIndivid = factory.getOWLNamedIndividual(c
.getIRI());
OWLObjectPropertyAssertionAxiom hasREAssertion = factory
.getOWLObjectPropertyAssertionAxiom(hasRE, in, cIndivid);
changes.add(new AddAxiom(ont, hasREAssertion));
// set timestamp DataProperty ("date")
OWLDataProperty dateDP = OMVChangeFactory
.getOWLDataProperty(IRI.create(OMVChangesURI + "date"));
OWLLiteral dateLiteral = factory.getOWLTypedLiteral(date,
OWL2Datatype.XSD_DATE_TIME);
OWLDataPropertyAssertionAxiom dateAssertion = factory
.getOWLDataPropertyAssertionAxiom(dateDP, in,
dateLiteral);
changes.add(new AddAxiom(ont, dateAssertion));
// create author Property if available
if (ci.getAuthor() != null) {
// not implemented yet
}
chgCounter++;
}
}
}
/**
* Returns the current Date and Time
*
* @return String representation of Date and Time
*/
private String getDateTime() {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
return dateFormat.format(date);
}
}