| /** |
| ******************************************************************************** |
| * Copyright (c) 2017-2020 Robert Bosch GmbH. |
| * |
| * This program and the accompanying materials are made |
| * available under the terms of the Eclipse Public License 2.0 |
| * which is available at https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Robert Bosch GmbH - initial API and implementation |
| ******************************************************************************** |
| */ |
| |
| package org.eclipse.app4mc.emf.viewer.plantuml.handlers; |
| |
| import java.io.File; |
| |
| import org.eclipse.app4mc.emf.viewer.plantuml.builders.AbstractPlantUMLBuilder; |
| import org.eclipse.app4mc.emf.viewer.plantuml.builders.BuilderResult; |
| import org.eclipse.app4mc.emf.viewer.plantuml.utils.DiagramCreator; |
| import org.eclipse.app4mc.emf.viewer.plantuml.utils.ExecutionCategory; |
| import org.eclipse.app4mc.emf.viewer.plantuml.utils.ExecutionUtil; |
| import org.eclipse.app4mc.emf.viewer.plantuml.views.DiagramView; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.e4.ui.di.UISynchronize; |
| import org.eclipse.e4.ui.model.application.ui.basic.MPart; |
| import org.eclipse.e4.ui.workbench.modeling.EPartService; |
| import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.swt.widgets.Shell; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| public abstract class AbstractPlantUMLHandler { |
| |
| private static final Logger LOGGER = LoggerFactory.getLogger(AbstractPlantUMLHandler.class); |
| |
| protected abstract AbstractPlantUMLBuilder createPlantUMLBuilder(UISynchronize sync); |
| |
| protected abstract ExecutionCategory getExecutionCategory(); |
| |
| public abstract String getFileNamePrefix(Object eObject); |
| |
| public void execute( |
| Shell shell, |
| UISynchronize sync, |
| String dotPath, |
| String genFolderPath, |
| IStructuredSelection selection, |
| EPartService partService) { |
| |
| EClass selectedObjClass = null; |
| |
| Object element = selection.getFirstElement(); |
| if (element instanceof EObject) { |
| if (element instanceof EClass) { |
| selectedObjClass = (EClass) element; |
| } else { |
| selectedObjClass = ((EObject) element).eClass(); |
| } |
| } else { |
| openErrorDialog(shell); |
| return; |
| } |
| |
| execute( |
| shell, |
| sync, |
| dotPath, |
| genFolderPath, |
| partService, |
| selectedObjClass, |
| (EObject)element); |
| } |
| |
| public void execute( |
| Shell shell, |
| UISynchronize sync, |
| String dotPath, |
| String genFolderPath, |
| EPartService partService, |
| Object selected, |
| EObject eObject) { |
| |
| // check if there is a valid dot path |
| if (verifyDotPath(shell, sync, dotPath)) { |
| |
| // generate UML |
| if (selected != null) { |
| |
| String genFolder = DiagramCreator.getGenFolder(genFolderPath, eObject != null ? eObject.eResource() : null); |
| if (genFolder == null || genFolder.length() == 0) { |
| openErrorDialog(shell, "Folder for diagram generation is not set. Configure a folder path in Preferences -> AMALTHEA Graphical Representation"); |
| return; |
| } else if (!new File(genFolder).exists()) { |
| openErrorDialog(shell, "Invalid folder path is specified. Configure a valid folder path in Preferences -> AMALTHEA Graphical Representation"); |
| return; |
| } |
| |
| // generate UML and SVG |
| Job job = Job.create("Generate diagram", monitor -> { |
| AbstractPlantUMLBuilder builder = createPlantUMLBuilder(sync); |
| BuilderResult result = builder.generatePlantUML(selected); |
| |
| LOGGER.info(result.getPlantUMLText()); |
| |
| ExecutionUtil.setExecutionCategory(getExecutionCategory()); |
| String fileNamePrefix = getFileNamePrefix(eObject != null ? eObject : selected); |
| String svgFilePath = DiagramCreator.generateSVG(result, genFolder, fileNamePrefix, eObject); |
| |
| sync.asyncExec(() -> { |
| // display view |
| MPart diagramPart = partService.findPart(DiagramView.ID); |
| if (diagramPart == null) { |
| diagramPart = partService.createPart(DiagramView.ID); |
| } |
| if (diagramPart != null) { |
| partService.showPart(diagramPart, PartState.VISIBLE); |
| DiagramView diagramView = (DiagramView) diagramPart.getObject(); |
| diagramView.showDiagram(fileNamePrefix, eObject, svgFilePath, result.getId2ObjectMap()); |
| } |
| }); |
| }); |
| job.schedule(); |
| } |
| } |
| } |
| |
| protected boolean verifyDotPath(Shell shell, UISynchronize sync, String dotPathFromPlantUMLPreferencePage) { |
| |
| String dotPathFromSystemProperty = System.getenv("GRAPHVIZ_DOT"); |
| |
| File dotFile = null; |
| |
| if (dotPathFromPlantUMLPreferencePage != null) { |
| dotFile = ensureValidDotFile(shell, sync, dotPathFromPlantUMLPreferencePage, "PlantUMLPreference"); |
| } else if (dotPathFromSystemProperty != null) { |
| dotFile = ensureValidDotFile(shell, sync, dotPathFromSystemProperty, "SystemProperty"); |
| } else { |
| showErrorDialog(shell, sync, "Missing Graphviz dot.exe location." |
| + "\nPlease specify location via Window - Preferences - PlantUML - Path to the dot executable of Graphviz."); |
| } |
| |
| if (dotFile == null) |
| return false; |
| |
| System.setProperty("GRAPHVIZ_DOT", dotFile.getAbsolutePath()); |
| |
| return true; |
| } |
| |
| private File ensureValidDotFile(Shell shell, UISynchronize sync, String dotPath, String origin) { |
| |
| |
| if (dotPath == null || dotPath.equals("")) { |
| showErrorDialog(shell, sync, "Missing Graphviz dot.exe location." |
| + "\nPlease specify location via Window - Preferences - PlantUML - Path to the dot executable of Graphviz."); |
| return null; |
| } |
| |
| final File dotFile = new File(dotPath); |
| if (!dotFile.canExecute()) { |
| |
| if(origin.equals("PlantUMLPreference")) { |
| showErrorDialog(shell, sync, "Invalid Graphviz dot.exe location: \'" + dotFile.getAbsolutePath()+"\'" |
| + "\nPlease set location via Window - Preferences - PlantUML - Path to the 'dot executable of Graphviz'."); |
| }else { |
| showErrorDialog(shell, sync, "Invalid Graphviz dot.exe location found in System Property 'GRAPHVIZ_DOT' : \'" + dotFile.getAbsolutePath()+"\'" |
| + "\nPlease update the System Property 'GRAPHVIZ_DOT' with valid Path to the 'dot executable of Graphviz'."); |
| } |
| return null; |
| } |
| |
| return dotFile; |
| } |
| |
| private void showErrorDialog(Shell shell, UISynchronize sync, String message) { |
| sync.asyncExec(() -> |
| MessageDialog.openError(shell, "AMALTHEA HW Visualization", message) |
| ); |
| } |
| |
| protected void openErrorDialog(Shell shell) { |
| openErrorDialog(shell, "Selected object is not a EMF object"); |
| } |
| |
| protected void openErrorDialog(Shell shell, String msg) { |
| MessageDialog.openError(shell, "EMF content extractor dialog", msg); |
| } |
| |
| } |