--- a
+++ b/src/main/java/net/timbusproject/extractors/modules/tavernaextractor/TavernaExtractor.java
@@ -0,0 +1,2209 @@
+/**
+ * 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.extractors.modules.tavernaextractor;
+
+import edu.uci.ics.jung.algorithms.layout.AbstractLayout;
+import edu.uci.ics.jung.algorithms.layout.ISOMLayout;
+import edu.uci.ics.jung.algorithms.layout.Layout;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.SparseGraph;
+import net.sf.taverna.t2.activities.beanshell.BeanshellActivity;
+import net.sf.taverna.t2.activities.beanshell.BeanshellActivityConfigurationBean;
+import net.sf.taverna.t2.activities.dataflow.DataflowActivity;
+import net.sf.taverna.t2.activities.externaltool.ExternalToolActivity;
+import net.sf.taverna.t2.activities.externaltool.ExternalToolActivityConfigurationBean;
+import net.sf.taverna.t2.activities.rest.RESTActivity;
+import net.sf.taverna.t2.activities.rshell.RshellActivity;
+import net.sf.taverna.t2.activities.rshell.RshellActivityConfigurationBean;
+import net.sf.taverna.t2.activities.wsdl.WSDLActivity;
+import net.sf.taverna.t2.commandline.CommandLineLauncher;
+import net.sf.taverna.t2.commandline.exceptions.DatabaseConfigurationException;
+import net.sf.taverna.t2.commandline.exceptions.InvalidOptionException;
+import net.sf.taverna.t2.commandline.exceptions.OpenDataflowException;
+import net.sf.taverna.t2.commandline.exceptions.ReadInputException;
+import net.sf.taverna.t2.invocation.TokenOrderException;
+import net.sf.taverna.t2.security.credentialmanager.CMException;
+import net.sf.taverna.t2.workbench.models.graph.DotWriter;
+import net.sf.taverna.t2.workbench.models.graph.Graph.Alignment;
+import net.sf.taverna.t2.workbench.models.graph.GraphController.PortStyle;
+import net.sf.taverna.t2.workbench.models.graph.svg.SVGGraphController;
+import net.sf.taverna.t2.workflowmodel.*;
+import net.sf.taverna.t2.workflowmodel.impl.ProcessorInputPortImpl;
+import net.sf.taverna.t2.workflowmodel.processor.activity.Activity;
+import net.sf.taverna.t2.workflowmodel.processor.activity.DisabledActivity;
+import net.sf.taverna.t2.workflowmodel.processor.activity.UnrecognizedActivity;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.IterationTypeMismatchException;
+import net.sf.taverna.t2.workflowmodel.serialization.DeserializationException;
+import net.timbusproject.extractors.core.Endpoint;
+import net.timbusproject.extractors.core.IExtractor;
+import net.timbusproject.extractors.core.OperatingSystem;
+import net.timbusproject.extractors.core.Parameter;
+import net.timbusproject.extractors.modules.tavernaextractor.utils.ArchiLayoutUtils;
+import net.timbusproject.extractors.modules.tavernaextractor.utils.ArchiUtils;
+import net.timbusproject.extractors.modules.tavernaextractor.utils.Container;
+import net.timbusproject.extractors.modules.tavernaextractor.utils.Container.Orientation;
+import org.apache.batik.swing.JSVGCanvas;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.DocumentHelper;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.osgi.framework.Version;
+import org.sbaresearch.licensecheck.LicenseCheck;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+import uk.ac.bolton.archimate.editor.model.viewpoints.IViewpoint;
+import uk.ac.bolton.archimate.model.*;
+import uk.ac.bolton.archimate.model.impl.BusinessEvent;
+import uk.ac.bolton.archimate.model.util.ArchimateResourceFactory;
+
+import static java.nio.file.FileVisitResult.*;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.*;
+import java.awt.*;
+import java.io.*;
+import java.net.URL;
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.*;
+import java.util.List;
+import java.util.Map.Entry;
+
+/**
+ * @author Rudolf Mayer (rmayer@sba-research.org)
+ * @author Marco Unterberger (munterberger@sba-research.org)
+ */
+public class TavernaExtractor extends CommandLineLauncher implements IExtractor {
+
+ private IArchimateFactory factory;
+ private Map<String, IDiagramModelArchimateObject> elementModelObjectMap;
+ private List<IRelationship> relations;
+ private IArchimateDiagramModel layeredView;
+ private Graph<IArchimateElement, IArchimateElement> graph;
+ private Layout<IArchimateElement, IArchimateElement> layout;
+ private int overall_X, overall_Y = 0;
+ private final int MIN_ELEMENTS_FOR_GROUPING = 3;
+ private Map<Processor, List<IBusinessObject>> processorObjectMapping = new HashMap<Processor, List<IBusinessObject>>();
+ private Map<IBusinessObject, IDataObject> business2dataMap = new HashMap<IBusinessObject, IDataObject>();
+ private Map<Processor, IOrJunction> loopsJunctions = new HashMap<Processor, IOrJunction>();
+ private HashMap<Processor, IBusinessProcess> processorProcessMap = new HashMap<Processor, IBusinessProcess>();
+ private List<BeanshellActivity> beanshellScripts = new ArrayList<BeanshellActivity>();
+ private Map<Processor, IAndJunction> processorInputMap = new HashMap<Processor, IAndJunction>();
+ private HashMap<Processor, IBusinessObject> processorValueMap = null;
+ private INode desktop;
+ private IDiagramModelArchimateObject diagramModelDesktop;
+ private IBusinessProcess parentProcessWorkflow;
+ private IBusinessEvent startEvent;
+ private IAndJunction andJunctionStart;
+ private IBusinessEvent endEvent;
+ private IAndJunction andJunctionEnd;
+
+ /*
+ * // Groups //////////////
+ */
+ private IDiagramModelGroup businessProcessModelGroup;
+ private IDiagramModelGroup externalApplicationModelGroup;
+ private IDiagramModelGroup applicationComponentModelGroup;
+ private IDiagramModelGroup externalInfrastructureModelGroup;
+ private IDiagramModelGroup infrastructureModelGroup;
+ private IDiagramModelGroup externalProviderModelGroup;
+ private IDiagramModelGroup processStepsModelGroup;
+
+ /*
+ * // Containers //////////////
+ */
+ private Container inputPorts;
+ private Container outputPorts;
+ private Container valueObjects = new Container(Orientation.VERTICAL);
+ private Container businessObjects;
+ private Container businessProcesses;
+ private Container infrastructureServices;
+ private Container externalApplicationServices;
+ private Container applicationComponents;
+ private Container infrastructure;
+ private Container externalProviders;
+ private Container dataObjects;
+
+ /*
+ * // Folders //////////////
+ */
+ private IFolder businessFolder;
+ private IFolder diagramFolder;
+ private IFolder infrastructureFolder;
+ private IFolder motivationFolder;
+ private IFolder applicationFolder;
+ private IFolder relationsFolder;
+
+
+ /*
+ * // PROPERTIES & ARGUMENTS //////////////
+ */
+ private static String archimateOutputPath;
+ private static String inputFileName;
+ private static String dotLocation;
+ private static Path tavernaHome;
+ private static Path tavernaHomeLib;
+ private static Path tavernaHomeRepo;
+
+ private List<IArchimateElement> nodeElements;
+ private static Logger LOGGER = LogManager.getLogger("TavernaExtractor");
+ private LicenseCheck licenseCheck = new LicenseCheck();
+ private IArtifact workflowFile;
+ private IArtifact taverna;
+ private IApplicationComponent workflowApplicationComponent = null;
+ private IApplicationFunction callScriptApplicationFunction = null;
+ private IApplicationFunction callWebServiceApplicationFunction = null;
+ private IApplicationFunction callToolInvocationFunction = null;
+
+ private Dataflow dataflow;
+
+ public TavernaExtractor(boolean verbose) {
+
+ if (verbose) {
+ LOGGER.setLevel(Level.DEBUG);
+ } else {
+ LOGGER.setLevel(Level.INFO);
+ }
+ }
+
+ /*
+ * // GETTER & SETTER ///////////////
+ */
+ public static void setDotLocation(String dotLocation) {
+ TavernaExtractor.dotLocation = dotLocation;
+ }
+
+ public static String getDotLocation() {
+ return dotLocation;
+ }
+
+ public static String getArchimateOutputPath() {
+ return archimateOutputPath;
+ }
+
+ public static void setArchimateOutputPath(String archimateOutputPath) {
+ TavernaExtractor.archimateOutputPath = archimateOutputPath;
+ }
+
+ public static String getInputFileName() {
+ return inputFileName;
+ }
+
+ public static void setInputFileName(String inputFileName) {
+ TavernaExtractor.inputFileName = inputFileName;
+ }
+
+ public static Path getTavernaHome() {
+ return tavernaHome;
+ }
+
+ public static void setTavernaHome(Path tavernaHome) {
+
+ TavernaExtractor.tavernaHome = tavernaHome;
+ }
+
+ public static Path getTavernaHomeLib() {
+ return tavernaHomeLib;
+ }
+
+ public static void setTavernaHomeLib(Path tavernaHomeLib) {
+ TavernaExtractor.tavernaHomeLib = tavernaHomeLib;
+ }
+
+ public static Path getTavernaHomeRepo() {
+ return tavernaHomeRepo;
+ }
+
+ public static void setTavernaHomeRepo(Path tavernaHomeRepo) {
+ TavernaExtractor.tavernaHomeRepo = tavernaHomeRepo;
+ }
+
+
+ public List<IRelationship> getRelations() {
+ return this.relations;
+ }
+
+ public List<IArchimateElement> getBusinessProcesses() {
+ return this.businessProcesses.getElements();
+ }
+
+ public List<IArchimateElement> getBusinessObjects() {
+ return this.businessObjects.getElements();
+ }
+
+ /*
+ * // Transform a Taverna (t2flow) file to an Archimate file ///////////////
+ */
+ public void process() throws EditException, OpenDataflowException, InvalidOptionException,
+ InvalidDataflowException, TokenOrderException, ReadInputException, DatabaseConfigurationException,
+ CMException, IOException, DeserializationException, IterationTypeMismatchException {
+
+ LOGGER.info("Start Taverna Extractor ...");
+
+ //setup
+ TavernaExtractor.setTavernaHomeLib(TavernaExtractor.getTavernaHome().resolve("lib"));
+ TavernaExtractor.setTavernaHomeRepo(TavernaExtractor.getTavernaHome().resolve("repository"));
+
+ validateDirectories(TavernaExtractor.getTavernaHome(), TavernaExtractor.getTavernaHomeLib(), TavernaExtractor.getTavernaHomeRepo());
+
+ LOGGER.info("TavernaHome is set to [" + TavernaExtractor.getTavernaHome() + "].");
+ LOGGER.info("TavernaHomeLib is set to [" + TavernaExtractor.getTavernaHomeLib() + "].");
+ LOGGER.info("TavernaHomeRepo is set to [" + TavernaExtractor.getTavernaHomeRepo() + "].");
+ LOGGER.info("Worflow input file is [" + TavernaExtractor.getInputFileName() + "].");
+ LOGGER.info("Archimate output file is [" + TavernaExtractor.getArchimateOutputPath() + "].");
+
+ inputPorts = new Container(Orientation.VERTICAL);
+ outputPorts = new Container(Orientation.VERTICAL);
+ businessObjects = new Container(Orientation.HORIZONTAL);
+ businessProcesses = new Container(Orientation.HORIZONTAL);
+ externalApplicationServices = new Container(Orientation.HORIZONTAL);
+ infrastructure = new Container(Orientation.HORIZONTAL);
+ infrastructureServices = new Container(Orientation.HORIZONTAL);
+ applicationComponents = new Container(Orientation.HORIZONTAL);
+ externalProviders = new Container(Orientation.HORIZONTAL);
+ dataObjects = new Container(Orientation.HORIZONTAL);
+
+ // project configured JRE!
+ final String JAVA_VERSION = System.getProperty("java.version");
+ final String JAVA_VENDOR = System.getProperty("java.vendor");
+
+ final String OS_SYSTEM_INFO = System.getProperty("os.name") + " [version=" + System.getProperty("os.version")
+ + "] [arch=" + System.getProperty("os.arch") + "]";
+
+ nodeElements = new ArrayList<IArchimateElement>();
+ elementModelObjectMap = new HashMap<String, IDiagramModelArchimateObject>();
+ relations = new ArrayList<IRelationship>();
+
+ try {
+ // try to load from classpath
+ URL workflowURL = getClass().getResource(inputFileName);
+
+ if (workflowURL == null) { // if not successful, try opening file
+
+ File f = new File(inputFileName);
+ if (f.exists()) {
+ workflowURL = f.toURI().toURL();
+ }
+ }
+
+ LOGGER.info("Reading workflow from " + workflowURL);
+ dataflow = openDataflow(workflowURL);
+ } catch (NullPointerException npe) {
+ npe.printStackTrace();
+ LOGGER.error("ERROR reading workflow from [" + inputFileName + "]." + npe.getMessage());
+ return;
+ }
+
+ // current classpath
+ String classpath = System.getProperty("java.class.path");
+ String[] classpathEntries = classpath.split(File.pathSeparator);
+ List<String> cleanClasspathEntries = cleanedClasspath(Arrays.asList(classpathEntries));
+
+ factory = IArchimateFactory.eINSTANCE;
+
+ IArchimateModel model = factory.createArchimateModel();
+ model.setDefaults();
+ model.setName("Converted Taverna Workflow " + inputFileName);
+
+ // FOLDERS
+ businessFolder = model.getFolder(FolderType.BUSINESS);
+ diagramFolder = model.getFolder(FolderType.DIAGRAMS);
+ infrastructureFolder = model.getFolder(FolderType.TECHNOLOGY);
+ motivationFolder = model.getFolder(FolderType.MOTIVATION);
+ applicationFolder = model.getFolder(FolderType.APPLICATION);
+ relationsFolder = model.getFolder(FolderType.RELATIONS);
+
+ // LAYERED VIEWS
+ layeredView = factory.createArchimateDiagramModel();
+ layeredView.setName("Layered View");
+ layeredView.setViewpoint(IViewpoint.LAYERED_VIEWPOINT);
+ diagramFolder.getElements().add(layeredView);
+
+ // GROUPINGS
+ businessProcessModelGroup = ArchiLayoutUtils.createSubModelGroup(layeredView, "Business process");
+ externalApplicationModelGroup = ArchiLayoutUtils.createSubModelGroup(layeredView,
+ "External Application Services");
+ applicationComponentModelGroup = ArchiLayoutUtils.createSubModelGroup(layeredView,
+ "Application Component + Services");
+ externalInfrastructureModelGroup = ArchiLayoutUtils.createSubModelGroup(layeredView,
+ "External Infrastructure Services");
+ infrastructureModelGroup = ArchiLayoutUtils.createSubModelGroup(layeredView, "Infrastructure");
+
+ // --- CREATING DEFAULT ELEMENTS ---
+ desktop = factory.createNode();
+ desktop.setName("Desktop Computer");
+ infrastructureFolder.getElements().add(desktop);
+
+ diagramModelDesktop = factory.createDiagramModelArchimateObject();
+ diagramModelDesktop.setArchimateElement(desktop);
+ diagramModelDesktop.setBounds(15, 15, 0, 0);
+
+ infrastructure.getElements().add(desktop);
+
+ // // BEGIN PATTERN v2.0 UPDATE
+ // --- BEGIN Taverna ---
+ taverna = (IArtifact) ArchiUtils.initElement(factory.createArtifact(), "Taverna 2.4", infrastructureFolder,
+ nodeElements);
+ IConstraint GNULicense = ArchiUtils.initElement(factory.createConstraint(),
+ "GNU Lesser General Public License (LGPL) 2.1", motivationFolder, infrastructure);
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), taverna, GNULicense, relationsFolder,
+ relations);
+
+ // Workflow file
+ workflowFile = (IArtifact) ArchiUtils.initElement(factory.createArtifact(), "Worfklow File",
+ infrastructureFolder, nodeElements);
+ ArchiUtils.initRelation(factory.createAssociationRelationship(), workflowFile, taverna, relationsFolder,
+ relations);
+
+ // Orchestration Service
+ parentProcessWorkflow = ArchiUtils.initElement(factory.createBusinessProcess(), dataflow.getLocalName()
+ + " Process", businessFolder, businessProcesses);
+ workflowApplicationComponent = ArchiUtils.initElement(factory.createApplicationComponent(),
+ "Workflow Execution Environment", applicationFolder, applicationComponents);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), taverna, workflowApplicationComponent,
+ relationsFolder, relations);
+
+ // add dependable Taverna jars from classpath
+ for(String jar : cleanClasspathEntries) {
+ taverna.getProperties().add(createDepProperties(jar));
+ }
+
+ // link relevant dependencies from taverna home to context model
+ IArtifact repoBundle = (IArtifact) ArchiUtils.initElement(factory.createArtifact(), "Repo Bundle", infrastructureFolder, nodeElements);
+ ArchiUtils.initRelation(factory.createAssociationRelationship(), taverna, repoBundle,
+ relationsFolder, relations);
+
+ if(TavernaExtractor.getTavernaHomeRepo().toFile().isDirectory()){
+
+ final List<File> jarFiles = new ArrayList<>();
+ final PathMatcher matcher = FileSystems.getDefault()
+ .getPathMatcher("glob:*.jar");
+ Files.walkFileTree(TavernaExtractor.getTavernaHomeRepo(), new FileVisitor<Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes basicFileAttributes) throws IOException {
+ return CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) throws IOException {
+
+ if (path != null && matcher.matches(path.getFileName())) {
+ jarFiles.add(path.toFile());
+ }
+ return CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFileFailed(Path path, IOException e) throws IOException {
+ return CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path path, IOException e) throws IOException {
+ return CONTINUE;
+ }
+ });
+
+ for(File jarDep : jarFiles){
+ String jarLocation = jarDep.getAbsolutePath();
+ repoBundle.getProperties().add(createDepProperties(jarLocation));
+ }
+ }
+ else{
+ LOGGER.error("ERROR: "+TavernaExtractor.getTavernaHomeRepo().toFile()+" is not a directory. No further dependecies processing.");
+ }
+ // --- END Taverna ---
+
+ // --- BEGIN Events ---
+ // Start Event
+ startEvent = ArchiUtils.initElement(factory.createBusinessEvent(), "Start Experiment", businessFolder,
+ businessProcesses);
+
+ // End Event
+ endEvent = ArchiUtils.initElement(factory.createBusinessEvent(), "Experiment End", businessFolder,
+ businessProcesses);
+ // --- END Events ---
+
+ // --- BEGIN Java Runtime Environment ---
+ ISystemSoftware java = (ISystemSoftware) ArchiUtils.initElement(factory.createSystemSoftware(), "JRE "
+ + JAVA_VERSION + " (" + JAVA_VENDOR + ")", infrastructureFolder, nodeElements);
+ // FIXME: this must not always be an ORACLE license
+ IConstraint oracleLicense = ArchiUtils.initElement(factory.createConstraint(), "Oracle Binary Code License",
+ motivationFolder, infrastructure);
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), java, oracleLicense, relationsFolder,
+ relations);
+ ArchiUtils.initRelation(factory.createUsedByRelationship(), java, taverna, relationsFolder, relations);
+
+ // --- BEGIN OS ---
+ ISystemSoftware operatingSystem = (ISystemSoftware) ArchiUtils.initElement(factory.createSystemSoftware(),
+ OS_SYSTEM_INFO, infrastructureFolder, nodeElements);
+ ArchiUtils.initRelationNodeElement(factory.createUsedByRelationship(), operatingSystem, java, relationsFolder,
+ nodeElements);
+ // --- END CREATING DEFAULT ELEMENTS ---
+
+ LOGGER.debug("Process Input ports");
+ for (DataflowInputPort inputPort : dataflow.getInputPorts()) {
+ IBusinessObject port_business = ArchiUtils.initElement(factory.createBusinessObject(), inputPort.getName(),
+ businessFolder, inputPorts);
+ IDataObject port_data = ArchiUtils.initElement(factory.createDataObject(), inputPort.getName(),
+ applicationFolder, dataObjects);
+ IArchimateElement port_infrastructure = ArchiUtils.initElement(factory.createArtifact(),
+ inputPort.getName(), infrastructureFolder, infrastructure);
+
+ business2dataMap.put(port_business, port_data);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), port_data, port_business, relationsFolder,
+ relations);
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), port_infrastructure, port_data,
+ relationsFolder, relations);
+ }
+ LOGGER.debug("Process Output ports");
+ for (DataflowOutputPort outputPort : dataflow.getOutputPorts()) {
+ IBusinessObject port_business = ArchiUtils.initElement(factory.createBusinessObject(),
+ outputPort.getName(), businessFolder, outputPorts);
+ IDataObject port_data = ArchiUtils.initElement(factory.createDataObject(), outputPort.getName(),
+ applicationFolder, dataObjects);
+ IArchimateElement port_infrastructure = ArchiUtils.initElement(factory.createArtifact(),
+ outputPort.getName(), infrastructureFolder, infrastructure);
+
+ business2dataMap.put(port_business, port_data);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), port_data, port_business, relationsFolder,
+ relations);
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), port_infrastructure, port_data,
+ relationsFolder, relations);
+ }
+
+ processorProcessMap = new HashMap<Processor, IBusinessProcess>();
+ processorValueMap = new HashMap<Processor, IBusinessObject>();
+
+ //
+ // first pass - get all Processors, and map them to IBusinessProcess, create business objects
+ //
+ treatProcessors(dataflow.getProcessors());
+
+ //
+ // (extend second pass) - redirect relations in case of multiple incoming ports
+ //
+ for (Entry<Processor, IAndJunction> entry : processorInputMap.entrySet()) {
+
+ Processor targetProcessor = entry.getKey();
+ IAndJunction andJunction = entry.getValue();
+
+ IBusinessProcess targetProcess = processorProcessMap.get(targetProcessor);
+
+ // detect incoming triggering relations
+ List<IRelationship> incomingTriggeringRelations = ArchiUtils.ofClass(relations,
+ ITriggeringRelationship.class, targetProcess, false);
+
+ List<IArchimateElement> sourceElements = ArchiUtils.getSourceElements(incomingTriggeringRelations);
+
+ // remove the original incoming relations
+ ArchiUtils.removeRelation(incomingTriggeringRelations, relations, relationsFolder);
+
+ // reconnect relations to AND junction
+ for (IArchimateElement sourceElement : sourceElements) {
+
+ ArchiUtils.initRelation(factory.createTriggeringRelationship(), sourceElement, andJunction,
+ relationsFolder, relations);
+ }
+
+ // create new relation
+ ArchiUtils.initRelation(factory.createTriggeringRelationship(), andJunction, targetProcess,
+ relationsFolder, relations);
+ }
+
+ //
+ // third pass - detail process steps on other layers
+ //
+ detailProcessorsOnLayers(dataflow.getProcessors());
+
+ // drawing archimate elements and relations
+ drawBusinessProcessGroup();
+ drawExternalApplicationServices();
+ drawApplicationComponentServices();
+ drawExternalInfrastructureServices();
+ drawInfrastructure();
+ drawExternalProviders();
+ drawRelations();
+
+ // set size of main process diagram element to hold all others
+ int padding = 5;
+ IBounds outerBounds = processStepsModelGroup.getBounds();
+ processStepsModelGroup.setBounds(outerBounds.getX() - padding / 2, outerBounds.getY(), outerBounds.getWidth()
+ + padding, outerBounds.getHeight() + 10);
+ IDiagramModelArchimateObject processDiagramObject = elementModelObjectMap.get(parentProcessWorkflow.getId());
+ processDiagramObject.setBounds(padding, padding, outerBounds.getWidth() - padding * 2, outerBounds.getHeight()
+ - padding * 2);
+
+ // Set new file
+ File outFile = new File(TavernaExtractor.getArchimateOutputPath());
+ model.setFile(outFile);
+
+ // Set model version
+ model.setVersion(ModelVersion.VERSION);
+
+ // Adapted from {@link ArchiveManager#saveModelToXMLFile}
+ ResourceSet resourceSet = ArchimateResourceFactory.createResourceSet();
+ Resource resource = resourceSet.createResource(URI.createFileURI(outFile.getAbsolutePath()));
+ resource.getContents().add(model);
+ resource.save(null);
+
+ LOGGER.info("Wrote model successfully to " + outFile.getAbsolutePath());
+ }
+
+ public void processWebServiceActivity(IFolder businessFolder, IFolder infrastructureFolder,
+ IFolder applicationFolder, IFolder relationsFolder, IApplicationComponent workflowApplicationComponent,
+ HashMap<Processor, IBusinessProcess> processorProcessMap,
+ IApplicationFunction callWebServiceApplicationFunction, Processor processor, String processorName,
+ Activity<?> a) {
+
+ // external service provider
+ INode externalNode = ArchiUtils.initElement(factory.createNode(), "External Service", infrastructureFolder,
+ externalProviders);
+
+ String type = null;
+ IProperty prop = factory.createProperty();
+ IProperty locationProp = factory.createProperty();
+ if (a instanceof WSDLActivity) {
+
+ LOGGER.debug("WSDL Service found = " + processor.getLocalName());
+ type = "SOAP";
+ WSDLActivity wsdlActivity = (WSDLActivity) a;
+ prop.setKey("WSDL_Location");
+ prop.setValue(wsdlActivity.getConfiguration().getWsdl());
+ externalNode.getProperties().add(prop);
+
+ locationProp = createDepProperties(WSDLActivity.class);
+ }
+
+ if (a instanceof RESTActivity) {
+
+ LOGGER.debug("RESTful Service found = " + processor.getLocalName());
+ type = "HTTP";
+ RESTActivity restActivity = (RESTActivity) a;
+ prop.setKey("URL");
+ prop.setValue(restActivity.getConfiguration().getUrlSignature());
+ externalNode.getProperties().add(prop);
+
+ locationProp = createDepProperties(RESTActivity.class);
+ }
+
+ // create archimate function call only once
+ if (callWebServiceApplicationFunction == null) {
+
+ callWebServiceApplicationFunction = ArchiUtils.initElement(factory.createApplicationFunction(),
+ "Calling Web Service", applicationFolder, applicationComponents);
+
+ ArchiUtils.initRelation(factory.createAssignmentRelationship(), callWebServiceApplicationFunction,
+ workflowApplicationComponent, relationsFolder, relations);
+
+ ArchiUtils.initRelation(factory.createUsedByRelationship(), workflowFile,
+ callWebServiceApplicationFunction, relationsFolder, relations);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), taverna,
+ callWebServiceApplicationFunction, relationsFolder, relations);
+ }
+
+ IApplicationInterface appIf = ArchiUtils.initElement(factory.createApplicationInterface(), type,
+ applicationFolder, externalApplicationServices);
+
+ IApplicationService appService = ArchiUtils.initElement(factory.createApplicationService(), processorName
+ + "Service", applicationFolder, externalApplicationServices);
+
+ appService.getProperties().add(locationProp);
+
+ ArchiUtils.initRelation(factory.createUsedByRelationship(), appService, processorProcessMap.get(processor),
+ relationsFolder, relations);
+
+ // used-by relation between business processor and application function
+ ArchiUtils.initRelation(factory.createUsedByRelationship(), callWebServiceApplicationFunction,
+ processorProcessMap.get(processor), relationsFolder, relations);
+
+ ArchiUtils.initRelation(factory.createAssignmentRelationship(), appService, appIf, relationsFolder, relations);
+
+ // creating request response data objects
+ for (IArchimateElement inputElement : ArchiUtils.getInputElementsOfProcess(processorProcessMap.get(processor),
+ relations)) {
+
+ if (!business2dataMap.containsKey(inputElement)) {
+
+ IDataObject requestObject = ArchiUtils.initElement(factory.createDataObject(), inputElement.getName()
+ + "(Request)", applicationFolder, applicationComponents);
+
+ business2dataMap.put((IBusinessObject) inputElement, requestObject);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), requestObject, inputElement,
+ relationsFolder, relations);
+ }
+ ArchiUtils.initAccessRelation(factory.createAccessRelationship(), appService,
+ business2dataMap.get(inputElement), applicationFolder, relations, IAccessRelationship.READ_ACCESS);
+ }
+
+ for (IArchimateElement outputElement : ArchiUtils.getOutputElementsOfProcess(
+ processorProcessMap.get(processor), relations)) {
+
+ if (!business2dataMap.containsKey(outputElement)) {
+
+ IDataObject responseObject = ArchiUtils.initElement(factory.createDataObject(), outputElement.getName()
+ + "(Response)", applicationFolder, applicationComponents);
+
+ business2dataMap.put((IBusinessObject) outputElement, responseObject);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), responseObject, outputElement,
+ relationsFolder, relations);
+ }
+ ArchiUtils
+ .initAccessRelation(factory.createAccessRelationship(), appService,
+ business2dataMap.get(outputElement), applicationFolder, relations,
+ IAccessRelationship.WRITE_ACCESS);
+ }
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), externalNode, appService, relationsFolder,
+ relations);
+ }
+
+ public void processRShellActivity(IFolder businessFolder, IFolder infrastructureFolder, IFolder applicationFolder,
+ IFolder relationsFolder, IApplicationComponent workflowApplicationComponent,
+ HashMap<Processor, IBusinessProcess> processorProcessMap,
+ IApplicationFunction callWebServiceApplicationFunction, Processor processor, String processorName,
+ Activity<?> a) {
+
+ if (!(a instanceof RshellActivity)) {
+ LOGGER.info("Activity [" + a + "] is not an instance of RshellActivity. Stop further processing!");
+ return;
+ }
+
+ RshellActivity rshellActivity = (RshellActivity) a;
+
+ // create archimate function call only once
+ if (callToolInvocationFunction == null) {
+
+ callToolInvocationFunction = ArchiUtils.initElement(factory.createApplicationFunction(),
+ "Tool Invocation Service", applicationFolder, applicationComponents);
+
+ ArchiUtils.initRelation(factory.createAssignmentRelationship(), callToolInvocationFunction,
+ workflowApplicationComponent, relationsFolder, relations);
+
+ ArchiUtils.initRelation(factory.createUsedByRelationship(), workflowFile, callToolInvocationFunction,
+ relationsFolder, relations);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), taverna, callToolInvocationFunction,
+ relationsFolder, relations);
+ }
+
+ IApplicationService appService = ArchiUtils.initElement(factory.createApplicationService(), processorName
+ + "Service", applicationFolder, externalApplicationServices);
+
+
+ appService.getProperties().add(createDepProperties(RshellActivity.class));
+
+ ArchiUtils.initRelation(factory.createUsedByRelationship(), appService, processorProcessMap.get(processor),
+ relationsFolder, relations);
+
+ // used-by relation between business processor and application function
+ ArchiUtils.initRelation(factory.createUsedByRelationship(), callToolInvocationFunction,
+ processorProcessMap.get(processor), relationsFolder, relations);
+
+ // creating input output data objects
+ for (IArchimateElement inputElement : ArchiUtils.getInputElementsOfProcess(processorProcessMap.get(processor),
+ relations)) {
+
+ if (!business2dataMap.containsKey(inputElement)) {
+
+ IDataObject requestObject = ArchiUtils.initElement(factory.createDataObject(), inputElement.getName()
+ + "(Input)", applicationFolder, applicationComponents);
+
+ business2dataMap.put((IBusinessObject) inputElement, requestObject);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), requestObject, inputElement,
+ relationsFolder, relations);
+ }
+ ArchiUtils.initAccessRelation(factory.createAccessRelationship(), appService,
+ business2dataMap.get(inputElement), applicationFolder, relations, IAccessRelationship.READ_ACCESS);
+ }
+
+ for (IArchimateElement outputElement : ArchiUtils.getOutputElementsOfProcess(
+ processorProcessMap.get(processor), relations)) {
+
+ if (!business2dataMap.containsKey(outputElement)) {
+
+ IDataObject responseObject = ArchiUtils.initElement(factory.createDataObject(), outputElement.getName()
+ + "(Output)", applicationFolder, applicationComponents);
+
+ business2dataMap.put((IBusinessObject) outputElement, responseObject);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), responseObject, outputElement,
+ relationsFolder, relations);
+ }
+ ArchiUtils
+ .initAccessRelation(factory.createAccessRelationship(), appService,
+ business2dataMap.get(outputElement), applicationFolder, relations,
+ IAccessRelationship.WRITE_ACCESS);
+
+ }
+
+ IApplicationInterface appIf = ArchiUtils.initElement(factory.createApplicationInterface(), "SSH",
+ applicationFolder, externalApplicationServices);
+
+ INode externalNode = ArchiUtils.initElement(factory.createNode(), "External Service", infrastructureFolder,
+ externalProviders);
+
+ ArchiUtils.initRelation(factory.createAssignmentRelationship(), appService, appIf, relationsFolder, relations);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), externalNode, appService, relationsFolder,
+ relations);
+
+ List<IProperty> props = createPropertiesOutOfRshellConfig(rshellActivity.getConfiguration());
+ externalNode.getProperties().addAll(props);
+ }
+
+ public void processToolActivity(IFolder businessFolder, IFolder infrastructureFolder, IFolder applicationFolder,
+ IFolder relationsFolder, IApplicationComponent workflowApplicationComponent,
+ HashMap<Processor, IBusinessProcess> processorProcessMap,
+ IApplicationFunction callWebServiceApplicationFunction, Processor processor, String processorName,
+ Activity<?> a, boolean isExternal) {
+
+ if (!(a instanceof ExternalToolActivity)) {
+ LOGGER.info("Activity [" + a + "] is not an instance of ExternalToolActivity. Stop further processing!");
+ return;
+ }
+
+ ExternalToolActivity externalInvocation = (ExternalToolActivity) a;
+
+ // create archimate function call only once
+ if (callToolInvocationFunction == null) {
+
+ callToolInvocationFunction = ArchiUtils.initElement(factory.createApplicationFunction(),
+ "Tool Invocation Service", applicationFolder, applicationComponents);
+
+ ArchiUtils.initRelation(factory.createAssignmentRelationship(), callToolInvocationFunction,
+ workflowApplicationComponent, relationsFolder, relations);
+
+ ArchiUtils.initRelation(factory.createUsedByRelationship(), workflowFile, callToolInvocationFunction,
+ relationsFolder, relations);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), taverna, callToolInvocationFunction,
+ relationsFolder, relations);
+ }
+
+ IApplicationService appService = isExternal ? ArchiUtils.initElement(factory.createApplicationService(),
+ processorName + "Service", applicationFolder, externalApplicationServices) : ArchiUtils
+ .initElement(factory.createApplicationService(), processorName + "Service", applicationFolder,
+ applicationComponents);
+
+ appService.getProperties().add(createDepProperties(ExternalToolActivity.class));
+
+ ArchiUtils.initRelation(factory.createUsedByRelationship(), appService, processorProcessMap.get(processor),
+ relationsFolder, relations);
+
+ // used-by relation between business processor and application function
+ ArchiUtils.initRelation(factory.createUsedByRelationship(), callToolInvocationFunction,
+ processorProcessMap.get(processor), relationsFolder, relations);
+
+ // creating input output data objects
+ for (IArchimateElement inputElement : ArchiUtils.getInputElementsOfProcess(processorProcessMap.get(processor),
+ relations)) {
+
+ if (!business2dataMap.containsKey(inputElement)) {
+
+ IDataObject requestObject = ArchiUtils.initElement(factory.createDataObject(), inputElement.getName()
+ + "(Input)", applicationFolder, applicationComponents);
+
+ business2dataMap.put((IBusinessObject) inputElement, requestObject);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), requestObject, inputElement,
+ relationsFolder, relations);
+ }
+ ArchiUtils.initAccessRelation(factory.createAccessRelationship(), appService,
+ business2dataMap.get(inputElement), applicationFolder, relations, IAccessRelationship.READ_ACCESS);
+ }
+
+ for (IArchimateElement outputElement : ArchiUtils.getOutputElementsOfProcess(
+ processorProcessMap.get(processor), relations)) {
+
+ if (!business2dataMap.containsKey(outputElement)) {
+
+ IDataObject responseObject = ArchiUtils.initElement(factory.createDataObject(), outputElement.getName()
+ + "(Output)", applicationFolder, applicationComponents);
+
+ business2dataMap.put((IBusinessObject) outputElement, responseObject);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), responseObject, outputElement,
+ relationsFolder, relations);
+ }
+ ArchiUtils
+ .initAccessRelation(factory.createAccessRelationship(), appService,
+ business2dataMap.get(outputElement), applicationFolder, relations,
+ IAccessRelationship.WRITE_ACCESS);
+
+ }
+
+ if (isExternal) {
+
+ IApplicationInterface appIf = ArchiUtils.initElement(factory.createApplicationInterface(), "SSH",
+ applicationFolder, externalApplicationServices);
+
+ INode externalNode = ArchiUtils.initElement(factory.createNode(), "External Service", infrastructureFolder,
+ externalProviders);
+
+ ArchiUtils.initRelation(factory.createAssignmentRelationship(), appService, appIf, relationsFolder,
+ relations);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), externalNode, appService, relationsFolder,
+ relations);
+
+ List<IProperty> props = createPropertiesOutOfXMLMechanism(externalInvocation.getConfiguration());
+ externalNode.getProperties().addAll(props);
+
+ } else {
+
+ IArtifact toolAsArtifact = (IArtifact) ArchiUtils.initElement(factory.createArtifact(), "Tool",
+ infrastructureFolder, nodeElements);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), toolAsArtifact, appService,
+ relationsFolder, relations);
+
+ IProperty commandProperty = factory.createProperty();
+ commandProperty.setKey("Command");
+ commandProperty.setValue(externalInvocation.getConfiguration().getUseCaseDescription().getCommand());
+ toolAsArtifact.getProperties().add(commandProperty);
+ }
+ }
+
+ public void processBeanshellActivity(IFolder infrastructureFolder, IFolder motivationFolder,
+ IFolder applicationFolder, IFolder relationsFolder, IApplicationComponent workflowApplicationComponent,
+ HashMap<Processor, IBusinessProcess> processorProcessMap, Processor processor, Activity<?> a)
+ throws IOException {
+ beanshellScripts.add((BeanshellActivity) a);
+
+ LOGGER.debug("Beanshell script found = " + processor.getLocalName());
+
+ // create external application service for each business process/function
+ if (callScriptApplicationFunction == null) {
+
+ callScriptApplicationFunction = ArchiUtils.initElement(factory.createApplicationFunction(),
+ "Calling Script", applicationFolder, applicationComponents);
+
+ ArchiUtils.initRelation(factory.createAssignmentRelationship(), callScriptApplicationFunction,
+ workflowApplicationComponent, relationsFolder, relations);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), taverna, callScriptApplicationFunction,
+ relationsFolder, relations);
+ }
+
+ IApplicationService appService = ArchiUtils.initElement(factory.createApplicationService(),
+ processor.getLocalName(), applicationFolder, externalApplicationServices);
+
+ appService.getProperties().add(createDepProperties(BeanshellActivity.class));
+
+ ArchiUtils.initRelation(factory.createUsedByRelationship(), appService, processorProcessMap.get(processor),
+ relationsFolder, relations);
+
+ ArchiUtils.initRelation(factory.createUsedByRelationship(), callScriptApplicationFunction,
+ processorProcessMap.get(processor), relationsFolder, relations);
+
+ IArtifact script = (IArtifact) ArchiUtils.initElement(factory.createArtifact(), processor.getLocalName()
+ + "Script", infrastructureFolder, nodeElements);
+
+ ArchiUtils.initRelation(factory.createCompositionRelationship(), workflowFile, script, relationsFolder,
+ relations);
+
+ ArchiUtils
+ .initRelation(factory.createRealisationRelationship(), script, appService, relationsFolder, relations);
+
+ // creating request response data objects
+ for (IArchimateElement inputElement : ArchiUtils.getInputElementsOfProcess(processorProcessMap.get(processor),
+ relations)) {
+
+ if (!business2dataMap.containsKey(inputElement)) {
+
+ IDataObject requestObject = ArchiUtils.initElement(factory.createDataObject(), inputElement.getName(),
+ applicationFolder, applicationComponents);
+
+ business2dataMap.put((IBusinessObject) inputElement, requestObject);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), requestObject, inputElement,
+ relationsFolder, relations);
+ }
+ ArchiUtils.initAccessRelation(factory.createAccessRelationship(), appService,
+ business2dataMap.get(inputElement), applicationFolder, relations, IAccessRelationship.READ_ACCESS);
+
+ }
+
+ for (IArchimateElement outputElement : ArchiUtils.getOutputElementsOfProcess(
+ processorProcessMap.get(processor), relations)) {
+
+ if (!business2dataMap.containsKey(outputElement)) {
+
+ IDataObject responseObject = ArchiUtils.initElement(factory.createDataObject(),
+ outputElement.getName(), applicationFolder, applicationComponents);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), responseObject, outputElement,
+ relationsFolder, relations);
+
+ business2dataMap.put((IBusinessObject) outputElement, responseObject);
+ }
+
+ ArchiUtils
+ .initAccessRelation(factory.createAccessRelationship(), appService,
+ business2dataMap.get(outputElement), applicationFolder, relations,
+ IAccessRelationship.WRITE_ACCESS);
+
+ }
+
+ BeanshellActivity bs = (BeanshellActivity) a;
+ BeanshellActivityConfigurationBean conf = bs.getConfiguration();
+
+ // one or more physical dependencies
+ if (conf.getLocalDependencies().size() > 0) {
+
+ Iterator<String> iter = conf.getLocalDependencies().iterator();
+ while (iter.hasNext()) {
+
+ String item = iter.next();
+
+ LOGGER.debug("\t Dependency for " + processor.getLocalName() + " [" + item + "]");
+
+ IArtifact beanshellScriptDep = (IArtifact) ArchiUtils.initElement(factory.createArtifact(), item,
+ infrastructureFolder, nodeElements);
+
+ ArchiUtils.initRelationNodeElement(factory.createAssociationRelationship(), script, beanshellScriptDep,
+ relationsFolder, nodeElements);
+
+ // Do the license checking
+ String fileName = TavernaExtractor.getTavernaHomeLib() + File.separator + item;
+
+ IProperty jarLocation = factory.createProperty();
+ jarLocation.setKey("hasSourceLocation");
+ jarLocation.setValue(fileName);
+ beanshellScriptDep.getProperties().add(jarLocation);
+
+ // do proper checking whether the file exists !
+ Path pathToDep = Paths.get(fileName);
+ if (Files.exists(pathToDep)) {
+ String license = licenseCheck.extract(pathToDep.toAbsolutePath().toString());
+
+ if (license.equals("Unknown license")) {
+ LOGGER.debug("\t Unknown license for dependency [" + item + "].");
+ }
+
+ if (license != null && !license.equals("Unknown license")) {
+
+ LOGGER.debug("\t Found license [" + license + "] for dependency [" + item + "].");
+
+ // create constraint element for dependency
+ IConstraint licenseConstraint = ArchiUtils.initElement(factory.createConstraint(), license,
+ motivationFolder, infrastructure);
+
+ ArchiUtils.initRelation(factory.createRealisationRelationship(), beanshellScriptDep,
+ licenseConstraint, relationsFolder, relations);
+ }
+ } else {
+ LOGGER.error("\t ERROR: Jar file [" + fileName + "] not found!");
+ }
+ }
+ }
+ }
+
+ private void drawBusinessProcessGroup() {
+ int maxX = 15;
+ int maxY = 15;
+
+ int defaultGroupWidth = 130;
+ int defaultGroupHeight = ArchiLayoutUtils.DEFAULT_ELEMENT_HEIGHT + 10;
+
+ businessProcessModelGroup.setBounds(0, 0, 0, 0);
+
+ // --- draw input ports ---
+ IDiagramModelGroup group_inputObjects = factory.createDiagramModelGroup();
+ group_inputObjects.setName("Input Ports");
+ businessProcessModelGroup.getChildren().add(group_inputObjects);
+ group_inputObjects.setBounds(15, 15, defaultGroupWidth, defaultGroupHeight * inputPorts.getElements().size());
+
+ Map<String, int[]> boundsMap = ArchiLayoutUtils.getBoundsForElements(inputPorts.getElements(),
+ inputPorts.getOrientation());
+ for (IArchimateElement inputPort : inputPorts.getElements()) {
+ IDiagramModelArchimateObject diagramModelBusinessObject = factory.createDiagramModelArchimateObject();
+ diagramModelBusinessObject.setArchimateElement(inputPort);
+ int[] bounds = boundsMap.get(inputPort.getId());
+ Dimension elementSize = ArchiLayoutUtils.getElementSize(inputPort);
+ diagramModelBusinessObject.setBounds(bounds[0], bounds[1] + 10, elementSize.width, elementSize.height);
+ group_inputObjects.getChildren().add(diagramModelBusinessObject);
+ elementModelObjectMap.put(inputPort.getId(), diagramModelBusinessObject);
+ }
+ ArchiLayoutUtils.resize(group_inputObjects);
+ maxY += ArchiLayoutUtils.getLowerEdgePosition(group_inputObjects);
+ maxX += ArchiLayoutUtils.getRightEdgePosition(group_inputObjects);
+
+ // --- draw value processors ---
+ if (valueObjects.getElements().size() > 0) { // only draw a group if elements exists
+ IDiagramModelGroup groupValueProcessors = factory.createDiagramModelGroup();
+ groupValueProcessors.setName("Constants Input Ports");
+ businessProcessModelGroup.getChildren().add(groupValueProcessors);
+ groupValueProcessors.setBounds(15, maxY, defaultGroupWidth, defaultGroupHeight
+ * valueObjects.getElements().size());
+
+ boundsMap = ArchiLayoutUtils
+ .getBoundsForElements(valueObjects.getElements(), valueObjects.getOrientation());
+ for (IArchimateElement valueProcessor : valueObjects.getElements()) {
+ IDiagramModelArchimateObject diagramModelBusinessObject = factory.createDiagramModelArchimateObject();
+ diagramModelBusinessObject.setArchimateElement(valueProcessor);
+ int[] bounds = boundsMap.get(valueProcessor.getId());
+ Dimension elementSize = ArchiLayoutUtils.getElementSize(valueProcessor);
+ diagramModelBusinessObject.setBounds(bounds[0], bounds[1] + 10, elementSize.width, elementSize.height);
+ groupValueProcessors.getChildren().add(diagramModelBusinessObject);
+ elementModelObjectMap.put(valueProcessor.getId(), diagramModelBusinessObject);
+ }
+ ArchiLayoutUtils.resize(groupValueProcessors);
+ maxY += ArchiLayoutUtils.getLowerEdgePosition(groupValueProcessors);
+ maxX = Math.max(maxX, ArchiLayoutUtils.getRightEdgePosition(groupValueProcessors));
+ }
+
+ // --- draw business objects ---
+ IDiagramModelGroup group_businessObjects = ArchiLayoutUtils.createSubModelGroup(businessProcessModelGroup,
+ "Business Objects");
+ group_businessObjects.setBounds(maxX, 15, 0, 0);
+
+ boundsMap = ArchiLayoutUtils.getBoundsForElements(businessObjects.getElements(),
+ businessObjects.getOrientation());
+
+ for (Entry<List<IArchimateElement>, List<IArchimateElement>> group : ArchiUtils.groupElements(
+ getBusinessProcesses(), relations).entrySet()) {
+
+ List<IArchimateElement> elementsInGroup = group.getValue();
+
+ IBusinessObject parentBusinessObject = null;
+ IDiagramModelArchimateObject diagramModelBusinessObjectParent = null;
+ if (elementsInGroup.size() >= MIN_ELEMENTS_FOR_GROUPING) {
+
+ String elementName = group.getKey().get(0).getName() + "=>" + group.getKey().get(1).getName();
+ parentBusinessObject = ArchiUtils.initElement(factory.createBusinessObject(), elementName,
+ businessFolder, businessObjects);
+ parentBusinessObject.setName(elementName);
+ diagramModelBusinessObjectParent = factory.createDiagramModelArchimateObject();
+ diagramModelBusinessObjectParent.setArchimateElement(parentBusinessObject);
+ diagramModelBusinessObjectParent.setBounds(100, 100, 100, 100);
+ elementModelObjectMap.put(parentBusinessObject.getId(), diagramModelBusinessObjectParent);
+ group_businessObjects.getChildren().add(diagramModelBusinessObjectParent);
+
+ // redirect connections to parent object
+ ArchiUtils.redirectRelations(parentBusinessObject, group.getKey().get(0), group.getKey().get(1),
+ elementsInGroup, relations);
+
+ ArchiUtils.initAccessRelation(factory.createAccessRelationship(), group.getKey().get(0),
+ parentBusinessObject, relationsFolder, relations, IAccessRelationship.WRITE_ACCESS);
+
+ ArchiUtils.initAccessRelation(factory.createAccessRelationship(), group.getKey().get(1),
+ parentBusinessObject, relationsFolder, relations, IAccessRelationship.READ_ACCESS);
+
+ }
+ for (IArchimateElement businessObject : elementsInGroup) {
+ IDiagramModelArchimateObject diagramModelBusinessObject = factory.createDiagramModelArchimateObject();
+ diagramModelBusinessObject.setArchimateElement(businessObject);
+ int[] bounds = boundsMap.get(businessObject.getId());
+ Dimension elementSize = ArchiLayoutUtils.getElementSize(businessObject);
+ diagramModelBusinessObject.setBounds(bounds[0], bounds[1], elementSize.width, elementSize.height);
+ group_businessObjects.getChildren().add(diagramModelBusinessObject);
+ elementModelObjectMap.put(businessObject.getId(), diagramModelBusinessObject);
+
+ // if parent exists -> add child & add composition relation & resize
+ if (diagramModelBusinessObjectParent != null) {
+
+ ArchiUtils.initRelation(factory.createCompositionRelationship(), parentBusinessObject,
+ businessObject, relationsFolder, relations);
+
+ diagramModelBusinessObjectParent.getChildren().add(diagramModelBusinessObject);
+ diagramModelBusinessObjectParent.setBounds(elementModelObjectMap
+ .get(elementsInGroup.get(0).getId()).getBounds().getX(),
+ elementModelObjectMap.get(elementsInGroup.get(0).getId()).getBounds().getY(),
+ diagramModelBusinessObject.getBounds().getX()
+ + diagramModelBusinessObject.getBounds().getWidth(), diagramModelBusinessObject
+ .getBounds().getY() + diagramModelBusinessObject.getBounds().getHeight());
+ }
+ }
+ }
+
+ ArchiLayoutUtils.resize(group_businessObjects);
+ maxX = Math.max(maxX, ArchiLayoutUtils.getRightEdgePosition(group_businessObjects));
+
+ // --- draw business process steps ---
+ processStepsModelGroup = ArchiLayoutUtils.createSubModelGroup(businessProcessModelGroup, "Business Processes");
+ int starting_y = ArchiLayoutUtils.boundsOf(group_businessObjects)[1]
+ + ArchiLayoutUtils.boundsOf(group_businessObjects)[3] + 10;
+ processStepsModelGroup.setBounds(group_businessObjects.getBounds().getX(), starting_y, 0, 0);
+
+ boundsMap = ArchiLayoutUtils.getBoundsForElements(businessProcesses.getElements(),
+ businessProcesses.getOrientation());
+
+ Map<String, Point> graph = null;
+ if (isDotAvailable()) {
+ graph = getGraph(dataflow);
+ }
+
+ for (IArchimateElement businessProcess : businessProcesses.getElements()) {
+
+ IDiagramModelArchimateObject diagramModelBusinessProcess = factory.createDiagramModelArchimateObject();
+ diagramModelBusinessProcess.setArchimateElement(businessProcess);
+
+ int[] bounds;
+ if (graph != null) {
+ bounds = this.getBounds(graph, businessProcess.getName());
+ } else {
+ bounds = boundsMap.get(businessProcess.getId());
+ }
+ diagramModelBusinessProcess.setBounds(bounds[0], bounds[1] + 15,
+ ArchiLayoutUtils.CUSTOM_BUSINESS_PROCESS_WIDTH, ArchiLayoutUtils.DEFAULT_ELEMENT_HEIGHT);
+
+ if (businessProcess instanceof BusinessEvent) {
+
+ businessProcessModelGroup.getChildren().add(diagramModelBusinessProcess);
+ elementModelObjectMap.put(businessProcess.getId(), diagramModelBusinessProcess);
+ continue;
+ }
+ processStepsModelGroup.getChildren().add(diagramModelBusinessProcess);
+ elementModelObjectMap.put(businessProcess.getId(), diagramModelBusinessProcess);
+ ArchiLayoutUtils.resize(processStepsModelGroup);
+ ArchiLayoutUtils.resize(businessProcessModelGroup);
+ }
+
+ // relocating loop junctions
+ for (Entry<Processor, IOrJunction> junction : loopsJunctions.entrySet()) {
+ IBusinessProcess processElement = processorProcessMap.get(junction.getKey());
+ IBounds bounds = elementModelObjectMap.get(processElement.getId()).getBounds();
+ int x = bounds.getX() + bounds.getWidth() / 2;
+ int y = bounds.getY() + bounds.getHeight() + 20;
+ elementModelObjectMap.get(junction.getValue().getId()).setBounds(x, y, 15, 15);
+ }
+
+ // relocating AND junctions
+ for (Entry<Processor, IAndJunction> junction : processorInputMap.entrySet()) {
+ IBusinessProcess processElement = processorProcessMap.get(junction.getKey());
+ IBounds bounds = elementModelObjectMap.get(processElement.getId()).getBounds();
+ int x = bounds.getX() + bounds.getWidth() / 2;
+ int y = bounds.getY() + bounds.getHeight() + 20;
+ elementModelObjectMap.get(junction.getValue().getId()).setBounds(x, y, 15, 15);
+ }
+
+ // relocate start and end event
+ elementModelObjectMap.get(startEvent.getId()).setBounds(processStepsModelGroup.getBounds().getX() - 100,
+ processStepsModelGroup.getBounds().getY() + processStepsModelGroup.getBounds().getHeight() / 2, 100,
+ ArchiLayoutUtils.DEFAULT_ELEMENT_HEIGHT);
+ if (andJunctionStart != null) {
+ elementModelObjectMap.get(andJunctionStart.getId()).setBounds(50,
+ processStepsModelGroup.getBounds().getHeight() / 2, 15, 15);
+ }
+
+ elementModelObjectMap.get(endEvent.getId()).setBounds(
+ processStepsModelGroup.getBounds().getX() + processStepsModelGroup.getBounds().getWidth() + 50,
+ processStepsModelGroup.getBounds().getY() + processStepsModelGroup.getBounds().getHeight() / 2, 100,
+ ArchiLayoutUtils.DEFAULT_ELEMENT_HEIGHT);
+
+ if (andJunctionEnd != null) {
+ elementModelObjectMap.get(andJunctionEnd.getId()).setBounds(processStepsModelGroup.getBounds().getWidth(),
+ processStepsModelGroup.getBounds().getHeight() / 2, 15, 15);
+ }
+
+ ArchiLayoutUtils.resize(processStepsModelGroup);
+ ArchiLayoutUtils.resize(businessProcessModelGroup);
+
+ // ArchiLayoutUtils.resize(processStepsModelGroup);
+ maxX = Math.max(maxX, ArchiLayoutUtils.getRightEdgePosition(processStepsModelGroup));
+
+ // all process steps are children of the parent process
+ for (IArchimateElement element : businessProcesses.getElements()) {
+ if (element != parentProcessWorkflow && !(element instanceof BusinessEvent)) {
+ elementModelObjectMap.get(parentProcessWorkflow.getId()).getChildren()
+ .add(elementModelObjectMap.get(element.getId()));
+ }
+ }
+
+ // --- draw output ports ---
+ IDiagramModelGroup groupOutputPorts = ArchiLayoutUtils.createSubModelGroup(businessProcessModelGroup,
+ "Output Ports");
+ groupOutputPorts.setBounds(maxX + 35, 15, defaultGroupWidth, defaultGroupHeight
+ * outputPorts.getElements().size());
+
+ boundsMap = ArchiLayoutUtils.getBoundsForElements(outputPorts.getElements(), outputPorts.getOrientation());
+ for (IArchimateElement outputPort : outputPorts.getElements()) {
+ IDiagramModelArchimateObject diagramModelBusinessObject = factory.createDiagramModelArchimateObject();
+ diagramModelBusinessObject.setArchimateElement(outputPort);
+ int[] bounds = boundsMap.get(outputPort.getId());
+ final Dimension elementSize = ArchiLayoutUtils.getElementSize(outputPort);
+ diagramModelBusinessObject.setBounds(bounds[0], bounds[1], elementSize.width, elementSize.height);
+ groupOutputPorts.getChildren().add(diagramModelBusinessObject);
+ elementModelObjectMap.put(outputPort.getId(), diagramModelBusinessObject);
+ ArchiLayoutUtils.resize(groupOutputPorts);
+ ArchiLayoutUtils.resize(businessProcessModelGroup);
+ }
+
+ maxX = businessProcessModelGroup.getBounds().getWidth() + businessProcessModelGroup.getBounds().getX();
+ maxY = businessProcessModelGroup.getBounds().getHeight() + businessProcessModelGroup.getBounds().getY();
+
+ overall_X = maxX;
+ overall_Y = maxY;
+ }
+
+ private void drawExternalApplicationServices() {
+
+ // hide empty container
+ if (externalApplicationServices.getElements().isEmpty()) {
+ externalApplicationModelGroup.setBounds(0, overall_Y + 30, 0, 0);
+ return;
+ }
+
+ externalApplicationModelGroup.setBounds(0, overall_Y + 30, overall_X, 150);
+ overall_Y += 150;
+
+ Map<String, int[]> boundsMap = ArchiLayoutUtils.getBoundsForElements(externalApplicationServices.getElements(),
+ externalApplicationServices.orientation);
+ for (IArchimateElement element : externalApplicationServices.getElements()) {
+
+ IDiagramModelArchimateObject diagramModelBusinessObject = factory.createDiagramModelArchimateObject();
+ diagramModelBusinessObject.setArchimateElement(element);
+ int[] bounds = boundsMap.get(element.getId());
+ Dimension elementSize = ArchiLayoutUtils.getElementSize(element);
+ diagramModelBusinessObject.setBounds(bounds[0], bounds[1], elementSize.width, elementSize.height);
+ externalApplicationModelGroup.getChildren().add(diagramModelBusinessObject);
+ elementModelObjectMap.put(element.getId(), diagramModelBusinessObject);
+ }
+ ArchiLayoutUtils.resize(externalApplicationModelGroup);
+ }
+
+ private void drawApplicationComponentServices() {
+
+ int starting_y = ArchiLayoutUtils.boundsOf(externalApplicationModelGroup)[1]
+ + ArchiLayoutUtils.boundsOf(externalApplicationModelGroup)[3] + 20;
+ applicationComponentModelGroup.setBounds(0, starting_y, overall_X, 150);
+ overall_Y += 150;
+
+ Map<String, int[]> boundsMap = ArchiLayoutUtils.getBoundsForElements(dataObjects.getElements(),
+ dataObjects.getOrientation());
+
+ List<IArchimateElement> alreadyDrawnElements = new ArrayList<IArchimateElement>();
+
+ // --- draw data objects ---
+ for (Entry<List<IArchimateElement>, List<IArchimateElement>> group : ArchiUtils.groupElements(
+ applicationComponents.getElements(), relations).entrySet()) {
+
+ List<IArchimateElement> elementsInGroup = group.getValue();
+
+ IDataObject parentDataObject = null;
+ IDiagramModelArchimateObject diagramModelDataObjectParent = null;
+ if (elementsInGroup.size() >= MIN_ELEMENTS_FOR_GROUPING) {
+
+ String elementName = group.getKey().get(0).getName() + "=>" + group.getKey().get(1).getName();
+ parentDataObject = ArchiUtils.initElement(factory.createDataObject(), elementName, applicationFolder,
+ dataObjects);
+ parentDataObject.setName(elementName);
+ diagramModelDataObjectParent = factory.createDiagramModelArchimateObject();
+ diagramModelDataObjectParent.setArchimateElement(parentDataObject);
+ diagramModelDataObjectParent.setBounds(0, 0, 10, 10);
+ elementModelObjectMap.put(parentDataObject.getId(), diagramModelDataObjectParent);
+ applicationComponentModelGroup.getChildren().add(diagramModelDataObjectParent);
+
+ // redirect connections to parent object
+ ArchiUtils.redirectRelations(parentDataObject, group.getKey().get(0), group.getKey().get(1),
+ elementsInGroup, relations);
+
+ ArchiUtils.initAccessRelation(factory.createAccessRelationship(), group.getKey().get(0),
+ parentDataObject, relationsFolder, relations, IAccessRelationship.WRITE_ACCESS);
+
+ ArchiUtils.initAccessRelation(factory.createAccessRelationship(), group.getKey().get(1),
+ parentDataObject, relationsFolder, relations, IAccessRelationship.READ_ACCESS);
+ alreadyDrawnElements.add(parentDataObject);
+ }
+ for (IArchimateElement dataObject : elementsInGroup) {
+ IDiagramModelArchimateObject diagramModelBusinessObject = factory.createDiagramModelArchimateObject();
+ diagramModelBusinessObject.setArchimateElement(dataObject);
+
+ int[] bounds = { 10, 10 };
+ if (boundsMap.containsKey(dataObject.getId())) {
+ bounds = boundsMap.get(dataObject.getId());
+ }
+ Dimension elementSize = ArchiLayoutUtils.getElementSize(dataObject);
+
+ diagramModelBusinessObject.setBounds(bounds[0], bounds[1], elementSize.width, elementSize.height);
+ applicationComponentModelGroup.getChildren().add(diagramModelBusinessObject);
+ elementModelObjectMap.put(dataObject.getId(), diagramModelBusinessObject);
+
+ alreadyDrawnElements.add(dataObject);
+
+ // if parent exists -> add child & add composition relation & resize
+ if (diagramModelDataObjectParent != null) {
+
+ ArchiUtils.initRelation(factory.createCompositionRelationship(), parentDataObject, dataObject,
+ relationsFolder, relations);
+
+ diagramModelDataObjectParent.getChildren().add(diagramModelBusinessObject);
+ diagramModelDataObjectParent.setBounds(elementModelObjectMap.get(elementsInGroup.get(0).getId())
+ .getBounds().getX(), elementModelObjectMap.get(elementsInGroup.get(0).getId()).getBounds()
+ .getY(), diagramModelBusinessObject.getBounds().getX()
+ + diagramModelBusinessObject.getBounds().getWidth(), diagramModelBusinessObject.getBounds()
+ .getY() + diagramModelBusinessObject.getBounds().getHeight());
+ }
+ }
+ }
+
+ ArrayList<IArchimateElement> objectsToDraw = (ArrayList<IArchimateElement>) dataObjects.getElements();
+ objectsToDraw.removeAll(alreadyDrawnElements);
+ objectsToDraw.addAll(applicationComponents.getElements());
+
+ boundsMap = ArchiLayoutUtils.getBoundsForElements(objectsToDraw, applicationComponents.orientation);
+
+ for (IArchimateElement element : objectsToDraw) {
+
+ IDiagramModelArchimateObject diagramModelBusinessObject = factory.createDiagramModelArchimateObject();
+ diagramModelBusinessObject.setArchimateElement(element);
+ int[] bounds = boundsMap.get(element.getId());
+ final Dimension elementSize = ArchiLayoutUtils.getElementSize(element);
+ diagramModelBusinessObject.setBounds(bounds[0], bounds[1], elementSize.width, elementSize.height);
+
+ applicationComponentModelGroup.getChildren().add(diagramModelBusinessObject);
+ elementModelObjectMap.put(element.getId(), diagramModelBusinessObject);
+ }
+ ArchiLayoutUtils.resize(applicationComponentModelGroup);
+ }
+
+ private void drawExternalInfrastructureServices() {
+
+ int starting_y = ArchiLayoutUtils.boundsOf(applicationComponentModelGroup)[1]
+ + ArchiLayoutUtils.boundsOf(applicationComponentModelGroup)[3] + 20;
+
+ // hide empty container
+ if (infrastructureServices.getElements().isEmpty()) {
+ externalInfrastructureModelGroup.setBounds(0, starting_y, 0, 0);
+ return;
+ }
+
+ externalInfrastructureModelGroup.setBounds(0, starting_y, overall_X, 150);
+ overall_Y += 150;
+
+ LOGGER.debug("drawExternalInfrastructureServices.getElements().size() = "
+ + infrastructureServices.getElements().size());
+
+ Map<String, int[]> boundsMap = ArchiLayoutUtils.getBoundsForElements(infrastructureServices.getElements(),
+ infrastructureServices.orientation);
+ for (IArchimateElement element : infrastructureServices.getElements()) {
+
+ IDiagramModelArchimateObject diagramModelBusinessObject = factory.createDiagramModelArchimateObject();
+ diagramModelBusinessObject.setArchimateElement(element);
+ int[] bounds = boundsMap.get(element.getId());
+ diagramModelBusinessObject.setBounds(bounds[0], bounds[1], bounds[2], bounds[3]);
+ externalInfrastructureModelGroup.getChildren().add(diagramModelBusinessObject);
+ elementModelObjectMap.put(element.getId(), diagramModelBusinessObject);
+ }
+ ArchiLayoutUtils.resize(externalInfrastructureModelGroup);
+ }
+
+ private void drawInfrastructure() {
+
+ int starting_y = ArchiLayoutUtils.boundsOf(externalInfrastructureModelGroup)[1]
+ + ArchiLayoutUtils.boundsOf(externalInfrastructureModelGroup)[3] + 20;
+ infrastructureModelGroup.setBounds(0, starting_y, overall_X, 150);
+
+ Map<String, int[]> boundsMap = ArchiLayoutUtils.getBoundsForElements(infrastructure.getElements(),
+ infrastructure.orientation);
+ for (IArchimateElement element : infrastructure.getElements()) {
+
+ IDiagramModelArchimateObject diagramModelBusinessObject = factory.createDiagramModelArchimateObject();
+ diagramModelBusinessObject.setArchimateElement(element);
+
+ int[] bounds = boundsMap.get(element.getId());
+ diagramModelBusinessObject.setBounds(bounds[0], bounds[1], bounds[2], bounds[3]);
+
+ infrastructureModelGroup.getChildren().add(diagramModelBusinessObject);
+ elementModelObjectMap.put(element.getId(), diagramModelBusinessObject);
+
+ if (element.getId().equals(desktop.getId())) {
+ createDiagramElements(generateLayout(nodeElements), diagramModelBusinessObject);
+ infrastructureModelGroup.setBounds(0, starting_y, overall_X, diagramModelBusinessObject.getBounds()
+ .getHeight() + 25);
+ }
+ }
+ ArchiLayoutUtils.resize(infrastructureModelGroup);
+ }
+
+ private void drawExternalProviders() {
+
+ if (!externalProviders.getElements().isEmpty()) {
+
+ // (*) Group "External Provider"
+ externalProviderModelGroup = ArchiLayoutUtils.createSubModelGroup(layeredView, "External Service Provider");
+
+ int starting_y = ArchiLayoutUtils.boundsOf(externalInfrastructureModelGroup)[1];
+ int starting_x = ArchiLayoutUtils.boundsOf(externalInfrastructureModelGroup)[0]
+ + ArchiLayoutUtils.boundsOf(externalInfrastructureModelGroup)[2] + 20;
+ externalProviderModelGroup.setBounds(starting_x, starting_y, 150, 150);
+
+ Map<String, int[]> boundsMap = ArchiLayoutUtils.getBoundsForElements(externalProviders.getElements(),
+ externalProviders.orientation);
+ for (IArchimateElement element : externalProviders.getElements()) {
+
+ IDiagramModelArchimateObject diagramModelBusinessObject = factory.createDiagramModelArchimateObject();
+ diagramModelBusinessObject.setArchimateElement(element);
+
+ int[] bounds = boundsMap.get(element.getId());
+ diagramModelBusinessObject.setBounds(bounds[0], bounds[1], bounds[2], bounds[3]);
+
+ externalProviderModelGroup.getChildren().add(diagramModelBusinessObject);
+ elementModelObjectMap.put(element.getId(), diagramModelBusinessObject);
+ }
+ ArchiLayoutUtils.resize(externalProviderModelGroup);
+ }
+ }
+
+ private void drawRelations() {
+ for (IRelationship relation : relations) {
+
+ if (relation.getSource() == null) {
+ return;
+ }
+ if (relation.getTarget() == null) {
+ return;
+ }
+
+ LOGGER.debug("drawing relation [" + relation.getSource().getName() + "("
+ + relation.getSource().eClass().getName() + ")] --> [" + relation.getTarget().getName() + "("
+ + relation.getTarget().eClass().getName() + ")]");
+
+ IDiagramModelArchimateObject source = elementModelObjectMap.get(relation.getSource().getId());
+ IDiagramModelArchimateObject target = elementModelObjectMap.get(relation.getTarget().getId());
+
+ ArchiLayoutUtils.createConnection(factory, relation, source, target);
+ }
+ }
+
+ private Map<IArchimateElement, Point> generateLayout(List<IArchimateElement> elements) {
+
+ Map<IArchimateElement, Point> items = new HashMap<IArchimateElement, Point>();
+ graph = new SparseGraph<IArchimateElement, IArchimateElement>();
+
+ for (IArchimateElement element : elements) {
+ if (element instanceof IRelationship) {
+ IArchimateElement source = ((IRelationship) element).getSource();
+ IArchimateElement target = ((IRelationship) element).getTarget();
+ graph.addEdge(element, source, target);
+ } else {
+ graph.addVertex(element);
+ }
+ }
+
+ layout = new ISOMLayout<IArchimateElement, IArchimateElement>(graph);
+ layout.setSize(new Dimension(650, 650));
+
+ for (IArchimateElement element : layout.getGraph().getVertices()) {
+
+ int x = (int) ((AbstractLayout<IArchimateElement, IArchimateElement>) layout).getX(element);
+ int y = (int) ((AbstractLayout<IArchimateElement, IArchimateElement>) layout).getY(element);
+ LOGGER.debug(element.getName() + "[" + x + "][" + y + "]");
+ items.put(element, new Point(x, y));
+ }
+ return items;
+ }
+
+ private void createDiagramElements(Map<IArchimateElement, Point> elements, IDiagramModelContainer parent) {
+
+ // draw elements
+ for (Entry<IArchimateElement, Point> entry : elements.entrySet()) {
+
+ IDiagramModelArchimateObject diagramModelObject = factory.createDiagramModelArchimateObject();
+ diagramModelObject.setArchimateElement(entry.getKey());
+ Dimension size = ArchiLayoutUtils.getElementSize(entry.getKey());
+
+ diagramModelObject.setBounds(entry.getValue().x, entry.getValue().y, size.width, size.height);
+ parent.getChildren().add(diagramModelObject);
+
+ // resize parent container
+ ArchiLayoutUtils.resize(parent);
+ elementModelObjectMap.put(entry.getKey().getId(), diagramModelObject);
+ }
+
+ // create connections
+ for (IArchimateElement edge : layout.getGraph().getEdges()) {
+
+ IRelationship relationShip = (IRelationship) edge;
+
+ String sourceID = relationShip.getSource().getId();
+ String targetID = relationShip.getTarget().getId();
+ IDiagramModelArchimateObject source = elementModelObjectMap.get(sourceID);
+ IDiagramModelArchimateObject target = elementModelObjectMap.get(targetID);
+
+ ArchiLayoutUtils.createConnection(factory, relationShip, source, target);
+ }
+ }
+
+ private boolean sshInvocation(String mechanismAsXMLString) {
+ return mechanismAsXMLString.contains("<sshInvocation>");
+ }
+
+ private IProperty createDepProperties(Class clazz) {
+
+ IProperty property = factory.createProperty();
+ property.setKey("hasSourceLocation");
+ property.setValue(getJarLocationOfClass(clazz).getPath().replaceFirst("/",""));
+ return property;
+ }
+
+ private IProperty createDepProperties(String pathToJar) {
+
+ IProperty property = factory.createProperty();
+ property.setKey("hasSourceLocation");
+ property.setValue(pathToJar);
+ return property;
+ }
+
+ private List<IProperty> createPropertiesOutOfXMLMechanism(ExternalToolActivityConfigurationBean configuration) {
+
+ List<IProperty> props = new ArrayList<IProperty>();
+
+ try {
+ Document document = DocumentHelper.parseText(configuration.getMechanismXML());
+
+ IProperty hostProperty = factory.createProperty();
+ hostProperty.setKey("Host");
+ hostProperty.setValue(document.selectSingleNode("//host").getText());
+ props.add(hostProperty);
+
+ IProperty portProperty = factory.createProperty();
+ portProperty.setKey("Port");
+ portProperty.setValue(document.selectSingleNode("//port").getText());
+ props.add(portProperty);
+
+ } catch (DocumentException e) {
+ LOGGER.error("ERROR parsing external tool invocation mechanism. " + e.getMessage());
+ }
+
+ IProperty commandProperty = factory.createProperty();
+ commandProperty.setKey("Command");
+ commandProperty.setValue(configuration.getUseCaseDescription().getCommand());
+ props.add(commandProperty);
+
+ return props;
+ }
+
+ private List<IProperty> createPropertiesOutOfRshellConfig(RshellActivityConfigurationBean configuration) {
+
+ List<IProperty> props = new ArrayList<IProperty>();
+
+ IProperty hostProperty = factory.createProperty();
+ hostProperty.setKey("Host");
+ hostProperty.setValue(configuration.getConnectionSettings().getHost());
+ props.add(hostProperty);
+
+ IProperty portProperty = factory.createProperty();
+ portProperty.setKey("Port");
+ portProperty.setValue("" + configuration.getConnectionSettings().getPort());
+ props.add(portProperty);
+
+ IProperty scriptProperty = factory.createProperty();
+ scriptProperty.setKey("Script");
+ scriptProperty.setValue(configuration.getScript());
+ props.add(scriptProperty);
+
+ return props;
+ }
+
+ private void printPortInformation(Processor processor) {
+
+ if (processor != null) {
+ for (ProcessorInputPort inputPort : processor.getInputPorts()) {
+ LOGGER.debug("--> Port = " + inputPort.getName() + "[depth = " + inputPort.getDepth() + "]");
+ }
+ for (ProcessorOutputPort outputPort : processor.getOutputPorts()) {
+ LOGGER.debug("<-- Port = " + outputPort.getName() + "[depth = " + outputPort.getDepth() + "]");
+ }
+ }
+ }
+
+ private List<Processor> findStartingProcessors(Dataflow dataflow) {
+
+ List<OutputPort> outputPorts = new ArrayList<OutputPort>();
+ for (Processor processor : dataflow.getProcessors()) {
+ for (OutputPort outputPort : processor.getOutputPorts()) {
+ outputPorts.add(outputPort);
+ }
+ }
+
+ List<Processor> startingProcessors = new ArrayList<Processor>();
+ for (Processor processor : dataflow.getProcessors()) {
+
+ // detect if first step processor
+
+ if (ArchiUtils.isValueProcessor(processor)) {
+ break;
+ }
+
+ if (hasNoPrecedentProcessor(processor, outputPorts)) {
+ LOGGER.debug("Processor '" + processor.getLocalName() + "' has no precendent processors.");
+ startingProcessors.add(processor);
+ }
+ }
+ return startingProcessors;
+ }
+
+ private List<Processor> findEndProcessors(Dataflow dataflow) {
+
+ List<InputPort> inputPorts = new ArrayList<InputPort>();
+ for (Processor processor : dataflow.getProcessors()) {
+ for (InputPort inputPort : processor.getInputPorts()) {
+ inputPorts.add(inputPort);
+ }
+ }
+
+ List<Processor> endingProcessors = new ArrayList<Processor>();
+ for (Processor processor : dataflow.getProcessors()) {
+
+ // detect if first step processor
+ if (hasNoSucceedProcessor(processor, inputPorts)) {
+ LOGGER.debug("Processor '" + processor.getLocalName() + "' has no succeed processors.");
+ endingProcessors.add(processor);
+ }
+ }
+ return endingProcessors;
+ }
+
+ private boolean hasNoPrecedentProcessor(Processor processor, List<OutputPort> outputPorts) {
+
+ for (ProcessorInputPort sink : processor.getInputPorts()) {
+ if (outputPorts.contains(sink.getIncomingLink().getSource())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean hasNoSucceedProcessor(Processor processor, List<InputPort> inputPort) {
+
+ for (ProcessorOutputPort out : processor.getOutputPorts()) {
+
+ for (Datalink links : out.getOutgoingLinks()) {
+ if (inputPort.contains(links.getSink())) {
+ return false;
+ }
+ }
+
+ }
+ return true;
+ }
+
+ public Map<String, Point> getGraph(Dataflow dataflow) {
+
+ SVGGraphController con = new SVGGraphController(dataflow, false, new JSVGCanvas(), Alignment.HORIZONTAL,
+ PortStyle.NONE);
+
+ StringWriter stringWriter = new StringWriter();
+ DotWriter dotWriter = new DotWriter(stringWriter);
+
+ try {
+
+ String tmpDirPath = System.getProperty("java.io.tmpdir");
+ File dotTmp = new File(tmpDirPath + File.separator + "tavernaExtractorToArchimate.dot");
+ FileWriter fw = new FileWriter(dotTmp);
+ dotWriter = new DotWriter(fw);
+ dotWriter.writeGraph(con.getGraph());
+ fw.close();
+
+ // Dot to SVG
+ File svgTmp = new File(tmpDirPath + File.separator + "tavernaExtractorToArchimate.dot.svg");
+
+ String[] COMMAND = { TavernaExtractor.getDotLocation(), "-Tsvg", dotTmp.getAbsolutePath(), "-o", svgTmp.getAbsolutePath() };
+
+ LOGGER.debug("Running command '" + StringUtils.join(COMMAND, " ") + "'.");
+
+ ProcessBuilder proc = new ProcessBuilder(COMMAND);
+ Process process = proc.start();
+
+ InputStream stderr = process.getErrorStream();
+ InputStreamReader isr = new InputStreamReader(stderr);
+ BufferedReader br = new BufferedReader(isr);
+ String line = null;
+ while ((line = br.readLine()) != null) {
+ ;
+ }
+ process.waitFor();
+
+ // parse SVG
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(false);
+ DocumentBuilder builder;
+ builder = factory.newDocumentBuilder();
+ org.w3c.dom.Document doc = builder.parse(svgTmp);
+ XPath xpath = XPathFactory.newInstance().newXPath();
+
+ final String XPATH_EXPRESSION = "//g[@class='node']/text/text() | //g[@class='node']/text/@x | //g[@class='node']/text/@y";
+ XPathExpression expr = xpath.compile(XPATH_EXPRESSION);
+ Object result = expr.evaluate(doc, XPathConstants.NODESET);
+ NodeList nodes = (NodeList) result;
+
+ return transform(nodes);
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (ParserConfigurationException e) {
+ e.printStackTrace();
+ } catch (SAXException e) {
+ e.printStackTrace();
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return Collections.emptyMap();
+ }
+
+ private Map<String, Point> transform(NodeList nodeList) {
+
+ Map<String, Point> reducedMap = new HashMap<String, Point>();
+ Map<String, Point> map = new HashMap<String, Point>();
+ for (int i = 0; i < nodeList.getLength() - 1; i += 3) {
+
+ String key = nodeList.item(i + 2).getTextContent();
+ try {
+ Integer x = (int) Math.abs(Double.parseDouble(nodeList.item(i).getTextContent()));
+ Integer y = (int) Math.abs(Double.parseDouble(nodeList.item(i + 1).getTextContent()));
+ map.put(key, new Point(x, y));
+ } catch (NumberFormatException nfe) {
+ LOGGER.error("ERROR: Unable to convert to integer. " + nfe.getMessage());
+ map.put(key, new Point(1, 1));
+ }
+ }
+
+ for (Entry<String, Point> entry : map.entrySet()) {
+ for (IArchimateElement businessProcess : businessProcesses.getElements()) {
+ if (businessProcess.getName().equals(entry.getKey())) {
+ reducedMap.put(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+ return reducedMap;
+ }
+
+ private int[] getBounds(Map<String, Point> map, String name) {
+
+ if (map.containsKey(name)) {
+ return new int[] { map.get(name).x, map.get(name).y };
+ }
+ return new int[] { -1, -1 };
+ }
+
+ private int numberOfTriggringInputProcessors(Dataflow dataflow, Processor processor) {
+
+ @SuppressWarnings("unchecked")
+ List<ProcessorInputPort> inputs = (List<ProcessorInputPort>) processor.getInputPorts();
+ int inputsNumber = inputs.size();
+ for (ProcessorInputPort processorInput : processor.getInputPorts()) {
+
+ for (DataflowInputPort dataflowInput : dataflow.getInputPorts()) {
+ if (processorInput.getIncomingLink().getSource().getName().equals(dataflowInput.getName())) {
+ inputsNumber--;
+ }
+ }
+ }
+ return inputsNumber;
+ }
+
+ private boolean isDotAvailable() {
+
+ if (dotLocation != null && !dotLocation.isEmpty()) {
+
+ try {
+ Paths.get(dotLocation);
+ }catch(InvalidPathException ipe){
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private void detailProcessorsOnLayers(List<? extends Processor> processors) throws IOException {
+ for (Processor processor : processors) {
+
+ String processorName = processor.getLocalName();
+
+ for (Activity<?> a : processor.getActivityList()) {
+
+ LOGGER.debug(processorName + " [" + processor.getActivityList().size() + "] -> "
+ + a.getClass().getName());
+
+ printPortInformation(processor);
+
+ // TODO UnrecognizedActivity detected !!
+ if (a instanceof UnrecognizedActivity) {
+ LOGGER.error("PROBLEM: UnrecognizedActivity detected! ");
+ }
+ // TODO DisabledActivity detected !!
+ // From the javadoc: A disabled activity is a wrapper for an Activity that is offline or similarly
+ // disabled
+ if (a instanceof DisabledActivity) {
+ LOGGER.error("PROBLEM: DisabledActivity detected! ");
+ // TODO: create a note element with information
+ }
+
+ // nested worklfow
+ if (a instanceof DataflowActivity) {
+ DataflowActivity nestedWF = (DataflowActivity) a;
+ detailProcessorsOnLayers(nestedWF.getNestedDataflow().getProcessors());
+ }
+
+ // processing RShellActivity
+ if (a instanceof RshellActivity) {
+
+ processRShellActivity(businessFolder, infrastructureFolder, applicationFolder, relationsFolder,
+ workflowApplicationComponent, processorProcessMap, callToolInvocationFunction, processor,
+ processorName, a);
+ }
+
+ // processing ExternalToolActivity
+ if (a instanceof ExternalToolActivity) {
+ ExternalToolActivityConfigurationBean conf = (ExternalToolActivityConfigurationBean) a
+ .getConfiguration();
+
+ if (conf != null && conf.getMechanismXML() != null) {
+
+ String mechanismAsXMLString = conf.getMechanismXML();
+ if (sshInvocation(mechanismAsXMLString)) { // SSH invocation
+
+ // treat like as an web service dependency
+ processToolActivity(businessFolder, infrastructureFolder, applicationFolder,
+ relationsFolder, workflowApplicationComponent, processorProcessMap,
+ callToolInvocationFunction, processor, processorName, a, true);
+
+ } else { // local tool invocation
+
+ processToolActivity(businessFolder, infrastructureFolder, applicationFolder,
+ relationsFolder, workflowApplicationComponent, processorProcessMap,
+ callToolInvocationFunction, processor, processorName, a, false);
+ }
+ }
+ }
+ // processing Beanshell activities
+ if (a instanceof BeanshellActivity) {
+ processBeanshellActivity(infrastructureFolder, motivationFolder, applicationFolder,
+ relationsFolder, workflowApplicationComponent, processorProcessMap, processor, a);
+ }
+ // processing REST activity
+ if (a instanceof RESTActivity) {
+ processWebServiceActivity(businessFolder, infrastructureFolder, applicationFolder, relationsFolder,
+ workflowApplicationComponent, processorProcessMap, callWebServiceApplicationFunction,
+ processor, processorName, a);
+ }
+ // processing WSDL activity
+ // IMPORTANT: Service(=Activity) MUST BE ONLINE !! Otherwise it will be of type DisabledActivity
+ // From the javadoc: A disabled activity is a wrapper for an Activity that is offline or similarly
+ // disabled
+ if (a instanceof WSDLActivity) {
+ processWebServiceActivity(businessFolder, infrastructureFolder, applicationFolder, relationsFolder,
+ workflowApplicationComponent, processorProcessMap, callWebServiceApplicationFunction,
+ processor, processorName, a);
+ }
+ }
+ }
+ }
+
+ private void validateDirectories(Path... dirs) throws IOException{
+
+ for(Path path : dirs) {
+ if (path == null || Files.notExists(path) || !Files.isDirectory(path) || !Files.isReadable(path)) {
+ throw new IOException("Directory '" + path + "' does not exists or is invalid.");
+ }
+ }
+ }
+
+ private List<String> cleanedClasspath(List<String> classpathEntries){
+
+ List<String> cleanedClasspathEntries = new ArrayList<String>();
+
+ for(String entry : classpathEntries)
+ if(entry.contains("taverna-2."))
+ cleanedClasspathEntries.add(entry);
+
+ return cleanedClasspathEntries;
+ }
+
+ private URL getJarLocationOfClass(Class clazz) {
+ return clazz.getProtectionDomain().getCodeSource().getLocation();
+ }
+
+ public void treatProcessors(List<? extends Processor> processors) {
+
+ for (Processor processor : dataflow.getProcessors()) {
+ IArchimateElement archimateElement = null;
+
+ // "value" processors are actually a constant input port, treat them special
+ if (ArchiUtils.isValueProcessor(processor)) {
+ IBusinessObject valueBusinessObject = ArchiUtils.initElement(factory.createBusinessObject(),
+ processor.getLocalName(), businessFolder, valueObjects);
+ archimateElement = valueBusinessObject;
+ processorValueMap.put(processor, valueBusinessObject);
+
+ }
+
+ else {
+ // create the archimate element
+ IBusinessProcess process = ArchiUtils.initElement(factory.createBusinessProcess(),
+ processor.getLocalName(), businessFolder, businessProcesses);
+ archimateElement = process;
+ // composition relation to parent workflow
+ ArchiUtils.initRelation(factory.createCompositionRelationship(), parentProcessWorkflow, process,
+ relationsFolder, relations);
+ // put created elements to lookup map for later when creating relations
+ processorProcessMap.put(processor, process);
+ }
+
+ // add additional relationship between processor and workflow input port
+ for (ProcessorInputPort port : processor.getInputPorts()) {
+ for (IArchimateElement item : ArchiUtils.getElementsByname(
+ port.getIncomingLink().getSource().getName(), inputPorts.getElements())) {
+ IAccessRelationship readAccessRelation = ArchiUtils.initRelation(
+ factory.createAccessRelationship(), archimateElement, item, relationsFolder, relations);
+ readAccessRelation.setAccessType(IAccessRelationship.READ_ACCESS);
+ }
+ }
+
+ // add additional relationship between processor and workflow output port
+ for (ProcessorOutputPort port : processor.getOutputPorts()) {
+ for (Datalink datalink : port.getOutgoingLinks()) {
+ for (IArchimateElement item : ArchiUtils.getElementsByname(datalink.getSink().getName(),
+ outputPorts.getElements())) {
+ IAccessRelationship readAccessRelation = ArchiUtils.initRelation(
+ factory.createAccessRelationship(), archimateElement, item, relationsFolder, relations);
+ readAccessRelation.setAccessType(IAccessRelationship.WRITE_ACCESS);
+ }
+ }
+ }
+ }
+
+ // connect all starting processors with the start event
+ List<Processor> startingProcessors = findStartingProcessors(dataflow);
+ for (Processor processor : startingProcessors) {
+
+ if (startingProcessors.size() <= 1) {
+ ArchiUtils.initRelation(factory.createTriggeringRelationship(), startEvent,
+ processorProcessMap.get(processor), relationsFolder, relations);
+ }
+ // additional AND junction
+ else {
+ if (andJunctionStart == null) {
+ andJunctionStart = ArchiUtils.initElement(factory.createAndJunction(), "AndJunction",
+ businessFolder, businessProcesses);
+ ArchiUtils.initRelation(factory.createTriggeringRelationship(), startEvent, andJunctionStart,
+ relationsFolder, relations);
+ }
+ ArchiUtils.initRelation(factory.createTriggeringRelationship(), andJunctionStart,
+ processorProcessMap.get(processor), relationsFolder, relations);
+ }
+ }
+
+ // connect all ending processors with the end event
+ List<Processor> endprocessors = findEndProcessors(dataflow);
+ for (Processor processor : endprocessors) {
+
+ if (endprocessors.size() <= 1) {
+ ArchiUtils.initRelation(factory.createTriggeringRelationship(), processorProcessMap.get(processor),
+ endEvent, relationsFolder, relations);
+ }
+ // additional AND junction
+ else {
+ if (andJunctionEnd == null) {
+ andJunctionEnd = ArchiUtils.initElement(factory.createAndJunction(), "EndingAndJunction",
+ businessFolder, businessProcesses);
+ ArchiUtils.initRelation(factory.createTriggeringRelationship(), andJunctionEnd, endEvent,
+ relationsFolder, relations);
+ }
+ ArchiUtils.initRelation(factory.createTriggeringRelationship(), processorProcessMap.get(processor),
+ andJunctionEnd, relationsFolder, relations);
+ }
+ }
+
+ //
+ // second pass - add relations between processes
+ //
+ Stack<Processor> processorStack = new Stack<Processor>();
+ for (Processor processor : dataflow.getProcessors()) {
+ boolean isValueProcessor = ArchiUtils.isValueProcessor(processor);
+
+ for (ProcessorOutputPort processorOutputPort : processor.getOutputPorts()) {
+
+ LOGGER.debug("Process processorOutputPort = '" + processorOutputPort.getName() + "'");
+
+ for (Datalink datalink : processorOutputPort.getOutgoingLinks()) {
+
+ EventHandlingInputPort sink = datalink.getSink();
+
+ if (sink instanceof ProcessorInputPortImpl) {
+
+ boolean split = false;
+ IOrJunction orJunction = null;
+
+ // after this processor we need an Or-junction
+ if (datalink.getSource().getDepth() - datalink.getSink().getDepth() > 0) {
+
+ split = true;
+
+ orJunction = ArchiUtils.initElement(factory.createOrJunction(), "OrJunctionMerge",
+ businessFolder, businessProcesses);
+
+ // if (!loopsJunctions.containsKey(processor)) {
+ loopsJunctions.put(processor, orJunction);
+ // }
+
+ processorStack.push(processor);
+ }
+
+ // after this processor we need an Or-junction
+ if (datalink.getSource().getDepth() - datalink.getSink().getDepth() < 0) {
+ split = true;
+ orJunction = ArchiUtils.initElement(factory.createOrJunction(), "OrJunctionSplit",
+ businessFolder, businessProcesses);
+
+ // if (!loopsJunctions.containsKey(processor)) {
+ loopsJunctions.put(processor, orJunction);
+ // }
+
+ if (!processorStack.isEmpty()) {
+ Processor startProcessor = processorStack.pop();
+
+ // draw loop back relation
+ IOrJunction splitJunction = loopsJunctions.get(startProcessor);
+ IOrJunction mergeJunction = loopsJunctions.get(processor);
+
+ ArchiUtils.initRelation(factory.createTriggeringRelationship(), mergeJunction,
+ splitJunction, relationsFolder, relations);
+
+ LOGGER.debug("loop detected between [" + startProcessor.getLocalName() + "] --> ["
+ + processor.getLocalName() + "]");
+ }
+ }
+
+ Processor targetProcessor = ((ProcessorInputPortImpl) sink).getProcessor();
+ IBusinessProcess targetProcess = processorProcessMap.get(targetProcessor);
+
+ if (isValueProcessor) {
+
+ // value processors are constants, we treat them like process inputs
+ IBusinessObject sourceBusinessObject = processorValueMap.get(processor);
+ // make sure we only create one triggering relation combining two elements
+ if (!ArchiUtils.containsRelation(targetProcess, sourceBusinessObject, relations)) {
+ ArchiUtils.initRelation(factory.createTriggeringRelationship(), sourceBusinessObject,
+ targetProcess, relationsFolder, relations);
+ }
+ } else {
+
+ // 1. create relation
+ IBusinessProcess sourceProcess = processorProcessMap.get(processor);
+
+ // check if source processor has more than one input port. if so, we need a additional AND
+ // junction
+ if (numberOfTriggringInputProcessors(dataflow, processor) > 1) {
+
+ // have to do that check, otherwise we will initialize (which means create and draw
+ // ) an Archimate element every time
+ if (!processorInputMap.containsKey(processor)) {
+
+ // create additional AND Junction
+ processorInputMap.put(processor, ArchiUtils.initElement(
+ factory.createAndJunction(), processor.getLocalName() + "_AND",
+ businessFolder, businessProcesses));
+ }
+ }
+
+ // make sure we only create one triggering relation combining two elements
+ if (!ArchiUtils.containsRelation(targetProcess, sourceProcess, relations)) {
+ if (split) {
+ ArchiUtils.initRelation(factory.createTriggeringRelationship(), sourceProcess,
+ orJunction, relationsFolder, relations);
+ ArchiUtils.initRelation(factory.createTriggeringRelationship(), orJunction,
+ targetProcess, relationsFolder, relations);
+
+ } else {
+ ArchiUtils.initRelation(factory.createTriggeringRelationship(), sourceProcess,
+ targetProcess, relationsFolder, relations);
+ }
+ split = false; // reset flags!
+ }
+
+ // 2. create business object
+ IBusinessObject businessObject = ArchiUtils.initElement(factory.createBusinessObject(),
+ sink.getName(), businessFolder, businessObjects);
+
+ LOGGER.debug("\t BusinessObject for datalink '" + datalink.getSource().getName() + " -> "
+ + sink.getName() + "' created.");
+
+ if (processorObjectMapping.get(processor) == null) {
+ processorObjectMapping.put(processor, new ArrayList<IBusinessObject>());
+ }
+ processorObjectMapping.get(processor).add(businessObject);
+
+ ArchiUtils.initAccessRelation(factory.createAccessRelationship(), sourceProcess,
+ businessObject, relationsFolder, relations, IAccessRelationship.WRITE_ACCESS);
+
+ // 3. create read access relation from target process to business object
+ ArchiUtils.initAccessRelation(factory.createAccessRelationship(), targetProcess,
+ businessObject, relationsFolder, relations, IAccessRelationship.READ_ACCESS);
+ }
+ } else { // TODO these are likely workflow output ports, need to be treated special
+ // System.out.println("Unknown sink type for processor " + processor + ", dataLink " + datalink
+ // + ": " + sink.getClass());
+ }
+ }
+ }
+ }
+
+ }
+
+ @Override
+ public String getName() {
+ return null;
+ }
+
+ @Override
+ public String getSymbolicName() {
+ return null;
+ }
+
+ @Override
+ public Version getVersion() {
+ return null;
+ }
+
+ @Override
+ public EnumSet<OperatingSystem> getSupportedOperatingSystems() {
+ return null;
+ }
+
+ @Override
+ public HashMap<String, Parameter> getParameters() {
+ return null;
+ }
+
+ @Override
+ public String extract(Endpoint endpoint, boolean b) throws Exception {
+ return null;
+ }
+}