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.jarfrom 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 ...
