Monday, 2 December 2013

Installing Eclipse Plugin Builder, accessing Eclipse objects and adding a new Menu Item that opens Owasp.org website

This post shows how to use the Eclipse Plugin Update site described in TeamMentor Plugin and Builder v1.5.6 (Source Code and Eclipse Update site) to install and use the Eclipse Builder Kit that we open sourced last week.

The objective is to do these actions, without needing to start Eclipse to see them:
  • Dynamically access eclipse objects like: Shell, Workbench, Worksapce, ActiveWorkbenchPage, Display, etc...
  • Open the http://www.owasp.org website in a browser (and put it inside an Action object)
  • Add new Menu called ‘OWASP’
  • Add a menu Item to the ‘OWASP’ menu called ‘Open OWASP website’ that calls the Action object that opens wht OWASP website.


Step 1: Install the TeamMentor Plugin version 1.5.6 in Kepler

In a default install of Kepler (this should also work in versions 3.7 (Indigo) and 4.2 (Juno))

image

…open the Install New Software… menu option:

image

…enter the value http://eclipse-plugin-builder.azurewebsites.net the Work with: Textbox

image

…select the TeamMentor Eclipse PlugIn – For Fortify option and click Next

image

… click Next:

image

… accept the terms and click Finish:

image

… click OK on the unsigned warning (this will be addressed on the final build)

image

… and finally click Yes to reboot:

image


Step 2: Enable script support and write a ‘Hello World’ script

Once Eclipse starts, you should see a TeamMentor menu, where you need to click on the Open Properties Page menu item

image

… select the Show Advanced Mode Features checkbox:

image

… click OK

image

… and open the Util – Write Script (TeamMentor DSL) menu item from the (new) Advanced and Debug Features menu

image

NOTE: if you are running this on Indigo, you will need to restart Eclipse since menu visibility is not loaded dynamically (as it is in Kepler). I’m sure there is a way to force its refresh, so if you know about it, let me know.

The scripting UI should look like this:

image

… where if you click on Execute you should see of one of TeamMentor’s article showing up in a browser window

image

… and an eclipse object string representation (in this case tm.eclipse.api.EclipseAPI@1ffbe29) in the script UI’s Execution result panel

image

To create the first Hello World example, replace the text inside the  Groovy Code panel with:

image

… and click on Execute to see the Hello World in the Execution result panel

image

Note that the Execution result will show the last object of the Groovy script execution, so you can just do this:

image


Step 3: Access Internal Eclipse objects to view/change properties values and invoke methods

What is really powerful about this scripting environment, is the fact that it is running on the Eclipse JVM, which means that it has access to all Eclipse objects in real time.

In practice, this means that we can access Eclipse objects and manipulate them right inside the Eclipse instance we are running the scripts! No more waiting 30s to see the effect of a code change or simple code test :)

To make life/coding easier, most of the common objects one needs when programming eclipse are exposed via the EclipseApi class, which is available via the eclipse object (or the eclipseAPI object) already mapped to the current Groovy script being executed:

image

Groovy has a nice Object Viewer helper UI in the groovy.inspect.swingui.ObjectBrowser class, which is exposed as the inspect({any object}) method that can be used (see below) to view all Public Fields and Properties of the eclipse object:

image

and all (Meta) Methods:

image 

Here is a quick view of the main helper fields mapped to Eclipse objects:

eclipse.shell

image

.... which is an instance of org.eclipse.swt.widgets.Shell:

image

eclipse.workbench (instance of org.eclipse.ui.internal.Workbench)

image

eclipse.workspace (instance of org.eclipse.ui.internal.resources.Workspace)

image

eclipse.activeWorkbenchPage (instance of org.eclipse.ui.internal.WorkbenchPage)

image

eclipse.activeWorkbenchWindow (instance of org.eclipse.ui.internal.WorkbenchWindow)

image

eclipse.display (instance of org.eclipse.swt.widgets.Display)

image

The reason why is very powerful to have access to these objects is that have real-time read/write access to its properties/fields

For example use inspect(eclipse.shell) to see the current Eclipse’s Shell object properties/fields:

image

note: since we are using Groovy we can also use: eclipse.shell.dump()

