Package org.eclipse.bpmn2.modeler.ui.wizards

Source Code of org.eclipse.bpmn2.modeler.ui.wizards.FileService

/*******************************************************************************
* 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 java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.command.CommandStack;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.Transaction;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.ui.editor.DiagramEditorFactory;

public class FileService {

  public static TransactionalEditingDomain createEmfFileForDiagram(URI diagramResourceUri, final Diagram diagram) {

    // Create a resource set and EditingDomain
    final TransactionalEditingDomain editingDomain = DiagramEditorFactory.createResourceSetAndEditingDomain();
    final ResourceSet resourceSet = editingDomain.getResourceSet();
    // Create a resource for this file.
    final Resource resource = resourceSet.createResource(diagramResourceUri);
    final CommandStack commandStack = editingDomain.getCommandStack();
    commandStack.execute(new RecordingCommand(editingDomain) {

      @Override
      protected void doExecute() {
        resource.setTrackingModification(true);
        resource.getContents().add(diagram);

      }
    });

    save(editingDomain, Collections.<Resource, Map<?, ?>> emptyMap());
    return editingDomain;
  }

  private static void save(TransactionalEditingDomain editingDomain, Map<Resource, Map<?, ?>> options) {
    saveInWorkspaceRunnable(editingDomain, options);
  }

  private static void saveInWorkspaceRunnable(final TransactionalEditingDomain editingDomain,
      final Map<Resource, Map<?, ?>> options) {

    final Map<URI, Throwable> failedSaves = new HashMap<URI, Throwable>();
    final IWorkspaceRunnable wsRunnable = new IWorkspaceRunnable() {
      @Override
      public void run(final IProgressMonitor monitor) throws CoreException {

        final Runnable runnable = new Runnable() {

          @Override
          public void run() {
            Transaction parentTx;
            if (editingDomain != null
                && (parentTx = ((TransactionalEditingDomainImpl) editingDomain).getActiveTransaction()) != null) {
              do {
                if (!parentTx.isReadOnly()) {
                  throw new IllegalStateException(
                      "FileService.save() called from within a command (likely produces a deadlock)"); //$NON-NLS-1$
                }
              } while ((parentTx = ((TransactionalEditingDomainImpl) editingDomain)
                  .getActiveTransaction().getParent()) != null);
            }

            final EList<Resource> resources = editingDomain.getResourceSet().getResources();
            // Copy list to an array to prevent
            // ConcurrentModificationExceptions
            // during the saving of the dirty resources
            Resource[] resourcesArray = new Resource[resources.size()];
            resourcesArray = resources.toArray(resourcesArray);
            final Set<Resource> savedResources = new HashSet<Resource>();
            for (int i = 0; i < resourcesArray.length; i++) {
              // In case resource modification tracking is
              // switched on, we can check if a resource
              // has been modified, so that we only need to same
              // really changed resources; otherwise
              // we need to save all resources in the set
              final Resource resource = resourcesArray[i];
              if (resource.isModified()) {
                try {
                  resource.save(options.get(resource));
                  savedResources.add(resource);
                } catch (final Throwable t) {
                  failedSaves.put(resource.getURI(), t);
                }
              }
            }
          }
        };

        try {
          editingDomain.runExclusive(runnable);
        } catch (final InterruptedException e) {
          throw new RuntimeException(e);
        }
        editingDomain.getCommandStack().flush();
      }
    };
    try {
      ResourcesPlugin.getWorkspace().run(wsRunnable, null);
      if (!failedSaves.isEmpty()) {
        throw new WrappedException(createMessage(failedSaves), new RuntimeException());
      }
    } catch (final CoreException e) {
      final Throwable cause = e.getStatus().getException();
      if (cause instanceof RuntimeException) {
        throw (RuntimeException) cause;
      }
      throw new RuntimeException(e);
    }
  }

  private static String createMessage(Map<URI, Throwable> failedSaves) {
    final StringBuilder buf = new StringBuilder("The following resources could not be saved:");
    for (final Entry<URI, Throwable> entry : failedSaves.entrySet()) {
      buf.append("\nURI: ").append(entry.getKey().toString()).append(", cause: \n")
          .append(getExceptionAsString(entry.getValue()));
    }
    return buf.toString();
  }

  private static String getExceptionAsString(Throwable t) {
    final StringWriter stringWriter = new StringWriter();
    final PrintWriter printWriter = new PrintWriter(stringWriter);
    t.printStackTrace(printWriter);
    final String result = stringWriter.toString();
    try {
      stringWriter.close();
    } catch (final IOException e) {
      // $JL-EXC$ ignore
    }
    printWriter.close();
    return result;
  }
}
TOP

Related Classes of org.eclipse.bpmn2.modeler.ui.wizards.FileService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.