/* $Id: AbstractExampleWizard.java,v 1.3 2008-08-07 09:39:21 dvojtise Exp $
* Project : org.kermeta.kmlogo.tutorial
* File : AbstractExampleWizard.java
* License : EPL
* Copyright : IRISA / INRIA
* -------------------------------------------------------------------
* Creation date : May 29, 2006
* Authors :
* Cyril Faucher
*/
package fr.inria.diverse.k3.sample.deployer.wizards;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.Collection;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
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.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.plugin.AbstractUIPlugin;
/**
* <p>
* This abstract example wizard simply unzips a number of zips
* into the workspace as projects. It does not offer any
* pages but can be added as a new wizard to the new wizards
* dialog through the org.eclipse.ui.newWizards extension point.
* </p>
* <p>
* Clients should subclass this class and override the <code>getProjectDescriptor()</code>
* method to provide the location of the project zips that
* should be unzipped into the workspace. Note that any projects
* that are already in the workspace will <i>not</i> be overwritten
* because the user could have made changes to them that would
* be lost.
* </p>
* <p>
* It is highly recommended when registering subclasses to the
* new wizards extension point that the wizard declaration should
* have canFinishEarly = true and hasPages = false. Any label
* and icon can be freely given to the wizard to suit the needs
* of the client.
* </p>
*/
public abstract class AbstractExampleWizard extends Wizard
implements INewWizard {
/**
* A descriptor class that describes where to find the zipped
* contents of a project and what that project should be named
* when unzipped into the workspace.
*/
public static class ProjectDescriptor {
private String bundleName;
private String zipLocation;
private String projectName;
/**
* Construct a descriptor that points to a zip file located
* in a particular bundle at the given location within that
* bundle. Also provided is the project name for which the
* zip is the contents. Note that this project name should
* be the same as is in the contents not some alternative name.
*
* @param bundleName The bundle in the runtime that contains the
* zipped up project contents.
* @param zipLocation The location within the bundle where the
* zip file is located.
* @param projectName The project name in the workspace that
* will be created to house the project contents.
*/
public ProjectDescriptor(String bundleName, String zipLocation, String projectName) {
super();
this.bundleName = bundleName;
this.zipLocation = zipLocation;
this.projectName = projectName;
}
public String getBundleName() {
return bundleName;
}
public String getProjectName() {
return projectName;
}
public String getZipLocation() {
return zipLocation;
}
}
public boolean performFinish() {
final Collection<ProjectDescriptor> projectDescriptors = getProjectDescriptors();
WorkspaceJob job = new WorkspaceJob("Unzipping Projects") {
@Override
public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
monitor.beginTask("Unzipping Projects", projectDescriptors.size());
//System.out.println("Unzipping projects...");
for ( ProjectDescriptor desc : projectDescriptors ) {
unzipProject(desc, monitor);
monitor.worked(1);
}
//System.out.println("Projects unzipped");
return Status.OK_STATUS;
}
};
job.setRule(ResourcesPlugin.getWorkspace().getRoot());
job.schedule();
return true;
}
/**
* The subclass provides the specific project descriptors for the
* projects that should be unzipped into the workspace. Note that
* any projects that already exist in the workspace will not be
* overwritten as they may contain changed made by the user.
*
* @return The collection of project descriptors that should be
* unzipped into the workspace.
*/
protected abstract Collection<ProjectDescriptor> getProjectDescriptors();
private void unzipProject(ProjectDescriptor descriptor, IProgressMonitor monitor) {
String bundleName = descriptor.getBundleName();
String zipLocation = descriptor.getZipLocation();
String projectName = descriptor.getProjectName();
URL interpreterZipUrl = FileLocator.find(Platform.getBundle(bundleName), new Path(zipLocation), null);
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
if (project.exists()) {
return;
}
try {
// We make sure that the project is created from this point forward.
project.create(monitor);
ZipInputStream zipFileStream = new ZipInputStream(interpreterZipUrl.openStream());
ZipEntry zipEntry = zipFileStream.getNextEntry();
// We derive a regexedProjectName so that the dots don't end up being
// interpreted as the dot operator in the regular expression language.
String regexedProjectName = projectName.replaceAll("\\.", "\\."); //$NON-NLS-1$ //$NON-NLS-2$
while (zipEntry != null) {
// We will construct the new file but we will strip off the project
// directory from the beginning of the path because we have already
// created the destination project for this zip.
File file = new File(project.getLocation().toString(), zipEntry.getName().replaceFirst("^"+regexedProjectName+"/", "")); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
if (false == zipEntry.isDirectory()) {
/*
* Copy files (and make sure parent directory exist)
*/
File parentFile = file.getParentFile();
if (null != parentFile && false == parentFile.exists()) {
parentFile.mkdirs();
}
OutputStream os = null;
try {
os = new FileOutputStream(file);
byte[] buffer = new byte[102400];
while (true) {
int len = zipFileStream.read(buffer);
if (zipFileStream.available() == 0)
break;
os.write(buffer, 0, len);
}
} finally {
if (null != os) {
os.close();
}
}
}
zipFileStream.closeEntry();
zipEntry = zipFileStream.getNextEntry();
}
project.open(monitor);
// in order to make sure the project natures are correctly identified close and reopen the project
project.close(monitor);
project.open(monitor);
project.refreshLocal(IFile.DEPTH_INFINITE, monitor);
} catch (IOException e) {
getContainerPlugin().getLog().log(new Status(IStatus.ERROR, getContainerPlugin().getBundle().getSymbolicName(),IStatus.ERROR, e.getMessage(),e));
} catch (CoreException e) {
getContainerPlugin().getLog().log(e.getStatus());
}
}
/**
* return the instance of the plugin that contain this wizard
* (used for log support)
* @return
*/
protected abstract AbstractUIPlugin getContainerPlugin();
public void init(IWorkbench workbench, IStructuredSelection selection) {
// No code is necessary.
}
}