image

If you look at the list of the properties/fields in the eclipse.shell object, notice that there is one called text,which is the value of the current Shell window title (in the case below ‘Java – Eclipse’)

image

Not only we have access to this value, we can be dynamically change it:

image

We can also easily open views like this:

image

.. or get a list of open views:

image

Step 4: Add a new Menu Item that opens OWASP.org website

Now, lets say that we want to so something more interesting like adding a new Menu Item that opened the http://www.owasp.org website.

We can start with this code snippet that will open the Eclipse internal browser:
def browserId = "Test Browser";
def website= "http://www.owasp.org";
def browser = eclipse.workbench.getBrowserSupport().createBrowser(browserId);
browser.openURL(new URL(website));


… which when executed will look like this:

image

Next lets move the code that opens a browser into an Action object:

import org.eclipse.jface.action.Action;
def final _eclipse = eclipse;
Action action = new Action()  {
                                 @Override
                                 public void run() {                            
                                                      def browserId = "Test Browser";
                                                      def website= "https://www.google.com"; //"http://www.owasp.org";  
                                                      def browser = _eclipse.workbench.getBrowserSupport().createBrowser(browserId);
                                                      browser.openURL(new URL(website));
                                                   }
                             }

return action.run();


Here is the code that will create a new Menu (not visible until it has an action)

def menuName = "New Menu";
def topMenuManager      = eclipse.activeWorkbenchWindow.getMenuManager()
MenuManager newMenu = new MenuManager(menuName);
topMenuManager.prependToGroup(IWorkbenchActionConstants.MB_ADDITIONS, newMenu);


Putting the two together:

import org.eclipse.jface.action.*;
import org.eclipse.ui.IWorkbenchActionConstants;

def final _eclipse = eclipse;

def menuName = "New Menu";
def actionName = "open owasp.org";
def topMenuManager      = eclipse.activeWorkbenchWindow.getMenuManager()
MenuManager newMenu = new MenuManager(menuName);
topMenuManager.prependToGroup(IWorkbenchActionConstants.MB_ADDITIONS, newMenu);

Action action = new Action(actionName)   {
                                                    @Override 
                                                    public void run() {                            
                                                                                    def browserId = "Test Browser";
                                                                                    def website= "http://www.owasp.org";
                                                                                    def browser = _eclipse.workbench.getBrowserSupport().createBrowser(browserId);
                                                                                    browser.openURL(new URL(website));
                                                }
                                            }


newMenu.add(action)

topMenuManager.update(true);

return topMenuManager;


We get a new menu:

image

…which when selected will open an browser with https://www.owasp.org

image


What is really interesting in the code sample above, is how close we are to programming in pure java in normal Eclipse plugin development mode (great when learning how the API works and following the existing code sample).

But since my view in API development is to make it as easy as possible to perform the desired action, I added an helper method to the EClipseAPI to create a menu item that opens a browser window

Using the helper API, the entire code above can be replaced with:
def testMenu = eclipse.menus.add_Menu("Test Menu")
eclipse.menus.add_MenuItem_OpenWebPage(testMenu, "Open OWASP website", https://www.owasp.org)


…which when executed will add the Test Menu to the top menu with a Open OWASP website menu item

image

Note1 : In C# I could had made that API even simpler since I could had used Extension methods to add the add_Menu_Item method to the MenuManager class

Note 2: There are a couple more helper methods which you can see at: https://github.com/TeamMentor/TeamMentor_Eclipse_Plugin/blob/develop/TeamMentor.Eclipse.PlugIn.Fortify/src/tm/eclipse/api/Menus.java



Appendix: Auto updates

Once you can have the Plug-in installed, you can get updates via the ‘Check for Updates’ menu option (note that moment fixes are pushed as minor updates, so you might not get the latest version after the first install):

image

If there is an update, you will get a window that looks like this:

image

… where you can review the updates and click ‘'Next’

image

… access the license and click Finish

image

… click OK (if you are not in an hostile network that is able to dynamically backdoor Eclipse plugins on the fly):

image

… and finally click YES to reboot:

image


Note: if you want the checks to happen automatically, you can set it here:

image