org.emftrace.ui.modelimport.EMFTraceImportHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.emftrace.ui.modelimport.EMFTraceImportHelper.java

Source

/*******************************************************************************
 * Copyright (c) 2010-2013 Software Systems/Process Informatics Group,
 * Ilmenau University of Technology.
 * All rights reserved. This program and the accompanying materials
 * are 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
 ******************************************************************************/

package org.emftrace.ui.modelimport;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Callable;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecp.core.ECPProject;
import org.eclipse.emf.emfstore.client.util.RunESCommand;
import org.eclipse.emf.emfstore.internal.common.CommonUtil;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.HandlerUtil;
import org.emftrace.ui.activator.Activator;
import org.emftrace.ui.util.UIHelper;
import org.emftrace.ui.util.UIHelper.ModelExchangeState;
import org.osgi.framework.Bundle;

/**
 * Handles the import of models into a project.
 * 
 * @author  Steffen Lehnert
 * @version 1.0
 */
public class EMFTraceImportHelper implements IRunnableWithProgress {
    private ECPProject project;
    private String fileName;
    private String fileExtension;
    private String template;
    private Shell shell;

    ///////////////////////////////////////////////////////////////////////////

    /**
     * Constructor
     * 
     * @param newProject the current {@link  ECPProject project}
     * @param name       the name of the model
     * @param extension  the file extension of the model
     * @param templ      the name of the template
     */
    EMFTraceImportHelper(final Shell shl, ECPProject newProject, String name, String extension, String templ) {
        project = newProject;
        fileName = name;
        fileExtension = extension;
        template = templ;
        shell = shl;
    }

    ///////////////////////////////////////////////////////////////////////////

    @Override
    public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
        if (project == null) {
            processResult(shell, ModelExchangeState.Project_Missing, false);
            return;
        }

        if (fileName == null) {
            processResult(shell, ModelExchangeState.File_Missing, false);
            return;
        }

        if (template == null) {
            processResult(shell, ModelExchangeState.Template_Missing, false);
            return;
        }

        if (fileExtension == null) {
            processResult(shell, ModelExchangeState.Extension_Missing, false);
            return;
        }

        String finalPath = "";
        FileOutputStream file = null;

        if (!template.contains(UIHelper.NO_TEMPLATE)) {
            TransformerFactory tFactory = TransformerFactory.newInstance();
            Transformer transformer = null;

            Bundle bundle = Platform.getBundle(Activator.PLUGIN_ID);
            URL url = bundle.getEntry(template);
            URL realUrl = null;

            try {
                realUrl = FileLocator.resolve(url);
            } catch (IOException e2) {
                e2.printStackTrace();
            }

            String path = realUrl.getPath();
            path.replace(" ", "%20");

            try {
                transformer = tFactory.newTransformer(new StreamSource(path));
            } catch (TransformerConfigurationException e1) {
                e1.printStackTrace();
                processResult(shell, ModelExchangeState.Transformation_Error, false);
                return;
            }
            try {
                monitor.beginTask("Transforming the input file...", 100);
                monitor.worked(1);
                finalPath = finalPath.concat(fileName);
                finalPath = finalPath.replace(fileExtension, "TEMP" + fileExtension);
                file = new FileOutputStream(finalPath);
                transformer.transform(new StreamSource(fileName), new StreamResult(file));
                monitor.worked(50);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                processResult(shell, ModelExchangeState.Transformation_Error, false);
                return;
            } catch (TransformerException e) {
                e.printStackTrace();
                processResult(shell, ModelExchangeState.Transformation_Error, false);
                return;
            }

            if (finalPath == null || finalPath.equals("")) {
                processResult(shell, ModelExchangeState.Misc_Error, false);
                return;
            }
        } else
            finalPath = fileName;

        final URI fileURI = URI.createFileURI(finalPath);

        // create resource set and resource
        ResourceSet resourceSet = new ResourceSetImpl();

        final Resource resource = resourceSet.getResource(fileURI, true);

        Callable<Void> call = new Callable<Void>() {
            @Override
            public Void call() throws Exception {
                monitor.setTaskName("Importing file...");
                importFile(project, fileURI, resource, monitor);
                monitor.worked(95);

                return null;
            }
        };

        RunESCommand.run(call);

