/******************************************************************************* * Copyright (c) 2006 IBM Corporation and others. * 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 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.obeonetwork.dsl.bpmn2.samples.wizards; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Enumeration; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExecutableExtension; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.Wizard; import org.eclipse.ui.INewWizard; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.actions.WorkspaceModifyOperation; import org.eclipse.ui.dialogs.WizardNewProjectCreationPage; import org.eclipse.ui.wizards.newresource.BasicNewProjectResourceWizard; import org.obeonetwork.dsl.bpmn2.samples.Bpmn2SamplesPlugin; import org.obeonetwork.dsl.bpmn2.samples.l10n.Messages; /** * This abstract wizard serves as the base for our zipped project wizards. At * minimum, the wizard uses its constructor parameter to create a 1 page wizard. * The page lets users define the name and location of the project where to * unzip the project archive. The wizard performs: project creation, the unzip * operation, the classpath update, the progress monitoring * * @see Wizard */ /* * This code comes from org.eclipse.gef.examples.ui.pde.internal.wizards */ public class ProjectUnzipperNewWizard extends Wizard implements INewWizard, IExecutableExtension { /** * */ private Bpmn2SampleWizardPage bpmn2SamplesPage; /** * */ private List<Bpmn2Sample> bpmn2Samples; /** * */ private final static String BPMN2_SAMPLES_EXTENSION_POINT_ID = "org.obeonetwork.dsl.bpmn2.samples.Bpmn2Sample"; //$NON-NLS-1$ /** * */ private static final String BPMN2_SAMPLES_POST_INIT_EXTENSION_POINT_ID = "oorg.obeonetwork.dsl.bpmn2.samples.Bpmn2Example.postInit";//$NON-NLS-1$ /** * The single page provided by this base implementation. It provides all the * functionality required to capture the name and location of the target * project */ public WizardNewProjectCreationPage wizardNewProjectCreationPage; /** * The configuration element associated with this new project wizard */ private IConfigurationElement config; /** * Constructor * */ public ProjectUnzipperNewWizard() { super(); setNeedsProgressMonitor(true); this.bpmn2Samples = new ArrayList<Bpmn2Sample>(); // Load BPMN2 examples (extension point) IConfigurationElement[] contributions = Platform.getExtensionRegistry() .getConfigurationElementsFor(BPMN2_SAMPLES_EXTENSION_POINT_ID); if (contributions != null) { for (IConfigurationElement extension : contributions) { if (extension != null) { try { Bpmn2Sample bpmn2Example = (Bpmn2Sample) extension .createExecutableExtension("class"); //$NON-NLS-1$ this.bpmn2Samples.add(bpmn2Example); } catch (CoreException e) { Bpmn2SamplesPlugin.getDefault().getLog().log( new Status(IStatus.ERROR, Bpmn2SamplesPlugin.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e)); } } } } // Let the samples being displayed in the order they are found in the // registry does not result in a nice list. // We have to sort samples to avoid that. The sort algorithm is the // following: // ++ Get the first word (Restaurant, Weather...) // ++ A different word results in an alphabetical ordering. // ++ In case of the same word, sort them by difficulty. Collections.sort(this.bpmn2Samples, new Comparator<Bpmn2Sample>() { public int compare(Bpmn2Sample o1, Bpmn2Sample o2) { String w1 = o1.getTitle().split("\\s", 2)[0]; //$NON-NLS-1$ String w2 = o2.getTitle().split("\\s", 2)[0]; //$NON-NLS-1$ int cmp = w1.compareTo(w2); if (cmp != 0) return cmp; return o1.getDifficulty() - o2.getDifficulty(); } }); } /** * Performs the bulk of the wizard functionality: project creation, the * unzip operation and classpath update * * @see Wizard#performFinish */ @Override public boolean performFinish() { try { IRunnableWithProgress operation = new WorkspaceModifyOperation() { @Override public void execute(IProgressMonitor monitor) throws InterruptedException { try { monitor .beginTask(Messages.monitor_creatingProject, 120); // Create the project folder IPath projectPath = wizardNewProjectCreationPage .getLocationPath(); String projectName = wizardNewProjectCreationPage .getProjectName(); String projectFolder = projectPath.toOSString() + File.separator + projectName; File projectFolderFile = new File(projectFolder); IWorkspace workspace = ResourcesPlugin.getWorkspace(); IProject project = workspace.getRoot().getProject( projectName); // If the project does not exist, we will create it // and populate it. if (!project.exists()) { projectFolderFile.mkdirs(); monitor.worked(10); // Copy plug-in project code extractProject(projectFolderFile, bpmn2Samples.get( bpmn2SamplesPage.getSelection()) .getZipURL(), new SubProgressMonitor(monitor, 100)); if (monitor.isCanceled()) { throw new InterruptedException(); } if (projectPath.equals(workspace.getRoot() .getLocation())) { project.create(monitor); } else { IProjectDescription desc = workspace .newProjectDescription(project .getName()); desc.setLocation(new Path(projectFolder)); project.create(desc, monitor); } } // Now, we ensure that the project is open. project.open(monitor); renameProject(project, projectName); // Load portInit extension point IConfigurationElement[] contributions = Platform .getExtensionRegistry() .getConfigurationElementsFor( BPMN2_SAMPLES_POST_INIT_EXTENSION_POINT_ID); if (contributions != null) { for (IConfigurationElement extension : contributions) { if (extension != null) { try { PostInit postInit = (PostInit) extension .createExecutableExtension("class"); //$NON-NLS-1$ postInit .postInit(wizardNewProjectCreationPage .getProjectName()); } catch (Exception e) { Bpmn2SamplesPlugin .getDefault() .getLog() .log( new Status( IStatus.ERROR, Bpmn2SamplesPlugin.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e)); } } } } } catch (IOException e) { throw new RuntimeException(e); } catch (CoreException e) { throw new RuntimeException(e); } finally { monitor.done(); } } }; getContainer().run(false, true, operation); // Set perspective //BasicNewProjectResourceWizard // .updatePerspective(getConfigurationElement()); } catch (InterruptedException e) { return false; } catch (Exception e) { Bpmn2SamplesPlugin.getDefault().getLog().log( new Status(IStatus.ERROR, Bpmn2SamplesPlugin.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e)); return false; } return true; } /** * Unzip the project archive to the specified folder * * @param projectFolderFile * The folder where to unzip the project archive * @param monitor * Monitor to display progress and/or cancel operation * @throws IOException * @throws IOException * @throws InterruptedException * @throws FileNotFoundException * * @throws FileNotFoundException * @throws InterruptedException */ private void extractProject(File projectFolderFile, URL url, IProgressMonitor monitor) throws FileNotFoundException, IOException, InterruptedException { // Get project archive URL urlZipLocal = FileLocator.toFileURL(url); // Walk each element and unzip ZipFile zipFile = new ZipFile(urlZipLocal.getPath()); try { // Allow for a hundred work units monitor .beginTask(Messages.monitor_unzippingProject, zipFile .size()); unzip(zipFile, projectFolderFile, monitor); } finally { zipFile.close(); monitor.done(); } } /** * Unzips the platform formatted zip file to specified folder * * @param zipFile * The platform formatted zip file * @param projectFolderFile * The folder where to unzip the project archive * @param monitor * Monitor to display progress and/or cancel operation * @throws IOException * @throws FileNotFoundException * @throws InterruptedException */ private void unzip(ZipFile zipFile, File projectFolderFile, IProgressMonitor monitor) throws IOException, FileNotFoundException, InterruptedException { Enumeration<?> e = zipFile.entries(); while (e.hasMoreElements()) { ZipEntry zipEntry = (ZipEntry) e.nextElement(); File file = new File(projectFolderFile, zipEntry.getName()); if (false == zipEntry.isDirectory()) { // Copy files (and make sure parent directory exist) File parentFile = file.getParentFile(); if (null != parentFile && false == parentFile.exists()) { parentFile.mkdirs(); } Path path = new Path(file.getPath()); if (path.getFileExtension().equals("java")) { //$NON-NLS-1$ InputStreamReader is = null; OutputStreamWriter os = null; try { is = new InputStreamReader(zipFile .getInputStream(zipEntry), "ISO-8859-1"); //$NON-NLS-1$ os = new OutputStreamWriter(new FileOutputStream(file), ResourcesPlugin.getEncoding()); char[] buffer = new char[102400]; while (true) { int len = is.read(buffer); if (len < 0) break; os.write(buffer, 0, len); } } finally { if (null != is) { is.close(); } if (null != os) { os.close(); } } } else { InputStream is = null; OutputStream os = null; try { is = zipFile.getInputStream(zipEntry); os = new FileOutputStream(file); byte[] buffer = new byte[102400]; while (true) { int len = is.read(buffer); if (len < 0) break; os.write(buffer, 0, len); } } finally { if (null != is) { is.close(); } if (null != os) { os.close(); } } } } monitor.worked(1); if (monitor.isCanceled()) { throw new InterruptedException(); } } } /** * Renames the specified project to the specified name * * @param project * Project to rename * @param projectName * New name for the project * @throws CoreException */ private void renameProject(IProject project, String projectName) throws CoreException { IProjectDescription description = project.getDescription(); description.setName(projectName); project.move(description, IResource.FORCE | IResource.SHALLOW, null); } /** * Creates the sole wizard page contributed by this base implementation; the * standard Eclipse WizardNewProjectCreationPage. * * @see WizardNewProjectCreationPage#WizardNewProjectCreationPage(String) */ public void init(IWorkbench workbench, IStructuredSelection selection) { bpmn2SamplesPage = new Bpmn2SampleWizardPage( Messages.Bpmn2SampleWizardPage_pageName); bpmn2SamplesPage.setTitle(Messages.Bpmn2SampleWizardPage_title); bpmn2SamplesPage.setDescription(Messages.Bpmn2SampleWizardPage_desc); addPage(bpmn2SamplesPage); wizardNewProjectCreationPage = new WizardNewProjectCreationPage( Messages.WizardNewProjectCreationPage_pageName); wizardNewProjectCreationPage .setTitle(Messages.WizardNewProjectCreationPage_title); wizardNewProjectCreationPage .setDescription(Messages.WizardNewProjectCreationPage_desc); wizardNewProjectCreationPage.setWizard(this); this.addPage(wizardNewProjectCreationPage); } /* * (non-Javadoc) * * @see org.eclipse.jface.wizard.Wizard#canFinish() */ @Override public boolean canFinish() { return wizardNewProjectCreationPage.isPageComplete(); } /** * Accessor to the config field * * @return The config field value */ private IConfigurationElement getConfigurationElement() { return config; } /* * (non-Javadoc) * * @see * org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org * .eclipse.core.runtime.IConfigurationElement, java.lang.String, * java.lang.Object) */ public void setInitializationData(IConfigurationElement configIn, String propertyName, Object data) throws CoreException { config = configIn; } /** * @return */ List<Bpmn2Sample> getBpmn2Samples() { return this.bpmn2Samples; } }