package org.jactr.eclipse.ui.wizards.project; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.IWizard; import org.eclipse.jface.wizard.IWizardNode; import org.eclipse.jface.wizard.Wizard; import org.eclipse.pde.internal.ui.wizards.IProjectProvider; import org.eclipse.pde.internal.ui.wizards.plugin.PluginFieldData; import org.eclipse.pde.ui.IFieldData; import org.eclipse.pde.ui.IPluginContentWizard; import org.eclipse.swt.graphics.Point; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.INewWizard; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.WizardNewProjectCreationPage; import org.eclipse.ui.ide.IDE; import org.jactr.eclipse.core.bundles.registry.InstrumentRegistry; import org.jactr.eclipse.core.bundles.registry.ModuleRegistry; import org.jactr.eclipse.core.bundles.registry.SensorRegistry; import org.jactr.eclipse.ui.UIPlugin; import org.jactr.eclipse.ui.wizards.pages.CommonExtensionDescriptorLabelProvider; import org.jactr.eclipse.ui.wizards.pages.CommonExtensionWizardPage; import org.jactr.eclipse.ui.wizards.pages.ToolsExplanationWizardPage; import org.jactr.eclipse.ui.wizards.templates.ModuleWizard; /** * This is a sample new wizard. Its role is to create a new file resource in the * provided container. If the container resource (a folder or a project) is * selected in the workspace when the wizard is opened, it will accept it as the * target container. The wizard creates one file with the extension "mpe". If a * sample multi-page editor (also available as a template) is registered for the * same extension, it will be able to open it. */ public class NewACTRProjectWizard extends Wizard implements INewWizard { /** * Logger definition */ static private final transient Log LOGGER = LogFactory .getLog(NewACTRProjectWizard.class); static public final String ID = NewACTRProjectWizard.class .getName(); private WizardNewProjectCreationPage mainPage; private ACTRWizardSelectionPage wizardPage; private Collection<CommonExtensionWizardPage> _commonPages = new ArrayList<CommonExtensionWizardPage>(); /** * Constructor for SampleNewWizard. */ public NewACTRProjectWizard() { super(); setWindowTitle("jACT-R Project Wizard"); setNeedsProgressMonitor(true); } /** * Adding the page to the wizard. */ @Override public void addPages() { mainPage = new WizardNewProjectCreationPage("ACT-R Project"); mainPage.setInitialProjectName("edu.your.institution.lab.project"); mainPage .setDescription("Provide a unique name for the project, preferably using the java reverse URL convention."); addPage(mainPage); addPage(new ToolsExplanationWizardPage( "toolsExp", "Library of Tools", "On the following pages you will select what tools you'd like your project to use.\n You can always change your mind later.", "jACT-R uses modular bundles of code to contribute or change your model's behavior.\n You need to select those tools in order to use them." + "\nThis is a convenience to avoid having to directly edit your projects dependencies.")); CommonExtensionWizardPage inst = new CommonExtensionWizardPage( () -> ModuleRegistry.getRegistry().getAllDescriptors(), new CommonExtensionDescriptorLabelProvider(), "module", "Modules", "Select modules you'd like to use in your project."); addPage(inst); _commonPages.add(inst); inst = new CommonExtensionWizardPage( () -> org.jactr.eclipse.core.bundles.registry.ExtensionRegistry .getRegistry().getAllDescriptors(), new CommonExtensionDescriptorLabelProvider(), "ext", "Extensions", "Select runtime extensions that you'd like to use in your project."); addPage(inst); _commonPages.add(inst); inst = new CommonExtensionWizardPage( () -> SensorRegistry.getRegistry().getAllDescriptors(), new CommonExtensionDescriptorLabelProvider(), "sensor", "Interfaces", "Select sensors/interfaces with CommonReality that you'd like to use in your project."); addPage(inst); _commonPages.add(inst); inst = new CommonExtensionWizardPage(() -> InstrumentRegistry.getRegistry() .getAllDescriptors(), new CommonExtensionDescriptorLabelProvider(), "inst", "Instruments", "Select instruments you'd like to use in your project."); addPage(inst); _commonPages.add(inst); Collection<IWizardNode> wizards = createTemplateWizards(); wizardPage = new ACTRWizardSelectionPage("ACT-R Selection", wizards); wizardPage .setDescription("Optionally, you can select code generating wizard for further customization, or just Finish."); addPage(wizardPage); } protected Collection<IWizardNode> createTemplateWizards() { ArrayList<IWizardNode> nodes = new ArrayList<IWizardNode>(); /* * we want to find all the wizard extensions that are under * org.jactr.project.wizard */ IExtensionRegistry extReg = Platform.getExtensionRegistry(); IExtensionPoint extPoint = extReg .getExtensionPoint("org.eclipse.pde.ui.pluginContent"); IExtension[] extensions = extPoint.getExtensions(); for (IExtension extension : extensions) { IConfigurationElement[] configs = extension.getConfigurationElements(); // looking for wizard for (IConfigurationElement element : configs) if (element.getName().equals("wizard")) // category : // org.jactr.project.wizard if (element.getAttribute("category") != null && element.getAttribute("category").equals( "org.jactr.project.wizard")) { String className = element.getAttribute("class"); String description = element.getAttribute("name"); try { nodes.add(new WizardNode((Class<? extends IWizard>) getClass() .getClassLoader().loadClass(className), description)); } catch (Exception e) { UIPlugin.log(IStatus.ERROR, String.format( "Could not load %s from %s", className, extension .getContributor().getName()), e); } } } // nodes.add(new WizardNode(ModuleWizard.class, // "Create a new ACT-R Module")); // nodes.add(new WizardNode(InstrumentWizard.class, // "Create a new ACT-R Instrument")); return nodes; } /** * 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. */ @Override public boolean performFinish() { final String name = mainPage.getProjectName(); final IProject project = mainPage.getProjectHandle(); final IPath location = mainPage.getLocationPath(); /* * the first thing we do is delegate */ IProjectProvider provider = new IProjectProvider() { public IPath getLocationPath() { return location; } public IProject getProject() { return project; } public String getProjectName() { return name; } }; PluginFieldData pluginData = new PluginFieldData(); pluginData.setDoGenerateClass(false); pluginData.setRCPApplicationPlugin(false); pluginData.setUIPlugin(false); pluginData.setName(name); pluginData.setVersion("0.0.0.qualifier"); pluginData.setId(name.replaceAll("[^a-zA-Z0-9\\._]", "_")); pluginData.setSimple(false); // so that java is available pluginData.setLegacy(false); pluginData.setSourceFolderName("java"); pluginData.setOutputFolderName("bin"); pluginData.setHasBundleStructure(true); pluginData.setProvider(System.getProperty("user.name")); if (LOGGER.isDebugEnabled()) LOGGER.debug("doGen:" + pluginData.doGenerateClass() + " ui:" + pluginData.isUIPlugin()); try { /** * make sure we are always at the very least running one of the wizards */ IPluginContentWizard wizard = wizardPage.getSelectedWizard(); if (wizard == null) wizard = new ModuleWizard(); getContainer().run( false, false, new NewProjectCreationOperation(pluginData, provider, wizard, _commonPages)); } catch (InterruptedException e) { return false; } catch (InvocationTargetException e) { Throwable realException = e.getTargetException(); UIPlugin.log("Could not perform finish", realException); return false; } return true; } public void init(IWorkbench workbench, IStructuredSelection selection) { // TODO Auto-generated method stub } static public class NewProjectCreationOperation extends org.eclipse.pde.internal.ui.wizards.plugin.NewProjectCreationOperation { private final IProject _project; private final Collection<CommonExtensionWizardPage> _commonPages; public NewProjectCreationOperation(IFieldData data, IProjectProvider provider, IPluginContentWizard contentWizard, Collection<CommonExtensionWizardPage> commonPages) { super(data, provider, contentWizard); _project = provider.getProject(); _commonPages = commonPages; } @Override protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException { super.execute(monitor); /* * the above automatically opens manifest, I want to close it.. */ final IWorkbenchWindow ww = PlatformUI.getWorkbench() .getActiveWorkbenchWindow(); ww.getShell().getDisplay().asyncExec(new Runnable() { public void run() { IWorkbenchPage page = ww.getActivePage(); if (page != null) try { IEditorPart part = IDE.openEditor(page, _project.getFile("META-INF/MANIFEST.MF"), true); if (part != null) page.closeEditor(part, false); } catch (Exception e) { } /* * make sure everyone is closed.. This is done here, otherwise we can * get some weird unmodifiable messages. */ for (CommonExtensionWizardPage extPage : _commonPages) extPage.ensureDependencies(_project); } }); } } static protected class WizardNode implements IWizardNode { private final Class<? extends IWizard> wizardClass; private IWizard wizard; private final String description; public WizardNode(Class<? extends IWizard> wizard, String description) { wizardClass = wizard; this.description = description; } public void dispose() { if (wizard != null) wizard.dispose(); wizard = null; } public Point getExtent() { return new Point(-1, -1); } public IWizard getWizard() { if (wizard == null) try { wizard = wizardClass.newInstance(); } catch (Exception e) { LOGGER.error("Could not create wizard from " + wizardClass, e); } return wizard; } public boolean isContentCreated() { return wizard != null && wizard.getPageCount() != 0; } @Override public String toString() { return description; } } }