        try {
            monitor.setTaskName("Removing temporary files...");
            if (file != null)
                file.close();
            if (!template.contains(UIHelper.NO_TEMPLATE))
                new File(finalPath).delete();
            monitor.worked(100);
            processResult(shell, ModelExchangeState.Import_OK, false);
        } catch (IOException e) {
            processResult(shell, ModelExchangeState.Misc_Error, false);
        }
    }

    ///////////////////////////////////////////////////////////////////////////

    /**
     * Processes the result of the import process and prints out the proper notification.
     * 
     * @param shell the shell for the dialog window
     * @param state the import state
     * @param usePopUp decides whether to open a pop-up or to write to Eclipse console
     * @return the state of the model import
     */
    protected static ModelExchangeState processResult(Shell shell, ModelExchangeState state, boolean usePopUp) {
        switch (state) {
        case Import_OK: {
            if (usePopUp)
                MessageDialog.openInformation(shell, "Import finished", "The model has been imported properly");
            else
                System.out.println("Import finished: The model has been imported properly");

            break;
        }

        case Transformation_Error: {
            if (usePopUp)
                MessageDialog.openInformation(shell, "Import abborted",
                        "An error occured during model transformation. See the Eclipse Log for more details.");
            else
                System.out.println(
                        "Import abborted: An error occured during model transformation. See the Eclipse Log for more details.");

            break;
        }

        case Template_Missing: {
            if (usePopUp)
                MessageDialog.openInformation(shell, "Import abborted", "XSLT-Template missing");
            else
                System.out.println("Import abborted: XSLT-Template missing");

            break;
        }

        case Project_Missing: {
            if (usePopUp)
                MessageDialog.openInformation(shell, "Import abborted", "Project missing");
            else
                System.out.println("Import abborted: Project missing");

            break;
        }

        case File_Missing: {
            if (usePopUp)
                MessageDialog.openInformation(shell, "Import abborted", "No file specified");
            else
                System.out.println("Import abborted: No file specified");

            break;
        }

        case Misc_Error: {
            if (usePopUp)
                MessageDialog.openInformation(shell, "Import abborted",
                        "An error occured during the import procedure. See the Eclipse Log for more details.");
            else
                System.out.println(
                        "Import abborted:  An error occured during the import procedure. See the Eclipse Log for more details.");

            break;
        }

        default:
            break;
        }

        return state;
    }

    ///////////////////////////////////////////////////////////////////////////

    /**
     * Runs the import
     * 
     * @param project  the current project
     * @param fileURI  the URI of the file
     * @param resource the file as resource
     */
    private static void importFile(ECPProject project, final URI fileURI, final Resource resource,
            final IProgressMonitor monitor) {
        try {
            Set<EObject> importElements = validation(resource, monitor);

            if (importElements.size() > 0) {
                monitor.setTaskName("Adding model elements...");

                int i = 0;
                for (EObject eObject : importElements) {
                    runImport(project, fileURI, (EObject) EcoreUtil.copy(eObject), i);
                    monitor.worked(90);
                    i++;
                }
            }
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
    }

    ///////////////////////////////////////////////////////////////////////////

    /**
     * Validates if the EObjects can be imported
     * 
     * @param resource
     * @return
     */
    private static Set<EObject> validation(Resource resource, final IProgressMonitor monitor) {
        monitor.setTaskName("Validating model elements. Phase 1/3...");

        Set<EObject> childrenSet = new HashSet<EObject>();
        Set<EObject> rootNodes = new HashSet<EObject>();

        EList<EObject> rootContent = resource.getContents();

        for (EObject rootNode : rootContent) {
            TreeIterator<EObject> contents = rootNode.eAllContents();
            // 1. Run: Put all children in set
            while (contents.hasNext()) {
                EObject content = contents.next();
                if (!(content instanceof EObject))
                    continue;
                childrenSet.add(content);
            }
        }

        monitor.worked(60);
        monitor.setTaskName("Validating model elements. Phase 2/3...");

        // 2. Run: Check if RootNodes are children -> set.contains(RootNode) -- no: RootNode in rootNode-Set -- yes:
        // Drop RootNode, will be imported as a child
        for (EObject rootNode : rootContent) {
            if (!(rootNode instanceof EObject))
                continue;
            if (!childrenSet.contains(rootNode))
                rootNodes.add(rootNode);
        }

        monitor.worked(70);
        monitor.setTaskName("Validating model elements. Phase 3/3...");

        // 3. Check if RootNodes are SelfContained -- yes: import -- no: error
        Set<EObject> notSelfContained = new HashSet<EObject>();
        for (EObject rootNode : rootNodes) {
            if (!CommonUtil.isSelfContained(rootNode)) {
                notSelfContained.add(rootNode);
            }
        }
        rootNodes.removeAll(notSelfContained);
        monitor.worked(75);

        return rootNodes;
    }

    ///////////////////////////////////////////////////////////////////////////

    /**
     * Runs the import command.
     * 
     * @param project - the projectSpace where the element should be imported in.
     * @param uri - the uri of the resource.
     * @param element - the modelElement to import.
     * @param resourceIndex - the index of the element inside the eResource.
     */
    private static void runImport(final ECPProject project, final org.eclipse.emf.common.util.URI uri,
            final EObject element, final int resourceIndex) {
        project.getContents().add(element);
    }

    ///////////////////////////////////////////////////////////////////////////

    /**
     * Return the currently selected {@link EObject}
     * 
     * @param event the current selection event
     * @return the selected EObject
     */
    protected static EObject getSelection(ExecutionEvent event) {
        EObject result = null;
        ISelection sel = HandlerUtil.getCurrentSelection(event);
        if (!(sel instanceof IStructuredSelection)) {
            return null;
        }
        IStructuredSelection ssel = (IStructuredSelection) sel;
        if (ssel.isEmpty()) {
            return null;
        }

        Object obj = ssel.getFirstElement();
        if (obj instanceof EObject) {
            result = (EObject) obj;
        }

        return result;
    }

    ///////////////////////////////////////////////////////////////////////////

    /**
     * Return a selected {@link EObject}
     *  
     * @param event the current selection event
     * @return the selected EObject
     */
    public static EObject getModelElement(ExecutionEvent event) {
        EObject me = null;

        String partId = HandlerUtil.getActivePartId(event);
        if (partId != null && partId.equals(UIHelper.ECP_EDITOR)) {
            // extract model element from editor input
            IEditorInput editorInput = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
                    .getActiveEditor().getEditorInput();
            Object obj = editorInput.getAdapter(EObject.class);
            me = (EObject) obj;
        } else {
            // extract model element from current selection in navigator
            EObject eObject = getSelection(event);
            if (eObject == null)
                return null;
            me = eObject;
        }

        return me;
    }
}