org.jbpm.gd.jpdl.wizard.NewProcessProjectWizard.java Source code

Java tutorial

Introduction

Here is the source code for org.jbpm.gd.jpdl.wizard.NewProcessProjectWizard.java

Source

/*
 * JBoss, Home of Professional Open Source
 * Copyright 2005, JBoss Inc., and individual contributors as indicated
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jbpm.gd.jpdl.wizard;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
import org.eclipse.core.resources.ICommand;
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.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
import org.eclipse.ui.part.ISetSelectionTarget;
import org.jboss.tools.jbpm.preferences.JbpmInstallation;
import org.jboss.tools.jbpm.preferences.PreferencesManager;
import org.jbpm.gd.jpdl.Logger;
import org.jbpm.gd.jpdl.util.JbpmClasspathContainer;

public class NewProcessProjectWizard extends Wizard implements INewWizard {

    private WizardNewProjectCreationPage mainPage;
    private ConfigureRuntimePage configureRuntimePage;
    private NewProcessProjectDetailsWizardPage coreJbpmPage;
    private IProject newProject;
    private IWorkbench workbench;

    public boolean canFinish() {
        return super.canFinish() && coreJbpmPage.combo.getItemCount() > 0
                && coreJbpmPage.combo.getSelectionIndex() != -1;
    }

    public void init(IWorkbench w, IStructuredSelection currentSelection) {
        this.workbench = w;
        setNeedsProgressMonitor(true);
        setWindowTitle("New Process Project");
    }

    public void addPages() {
        addMainPage();
        if (!isJbpm3RuntimeAvailable()) {
            addConfigureRuntimePage();
        }
        addChooseRuntimePage();
    }

    private boolean isJbpm3RuntimeAvailable() {
        Map<String, JbpmInstallation> installations = PreferencesManager.getInstance().getJbpmInstallationMap();
        Iterator<String> iterator = installations.keySet().iterator();
        while (iterator.hasNext()) {
            JbpmInstallation installation = installations.get(iterator.next());
            if ("jBPM3".equals(installation.version)) {
                return true;
            }
        }
        return false;
    }

    private void addConfigureRuntimePage() {
        configureRuntimePage = new ConfigureRuntimePage();
        addPage(configureRuntimePage);
    }

    private void addChooseRuntimePage() {
        coreJbpmPage = new NewProcessProjectDetailsWizardPage();
        addPage(coreJbpmPage);
    }

    private void addMainPage() {
        super.addPages();
        setWindowTitle("New Process Project");
        mainPage = new WizardNewProjectCreationPage("basicNewProjectPage");
        mainPage.setTitle("Process Project");
        mainPage.setDescription("Create a new process project.");
        addPage(mainPage);
    }

    private IProject createNewProject() {
        final IProject newProjectHandle = mainPage.getProjectHandle();
        final IProjectDescription description = createProjectDescription(newProjectHandle);
        WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
            protected void execute(IProgressMonitor monitor) throws CoreException {
                createProject(description, newProjectHandle, monitor);
            }
        };
        runProjectCreationOperation(op, newProjectHandle);
        return newProjectHandle;
    }

    private void addJRELibraries(IJavaProject javaProject) throws JavaModelException {
        ArrayList entries = new ArrayList();
        entries.addAll(Arrays.asList(javaProject.getRawClasspath()));
        entries.addAll(Arrays.asList(PreferenceConstants.getDefaultJRELibrary()));
        javaProject.setRawClasspath((IClasspathEntry[]) entries.toArray(new IClasspathEntry[entries.size()]), null);
    }

    private void addSourceFolders(IJavaProject javaProject) throws JavaModelException, CoreException {
        ArrayList entries = new ArrayList();
        entries.addAll(Arrays.asList(javaProject.getRawClasspath()));
        addSourceFolder(javaProject, entries, "src/main/java");
        addSourceFolder(javaProject, entries, "src/main/config");
        addSourceFolder(javaProject, entries, "src/main/jpdl");
        addSourceFolder(javaProject, entries, "src/test/java");
        javaProject.setRawClasspath((IClasspathEntry[]) entries.toArray(new IClasspathEntry[entries.size()]), null);
    }

    private void addSourceFolder(IJavaProject javaProject, ArrayList entries, String path) throws CoreException {
        IFolder folder = javaProject.getProject().getFolder(path);
        createFolder(folder);
        IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(folder);
        entries.add(JavaCore.newSourceEntry(root.getPath()));
    }

    private void createFolder(IFolder folder) throws CoreException {
        IContainer parent = folder.getParent();
        if (parent != null && !parent.exists() && parent instanceof IFolder) {
            createFolder((IFolder) parent);
        }
        if (!(folder.exists())) {
            folder.create(true, true, null);
        }
    }

    private JbpmInstallation getJbpmInstallation() {
        return PreferencesManager.getInstance().getJbpmInstallation(getCoreJbpmName());
    }

    private void createJbpmLibraryContainer(IJavaProject javaProject) throws JavaModelException {
        JavaCore.setClasspathContainer(new Path("JBPM/" + getJbpmInstallation().name),
                new IJavaProject[] { javaProject },
                new IClasspathContainer[] { new JbpmClasspathContainer(javaProject, getJbpmInstallation()) }, null);
    }

    private String getCoreJbpmName() {
        return coreJbpmPage.getCoreJbpmName();
    }

    private void addJbpmLibraries(IJavaProject javaProject) throws JavaModelException {
        createJbpmLibraryContainer(javaProject);
        ArrayList entries = new ArrayList();
        entries.addAll(Arrays.asList(javaProject.getRawClasspath()));
        entries.add(JavaCore.newContainerEntry(new Path("JBPM/" + getJbpmInstallation().name)));
        javaProject.setRawClasspath((IClasspathEntry[]) entries.toArray(new IClasspathEntry[entries.size()]), null);
    }

    private void createOutputLocation(IJavaProject javaProject) throws JavaModelException, CoreException {
        IFolder binFolder = javaProject.getProject().getFolder("bin");
        createFolder(binFolder);
        IPath outputLocation = binFolder.getFullPath();
        javaProject.setOutputLocation(outputLocation, null);
    }

    private void addJavaBuilder(IJavaProject javaProject) throws CoreException {
        IProjectDescription desc = javaProject.getProject().getDescription();
        ICommand command = desc.newCommand();
        command.setBuilderName(JavaCore.BUILDER_ID);
        desc.setBuildSpec(new ICommand[] { command });
        javaProject.getProject().setDescription(desc, null);
    }

    private void createJavaProject() {
        try {
            newProject = createNewProject();
            newProject.setPersistentProperty(new QualifiedName("", "jbpmName"), getCoreJbpmName());
            IJavaProject javaProject = JavaCore.create(newProject);
            createOutputLocation(javaProject);
            addJavaBuilder(javaProject);
            setClasspath(javaProject);
            createInitialContent(javaProject);
            newProject.build(IncrementalProjectBuilder.FULL_BUILD, null);
        } catch (JavaModelException e) {
            ErrorDialog.openError(getShell(), "Problem creating java project", null, e.getStatus());
        } catch (CoreException e) {
            ErrorDialog.openError(getShell(), "Problem creating java project", null, e.getStatus());
        } catch (IOException e) {
            ErrorDialog.openError(getShell(), "Problem creating java project", null, null);
        }
    }

    private void createInitialContent(IJavaProject javaProject)
            throws CoreException, JavaModelException, IOException {
        if (coreJbpmPage.checkbox.getSelection()) {
            createMessageActionHandler(javaProject);
            createSimpleProcessTest(javaProject);
            createSimpleProcessDefinition(javaProject);
        }
        copyJbpmResources(javaProject);
    }

    private void createSimpleProcessDefinition(IJavaProject javaProject)
            throws CoreException, JavaModelException, IOException {
        JbpmInstallation jbpmInstallation = PreferencesManager.getInstance().getJbpmInstallation(getCoreJbpmName());
        if (jbpmInstallation == null)
            return;
        //      IFolder processesFolder = javaProject.getProject().getFolder("processes");
        //      if (!processesFolder.exists()) {
        //         processesFolder.create(true, true, null);
        //      }
        IFolder folder = javaProject.getProject().getFolder("src/main/jpdl");
        if (!folder.exists()) {
            folder.create(true, true, null);
        }
        String location = VariablesPlugin.getDefault().getStringVariableManager()
                .performStringSubstitution(jbpmInstallation.location);
        String fromPath = getLocation("examples", location);
        if (fromPath == null) {
            fromPath = "/src/process.examples/simple.par";
        } else {
            fromPath = fromPath + "/simple/src/main/jpdl";
        }
        fromPath = new Path(location).append(fromPath).toOSString();
        File fromDir = new File(fromPath);
        if (!fromDir.exists())
            return;
        File[] files = fromDir.listFiles();
        IFile destination = null;
        for (int i = 0; i < files.length; i++) {
            if ("processdefinition.xml".equals(files[i].getName())) {
                destination = folder.getFile("simple.jpdl.xml");
            } else if ("gpd.xml".equals(files[i].getName())) {
                destination = folder.getFile(".simple.gpd.xml");
            } else if ("processimage.jpg".equals(files[i].getName())) {
                destination = folder.getFile("simple.jpg");
            }
            if (destination != null) {
                destination.create(new FileInputStream(files[i]), true, null);
            }
        }
    }

    private void createSimpleProcessTest(IJavaProject javaProject) throws JavaModelException, IOException {
        String resourceName = "org/jbpm/gd/jpdl/resource/SimpleProcessTest.java.template";
        IFolder folder = javaProject.getProject().getFolder("src/test/java");
        IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(folder);
        IPackageFragment pack = root.createPackageFragment("com.sample", true, null);
        InputStream stream = getClass().getClassLoader().getResourceAsStream(resourceName);
        byte[] content = readStream(stream);
        pack.createCompilationUnit("SimpleProcessTest.java", new String(content), true, null);
    }

    private void createMessageActionHandler(IJavaProject javaProject) throws JavaModelException, IOException {
        String resourceName = "org/jbpm/gd/jpdl/resource/MessageActionHandler.java.template";
        IFolder folder = javaProject.getProject().getFolder("src/main/java");
        IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(folder);
        IPackageFragment pack = root.createPackageFragment("com.sample.action", true, null);
        InputStream stream = getClass().getClassLoader().getResourceAsStream(resourceName);
        byte[] content = readStream(stream);
        pack.createCompilationUnit("MessageActionHandler.java", new String(content), true, null);
    }

    private void copyJbpmResources(IJavaProject javaProject) throws CoreException {
        JbpmInstallation jbpmInstallation = PreferencesManager.getInstance().getJbpmInstallation(getCoreJbpmName());
        if (jbpmInstallation == null)
            return;
        String location = VariablesPlugin.getDefault().getStringVariableManager()
                .performStringSubstitution(jbpmInstallation.location);
        IFolder folder = javaProject.getProject().getFolder("src/main/config");
        String fromPath = getLocation("config", location);
        if (fromPath == null) {
            fromPath = "/src/config.files";
        }
        fromPath = new Path(location).append(fromPath).toOSString();
        File fromDir = new File(fromPath);
        if (!fromDir.exists())
            return;
        File[] files = fromDir.listFiles();
        for (int i = 0; i < files.length; i++) {
            if (!files[i].isDirectory()) {
                copyJbpmResource(files[i], folder);
            }
        }
    }

    private String getLocation(String selector, String baseLocation) {
        String result = null;
        try {
            IPath locationPath = new Path(baseLocation);
            Document document = new SAXReader()
                    .read(locationPath.append("src/resources/gpd/version.info.xml").toFile());
            XPath xpath = document.createXPath("/jbpm-version-info/" + selector);
            List list = xpath.selectNodes(document);
            if (!list.isEmpty()) {
                result = (String) ((Element) list.get(0)).attribute("path").getData();
            }
        } catch (MalformedURLException e) {
        } catch (DocumentException e) {
        }
        return result;
    }

    private void copyJbpmResource(File source, IFolder destination) throws CoreException {
        try {
            IFile file = destination.getFile(source.getName());
            file.create(new FileInputStream(source), true, null);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    private void setClasspath(IJavaProject javaProject) throws JavaModelException, CoreException {
        javaProject.setRawClasspath(new IClasspathEntry[0], null);
        addSourceFolders(javaProject);
        addJRELibraries(javaProject);
        addJbpmLibraries(javaProject);
        // Hack to overcome the problems of the classpath container not being created in the classpath.
        javaProject.getRawClasspath();
    }

    private IProjectDescription createProjectDescription(IProject newProjectHandle) {
        IPath newPath = null;
        if (!mainPage.useDefaults())
            newPath = mainPage.getLocationPath();
        IWorkspace workspace = ResourcesPlugin.getWorkspace();
        IProjectDescription description = workspace.newProjectDescription(newProjectHandle.getName());
        description.setLocation(newPath);
        addJavaNature(description);
        return description;
    }

    private void addJavaNature(IProjectDescription description) {
        ArrayList natures = new ArrayList();
        natures.addAll(Arrays.asList(description.getNatureIds()));
        natures.add(JavaCore.NATURE_ID);
        description.setNatureIds((String[]) natures.toArray(new String[natures.size()]));
    }

    private void runProjectCreationOperation(WorkspaceModifyOperation op, IProject newProjectHandle) {
        try {
            getContainer().run(false, true, op);
        } catch (InterruptedException e) {
            Logger.logError("InterruptedException while creating project", e);
        } catch (InvocationTargetException e) {
            Throwable t = e.getTargetException();
            if (t instanceof CoreException) {
                handleCoreException(newProjectHandle, (CoreException) t);
            } else {
                handleOtherProblem(t);
            }
        }
    }

    private void handleOtherProblem(Throwable t) {
        MessageDialog.openError(getShell(), "Creation Problems", "Internal error: " + t.getMessage());
    }

    private void handleCoreException(final IProject newProjectHandle, CoreException e) {
        if (e.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) {
            MessageDialog.openError(getShell(), "Creation Problems",
                    "The underlying file system is case insensitive. There is an existing project which conflicts with '"
                            + newProjectHandle.getName() + "'.");
        } else {
            ErrorDialog.openError(getShell(), "Creation Problems", null, e.getStatus());
        }
    }

    void createProject(IProjectDescription description, IProject projectHandle, IProgressMonitor monitor)
            throws CoreException, OperationCanceledException {
        try {
            monitor.beginTask("", 2000);
            projectHandle.create(description, new SubProgressMonitor(monitor, 1000));
            if (monitor.isCanceled()) {
                throw new OperationCanceledException();
            }
            projectHandle.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor(monitor, 1000));
        } finally {
            monitor.done();
        }
    }

    public IProject getNewProject() {
        return newProject;
    }

    public boolean performFinish() {
        if (!isJbpm3RuntimeAvailable()) {
            String name = configureRuntimePage.nameText.getText();
            String location = configureRuntimePage.locationText.getText();
            String version = "jBPM3";
            PreferencesManager.getInstance().initializeDefaultJbpmInstallation(name, location, version);
        }
        getContainer().updateButtons();
        createJavaProject();
        if (newProject == null) {
            getContainer().updateButtons();
            return false;
        }
        updatePerspective();
        selectAndReveal(newProject);
        getContainer().updateButtons();
        return true;
    }

    protected void updatePerspective() {
        try {
            IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
            if (page.findView("org.eclipse.ui.views.PropertySheet") == null) {
                page.showView("org.eclipse.ui.views.PropertySheet");
            }
        } catch (PartInitException e) {
            e.printStackTrace();
        }
    }

    protected void selectAndReveal(IResource newResource) {
        selectAndReveal(newResource, workbench.getActiveWorkbenchWindow());
    }

    private void selectAndReveal(IResource resource, IWorkbenchWindow window) {
        if (!inputValid(resource, window))
            return;
        Iterator itr = getParts(window.getActivePage()).iterator();
        while (itr.hasNext()) {
            selectAndRevealTarget(window, new StructuredSelection(resource),
                    getTarget((IWorkbenchPart) itr.next()));
        }
    }

    private boolean inputValid(IResource resource, IWorkbenchWindow window) {
        if (window == null || resource == null)
            return false;
        else if (window.getActivePage() == null)
            return false;
        else
            return true;
    }

    private void selectAndRevealTarget(IWorkbenchWindow window, final ISelection selection,
            ISetSelectionTarget target) {
        if (target == null)
            return;
        final ISetSelectionTarget finalTarget = target;
        window.getShell().getDisplay().asyncExec(new Runnable() {
            public void run() {
                finalTarget.selectReveal(selection);
            }
        });
    }

    private ISetSelectionTarget getTarget(IWorkbenchPart part) {
        ISetSelectionTarget target = null;
        if (part instanceof ISetSelectionTarget) {
            target = (ISetSelectionTarget) part;
        } else {
            target = (ISetSelectionTarget) part.getAdapter(ISetSelectionTarget.class);
        }
        return target;
    }

    private List getParts(IWorkbenchPage page) {
        List result = new ArrayList();
        addParts(result, page.getViewReferences());
        addParts(result, page.getEditorReferences());
        return result;
    }

    private void addParts(List parts, IWorkbenchPartReference[] refs) {
        for (int i = 0; i < refs.length; i++) {
            IWorkbenchPart part = refs[i].getPart(false);
            if (part != null) {
                parts.add(part);
            }
        }
    }

    private byte[] readStream(InputStream in) throws IOException {
        byte[] contents = null;
        int fileSize = 0;
        byte[] buffer = new byte[1024];
        int bytesRead = in.read(buffer);
        while (bytesRead != -1) {
            byte[] newContents = new byte[fileSize + bytesRead];
            if (fileSize > 0) {
                System.arraycopy(contents, 0, newContents, 0, fileSize);
            }
            System.arraycopy(buffer, 0, newContents, fileSize, bytesRead);
            contents = newContents;
            fileSize += bytesRead;
            bytesRead = in.read(buffer);
        }
        return contents;
    }

}