package net.certware.example.wizards; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.net.MalformedURLException; import java.net.URL; import java.text.MessageFormat; import java.util.Enumeration; import net.certware.core.ui.CertWareUI; import net.certware.core.ui.log.CertWareLog; import net.certware.example.Activator; import net.certware.example.Example; import net.certware.example.ExampleContributions; import net.certware.example.ExampleResource; import net.certware.example.ExampleSite; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; 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.Path; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.IWizardContainer; import org.eclipse.jface.wizard.Wizard; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.INewWizard; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchWizard; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.forms.widgets.FormToolkit; /** * A wizard to present a list of examples to the user for selection and copying to a workspace container. * @author mrb * @since 1.0 */ public class ExampleWizard extends Wizard implements INewWizard { /** dialog height key */ private static final String EXAMPLE_WIZARD_HEIGHT = "EXAMPLE_WIZARD_HEIGHT"; /** dialog width key */ private static final String EXAMPLE_WIZARD_WIDTH = "EXAMPLE_WIZARD_WIDTH"; /** dialog title */ private static final String TITLE = "CertWare Examples"; /** wizard page */ private ExampleWizardPage page; /** form toolkit */ private FormToolkit toolkit; /** example contributions to host plugin */ private ExampleContributions ec; /** target workspace container, a project or folder */ private IContainer targetContainer; /** * Provides an example selection wizard. * Uses the examples populated by extension point contributions. * Copies the selected example's resources into the selected workspace container. */ public ExampleWizard() { super(); setWindowTitle(TITLE); setNeedsProgressMonitor(true); setDefaultPageImageDescriptor(CertWareUI.getDefault().getImageRegistry().getDescriptor(CertWareUI.CERTWARE_WIZARD_BANNER)); setDialogSettings( Activator.getDefault().getDialogSettings() ); setHelpAvailable(true); toolkit = new FormToolkit(Display.getCurrent()); } @Override public void createPageControls(Composite pageContainer) { super.createPageControls(pageContainer); // overriding this method so as to resize the dialog when the container exists setDialogSize(); } /** * Sets the parent dialog size according to previous resized dimensions. */ private void setDialogSize() { IWizardContainer wc = this.getContainer(); if ( wc != null ) { IDialogSettings ds = getDialogSettings(); try { int w = ds.getInt(EXAMPLE_WIZARD_WIDTH); int h = ds.getInt(EXAMPLE_WIZARD_HEIGHT); wc.getShell().setSize(w, h); } catch( Exception e ) { CertWareLog.logWarning("Dialog settings not found for example wizard"); } return; } } /** * Adding the scrolled block page to the wizard. */ public void addPages() { page = new ExampleWizardPage(ec,toolkit); addPage(page); setDialogSize(); } /** * Saves the dialog dimensions in the plugin's dialog store. * Calls the super class dispose to handle the pages. */ public void dispose() { Point p = getShell().getSize(); IDialogSettings ds = getDialogSettings(); ds.put(EXAMPLE_WIZARD_WIDTH,p.x); ds.put(EXAMPLE_WIZARD_HEIGHT,p.y); super.dispose(); } /** * This method is called when 'Finish' button is pressed in * the wizard. We will create an operation and run it * using wizard as execution context. */ public boolean performFinish() { // find the selected example final Example example = page.getSelectedExample(); // create a runnable to copy resources IRunnableWithProgress op = new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException { try { doFinish(example, targetContainer, monitor); } catch (Exception e) { throw new InvocationTargetException(e); } finally { monitor.done(); } } }; try { getContainer().run(true, false, op); } catch (InterruptedException e) { return false; } catch (InvocationTargetException e) { Throwable realException = e.getTargetException(); String message = "Exception in wizard finish:" + ' ' + realException.getMessage(); MessageDialog.openError(getShell(), TITLE, message); return false; } return true; } /** * Finds the contribution in the bundle then copies it to the target container in the workspace. * @throws IOException for file access problems * @throw CoreException for resource problems */ private void doFinish(Example example, IContainer target, IProgressMonitor monitor) throws CoreException, IOException { Activator examplePlugin = Activator.getDefault(); // open sites monitor.beginTask(MessageFormat.format("Opening sites from example {0}",example.getName()), example.getRelatedSites().size() ); for ( ExampleSite exampleSite : example.getRelatedSites() ) { monitor.subTask(exampleSite.getDescription()); String location = exampleSite.getLocation(); if ( location != null ) { if ( location.length() > 0 ) { String message = MessageFormat.format("Opening contributed site {0}", location); CertWareLog.logInfo(message); try { PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser().openURL(new URL(location)); } catch( MalformedURLException e) { CertWareLog.logError("Example could not open browser for URL:" + ' ' + location, e); } catch( PartInitException e) { CertWareLog.logError("Example could not launch browser from workbench",e); } } } monitor.worked(1); } // example sites // done with sites // copy resources monitor.beginTask(MessageFormat.format("Copying resources from example {0}", example.getName()), example.getRelatedResources().size() ); // for each resource found in the contributing example's resource list for ( ExampleResource exampleResource : example.getRelatedResources() ) { monitor.subTask(exampleResource.getDescription()); String structure = exampleResource.getStructure(); String subStructure = structure; int lio = subStructure.lastIndexOf( IPath.SEPARATOR ); if ( lio > 0 ) subStructure = subStructure.substring(lio+1); // find all entries in the bundle // finding more specific matches seems not to work in the expected way // scan all returned values and choose the last match Enumeration<URL> e = examplePlugin.getBundle().findEntries("/","*", true); URL matchedEntry = null; while( e.hasMoreElements() ) { URL entry = e.nextElement(); //if ( entry.getFile().contains( structure ) ) { // contribution sequence dependent //matchedEntry = entry; //} if ( entry.getFile().endsWith( structure ) ) { matchedEntry = entry; } } // if not found for some reason, skip if ( matchedEntry == null ) { String message = MessageFormat.format("Example file {0} not found in contribution", structure); CertWareLog.logWarning(message); continue; } // found entry // trim any folder segments from the entry for the target String urlFile = matchedEntry.getFile(); lio = urlFile.lastIndexOf(IPath.SEPARATOR); if ( lio > 0 ) urlFile = urlFile.substring(lio+1); IPath targetPath = new Path(target.getFullPath().toString() + IPath.SEPARATOR + urlFile); IFile targetFile = ResourcesPlugin.getWorkspace().getRoot().getFile(targetPath); // open the bundle URL and pass it as input stream to workspace file // the resource copies the URL reference to the workspace if ( targetFile.exists() == false ) { try { InputStream is = matchedEntry.openStream(); targetFile.create(is, true, monitor); is.close(); String message = MessageFormat.format("Copied example resource {0} to {1}", subStructure, target.getName() ); CertWareLog.logInfo(message); } catch( IOException ioe ) { String message = MessageFormat.format("Copying file from {0} to {1}", urlFile, targetFile.toString()); CertWareLog.logError(message,ioe); throw ioe; } catch( CoreException ce) { String message = MessageFormat.format("Copying file from {0} to {1}", urlFile, targetFile.toString()); CertWareLog.logError(message,ce); throw ce; } } // does not exist else { // already exists, do not overwrite String message = MessageFormat.format( "Example resource {0} already exists; overwrite not performed", targetFile.toString()); CertWareLog.logWarning(message); } monitor.worked(1); } } /** * We will accept the selection in the workbench to see if we can initialize from it. * @see IWorkbenchWizard#init(IWorkbench, IStructuredSelection) */ public void init(IWorkbench workbench, IStructuredSelection selection) { if ( selection == null || (selection.getFirstElement() instanceof IContainer) == false) { String message = "Wizard must have a container selection for examples"; CertWareLog.logWarning(message); MessageDialog.openWarning(getShell(), TITLE, message); return; } // target container destination for copying resources targetContainer = (IContainer)selection.getFirstElement(); if ( targetContainer.isAccessible() == false ) { String message = MessageFormat.format("Wizard found target container is not accessible: {0}", targetContainer.getName()); CertWareLog.logWarning(message); MessageDialog.openWarning(getShell(), TITLE, message); return; } // load the example contributions attached to the plugin ec = new ExampleContributions(); ec.initialize(); } @Override public boolean canFinish() { return page.isPageComplete(); } }