/*******************************************************************************
* Copyright (c) 2009 the CHISEL group and contributors.
* 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:
* the CHISEL group - initial API and implementation
*******************************************************************************/
package ca.uvic.chisel.javasketch.ui.internal.wizards;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.Enumeration;
import java.util.Timer;
import java.util.TimerTask;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jface.dialogs.DialogPage;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
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.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import ca.uvic.chisel.javasketch.FilterSettings;
import ca.uvic.chisel.javasketch.SketchPlugin;
import ca.uvic.chisel.javasketch.persistence.ui.internal.FiltersComposite;
import ca.uvic.chisel.javasketch.utils.LaunchConfigurationUtilities;
/**
* @author Del Myers
*
*/
public class ImportTraceWizardPage1 extends WizardPage {
private Text fileText;
private File file;
private FileValidator validator;
private FiltersComposite filtersComposite;
private class FileValidator implements IRunnableWithProgress, Runnable {
private int WAITING = 0;
private int RUNNING = 1;
private int SCHEDULED = 2;
private int state = WAITING;
private Timer timer = new Timer();
private TimerTask task = null;
private String error = null;
private String installLocation;
FilterSettings filterSettings;
public ILaunchConfiguration launchConfiguration;
/* (non-Javadoc)
* @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public void run(IProgressMonitor monitor)
throws InvocationTargetException, InterruptedException {
File file = getFile();
error = null;
filterSettings = null;
ZipFile zFile = null;
installLocation = null;
try {
zFile = new ZipFile(file);
Enumeration<? extends ZipEntry> entries = zFile.entries();
ZipEntry configurationEntry = null;
ZipEntry filtersEntry = null;
monitor.beginTask("Validating trace file", 3);
monitor.subTask("Scanning file");
while (entries.hasMoreElements() && ((configurationEntry == null) || (filtersEntry == null))) {
ZipEntry entry = entries.nextElement();
if (entry.getName().endsWith("launch.configuration")) {
configurationEntry = entry;
} else if (entry.getName().endsWith(".filters")) {
filtersEntry = entry;
int slash = entry.getName().lastIndexOf('/');
if (slash > 0) {
installLocation = entry.getName().substring(0, slash);
}
}
if (monitor.isCanceled()) {
throw new InterruptedException();
}
}
if (configurationEntry == null || filtersEntry == null) {
error = "Invalid trace file";
return;
}
if (installLocation == null) {
error = "Invalid trace file";
}
monitor.worked(2);
monitor.subTask("Reading...");
InputStreamReader filterReader = new InputStreamReader(zFile.getInputStream(filtersEntry));
InputStreamReader configurationReader = new InputStreamReader(zFile.getInputStream(configurationEntry));
StringBuilder mementoBuilder = new StringBuilder();
char[] buf = new char[512];
int read = -1;
while ((read = configurationReader.read(buf)) != -1) {
mementoBuilder.append(buf, 0, read);
}
launchConfiguration = DebugPlugin.getDefault().getLaunchManager().getLaunchConfiguration(mementoBuilder.toString());
filterSettings = FilterSettings.load(filterReader, launchConfiguration);
} catch (ZipException e) {
error = "Error reading trace file";
} catch (IOException e) {
throw new InvocationTargetException(e);
} catch (CoreException e) {
error = "Error reading trace configuration";
} finally {
monitor.done();
if (zFile != null) {
try {
zFile.close();
} catch (IOException e) {
throw new InvocationTargetException(e);
}
}
}
}
private void schedule() {
long time = System.currentTimeMillis();
synchronized (timer) {
if (state == SCHEDULED && task != null) {
task.cancel();
state = WAITING;
}
task = new TimerTask() {
@Override
public void run() {
synchronized(timer) {
if (state != SCHEDULED) return;
state = RUNNING;
getShell().getDisplay().syncExec(FileValidator.this);
state = WAITING;
}
}
};
state = SCHEDULED;
timer.schedule(task, new Date(time + 1000));
}
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
ProgressMonitorDialog dialog = new ProgressMonitorDialog(getShell());
try {
dialog.run(true, true, this);
if (error != null) {
setErrorMessage(error);
setPageComplete(false);
} else {
setPageComplete(true);
setErrorMessage(null);
if (filterSettings != null) {
filtersComposite.setEnabled(true);
filtersComposite.setJavaContext(filterSettings.getJavaProjects());
filtersComposite.setInclusionFilters(filterSettings.getInclusionFilters());
filtersComposite.setExclusionFilters(filterSettings.getExclusionFilters());
filtersComposite.setLaunchType(filterSettings.getLaunchType());
filtersComposite.setFilterShortcut((filterSettings.isUsingProjectClassesOnly()) ?
FiltersComposite.SHORTCUT_PROJECT_CLASSES :
FiltersComposite.SHORTCUT_NONE);
setMessage(null, DialogPage.WARNING);
//check the file name
IPath stateLocation = SketchPlugin.getDefault().getStateLocation();
File stateFile = stateLocation.toFile();
File newLocation = new File(stateFile, installLocation);
if (newLocation.exists()) {
setMessage("Trace already exists", DialogPage.WARNING);
}
} else {
filtersComposite.setJavaContext(new IJavaProject[0]);
filtersComposite.setInclusionFilters(new String[0]);
filtersComposite.setExclusionFilters(new String[0]);
filtersComposite.setLaunchType(LaunchConfigurationUtilities.JAVA_LAUNCH_TYPE);
filtersComposite.setEnabled(false);
}
}
} catch (InvocationTargetException e) {
SketchPlugin.getDefault().log(e);
MessageDialog.openError(getShell(), "Error validating trace file", "An error occurred validating the trace file. See the log for more information.");
setErrorMessage("Error validating trace file.");
setPageComplete(false);
} catch (InterruptedException e) {
setErrorMessage("Trace file was not validated");
setPageComplete(false);
}
getWizard().getContainer().updateButtons();
getWizard().getContainer().updateMessage();
}
}
/**
* @param pageName
*/
protected ImportTraceWizardPage1() {
super("Import a Trace", "Import a Trace", getTitleImage());
validator = new FileValidator();
}
/**
* @return
*/
public File getFile() {
return file;
}
/**
* @return
*/
private static ImageDescriptor getTitleImage() {
return SketchPlugin.imageDescriptorFromPlugin("images/wizban/import-trace.png");
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
*/
@Override
public void createControl(Composite parent) {
Composite page = new Composite(parent, SWT.NONE);
page.setLayout(new GridLayout());
Composite filtersArea = createFiltersComposite(page);
filtersArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Control fileArea = createFileArea(page);
fileArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
setControl(page);
}
/**
* @param page
* @return
*/
private Control createFileArea(Composite page) {
Composite fileLine = new Composite(page, SWT.NONE);
fileLine.setLayout(new GridLayout(3, false));
Label nameLabel = new Label(fileLine, SWT.NONE);
nameLabel.setText("File name:");
nameLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
fileText = new Text(fileLine, SWT.SINGLE | SWT.BORDER);
fileText.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
setFileName(fileText.getText().trim());
}
});
fileText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
Button browseButton = new Button(fileLine, SWT.PUSH);
browseButton.setText("Browse...");
browseButton.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);
dialog.setFilterExtensions(new String[] { "*.dvt" });
String fileName = dialog.open();
fileText.setText(fileName);
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
}
});
String fileName = getDialogSettings().get("filename");
if (fileName != null) {
fileText.setText(fileName);
}
browseButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
return fileLine;
}
/**
* @param page
* @return
*/
private Composite createFiltersComposite(Composite page) {
Group filtersGroup = new Group(page, SWT.NONE);
filtersGroup.setText("Filters");
filtersGroup.setLayout(new GridLayout());
filtersComposite = new FiltersComposite(filtersGroup);
filtersComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
return filtersGroup;
}
private void setFileName(String fileName) {
File file = new File(fileName);
if (!file.isFile()) {
filtersComposite.setEnabled(false);
setErrorMessage("Please select a file to import");
setPageComplete(false);
getWizard().getContainer().updateButtons();
getWizard().getContainer().updateMessage();
} else {
this.file = file;
validator.schedule();
}
}
protected FilterSettings getTempFilterSettings() {
return validator.filterSettings;
}
protected ILaunchConfiguration getTempLaunchConfiguration() {
return validator.launchConfiguration;
}
protected String getTempInstallLocation() {
return validator.installLocation;
}
}