/******************************************************************************* * Copyright (c) 2011 Red Hat, Inc. * All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.eclipse.bpmn2.modeler.ui.wizards; import org.eclipse.bpmn2.modeler.ui.Activator; import org.eclipse.bpmn2.modeler.ui.editor.BPMN2Editor; import org.eclipse.bpmn2.modeler.ui.util.ErrorUtils; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.graphiti.mm.pictograms.Diagram; import org.eclipse.graphiti.services.Graphiti; import org.eclipse.graphiti.ui.editor.DiagramEditorInput; import org.eclipse.graphiti.ui.services.GraphitiUi; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; public class BPMN2DiagramCreator { private final static String TEMPFILE_EXTENSION = "bpmn2d"; private IFolder diagramFolder; private IFile diagramFile; private URI uri; public void createDiagram() throws CoreException { createDiagram(true); } public DiagramEditorInput createDiagram(boolean openEditor) throws CoreException { if (diagramFolder != null && !diagramFolder.exists()) { diagramFolder.create(false, true, null); } final Diagram diagram = Graphiti.getPeCreateService().createDiagram("BPMN2", diagramFile.getFullPath().removeFileExtension().lastSegment(), true); uri = URI.createPlatformResourceURI(diagramFile.getFullPath().toString(), true); TransactionalEditingDomain domain = FileService.createEmfFileForDiagram(uri, diagram); String providerId = GraphitiUi.getExtensionManager().getDiagramTypeProviderId(diagram.getDiagramTypeId()); final DiagramEditorInput editorInput = new Bpmn2DiagramEditorInput(EcoreUtil.getURI(diagram), domain, providerId); if (openEditor) { openEditor(editorInput); } return editorInput; } private void openEditor(final DiagramEditorInput editorInput) { PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { @Override public void run() { try { PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() .openEditor(editorInput, BPMN2Editor.EDITOR_ID); } catch (PartInitException e) { String error = "Error while opening diagram editor"; IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, error, e); ErrorUtils.showErrorWithLogging(status); } } }); } public IFolder getDiagramFolder() { return diagramFolder; } public void setDiagramFolder(IFolder diagramFolder) { this.diagramFolder = diagramFolder; } public IFile getDiagramFile() { return diagramFile; } public void setDiagramFile(IFile diagramFile) { this.diagramFile = diagramFile; } public URI getUri() { return uri; } /** * Construct a temporary folder based on the given path. The folder is constructed * in the project root and its name will be the same as the given path's file extension. * * @param fullPath - path of the actual BPMN2 model file * @return an IFolder for the temporary folder. * @throws CoreException */ public static IFolder getTempFolder(IPath fullPath) throws CoreException { IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); String name = fullPath.getFileExtension(); if (name==null || name.length()==0) name = "bpmn2"; IFolder folder = root.getProject(fullPath.segment(0)).getFolder("."+name); if (!folder.exists()) { folder.create(true, true, null); } String[] segments = fullPath.segments(); for (int i = 1; i < segments.length - 1; i++) { String segment = segments[i]; folder = folder.getFolder(segment); if (!folder.exists()) { folder.create(true, true, null); } } return folder; } /** * Return the temporary file to be used as editor input. Conceptually, this is the * "diagramFile" mentioned here which is just a placeholder for use by Graphiti * as the DiagramEditorInput file. * * @param fullPath - path of the actual BPMN2 model file * @param folder - folder containing the model file * @return an IFile for the temporary file. If the file exists, it is first deleted. */ public static IFile getTempFile(IPath fullPath, IFolder folder) { IPath path = fullPath.removeFileExtension().addFileExtension(TEMPFILE_EXTENSION); IFile tempFile = folder.getFile(path.lastSegment()); // We don't need anything from that file and to be sure there are no side effects we delete the file if (tempFile.exists()) { try { tempFile.delete(true, null); } catch (CoreException e) { Activator.showErrorWithLogging(e); } } return tempFile; } /** * Return the BPMN2 model file given a path to either the "diagramFile" temporary file, * or the acutal model file. * * @param fullPath - path of the actual BPMN2 model file * @return an IFile for the model file. */ public static IFile getModelFile(IPath fullPath) { IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(fullPath); IProject project = ResourcesPlugin.getWorkspace().getRoot().getFile(fullPath).getProject(); int matchingSegments = project.getFullPath().matchingFirstSegments(fullPath); int totalSegments = fullPath.segmentCount(); String ext = fullPath.getFileExtension(); // sanity check: make sure the fullPath is not the project if (totalSegments<=matchingSegments) return null; String[] segments = fullPath.segments(); IPath path = null; if (TEMPFILE_EXTENSION.equals(ext)) { // this is a tempFile - rebuild the BPMN2 model file name from its path ext = fullPath.segment(matchingSegments); if (ext.startsWith(".")) ext = ext.substring(1); path = project.getFullPath(); for (int i=matchingSegments+1; i<segments.length; ++i) { path = path.append(segments[i]); } path = path.removeFileExtension().addFileExtension(ext); } else { // this is a model file - normalize path path = fullPath.makeAbsolute(); } return ResourcesPlugin.getWorkspace().getRoot().getFile(path); } /** * Delete the temporary diagram file. If the containing folder hierarchy is empty, * it will also be deleted. * * @param file - the temporary diagram file. */ public static void dispose(IFile file) { try { IContainer container = file.getParent(); file.delete(true, null); while ( isEmptyFolder(container) ) { container.delete(true, null); container = container.getParent(); } } catch (CoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * Check if the given folder is empty. This is true if it contains no files, or only * empty folders. * * @param container - folder to check * @return true if the folder is empty. */ public static boolean isEmptyFolder(IContainer container) { try { IResource[] members = container.members(); for ( IResource res : members ) { int type = res.getType(); if (type==IResource.FILE || type==IResource.PROJECT || type==IResource.ROOT) return false; if ( !isEmptyFolder((IContainer)res) ) return false; } } catch (CoreException e) { return false; } return true; } }