Import previewer implemented
authorEugene Ostroukhov
Fri, 08 Jan 2010 14:34:03 -0800
changeset 11 05e53cfc29d8
parent 7 1a02e8a8be9c
child 12 f9228bed5aaf
Import previewer implemented
org.symbian.tools.wrttools.debug.core/launch/WRT Debugger.launch
org.symbian.tools.wrttools/bin/org/symbian/tools/wrttools/projects/ProjectUtils.class
org.symbian.tools.wrttools/icons/main16.gif
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/internal/validation/CssBuildValidator.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/dialogs/AptanaProjectSelectionDialog.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/projects/ProjectUtils.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/util/NonClosingStream.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/util/ProjectUtils.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/wizards/AptanaProjectLocationWizardPage.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/wizards/AptanaProjectsImportWizard.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/wizards/WrtWidgetWizard.java
--- a/org.symbian.tools.wrttools.debug.core/launch/WRT Debugger.launch	Thu Jan 07 14:06:06 2010 -0800
+++ b/org.symbian.tools.wrttools.debug.core/launch/WRT Debugger.launch	Fri Jan 08 14:34:03 2010 -0800
@@ -23,6 +23,7 @@
 <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms128m -Xmx768m -XX:MaxPermSize=192m"/>
 <stringAttribute key="pde.version" value="3.3"/>
 <stringAttribute key="product" value="org.eclipse.platform.ide"/>
+<booleanAttribute key="restart" value="false"/>
 <booleanAttribute key="show_selected_only" value="false"/>
 <stringAttribute key="templateConfig" value="${target_home}\configuration\config.ini"/>
 <booleanAttribute key="tracing" value="false"/>
Binary file org.symbian.tools.wrttools/bin/org/symbian/tools/wrttools/projects/ProjectUtils.class has changed
Binary file org.symbian.tools.wrttools/icons/main16.gif has changed
--- a/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/internal/validation/CssBuildValidator.java	Thu Jan 07 14:06:06 2010 -0800
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/internal/validation/CssBuildValidator.java	Fri Jan 08 14:34:03 2010 -0800
@@ -105,7 +105,7 @@
 			String msg = cssError.getException().getLocalizedMessage();
 			if (msg != null && msg.trim().length() > 0) {
 				ValidatorMessage message = createMessage(resource, cssError
-						.getLine(), msg, IMarker.SEVERITY_ERROR);
+						.getLine(), msg, IMarker.SEVERITY_WARNING);
 				result.add(message);
 			}
 		}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/dialogs/AptanaProjectSelectionDialog.java	Fri Jan 08 14:34:03 2010 -0800
