--- a
+++ b/src/net/timbusproject/context/converter/OWLExport.java
@@ -0,0 +1,347 @@
+/**
+ * Copyright (c) 2013/2014 Verein zur Foerderung der IT-Sicherheit in Oesterreich (SBA).
+ * The work has been developed in the TIMBUS Project and the above-mentioned are Members of the TIMBUS Consortium.
+ * TIMBUS is supported by the European Union under the 7th Framework Programme for research and technological
+ * development and demonstration activities (FP7/2007-2013) under grant agreement no. 269940.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including without
+ * limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTIBITLY, or FITNESS FOR A PARTICULAR
+ * PURPOSE. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise,
+ * unless required by applicable law or agreed to in writing, shall any Contributor be liable for damages, including
+ * any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this
+ * License or out of the use or inability to use the Work.
+ * See the License for the specific language governing permissions and limitation under the License.
+ */
+
+package net.timbusproject.context.converter;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.semanticweb.owlapi.apibinding.OWLManager;
+import org.semanticweb.owlapi.io.FileDocumentTarget;
+import org.semanticweb.owlapi.io.OWLXMLOntologyFormat;
+import org.semanticweb.owlapi.model.AddAxiom;
+import org.semanticweb.owlapi.model.AddImport;
+import org.semanticweb.owlapi.model.IRI;
+import org.semanticweb.owlapi.model.OWLAnnotation;
+import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom;
+import org.semanticweb.owlapi.model.OWLClass;
+import org.semanticweb.owlapi.model.OWLClassAssertionAxiom;
+import org.semanticweb.owlapi.model.OWLDataFactory;
+import org.semanticweb.owlapi.model.OWLDataProperty;
+import org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom;
+import org.semanticweb.owlapi.model.OWLDeclarationAxiom;
+import org.semanticweb.owlapi.model.OWLImportsDeclaration;
+import org.semanticweb.owlapi.model.OWLLiteral;
+import org.semanticweb.owlapi.model.OWLNamedIndividual;
+import org.semanticweb.owlapi.model.OWLObjectProperty;
+import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom;
+import org.semanticweb.owlapi.model.OWLOntology;
+import org.semanticweb.owlapi.model.OWLOntologyCreationException;
+import org.semanticweb.owlapi.model.OWLOntologyManager;
+import org.semanticweb.owlapi.model.OWLOntologyStorageException;
+import org.semanticweb.owlapi.vocab.OWL2Datatype;
+
+import uk.ac.bolton.archimate.editor.model.viewpoints.IViewpoint;
+import uk.ac.bolton.archimate.model.FolderType;
+import uk.ac.bolton.archimate.model.IAccessRelationship;
+import uk.ac.bolton.archimate.model.IArchimateElement;
+import uk.ac.bolton.archimate.model.IArchimateModel;
+import uk.ac.bolton.archimate.model.IDiagramModelObject;
+import uk.ac.bolton.archimate.model.IFolder;
+import uk.ac.bolton.archimate.model.IProperty;
+import uk.ac.bolton.archimate.model.IRelationship;
+import uk.ac.bolton.archimate.model.impl.ArchimateDiagramModel;
+import uk.ac.bolton.archimate.model.impl.DiagramModelArchimateObject;
+import uk.ac.bolton.archimate.model.impl.DiagramModelGroup;
+import uk.ac.manchester.cs.owl.owlapi.OWL2DatatypeImpl;
+
+/**
+ * Methods to export an Archimate Model to OWL (Web Ontology Language)
+ *
+ * @author Rudolf Mayer (rmayer@sba-research.org)
+ */
+public class OWLExport {
+
+ private static final String SCENARIOS_URL = "ScenariosURL";
+
+ private static final String DIOURL = "DIOURL";
+
+ public static final Properties owlExportProperties = new Properties();
+
+ static {
+ String propertiesFileName = "owlExport.properties";
+ URL resource = OWLExportPlugin.class.getResource(propertiesFileName);
+
+ try {
+ owlExportProperties.load(resource.openStream());
+ System.out.println();
+ System.out.println("\nLoaded OWL Export properties from " + resource);
+ System.out.println("Properties:");
+ System.out.println(owlExportProperties);
+ System.out.println("------------------------------\n");
+ } catch (Exception e) {
+ System.err.println("\nCould not load OWL Export properties, tried file with name '" + propertiesFileName
+ + "'.");
+ e.printStackTrace();
+
+ // default: using the TIMBUS scenarios URL
+ owlExportProperties.put(SCENARIOS_URL, "http://timbus.teco.edu/ontologies/Scenarios/");
+ owlExportProperties.put(DIOURL, "http://timbus.teco.edu/ontologies/DIO.owl");
+ System.out.println("==> Using default properties:");
+ System.out.println("\t" + owlExportProperties);
+ System.out.println();
+ }
+
+ }
+
+ /** a mapping of some Archimate relation names to the OWL names */
+ public static final HashMap<String, String> propertyNamesMap = new HashMap<String, String>();
+ static {
+ propertyNamesMap.put("access", "accesses");
+ propertyNamesMap.put("aggregation", "aggregates");
+ propertyNamesMap.put("assignment", "assignment");
+ propertyNamesMap.put("composition", "composedOf");
+ propertyNamesMap.put("flow", "flowTo");
+ propertyNamesMap.put("influence", "influencedBy");
+ propertyNamesMap.put("realisation", "realizes");
+ propertyNamesMap.put("specialisation", "specialization");
+ propertyNamesMap.put("triggering", "triggers");
+ propertyNamesMap.put("usedby", "usedBy");
+ }
+
+ /** subtypes of the relation "access" */
+ public static final String[] relationAccessTypes = { "hasAccessTypeWrite", "hasAccessTypeRead",
+ "hasAccessTypeAccess", "hasAccessTypeRead_Write" };
+
+ /** the default property names */
+ public static final String DEFAULT_PROPERTY = "association";
+
+ /** The URL of the TIMBUS DIO */
+ public static final String TIMBUS_DIO_URL = owlExportProperties.getProperty(DIOURL);
+
+ /** The IRI for the TIMBUS DIO, see {@link #TIMBUS_DIO_URL} */
+ public static final IRI TIMBUS_DIO_IRI = IRI.create(TIMBUS_DIO_URL);
+
+ /** Prefix on the OWL name */
+ public static final String SCENARIOS_PREFIX = owlExportProperties.getProperty(SCENARIOS_URL);
+
+ /** The types of folders in Archi */
+ public static final FolderType[] FOLDER_TYPES = { FolderType.BUSINESS, FolderType.APPLICATION,
+ FolderType.TECHNOLOGY, FolderType.MOTIVATION, FolderType.IMPLEMENTATION_MIGRATION, FolderType.CONNECTORS,
+ FolderType.RELATIONS };
+
+ public static void exportToOwl(IArchimateModel model, File file) throws IOException {
+
+ // create Ontology manager
+ OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
+ OWLDataFactory df = OWLManager.getOWLDataFactory();
+
+ String iriThisOntology = getDefaultIRI(file);
+ OWLOntology ontology;
+ try {
+ ontology = manager.createOntology(IRI.create(iriThisOntology));
+ } catch (OWLOntologyCreationException e) {
+ e.printStackTrace();
+ throw new IOException(e);
+ }
+
+ // import the DIO
+ OWLImportsDeclaration importDeclaraton = df.getOWLImportsDeclaration(TIMBUS_DIO_IRI);
+ manager.applyChange(new AddImport(ontology, importDeclaraton));
+
+ Set<OWLAnnotation> emptyAnnotations = Collections.<OWLAnnotation> emptySet();
+
+ for (FolderType folderType : FOLDER_TYPES) {
+ IFolder folder = model.getFolder(folderType);
+
+ List<EObject> elements = new ArrayList<EObject>((int) (folder.getElements().size() * 1.2));
+ Util.getElements(folder, elements);
+ for (EObject eObject : elements) {
+
+ if (eObject instanceof IArchimateElement) {
+ IArchimateElement element = (IArchimateElement) eObject;
+
+ String elementName = element.getId();
+ String elementClassName = element.eClass().getName();
+
+ if (eObject instanceof IRelationship) { // write relationships
+ IRelationship relationship = (IRelationship) eObject;
+
+ String sourceName = relationship.getSource().getId();
+ String tagetName = relationship.getTarget().getId();
+
+ OWLNamedIndividual source = df.getOWLNamedIndividual(IRI.create("#" + sourceName));
+ OWLNamedIndividual object = df.getOWLNamedIndividual(IRI.create("#" + tagetName));
+
+ // derive the name of the relation from the class name
+ String propertyName = relationship.eClass().getName().replace("Relationship", "");
+ if (propertyNamesMap.containsKey(propertyName.toLowerCase())) {
+ // some relations have a mapping to a better name
+ propertyName = propertyNamesMap.get(propertyName.toLowerCase());
+ } else {
+ propertyName = DEFAULT_PROPERTY;
+ }
+
+ if (eObject instanceof IAccessRelationship) {
+ // access relations have several subtypes, we add the correct name here
+ IAccessRelationship accessRelationship = (IAccessRelationship) eObject;
+ int accesstype = accessRelationship.getAccessType();
+ propertyName = relationAccessTypes[accesstype];
+ }
+
+ OWLObjectProperty property = df.getOWLObjectProperty(IRI.create(TIMBUS_DIO_URL + "#"
+ + propertyName));
+
+ OWLObjectPropertyAssertionAxiom objectPropertyAssertion = df
+ .getOWLObjectPropertyAssertionAxiom(property, source, object);
+ manager.applyChange(new AddAxiom(ontology, objectPropertyAssertion));
+
+ } else { // write individuals (and data properties)
+
+ // writes the indiv with the ID as name
+ OWLNamedIndividual indiv = df.getOWLNamedIndividual(IRI.create("#" + elementName));
+ OWLDeclarationAxiom indivDeclaration = df.getOWLDeclarationAxiom(indiv);
+ manager.applyChange(new AddAxiom(ontology, indivDeclaration));
+
+ // add an rdfs:label property as annotation
+ String labelName = formatString(Util.replaceSpecialWhiteSpace(element.getName()));
+ OWLAnnotation annotation = df.getOWLAnnotation(df.getRDFSLabel(), df.getOWLLiteral(labelName));
+ OWLAnnotationAssertionAxiom annotationAssertionAxiom = df.getOWLAnnotationAssertionAxiom(
+ indiv.getIRI(), annotation);
+ manager.applyChange(new AddAxiom(ontology, annotationAssertionAxiom));
+
+ // add a class expression
+ OWLClass classExpression = df.getOWLClass(IRI.create(TIMBUS_DIO_URL + "#" + elementClassName));
+ OWLClassAssertionAxiom classAssertion = df.getOWLClassAssertionAxiom(classExpression, indiv);
+ manager.applyChange(new AddAxiom(ontology, classAssertion));
+
+ if (!element.getProperties().isEmpty()) { // add data properties
+ for (IProperty eProperty : element.getProperties()) {
+ OWLDataProperty property = df.getOWLDataProperty(IRI.create(TIMBUS_DIO_URL + "#"
+ + eProperty.getKey()));
+ OWLLiteral owlLiteral = df.getOWLLiteral(eProperty.getValue(),
+ OWL2DatatypeImpl.getDatatype(OWL2Datatype.RDF_PLAIN_LITERAL));
+ OWLDataPropertyAssertionAxiom dataPropertyAssertion = df
+ .getOWLDataPropertyAssertionAxiom(property, indiv, owlLiteral, emptyAnnotations);
+ manager.applyChange(new AddAxiom(ontology, dataPropertyAssertion));
+ }
+ }
+ }
+ }
+
+ }
+
+ }
+
+ FileDocumentTarget fileTarget = new FileDocumentTarget(file);
+ try {
+ manager.saveOntology(ontology, new OWLXMLOntologyFormat(), fileTarget);
+ } catch (OWLOntologyStorageException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ public static String getDefaultIRI(File file) {
+ return SCENARIOS_PREFIX + file.getName();
+ }
+
+ public static void exportLayout(IArchimateModel model, File layoutFile, File owlFile) throws FileNotFoundException {
+ exportLayout(layoutFile, getDefaultIRI(owlFile), getLayeredView(model));
+ }
+
+ /** Exports the layout of the layered view ({@link IViewpoint#LAYERED_VIEWPOINT}) of a model to a CSV separated file */
+ public static void exportLayout(IArchimateModel model, File layoutFile, String defaultIRI)
+ throws FileNotFoundException {
+ exportLayout(layoutFile, defaultIRI, getLayeredView(model));
+ }
+
+ /** Exports the layout of a model to a CSV separated file */
+ public static void exportLayout(File layoutFile, String defaultIRI, ArchimateDiagramModel layeredView)
+ throws FileNotFoundException {
+ if (layeredView != null) {
+ EList<IDiagramModelObject> children = layeredView.getChildren();
+
+ ArrayList<String> export = new ArrayList<String>();
+ exportChildrenLayout(children, 0, 0, export, defaultIRI);
+ Collections.sort(export);
+
+ PrintWriter pw = new PrintWriter(layoutFile);
+ for (String string : export) {
+ pw.println(string);
+ }
+
+ pw.flush();
+ pw.close();
+ }
+ }
+
+ public static ArchimateDiagramModel getLayeredView(IArchimateModel model) {
+ IFolder diagramFolder = model.getFolder(FolderType.DIAGRAMS);
+ ArchimateDiagramModel layeredView = null;
+
+ for (EObject eObject : diagramFolder.getElements()) {
+ if (eObject instanceof ArchimateDiagramModel) {
+ ArchimateDiagramModel diagramModel = (ArchimateDiagramModel) eObject;
+ if (diagramModel.getViewpoint() == IViewpoint.LAYERED_VIEWPOINT) {
+ layeredView = diagramModel;
+ }
+ }
+ }
+ return layeredView;
+ }
+
+ public static File getDefaultLayoutFile(File file) {
+ return new File(file.getAbsolutePath() + ".layout.csv");
+ }
+
+ private static void exportChildrenLayout(EList<IDiagramModelObject> children, int x, int y,
+ ArrayList<String> export, String iriPrefix) {
+ for (IDiagramModelObject diagramModelObject : children) {
+
+ int coordX = x + diagramModelObject.getBounds().getX();
+ int coordY = y + diagramModelObject.getBounds().getY();
+ if (diagramModelObject instanceof DiagramModelGroup) {
+ exportChildrenLayout(((DiagramModelGroup) diagramModelObject).getChildren(), coordX, coordY, export,
+ iriPrefix);
+ } else {
+ String elementName = diagramModelObject.getId();
+ if (diagramModelObject instanceof DiagramModelArchimateObject) {
+ elementName = ((DiagramModelArchimateObject) diagramModelObject).getArchimateElement().getId();
+ }
+ StringBuilder sb = new StringBuilder(iriPrefix).append("#").append(elementName).append("\t")
+ .append(coordX).append("\t").append(coordY);
+
+ if (diagramModelObject instanceof DiagramModelArchimateObject
+ && ((DiagramModelArchimateObject) diagramModelObject).getChildren() != null
+ && ((DiagramModelArchimateObject) diagramModelObject).getChildren().size() > 0) {
+ sb.append("\t").append(diagramModelObject.getBounds().getWidth()).append("\t")
+ .append(diagramModelObject.getBounds().getHeight());
+ exportChildrenLayout(((DiagramModelArchimateObject) diagramModelObject).getChildren(), coordX,
+ coordY, export, iriPrefix);
+ }
+ export.add(sb.toString());
+ }
+ }
+ }
+
+ public static String formatString(String s) {
+ return s.replace(" ", "_").replace("(", "-").replace(")", "-").replace("/", "_");
+ }
+}