July 2nd, 2008 at 11:26 am

How to make an Eclipse Plugin Scriptable with Groovy

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 …

Leave a Comment

You must be logged in to post a comment.