@@ -0,0 +1,131 @@
+package org.symbian.tools.wrttools.dialogs;
+
+import java.io.File;
+import java.text.MessageFormat;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.symbian.tools.wrttools.util.ProjectUtils;
+
+public class AptanaProjectSelectionDialog extends TitleAreaDialog {
+	private File project;
+	private Text location;
+
+	public AptanaProjectSelectionDialog(Shell parentShell) {
+		super(parentShell);
+	}
+
+	@Override
+	protected void configureShell(Shell newShell) {
+		super.configureShell(newShell);
+		newShell.setText("WebRuntime Tools");
+	}
+	
+	@Override
+	protected Control createDialogArea(Composite parent) {
+		setTitle("Select Aptana WRT Project");
+		setMessage("Select an Aptana WRT project or Aptana workspace containing one");
+		Composite root = (Composite) super.createDialogArea(parent);
+
+		Composite workingArea = new Composite(root, SWT.NONE);
+		workingArea.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		workingArea.setLayout(new GridLayout(2, false));
+		Label label = new Label(workingArea, SWT.NONE);
+		label.setLayoutData(new GridData(GridData.BEGINNING,
+				GridData.BEGINNING, false, false, 2, 1));
+		label.setText("Specify Aptana project or Aptana workspace location:");
+		location = new Text(workingArea, SWT.BORDER);
+		location.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		location.addModifyListener(new ModifyListener() {
+			@Override
+			public void modifyText(ModifyEvent e) {
+				validate();
+			}
+		});
+
+		Button browse = new Button(workingArea, SWT.NONE);
+		browse.setText("Browse...");
+		browse.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				browse();
+			}
+		});
+
+		location.setText(ProjectUtils.getDefaultAptanaLocation());
+
+		return root;
+	}
+
+	@Override
+	protected void createButtonsForButtonBar(Composite parent) {
+		super.createButtonsForButtonBar(parent);
+		validate();
+		setErrorMessage(null);
+	}
+	
+	protected void browse() {
+		DirectoryDialog dialog = new DirectoryDialog(getShell());
+		dialog.setFilterPath(location.getText());
+		dialog.setMessage("Select Aptana WRT project or workspace");
+		dialog.setText("Web Runtime Tools");
+
+		String string = dialog.open();
+		if (string != null) {
+			location.setText(string);
+		}
+	}
+
+	protected void validate() {
+		String error = null;
+		File f = new File(location.getText());
+		if (f.isDirectory()) {
+			if (!ProjectUtils.isAptanaProject(f)) {
+				File[] files = f.listFiles();
+				f = null;
+				for (File file : files) {
+					if (ProjectUtils.isAptanaProject(file)) {
+						f = file;
+						break;
+					}
+				}
+				if (f == null) {
+					error = MessageFormat.format("{0} is not a WRT project or an Aptana workspace containing WRT projects", location.getText());
+				}
+			}
+		} else {
+			error = "Specified folder does not exist";
+		}
+		project = f;
+		setErrorMessage(error);
+		Button button = getButton(IDialogConstants.OK_ID);
+		if (button != null) {
+			button.setEnabled(error == null);
+		}
+	}
+
+	@Override
+	protected void cancelPressed() {
+		project = null;
+		super.cancelPressed();
+	}
+
+	public File getProject() {
+		return project;
+	}
+}
--- a/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/projects/ProjectUtils.java	Thu Jan 07 14:06:06 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/**
- * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
- * All rights reserved.
- * This component and the accompanying materials are made available
- * under the terms of the License "Eclipse Public License v1.0"
- * which accompanies this distribution, and is available
- * at the URL "http://www.eclipse.org/legal/epl-v10.html".
- *
- * Initial Contributors:
- * Symbian Foundation - initial contribution.
- * Contributors:
- * Description:
- * Overview:
- * Details:
- * Platforms/Drives/Compatibility:
- * Assumptions/Requirement/Pre-requisites:
- * Failures and causes:
- */
-package org.symbian.tools.wrttools.projects;
-
-import java.net.URI;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.wst.jsdt.internal.ui.wizards.buildpaths.BuildPathsBlock;
-import org.eclipse.wst.validation.ValidationFramework;
-
-public class ProjectUtils {
-	public static IProject createWrtProject(String name, URI uri, IProgressMonitor monitor) throws CoreException {
-		monitor.beginTask("Create project resources", 20);
-		IWorkspace workspace = ResourcesPlugin.getWorkspace();
-		IProject project = workspace.getRoot().getProject(
-				name);
-		BuildPathsBlock.createProject(project, uri,
-				new SubProgressMonitor(monitor, 10));
-
-		BuildPathsBlock.addJavaNature(project, new SubProgressMonitor(monitor,
-				10));
-
-		// TODO: Build path, super type, etc.
-		// BuildPathsBlock.flush(classPathEntries, javaScriptProject, superType,
-		// monitor)
-
-		ValidationFramework.getDefault().addValidationBuilder(project);
-
-		monitor.done();
-		return project;
-	}
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/util/NonClosingStream.java	Fri Jan 08 14:34:03 2010 -0800
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.util;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * This allows blocking the IP clients from closing the stream. This
+ * class is needed when creating workbench files from the Zip archives.
+ */
+public final class NonClosingStream extends FilterInputStream {
+	public NonClosingStream(InputStream in) {
+		super(in);
+	}
+
+	@Override
+	public void close() throws IOException {
+		// We do not need Eclipse closing the Zip stream
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/util/ProjectUtils.java	Fri Jan 08 14:34:03 2010 -0800
@@ -0,0 +1,224 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.util;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+import javax.swing.filechooser.FileSystemView;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspace;
+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.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.statushandlers.StatusManager;
+import org.eclipse.wst.jsdt.internal.ui.wizards.buildpaths.BuildPathsBlock;
+import org.eclipse.wst.validation.ValidationFramework;
+import org.symbian.tools.wrttools.Activator;
+import org.symbian.tools.wrttools.dialogs.AptanaProjectSelectionDialog;
+
+public class ProjectUtils {
+	public static IProject createWrtProject(String name, URI uri,
+			IProgressMonitor monitor) throws CoreException {
+		monitor.beginTask("Create project resources", 20);
+		IWorkspace workspace = ResourcesPlugin.getWorkspace();
+		IProject project = workspace.getRoot().getProject(name);
+		BuildPathsBlock.createProject(project, uri, new SubProgressMonitor(
+				monitor, 10));
+
+		BuildPathsBlock.addJavaNature(project, new SubProgressMonitor(monitor,
+				10));
+
+		// TODO: Build path, super type, etc.
+		// BuildPathsBlock.flush(classPathEntries, javaScriptProject, superType,
+		// monitor)
+
+		ValidationFramework.getDefault().addValidationBuilder(project);
+
+		monitor.done();
+		return project;
+	}
+
+	public static void addPreviewer(IProject project, IPath mainHtml) {
+		URI archive = getPreviewerArchive();
+		try {
+			if (archive != null) {
+				ZipInputStream stream = new ZipInputStream(archive.toURL().openStream());
+				ZipEntry entry;
+				while ((entry = stream.getNextEntry()) != null) {
+					if (!entry.isDirectory()) {
+						copyFile(project, entry.getName(), stream, entry.getSize(), new NullProgressMonitor());
+					} else {
+						IFolder folder = project.getFolder(entry.getName());
+						if (!folder.exists()) {
+							folder.create(false, true, new NullProgressMonitor());
+						}
+					}
+					stream.closeEntry();
+				}
+			}
+			IFile file = project.getFile(mainHtml + ".html");
+			if (file.exists()) {
+				file.copy(project.getFullPath().append("wrt_preview_main.html"), false, new NullProgressMonitor());
+			}
+			
+		} catch (IOException e) {
+			StatusManager.getManager().handle(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Unable to add previewer to project"));
+		} catch (CoreException e) {
+			StatusManager.getManager().handle(e, Activator.PLUGIN_ID);
+		}
+	}
+
+	private static URI getPreviewerArchive() {
+		File file = getPreviewerZip();
+		if (file.isFile()) {
+			return file.toURI();
+		}
+		Display display = Display.getDefault();
+		display.syncExec(new Runnable() {
+			@Override
+			public void run() {
+				importPreviewer();
+			}
+		});
+		if (file.isFile()) {
+			return file.toURI();
+		}
+		return null;
+	}
+
+	private static File getPreviewerZip() {
+		return Activator.getDefault().getStateLocation()
+				.append("previewer.zip").toFile();
+	}
+
+	protected static void importPreviewer() {
+		AptanaProjectSelectionDialog dialog = new AptanaProjectSelectionDialog(
+				PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
+		int open = dialog.open();
+		if (open == Window.OK) {
+			File project = dialog.getProject();
+			try {
+				zipPreviewer(project);
+			} catch (IOException e) {
+				StatusManager
+						.getManager()
+						.handle(
+								new Status(
+										IStatus.ERROR,
+										Activator.PLUGIN_ID,
+										"Failed to create Web Runtime previewer archive.",
+										e), StatusManager.SHOW);
+			}
+		}
+	}
+
+	private static void zipPreviewer(File project) throws IOException {
+		ZipOutputStream stream = new ZipOutputStream(new FileOutputStream(
+				getPreviewerZip()));
+		try {
+			zip(new File(project, "preview"), stream, "preview/");
+			zipFile(new File(project, "wrt_preview_frame.html"),
+					"wrt_preview_frame.html", stream);
+		} finally {
+			stream.close();
+		}
+	}
+
+	private static void zip(File folder, ZipOutputStream stream, String path)
+			throws IOException {
+		ZipEntry entry = new ZipEntry(path);
+		stream.putNextEntry(entry);
+		stream.closeEntry();
+		File[] files = folder.listFiles();
+		for (File file : files) {
+			if (file.isFile()) {
+				zipFile(file, path + file.getName(), stream);
+			} else {
+				zip(file, stream, path + file.getName() + "/");
+			}
+		}
+	}
+
+	private static void zipFile(File file, String zipEntry,
+			ZipOutputStream stream) throws IOException, FileNotFoundException {
+		ZipEntry entry = new ZipEntry(zipEntry);
+		stream.putNextEntry(entry);
+		BufferedInputStream inputStream = new BufferedInputStream(
+				new FileInputStream(file));
+		try {
+			copy(inputStream, stream);
+		} finally {
+			inputStream.close();
+		}
+		stream.closeEntry();
+	}
+
+	private static void copy(InputStream in, OutputStream out)
+			throws IOException {
+		byte[] buffer = new byte[131072]; // 128k - should be enough for most
+		// JS/CSS files
+		int count;
+		while ((count = in.read(buffer)) > 0) {
+			out.write(buffer, 0, count);
+		}
+	}
+
+	public static String getDefaultAptanaLocation() {
+		File myDocuments = FileSystemView.getFileSystemView()
+				.getDefaultDirectory();
+		File file = new File(myDocuments, "Aptana Studio Workspace");
+		return file.exists() ? file.getAbsolutePath() : "";
+	}
+
+	public static boolean isAptanaProject(File f) {
+		return new File(f, "preview").isDirectory()
+				&& new File(f, "wrt_preview_frame.html").isFile();
+	}
+
+	public static void copyFile(IProject project, String name, ZipInputStream stream,
+			long size, IProgressMonitor monitor) throws CoreException,
+			IOException {
+		IFile file = project.getFile(name);
+		file.create(new NonClosingStream(stream), true,
+				new SubProgressMonitor(monitor, 1));
+	}
+}
--- a/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/wizards/AptanaProjectLocationWizardPage.java	Thu Jan 07 14:06:06 2010 -0800
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/wizards/AptanaProjectLocationWizardPage.java	Fri Jan 08 14:34:03 2010 -0800
@@ -36,8 +36,6 @@
 import java.util.zip.ZipException;
 import java.util.zip.ZipFile;
 
-import javax.swing.filechooser.FileSystemView;
-
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IProjectDescription;
 import org.eclipse.core.runtime.CoreException;
@@ -103,7 +101,7 @@
 import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
 import org.eclipse.ui.wizards.datatransfer.ImportOperation;
 import org.symbian.tools.wrttools.Activator;
-import org.symbian.tools.wrttools.projects.ProjectUtils;
+import org.symbian.tools.wrttools.util.ProjectUtils;
 
 public class AptanaProjectLocationWizardPage extends WizardPage implements
 		IOverwriteQuery {
@@ -805,7 +803,7 @@
 				.convertWidthInCharsToPixels(25);
 		directoryPathField.setLayoutData(directoryPathData);
 
-		directoryPathField.setText(getDefaultImportLocation());
+		directoryPathField.setText(ProjectUtils.getDefaultAptanaLocation());
 		
 		// browse button
 		browseDirectoriesButton = new Button(projectGroup, SWT.PUSH);
@@ -951,12 +949,6 @@
 		});
 	}
 
-	private String getDefaultImportLocation() {
-		File myDocuments = FileSystemView.getFileSystemView().getDefaultDirectory();
-		File file = new File(myDocuments, "Aptana Studio Workspace");
-		return file.exists() ? file.getAbsolutePath() : "";
-	}
-
 	/**
 	 * Create the selection buttons in the listComposite.
 	 * 
--- a/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/wizards/AptanaProjectsImportWizard.java	Thu Jan 07 14:06:06 2010 -0800
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/wizards/AptanaProjectsImportWizard.java	Fri Jan 08 14:34:03 2010 -0800
@@ -50,8 +50,7 @@
 	
 	@Override
 	public void init(IWorkbench workbench, IStructuredSelection selection) {
-		// TODO Auto-generated method stub
-
+		// Do nothing
 	}
 
 }
--- a/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/wizards/WrtWidgetWizard.java	Thu Jan 07 14:06:06 2010 -0800
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/wizards/WrtWidgetWizard.java	Fri Jan 08 14:34:03 2010 -0800
@@ -38,13 +38,13 @@
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IFolder;
 import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IWorkspace;
 import org.eclipse.core.resources.IWorkspaceRunnable;
 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.IStatus;
+import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.SubProgressMonitor;
 import org.eclipse.jface.operation.IRunnableWithProgress;
@@ -54,11 +54,10 @@
 import org.eclipse.ui.INewWizard;
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
-import org.eclipse.wst.jsdt.internal.ui.wizards.buildpaths.BuildPathsBlock;
-import org.eclipse.wst.validation.ValidationFramework;
 import org.symbian.tools.wrttools.Activator;
 import org.symbian.tools.wrttools.core.ProjectTemplate;
-import org.symbian.tools.wrttools.projects.ProjectUtils;
+import org.symbian.tools.wrttools.util.NonClosingStream;
+import org.symbian.tools.wrttools.util.ProjectUtils;
 
 public class WrtWidgetWizard extends Wizard implements INewWizard {
 	private WizardNewProjectCreationPage resourcePage;
@@ -150,11 +149,10 @@
 					copyTemplate(project, name, stream, (int) entry.getSize(),
 							ctx, monitor);
 				} else {
-					copyFile(project, name, stream, entry.getSize(), monitor);
+					ProjectUtils.copyFile(project, name, stream, entry.getSize(), monitor);
 				}
 				stream.closeEntry();
 			}
-
 			monitor.done();
 		} catch (Exception e) {
 			throw new CoreException(new Status(IStatus.ERROR,
@@ -168,37 +166,16 @@
 				}
 			}
 		}
-	}
-
-	private void copyFile(IProject project, String name, ZipInputStream stream,
-			long size, IProgressMonitor monitor) throws CoreException,
-			IOException {
-		byte[] contents = readBytes(stream, (int) size);
-		IFile file = project.getFile(name);
-		file.create(new ByteArrayInputStream(contents), true,
-				new SubProgressMonitor(monitor, 1));
-	}
-
-	private byte[] readBytes(ZipInputStream stream, int size)
-			throws IOException {
-		byte[] contents = new byte[size];
-		int len = 0;
-		do {
-			int read = stream.read(contents, len, size - len);
-			len += read;
-		} while (len < size);
-		return contents;
+		ProjectUtils.addPreviewer(project, new Path(context.getHtmlFile()));
 	}
 
 	private void copyTemplate(IProject project, String name,
 			ZipInputStream stream, int size, VelocityContext ctx,
 			IProgressMonitor monitor) throws IOException, CoreException {
 		// Templates will not be more then a few megs - we can afford the memory
-		final byte[] template = readBytes(stream, size);
 		ByteArrayOutputStream file = new ByteArrayOutputStream();
 
-		Reader reader = new InputStreamReader(
-				new ByteArrayInputStream(template));
+		Reader reader = new InputStreamReader(new NonClosingStream(stream));
 		Writer writer = new OutputStreamWriter(file);
 
 		Velocity.evaluate(ctx, writer, name, reader);