Say, you want to implement a quick and flexible automation enhancement to one of your eclipse RCP plugins - for example, because you are writing some sort of business application in which you always have to create a few standard structures manually in order to play with it and test it. Here's how you can do it the groovy way:
- create a new plugin project that depends on all plug-ins you want the automation script to be able to access.
- download
groovy-all-x.y.z.jar
from the Groovy homepage and put it into your plug-in's runtime classpath. - create an objectContribution like this:
<objectContribution adaptable="false" id="myproject.groovyRunner" nameFilter="*.groovy" objectClass="org.eclipse.core.resources.IFile"> <action class="myproject.automate.RunGroovyAction" enablesFor="1" id="myproject.groovyRunnerAction" label="Execute as Automation Script" menubarPath="additions"> </action> </objectContribution>
- implement the action like this
package myproject.automate; import java.io.PrintWriter; import java.io.StringWriter; import groovy.lang.GroovyClassLoader; import org.codehaus.groovy.control.ErrorCollector; import org.codehaus.groovy.control.MultipleCompilationErrorsException; import org.codehaus.groovy.control.messages.Message; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IObjectActionDelegate; import org.eclipse.ui.IWorkbenchPart; import myproject.MyPlugin; public class RunGroovyAction implements IObjectActionDelegate { /** store the parent shell */ private Shell shell = null; /** store the selected file */ private IFile file; @Override public void setActivePart(IAction action, IWorkbenchPart targetPart) { shell = targetPart.getSite().getShell(); } @Override public void selectionChanged(IAction action, ISelection selection) { file = (IFile) ((IStructuredSelection)selection).getFirstElement(); } @Override public void run(IAction action) { Assert.isNotNull(shell); Assert.isNotNull(file); try { /* initialize the GroovyClassLoader with the Eclipse class loader */ GroovyClassLoader loader = new GroovyClassLoader(getClass().getClassLoader()); /* parse the groovy file */ Class<?> parsed = loader.parseClass(file.getContents()); /* cast it to runnable (or whatever you like to implement */ Class<? extends Runnable> clazz = parsed.asSubclass(Runnable.class); /* instantiate and rum */ Runnable r = clazz.newInstance(); r.run(); } catch(MultipleCompilationErrorsException e) { /* report compilation errors in an error dialog */ StringWriter messages = new StringWriter(); PrintWriter printWriter = new PrintWriter(messages); ErrorCollector ec = e.getErrorCollector(); if(ec.hasErrors()) { for(Object o : ec.getErrors()) { ((Message) o).write(printWriter); printWriter.append('\n'); } } Status status = new Status(IStatus.ERROR, MyPlugin.PLUGIN_ID, messages.toString(), e); ErrorDialog.openError(shell, "Compilation errors", messages.toString(), status); } catch(Exception e) { /* report all other errors here */ Status status = new Status(IStatus.ERROR, MyPlugin.PLUGIN_ID, "Execution error", e.getCause() == null ? e : e .getCause()); ErrorDialog.openError(shell, "Error", "Execution error", status); } } }
Now you can run your Eclipse application, create a .groovy class (implementing Runnable in the case above) in a file and run it from within your runtime workspace. Happy scripting ...