Commit 6937bf0e authored by amccaskey's avatar amccaskey
Browse files

ICEExtensionContributionFactory creates Parameterized Commands



Setup the ICE Developer Menu generation utility to create parameterized
commands where the parameters are all the attributes from the provided
extension point. 
Signed-off-by: default avataramccaskey <mccaskeyaj@ornl.gov>
parent 63058ab1
......@@ -8,16 +8,14 @@
<code
codeCategory="Framework"
codeName="MOOSE"
generateDefaultCommands="false"
repoURL="https://github.com/idaholab/moose"
versionControlType="git">
repoURL="https://github.com/idaholab/moose">
<command
commandName="Fork the Stork"
implementation="org.eclipse.ice.developer.moose.actions.ForkStorkHandler">
</command>
<command
commandName="Clone MOOSE"
implementation="org.eclipse.ice.developer.moose.actions.CloneMOOSEHandler">
implementation="org.eclipse.ice.developer.actions.GitHubCloneHandler">
</command>
<command
commandName="Fork MOOSE"
......
......@@ -8,6 +8,20 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: org.eclipse.core.runtime;bundle-version="3.11.0",
org.eclipse.jface;bundle-version="3.11.0",
org.eclipse.core.expressions;bundle-version="3.5.0",
org.eclipse.ui
Import-Package: org.eclipse.ui.menus,
org.eclipse.ui.services
org.eclipse.ui,
org.eclipse.core.resources,
org.eclipse.egit.core;bundle-version="4.0.0",
org.eclipse.jgit;bundle-version="4.0.0",
org.eclipse.egit.ui;bundle-version="4.0.0",
org.eclipse.core.commands
Import-Package: org.apache.commons.io;version="2.2.0",
org.eclipse.egit.github.core;version="4.0.0",
org.eclipse.egit.github.core.service;version="4.0.0",
org.eclipse.jgit.api;version="4.0.0",
org.eclipse.jgit.api.errors;version="4.0.0",
org.eclipse.ui.actions,
org.eclipse.ui.menus,
org.eclipse.ui.services,
org.eclipse.ui.wizards.datatransfer,
org.slf4j;version="1.7.2"
Export-Package: org.eclipse.ice.developer.actions
......@@ -21,9 +21,11 @@
<code
codeCategory="Framework"
codeName="ICE"
generateDefaultCommands="true"
repoURL="https://github.com/eclipse/ice"
versionControlType="git">
repoURL="https://github.com/eclipse/ice">
<command
commandName="Clone ICE"
implementation="org.eclipse.ice.developer.actions.GitHubCloneHandler">
</command>
</code>
</extension>
......
......@@ -82,21 +82,6 @@
</restriction>
</simpleType>
</attribute>
<attribute name="versionControlType">
<annotation>
<documentation>
The type of version control this code uses.
</documentation>
</annotation>
<simpleType>
<restriction base="string">
<enumeration value="git">
</enumeration>
<enumeration value="svn">
</enumeration>
</restriction>
</simpleType>
</attribute>
<attribute name="codeName" type="string" use="required">
<annotation>
<documentation>
......@@ -104,13 +89,6 @@
</documentation>
</annotation>
</attribute>
<attribute name="generateDefaultCommands" type="boolean" use="required">
<annotation>
<documentation>
This boolean is for indicating if this extension point wants to use the default git clone and fork actions.
</documentation>
</annotation>
</attribute>
</complexType>
</element>
......
package org.eclipse.ice.developer.actions;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
public class GitCloneHandler extends AbstractHandler {
private String repo;
public GitCloneHandler(String repoURL) {
repo = repoURL;
}
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
// TODO Auto-generated method stub
return null;
}
}
package org.eclipse.ice.developer.actions;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.URISyntaxException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.egit.core.internal.util.ProjectUtil;
import org.eclipse.egit.core.op.CloneOperation;
import org.eclipse.egit.core.op.CloneOperation.PostCloneTask;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.clone.ProjectRecord;
import org.eclipse.egit.ui.internal.clone.ProjectUtils;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.ui.wizards.IWizardDescriptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings("restriction")
public class GitHubCloneHandler extends AbstractHandler {
private boolean noProjects;
/**
* Logger for handling event messages and other information.
*/
private static final Logger logger = LoggerFactory.getLogger(GitHubCloneHandler.class);
public GitHubCloneHandler() {
noProjects = false;
}
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
// Get the repository
String repo = (String) event.getParameters().get("repoURLID");
// Create the Job to be executed
final Job job = new Job("Cloning " + repo) {
@Override
protected IStatus run(IProgressMonitor monitor) {
// Create the workspace file
File workspaceFile = new File(ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString()
+ System.getProperty("file.separator")
+ repo.substring(repo.lastIndexOf("/") + 1, repo.length()));
try {
CloneOperation cloneOp = new CloneOperation(new URIish(repo), true, null, workspaceFile, "master",
"origin", 100);
cloneOp.addPostCloneTask(new PostCloneTask() {
@Override
public void execute(Repository repository, IProgressMonitor monitor) throws CoreException {
importProjects(repository, new IWorkingSet[0]);
if (noProjects) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
Shell shell = HandlerUtil.getActiveShell(event);
openWizard("org.eclipse.egit.ui.internal.clone.GitCloneWizard", shell);
}
});
}
}
});
cloneOp.run(monitor);
} catch (URISyntaxException | InvocationTargetException | InterruptedException e) {
e.printStackTrace();
}
return Status.OK_STATUS;
}
};
job.schedule();
return null;
}
private void importProjects(final Repository repository, final IWorkingSet[] sets) {
String repoName = org.eclipse.egit.ui.Activator.getDefault().getRepositoryUtil().getRepositoryName(repository);
Job importJob = new WorkspaceJob(MessageFormat.format(UIText.GitCloneWizard_jobImportProjects, repoName)) {
@Override
public IStatus runInWorkspace(IProgressMonitor monitor) {
List<File> files = new ArrayList<File>();
ProjectUtil.findProjectFiles(files, repository.getWorkTree(), true, monitor);
if (files.isEmpty()) {
noProjects = true;
return Status.OK_STATUS;
}
Set<ProjectRecord> records = new LinkedHashSet<ProjectRecord>();
for (File file : files) {
records.add(new ProjectRecord(file));
}
try {
ProjectUtils.createProjects(records, sets, monitor);
} catch (InvocationTargetException e) {
Activator.logError(e.getLocalizedMessage(), e);
} catch (InterruptedException e) {
Activator.logError(e.getLocalizedMessage(), e);
}
return Status.OK_STATUS;
}
};
importJob.schedule();
}
public void openWizard(String id, Shell shell) {
// First see if this is a "new wizard".
IWizardDescriptor descriptor = PlatformUI.getWorkbench().getNewWizardRegistry().findWizard(id);
// If not check if it is an "import wizard".
if (descriptor == null) {
descriptor = PlatformUI.getWorkbench().getImportWizardRegistry().findWizard(id);
}
// Or maybe an export wizard
if (descriptor == null) {
descriptor = PlatformUI.getWorkbench().getExportWizardRegistry().findWizard(id);
}
try {
// Then if we have a wizard, open it.
if (descriptor != null) {
IWizard wizard = descriptor.createWizard();
WizardDialog wd = new WizardDialog(shell, wizard);
wd.setTitle(wizard.getWindowTitle());
wd.open();
}
} catch (CoreException e) {
e.printStackTrace();
}
}
}
......@@ -11,16 +11,25 @@
*******************************************************************************/
package org.eclipse.ice.developer.menu;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.commands.IParameter;
import org.eclipse.core.commands.IParameterValues;
import org.eclipse.core.commands.ParameterValuesException;
import org.eclipse.core.commands.Parameterization;
import org.eclipse.core.commands.ParameterizedCommand;
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.Platform;
import org.eclipse.ice.developer.actions.GitCloneHandler;
import org.eclipse.ice.developer.actions.GitHubCloneHandler;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.swt.SWT;
import org.eclipse.ui.commands.ICommandService;
......@@ -43,103 +52,132 @@ import org.osgi.framework.Bundle;
*/
public class ICEExtensionContributionFactory extends ExtensionContributionFactory {
/**
* Reference to the provided IServiceLocator
* - Used for getting the ICommand and IHandler
* Services
*/
private IServiceLocator serviceLocator;
/**
* Reference to the Extension Registry
*/
private IExtensionRegistry registry;
/**
* Reference to the top-level Developer Menu
*/
private MenuManager developerMenu;
/**
* Reference to the list of IParameters
* we can provide to the created Commands
*/
private ArrayList<IParameter> parameters;
/**
* The constructor
*/
public ICEExtensionContributionFactory() {
parameters = new ArrayList<IParameter>();
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.menus.AbstractContributionFactory#createContributionItems(org.eclipse.ui.services.IServiceLocator, org.eclipse.ui.menus.IContributionRoot)
*
* This implementation adds a Developer Menu Item to the Eclipse ICE Menu Bar.
* @see
* org.eclipse.ui.menus.AbstractContributionFactory#createContributionItems(
* org.eclipse.ui.services.IServiceLocator,
* org.eclipse.ui.menus.IContributionRoot)
*
* This implementation adds a Developer Menu Item to the Eclipse ICE Menu
* Bar.
*
*/
@Override
public void createContributionItems(IServiceLocator serviceLocator, IContributionRoot additions) {
public void createContributionItems(IServiceLocator serviceLoc, IContributionRoot additions) {
// Local Declarations
HashMap<String, MenuManager> categoryMenus = new HashMap<String, MenuManager>();
String codeName = "", repoURL = "", vcType = "", category = "";
MenuManager developer = null, codeMenu = null;
String codeName = "", category = "";
MenuManager codeMenu = null;
// Set the ServiceLocator
serviceLocator = serviceLoc;
// Create the Developer Menu Item
developer = new MenuManager("&Developer", "iceDev");
developerMenu = new MenuManager("&Developer", "iceDev");
// Get the registry and the extensions
IExtensionRegistry registry = Platform.getExtensionRegistry();
IExtensionPoint extensionPoint = registry.getExtensionPoint("org.eclipse.ice.developer.code");
IExtension[] codeExtensions = extensionPoint.getExtensions();
registry = Platform.getExtensionRegistry();
// Create the ICE Menu first...
IExtension iceExtension = extensionPoint.getExtension("org.eclipse.ice.developer.icedev");
// We will always have only one IConfigurationElement for this extension
IConfigurationElement element = iceExtension.getConfigurationElements()[0];
// Get the attribute data
codeName = element.getAttribute("codeName");
repoURL = element.getAttribute("repoURL");
// Create the ICE Menu
codeMenu = new MenuManager(codeName, codeName + "ID");
createDefaultCommands(serviceLocator, "git", codeName, repoURL, codeMenu);
developer.add(codeMenu);
// Create the ICE Menu here so it's first in the list
MenuManager ice = new MenuManager("ICE", "ICEID");
categoryMenus.put("ICE", ice);
developerMenu.add(ice);
// Create the category sub-menus
for (CodeCategory c : CodeCategory.values()) {
MenuManager manager = new MenuManager(c.name(), c.name() + "ID");
manager.setVisible(true);
categoryMenus.put(c.name(), manager);
developer.add(manager);
developerMenu.add(manager);
}
// Loop over the rest of the Extensions and create
// their sub-menus.
// Get the Extension Points
IExtensionPoint extensionPoint = registry.getExtensionPoint("org.eclipse.ice.developer.code");
IExtension[] codeExtensions = extensionPoint.getExtensions();
// Loop over the rest of the Extensions and create
// their sub-menus.
for (IExtension code : codeExtensions) {
// Don't add ICE again...
if (!code.getContributor().getName().equals("org.eclipse.ice.developer")) {
// Get the name of the bundle this extension comes from
// so we can instantiate its AbstractHandlers
String contributingPlugin = code.getContributor().getName();
// Get the name of the bundle this extension comes from
// so we can instantiate its AbstractHandlers
String contributingPlugin = code.getContributor().getName();
// Get the elements of this extension
IConfigurationElement[] elements = code.getConfigurationElements();
for (IConfigurationElement e : elements) {
// Get the Code Name
codeName = e.getAttribute("codeName");
// Get the elements of this extension
IConfigurationElement[] elements = code.getConfigurationElements();
for (IConfigurationElement e : elements) {
// Get the attribute data
category = e.getAttribute("codeCategory");
codeName = e.getAttribute("codeName");
repoURL = e.getAttribute("repoURL");
vcType = e.getAttribute("versionControlType");
boolean genDefault = Boolean.valueOf(e.getAttribute("generateDefaultCommands"));
// Create a sub menu for the code in the
// correct category
codeMenu = new MenuManager(codeName, codeName + "ID");
// If requested, create the default commands
if (genDefault) {
createDefaultCommands(serviceLocator, vcType, codeName, repoURL, codeMenu);
}
// Get whether this is the ICE declaration
boolean isICE = "ICE".equals(codeName);
// Get the Code Category - Framework, Physics, etc...
category = isICE ? codeName : e.getAttribute("codeCategory");
// Create a menu item for each extra command they provided
for (IConfigurationElement command : e.getChildren("command")) {
createCommand(serviceLocator, contributingPlugin, command.getAttribute("implementation"),
command.getAttribute("commandName"), codeMenu);
}
// Create a sub menu for the code in the
// correct category, if this is not ICE ( we've already done it for ICE)
codeMenu = isICE ? categoryMenus.get(codeName)
: new MenuManager(codeName, codeName + "ID");
// Add it to the correct category menu
categoryMenus.get(category).add(codeMenu);
// Generate the IParameters for the Command
generateParameters(e);
// Create a menu item for each extra command they provided
for (IConfigurationElement command : e.getChildren("command")) {
generateParameters(command);
createCommand(contributingPlugin, command.getAttribute("implementation"), codeMenu);
}
// Add it to the correct category menu
if (!"ICE".equals(codeName)) {
categoryMenus.get(category).add(codeMenu);
}
}
}
// Add the newly constructed developer menu
additions.addContributionItem(developer, null);
additions.addContributionItem(developerMenu, null);
return;
}
/**
* This private method creates specified commands that are attached to
* a given MenuManager.
* This private method creates specified commands that are attached to a
* given MenuManager.
*
* @param serviceLocator
* @param plugin
......@@ -147,68 +185,101 @@ public class ICEExtensionContributionFactory extends ExtensionContributionFactor
* @param commandName
* @param codeMenu
*/
private void createCommand(IServiceLocator serviceLocator, String plugin, String impl, String commandName,
MenuManager codeMenu) {
private void createCommand(String plugin, String impl, MenuManager codeMenu) {
// Local Declarations
HashMap<String, String> map = new HashMap<String, String>();
// Get the services we need
ICommandService commandService = serviceLocator.getService(ICommandService.class);
IHandlerService handlerService = serviceLocator.getService(IHandlerService.class);
// Map the list of Parameters to a HashMap
for (IParameter p : parameters) {
map.put(p.getId(), p.getName());
}
// Create a new undefined command and then define it
Command command = commandService.getCommand(impl);
command.define("Git Clone", "This is created Programatically!",
commandService.getCategory("org.eclipse.ice.developer.command.category"));
command.define(map.get("commandNameID"), "This is created Programatically!",
commandService.getCategory("org.eclipse.ice.developer.command.category"),
parameters.toArray(new IParameter[parameters.size()]));
// Create the ParameterizedCommand to be executed
ParameterizedCommand parameterizedCommand = ParameterizedCommand.generateCommand(command, map);
// Load the associated IHandler for this command!
try {
Bundle bundle = Platform.getBundle(plugin);
Class<?> commandClass = bundle.loadClass(impl);
IHandler handler = (IHandler) commandClass.newInstance();
handlerService.activateHandler(command.getId(), handler);
final IHandler handler = (IHandler) commandClass.newInstance();
handlerService.activateHandler(parameterizedCommand.getId(), handler);
// Create a custom Action that executes the
// Parameterized Command instead of the Command
Action launchAction = new Action() {
@Override
public void run() {
try {
handler.execute(handlerService.createExecutionEvent(parameterizedCommand, null));
} catch (ExecutionException e) {
e.printStackTrace();
}
}
};
// Set it's text then add it to the Menu!
launchAction.setText(map.get("commandNameID"));
codeMenu.add(launchAction);
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
return;
}
// Create the ContributionItem and add it to the menu
CommandContributionItemParameter p = new CommandContributionItemParameter(serviceLocator, "", impl, SWT.PUSH);
p.label = commandName;
CommandContributionItem item = new CommandContributionItem(p);
item.setVisible(true);
codeMenu.add(item);
}
/**
* This private method is used to create default clone and fork commands.
* This private method is for generating the list of parameters
* to be used by the Command.
*
* @param serviceLocator
* @param vcType
* @param codeName