/******************************************************************************* * 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; import java.io.File; import java.io.FileInputStream; import java.net.URI; import java.util.Properties; import org.apache.log4j.Logger; import org.semanticweb.owlapi.model.OWLOntology; import org.semanticweb.owlapi.reasoner.IllegalConfigurationException; import org.semanticweb.owlapi.reasoner.OWLReasoner; import org.semanticweb.owlapi.reasoner.OWLReasonerConfiguration; import org.semanticweb.owlapi.reasoner.OWLReasonerFactory; import org.semanticweb.owlapi.reasoner.structural.StructuralReasonerFactory; import cz.cvut.kbss.owldiff.OWLDiffException; import cz.cvut.kbss.owldiff.diff.OWLDiffConfiguration; import de.fuberlin.agcsw.svont.changedetection.BaseDiffAlgorithm; import de.fuberlin.agcsw.svont.changedetection.CEXDiffAlgorithm; import de.fuberlin.agcsw.svont.changedetection.DiffExecutor; import de.fuberlin.agcsw.svont.changedetection.DiffResult; import de.fuberlin.agcsw.svont.changelog.ChangeLogWriter; import de.fuberlin.agcsw.svont.changelog.OWLAPIChangeLogWriter; import de.fuberlin.agcsw.svont.preprocessing.CommitInfo; import de.fuberlin.agcsw.svont.validation.PelletValidator; import de.fuberlin.agcsw.svont.validation.ValidationReport; import de.fuberlin.agcsw.svont.validation.Validator; /** * Main class for the Ontology specific processing of the SVoNt Server System It * initialises the implementations of the Modules used and runs them. * * * @author mario * */ public class SVoNtRunner { final static Logger log = Logger.getLogger(SVoNtRunner.class); /** * the Validator */ private static Validator validator; /** * the DiffExecutor */ private static DiffExecutor diffExecutor; /** * the Change Log Writer */ private static ChangeLogWriter clWriter; /** * Properties that got loaded from svont.conf */ private static Properties props; /** * represents the state of the ontology processing this class is in */ private static String state = "None"; /** * Informations about the Commitment */ private static CommitInfo commitInfo; /** * URI of physical path of owl File that just got commited */ private static URI owlUpdateFile; /** * URI of physical path of owl File that represents the Repository Base */ private static URI owlBaseFile; /** * Result of the Validator */ private static ValidationReport validationReport; /** * Result of the Diff */ private static DiffResult diffResult; /** * Initialises the Modules used by coniguration and prepares the Runner for * the SVoNt processing * * @param p * Property Object, containing the configuration of the system * @param ci * CommitInformations */ public static void init(Properties p, CommitInfo ci) { state = "init"; props = p; commitInfo = ci; OWLDiffConfiguration.setReasonerProvider(new StructuralReasonerFactory()); String prefix = (!ci.getOwlUpdateFile().startsWith("/")) ? "/" : ""; owlBaseFile = URI.create("file:" + prefix + ci.getOwlBaseFile()) .normalize(); owlUpdateFile = URI.create("file:" + prefix + ci.getOwlUpdateFile()) .normalize(); validator = getValidator(props.getProperty("validator", "Pellet")); diffExecutor = getDiffExecutor(props.getProperty("diff", "Base")); clWriter = getChangeLogWriter(props.getProperty("CLWriter", "OWLAPI")); log.info("Using Validator of type: " + props.getProperty("validator")); log.info("Using DiffExecuter of type: " + props.getProperty("diff")); log.info("Using Change Log Writer of type: " + props.getProperty("CLWriter")); } /** * Return an java object for the given Validator type * * @param validatorType * Type of validator * @return ValidatorImplementation Object */ private static Validator getValidator(String validatorType) { if (validatorType.equals("Pellet")) { return new PelletValidator(); } // ... more Validators to implement // Pellet is default; return new PelletValidator(); } /** * Return an java object for the given Diff Type * * @param diffType * type of hangeDetector * @return DiffExecuterImplementation Object */ private static DiffExecutor getDiffExecutor(String diffType) { if (diffType.equals("Base")) { return new BaseDiffAlgorithm(); } if (diffType.equals("CEX")) { return new CEXDiffAlgorithm(); } // ... more Diff Algorithmns can be implemented here // BaseDiff is default; return new BaseDiffAlgorithm(); } /** * Returns an java object for the Given Change Log Writer type * * @param clType * type of Change Log Writer * @return ChangeLogWriterImplementation object */ private static ChangeLogWriter getChangeLogWriter(String clType) { if (clType.equals("OWLAPI")) { return new OWLAPIChangeLogWriter(props, commitInfo); } // ... more Change Log Writer can be implemented here // OWLAPI ChangeLogWrter is default; return new OWLAPIChangeLogWriter(props, commitInfo); } /** * Starts the ontology processing 1. Validate the Update Ontology 2. Creates * a Diff between the given Ontologies 3. Write the differences to the * Change Log * * @throws Exception * if error occured */ public static void run() throws Exception { // first step is to check the consistency of the ontology validateOntology(); // second step is to diff the commit Ontology with the Base revision diff(); // last step: we write the diffresult to a changelog. writeChangeLog(); } /** * Starts the ontology Processing with module section flags This exists for * testing reasons * * @param doVal * Flag for Validation * @param doDiff * Flaf for Change Detection * @param doWriteChangeLog * Flag for writing Changelog * @throws Exception */ public static void run(boolean doVal, boolean doDiff, boolean doWriteChangeLog) throws Exception { if (doVal) validateOntology(); if (doDiff) diff(); if (doWriteChangeLog) writeChangeLog(); } /** * Validates the Update Ontology * * @throws Exception * if something fails */ private static void validateOntology() throws Exception { state = "Validation"; // only the updateOntology gets validated // baseOntology from the repository is consistent validationReport = validator.validate(owlUpdateFile); if (!validationReport.isValid()) { // Ontology is not valid, throwing Exception with ValidationReport String errorString = "Validation of Ontology Failed\r\n"; errorString += validationReport.getTextReport(); throw new SVoNtException(errorString); } log.info("Incomming Ontology successfully validated!"); } /** * Creates the Difference for the Base Ontology and Update Ontology * * @throws Exception * if something fails */ private static void diff() throws Exception { try { state = "Diff"; // test if BaseOntologyFile is emtpy -- happens if an ontology File just // got added to the Repository if (emptyOntologyFile(owlBaseFile)) { log .debug("No Ontology File in Repository for Diff... creating dummy Ontology"); // replace baseOwlFile with empty Dummy Ontology File String prefix = (!commitInfo.getOwlUpdateFile().startsWith("/")) ? "/" : ""; String replaceFile = "file:" + prefix + props.getProperty("svontBase") + props.getProperty("ontologyDir") + "emptyOntology.owl"; owlBaseFile = URI.create(replaceFile); log.debug("owlBaseFile got replaced by Following URI:" + owlBaseFile); } log.debug("Going to diff following Ontologie Files:" + owlUpdateFile + "," + owlBaseFile); diffResult = diffExecutor.executeDiff(owlBaseFile, owlUpdateFile); log.info("Diffing of Ontologies successfully finished!"); } catch (OWLDiffException oe) { throw new SVoNtException(oe.getMessage()); } } /** * Writes found differences to the ChangeLog * * @throws Exception */ private static void writeChangeLog() throws Exception { state = "ChangeLog"; if (diffResult.isEmpty()) { // no conceptional changes -- skip writing changelog log .info("Conceptional Diffresult is empty - skip writing ChangeLog"); return; } clWriter.writeToChangeLog(diffResult); log.info("Changelog successfully written!"); } /** * Tests if given URI is an empty File * * @param URI * of the Ontology to test * @return true if empty file * @throws Exception * if File doesnt exist */ private static boolean emptyOntologyFile(URI obf) throws Exception { FileInputStream fis = new FileInputStream(new File(obf)); int b = fis.read(); return b == -1; } /** * Get the state of the SVoNtRunner * * @return the state of this Runner */ public static String getState() { return state; } /** * Get the Report of the Validation * @return the validationReport */ public static ValidationReport getValidationReport() { return validationReport; } /** * Get the Result of the Diff * @return the diffResult */ public static DiffResult getDiffResult() { return diffResult; } }