/* * Copyright 2020 ETSI * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ package fr.mines_stetienne.ci.saref.managers; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import org.apache.commons.io.FileUtils; import org.apache.jena.atlas.io.IndentedWriter; import org.apache.jena.query.Dataset; import org.apache.jena.query.DatasetFactory; import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ModelFactory; import org.apache.jena.rdf.model.Property; import org.apache.jena.rdf.model.Resource; import org.apache.jena.vocabulary.OWL2; import org.apache.jena.vocabulary.RDF; import org.semanticweb.owlapi.model.OWLAnnotationValue; import org.semanticweb.owlapi.model.OWLLiteral; import org.semanticweb.owlapi.model.OWLOntology; import org.semanticweb.owlapi.model.parameters.Imports; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.io.Files; import fr.mines_stetienne.ci.saref.SAREF; import fr.mines_stetienne.ci.saref.SAREFPipelineException; import fr.mines_stetienne.ci.saref.SAREFRepositoryVersionErrorLogger; import fr.mines_stetienne.ci.saref.entities.SAREFExample; import fr.mines_stetienne.ci.saref.entities.SAREFVersionName; import fr.mines_stetienne.ci.saref.utils.Languages; import fr.mines_stetienne.ci.saref.utils.StreamManagerFactory; import fr.mines_stetienne.ci.sparql_generate.stream.SPARQLExtStreamManager; public class VersionSiteManager extends SAREFRepositoryVersionErrorLogger { private static final Logger LOG = LoggerFactory.getLogger(VersionSiteManager.class); private static final String SITE = "site"; private final static Logger getLogger(RepositoryManager repositoryManager) { String repositoryName = repositoryManager.getRepository().getName(); SAREFVersionName versionName = repositoryManager.getCurrentVersionName(); final String loggerName = SAREF.getMessage(SITE, repositoryName, versionName); return repositoryManager.getPipeline().getLogger(loggerName); } private static enum MESSAGE { version_folder, diagrams_folder, ontology_file, example_file; } private final File siteDir; private final File ontoDir; private final File exDir; private final SPARQLExtStreamManager streamManager; public VersionSiteManager(RepositoryManager repositoryManager) { super(repositoryManager, getLogger(repositoryManager)); this.siteDir = new File(pipeline.targetDir, SAREF.NAME_SITE); this.ontoDir = new File(siteDir, version.getVersionPath()); this.exDir = new File(ontoDir, "example"); this.streamManager = StreamManagerFactory.get(repository.getDirectory()); } public void generateSite() throws SAREFPipelineException { LOG.info("Generating site for " + version); prepareDirectory(); generateRDFFiles(); generateHTMLFile(); if (!pipeline.ignoreExamples) { for(SAREFExample example : version.getExamples().values()) { LOG.info("Generating site for " + example); generateRDFFiles(example); generateHTMLFile(example); } } } private File prepareDirectory() throws SAREFPipelineException { try { FileUtils.forceMkdir(exDir); File diagramsDir = new File(repository.getDirectory(), "documentation/diagrams"); if(diagramsDir.isDirectory()) { try { FileUtils.copyDirectory(diagramsDir, new File(ontoDir, "diagrams")); } catch (IOException ex) { String msg = getMessage(MESSAGE.diagrams_folder, repository.getName(), version); errorLogger.warn(msg, ex); } } return ontoDir; } catch (IOException ex) { String msg = getMessage(MESSAGE.version_folder, repository.getName(), version); errorLogger.warn(msg, ex); throw new SAREFPipelineException(msg, ex); } } private void generateRDFFiles() throws SAREFPipelineException { Model model = version.getModel(); for (Languages l : Languages.values()) { if(l.equals(Languages.TEXT_TURTLE)) { continue; } String ontologyFileName = repository.getOntologyFileName(l); File file = new File(ontoDir, ontologyFileName); try (FileOutputStream fos = new FileOutputStream(file)) { model.write(fos, l.getLang()); } catch (IOException ex) { String msg = getMessage(MESSAGE.ontology_file, version, ontologyFileName); errorLogger.warn(msg, ex); } } String ontologyFileName = repository.getOntologyFileName(Languages.TEXT_TURTLE); File dir = new File(repository.getDirectory(), "ontology"); File from = new File(dir, ontologyFileName); File to = new File(ontoDir, ontologyFileName); try { Files.copy(from, to); } catch (IOException ex) { String msg = getMessage(MESSAGE.ontology_file, version, ontologyFileName); errorLogger.warn(msg, ex); } } private void generateHTMLFile() throws SAREFPipelineException { Dataset dataset = DatasetFactory.create(); Model model = ModelFactory.createDefaultModel(); model.add(version.getModel()); OWLOntology ontology = ontologyManager.loadOntology(version, errorLogger); ontology.classesInSignature(Imports.INCLUDED).forEach(c->{ if(ontology.isDeclared(c)) { return; } Resource r = model.getResource(c.getIRI().toString()); model.add(r, RDF.type, OWL2.Class); ontology.annotationAssertionAxioms(c.getIRI(), Imports.INCLUDED).forEach(axiom->{ Property p = model.getProperty(axiom.getProperty().getIRI().toString()); OWLAnnotationValue value = axiom.getValue(); if(value instanceof OWLLiteral) { OWLLiteral literal = (OWLLiteral) value; model.add(r, p, literal.getLiteral()); } });; }); ontology.objectPropertiesInSignature(Imports.INCLUDED).forEach(op->{ if(ontology.isDeclared(op)) { return; } Resource r = model.getResource(op.getIRI().toString()); model.add(r, RDF.type, OWL2.ObjectProperty); ontology.annotationAssertionAxioms(op.getIRI(), Imports.INCLUDED).forEach(axiom->{ Property p = model.getProperty(axiom.getProperty().getIRI().toString()); OWLAnnotationValue value = axiom.getValue(); if(value instanceof OWLLiteral) { OWLLiteral literal = (OWLLiteral) value; model.add(r, p, literal.getLiteral()); } });; }); ontology.dataPropertiesInSignature(Imports.INCLUDED).forEach(dp->{ if(ontology.isDeclared(dp)) { return; } Resource r = model.getResource(dp.getIRI().toString()); model.add(r, RDF.type, OWL2.DatatypeProperty); ontology.annotationAssertionAxioms(dp.getIRI(), Imports.INCLUDED).forEach(axiom->{ Property p = model.getProperty(axiom.getProperty().getIRI().toString()); OWLAnnotationValue value = axiom.getValue(); if(value instanceof OWLLiteral) { OWLLiteral literal = (OWLLiteral) value; model.add(r, p, literal.getLiteral()); } });; }); ontology.individualsInSignature(Imports.INCLUDED).forEach(i->{ if(ontology.isDeclared(i)) { return; } Resource r = model.getResource(i.getIRI().toString()); model.add(r, RDF.type, OWL2.NamedIndividual); ontology.annotationAssertionAxioms(i.getIRI(), Imports.INCLUDED).forEach(axiom->{ Property p = model.getProperty(axiom.getProperty().getIRI().toString()); OWLAnnotationValue value = axiom.getValue(); if(value instanceof OWLLiteral) { OWLLiteral literal = (OWLLiteral) value; model.add(r, p, literal.getLiteral()); } });; }); dataset.addNamedModel(version.getIRI(), model); String htmlFileName = String.format("%s.html", repository.getOntologyFileName()); File file = new File(ontoDir, htmlFileName); try (IndentedWriter writer = new IndentedWriter(new FileOutputStream(file))) { siteManager.generateOntologyDocumentation(version, writer, streamManager, dataset); } catch (Exception ex) { String msg = getMessage(MESSAGE.ontology_file, project, version.getName()); errorLogger.warn(msg, ex); } } private void generateRDFFiles(SAREFExample example) throws SAREFPipelineException { Model model = example.getModel(); for (Languages l : Languages.values()) { String fileName = example.getFileName(l); File file = new File(exDir, fileName); try (FileOutputStream fos = new FileOutputStream(file)) { model.write(fos, l.getLang()); } catch (IOException ex) { String msg = getMessage(MESSAGE.example_file, project, version.getName(), example.getName()); errorLogger.warn(msg, ex); } } } private void generateHTMLFile(SAREFExample example) throws SAREFPipelineException { Dataset dataset = DatasetFactory.create(); dataset.addNamedModel(version.getIRI(), version.getModel()); dataset.addNamedModel(example.getIRI(), example.getModel()); String htmlFileName = String.format("%s.html", example.getName()); File file = new File(exDir, htmlFileName); try (IndentedWriter writer = new IndentedWriter(new FileOutputStream(file))) { siteManager.generateExampleDocumentation(example, writer, streamManager, dataset); } catch (Exception ex) { String msg = getMessage(MESSAGE.ontology_file, project, version.getName()); errorLogger.warn(msg, ex); } } }