Jun 14

I recently got a request from my one client: “Please add logging of the time it takes to do remote service calls, with minimal impact on the existing code.”

Now I immediately thought of the Proxy design pattern.

The existing code had quite a large number of business interfaces defined, with an implementation for each one that made use of RMI to call the remote objects. I’ll spare you the unnecessary details (JAAS, etc). It boiled down to basically every public method in each business interface implementation making use of an anonymous inner class with a simple public Object run() method to make the actual call to the remote object. A lot of code to change by hand, if logging and measurement of the time it took for remote calls were to be added.

A drastically reduced business interface might look like:

package com.richclientgui.blog.delegate;

public interface SoccerScoreService {
    public int getTeamScore(String teamName);
}

In order to re-enact the work of the JAAS Subject.doAs(…) code that is involved with the actual code, I created a MockSubject class for this example, which just calls the run() method of whatever Runnable gets passed to it:

import java.util.concurrent.Callable;

public class MockSubject {
    public static <T> T doAs(Callable<T> action) throws Exception {
        return action.call();
    }
}

We add a very basic mock implementation (no real remote calls happening here…):

import java.util.concurrent.Callable;

public class MockSoccerScoreServiceImpl implements SoccerScoreService {

    @Override
    public int getTeamScore(String teamName) {
        try {
                
            Integer result = MockSubject.doAs(
                                    new Callable<Integer>() {
                public Integer call() throws Exception {
                    System.out.print("Doing some work...");
                    try {
                         Thread.sleep(1000);
                    } catch (InterruptedException e) {
                         e.printStackTrace();
                    }
                    System.out.println("completed.");
                    return new Integer(50);
                }
             });
             return result.intValue();
                        
        } catch (Exception e) {
             //for this blog, I don't care about the
             //exception handling...
             e.printStackTrace();
             return -1;
        }
    }
}

Now we can just create a simple class with a main method that calls getTeamScore(…) on an instance of MockSoccerScoreServiceImpl.

Now to add the logging…

Approach A: Use a Proxy
We can create a Proxy for the Callable, since all our calls to the server are done using Callable instances. This proxy class measures the time it takes to perform the call() method of the real Callable, and logs it to sysout.

import java.util.concurrent.Callable;

public class LoggingCallableProxy <T> implements Callable<T> {
        private final Callable<T> realCallable;
        
        public LoggingCallableProxy(Callable<T> realCallable){
                this.realCallable = realCallable;
        }
        
        @Override
        public T call() throws Exception {
                long time = System.currentTimeMillis();
                T result = realCallable.call();
                time = System.currentTimeMillis()-time;
                //find calling method, using call level of 3
                //for this example
                final StackTraceElement stackTrace
                        = Thread.currentThread().getStackTrace()[3];
                //using sysout for example, but of course
                //use proper logging in real life
                System.out.println(
                                stackTrace.getClassName()+"."
                                +stackTrace.getMethodName()
                                +" took "+time+"ms to execute.");
                return result;
        }
}

Now comes the disadvantage of using a Proxy: we now have to change all the existing code to now create the instance of LoggingCallableProxy where the Callable was used up to now. This is not so bad if you have the source code, it is just a simple find&replace, so we can be pragmatic and live with it (I’ve always wanted to use the word “pragmatic” in a blog). Our MockSoccerScoreServiceImpl class changes to look like:

import java.util.concurrent.Callable;
import com.richclientgui.blog.proxy.LoggingCallableProxy;

public class MockSoccerScoreServiceImpl implements SoccerScoreService {

        @Override
        public int getTeamScore(String teamName) {
                try {
                
                    Integer result = MockSubject.doAs(
                           new LoggingCallableProxy<Integer>(
                               new Callable<Integer>() {
                         public Integer call() throws Exception {
                             System.out.print("Doing some work...");
                             try {
                                     Thread.sleep(1000);
                             } catch (InterruptedException e) {
                                     e.printStackTrace();
                             }
                             System.out.println("completed.");
                                     return new Integer(50);
                         }
                     }));
                     return result.intValue();
                        
                } catch (Exception e) {
                     //for this blog, I don't care about the
                     //exception handling...
                     e.printStackTrace();
                     return -1;
                }
        }
}

Now we have logging of the time measurements, with minimal code impact.

However, that simple yet far-reaching find&replace operation one potentially hundreds of methods in a huge number of classes still worries me…

Approach B: use Aspects

Aspect-oriented programming (AOP) has been around for a while, and it allows us to weave in functionality without changing existing java classes. That is an extremely brief and potentially inaccurate summary, but it will suffice for this blog. Go read more about aspects and AspectJ.

First, we need to enable aspects on our project. Do this, you must:

  1. Download the AspectJ Development Tools (AJDT) if you are using the Eclipse IDE (AspectJ also integrates with other IDEs).
  2. Convert the project to an AspectJ project: Right-click on project, choose Configure -> Convert to AspectJ project
  3. Now you are ready to start implementing aspects.

Second: change back the MockSoccerScoreServiceImpl class to now make use of the LoggingCallableProxy anymore.

Then we can implement our aspect:

import com.richclientgui.blog.delegate.MockSubject;

/**
 * This aspect will find all occurrences of the MockSubject.doAs(...)
 * method being called, and wrap that in code to log the time
 * measurements.
 */
public aspect TimeLoggerAspect  {

        // the pointcut defines what method calls to intercept
        // All calls to the MockSubject.doAs(...) method
        // (wildcards for return and param types)
        pointcut doingRemoteCalls() :
                call(* MockSubject.doAs(..));

        /* around() defines an advise that will be executed whenever
         * the doingRemoteCalls() pointcut is matched.
         * It measures the time that it takes to execute the actual
         * doAs(...)method at that point, and prints out the time,
         * class and method calling the MockSubject.doAs(..) method
         */
        Object around() : doingRemoteCalls() {
                long time = System.currentTimeMillis();
                Object result = proceed();
                time = System.currentTimeMillis()-time;
                //find calling method
                final StackTraceElement stackTrace
                        = Thread.currentThread().getStackTrace()[2];
                System.out.println(
                                stackTrace.getClassName()+"."
                                +stackTrace.getMethodName()+" took "
                                +time+"ms to execute.");
                return result;
        }
}

Now you can run your main/test class as an AspectJ application, by using the Run As -> AspectJ/Java Application menu option in Eclipse.
(Visit the AspectJ website to see how to run it from commandline or other IDEs.)

We added logging to the remote calls, without changing any existing code, by just adding one simple aspect. This is only the tip of the iceberg of what you can do with AOP.

Eclipse RCP tip:
For Eclipse RCP applications, you will need to add a dependency to the org.aspectj.runtime plug-in to your plug-in project in order to use AspectJ.

Tagged with:
Jun 10

I recently blogged (on my blogger site) about my quest to find a more effective way of coding Java GUI applications. This resulted in the creation of a one-day workshop that I am very excited about.

The details from the JTraining website are:

Fast-tracking Java GUI Development
This is a great one-day workshop that discusses a number of concerns with developing Graphical User Interfaces applications with Java, and explore various ways to improve the speed and efficiency of development.

  • Do you sometimes think that coding in Java is perhaps not the best way of constructing GUIs?
  • Do you feel that your team should be able to develop GUI applications much faster?
  • Are you frustrated with the amount of “donkey code” you are writing to implement some basic GUI features?
  • Are the new team members struggling with the high learning curve of the Java GUI framework you are using?
  • Are you spending more time on coding GUI behaviour than you spend on coding domain behaviour?
  • Do your team find it difficult to add or modify existing features of a GUI application?

The above questions highlight some of the issues typically found when doing GUI application development. We have been specialising in Java GUI development for more than a decade, and in this time we have investigated and used a wide range of frameworks, tools and techniques to help us build GUI applications more effectively. This workshop explores a number of these options, in a highly interactive and hands-on way.

Visual GUI builder tools, code generators, UI DSLs: these are some of the topics we will investigate.

However, none of these have any meaning if a good foundation of UI development principles and practices is not embraced in a project. The workshop also aims to instil a number of important principles and practices that is a must for any good GUI development team.

I’m also giving away more detail here (I still have to finalize the content and outline, will add that to our website later):
A) discussion of frustrations & issues with “traditional” approach to GUI development using something like RCP/Swing
[interactive discussion]
B) exploration of alternatives:
* Tools (e.g. SWT Designer, Eclipse e4, etc)
* UI DSLs (e.g. Glimmer, Gryphon, XScalaWT)
* Code Generation (e.g. XText, ANTler)
[I want to demo some of the options, and allow for practical hands-on use of at least one. My current idea is that we divide in groups, and each develop a UI DSL, using something like XText, or a more dynamic language like Scala]
C) Discussion of Practices and Principles when doing GUI development, including:
- UI Design
- UI Testing
- Tool (in)dependency
- Domain Driven UIs
[This discussion will also involve a whiteboard/interactive design session (also done in groups).]

And all this will be taking place on 1 July 2010 at my new training and agile office venue in Worcester (or if the group gets to big, we’ll move to an extremely nice country lodge nearby).

Please see our training website for more details.

Tagged with:
May 27

I have been doing a lot of work around renewing my Java courses, talking to Heinz Kabutz in Crete, creating a new website.
Why?
Because I realized I have a passion for teaching others how to become great programmers. So am starting to concentrate more on training (while still doing enough real development work to keep the balance).

I am very excited to announce three new open Java courses that are going to be presented in June/July in South Africa by me.

First we have the Java and OO Foundation course, from 14-15 and 17-18 June 2010 (16th is Youth Day), happening in Worcester, South Africa, at our new training facility there. I can recommend this course to anyone starting out with OO and Java. Most of the content comes from my friend Heinz Kabutz’s JavaSpecialist Java Foundation course.

Then we have our first presentation of the Java Intermediate Course happening from 5 to 8 July, also in Worcester. I can recommend this course to developers who are comfortable with the basics of the Java language and OO, and who wants to learn more about real life Java topics like using JUnit, concurrency, generics and annotations.

Finally we have another big first for Africa: the first presentation of the now famous Java Specialist Master Course, from 13 to 16 July 2010. All those Soccer World Cup fans out there: stay a week longer in South Africa and come attend this brilliant course, authored by Heinz Kabutz.

I am extremely excited about our new training facilities in Worcester, which we call “The Loft @ PolymorphHQ”. Worcester is only about 100km away from Cape Town, a very scenic drive over the mountains. I am planning to combine all courses presented in Worcester with a bit of wine-tasting or even game-drive experiences. We are also investigating providing special packages that include accommodation. And we will definitely work in a nice steak and some good red wine with great Java discussions one of the evenings of the course.

I also want to announce our The Loft opening special: if you register for both the Java and OO Foundation (14 June 2010) and the Java Intermediate (5 July 2010) courses, you save R7,000.

I hope to have a lot of great Java developers coming out of Worcester these next few years :-)

Tagged with:
Jan 14

If you:

  • are a fast and willing learner
  • are passionate about developing quality software
  • are self-disciplined and self-motivating
  • tired of the typical city and office life
  • need more flexibility in your working day
  • have experience in Object-oriented development
  • have experience in Java (acronyms optional)
  • are willing to either move to Worcester or work remotely with regular visits to Worcester

Then we:

  • want to talk to you about contracting or permanent employee options
  • want to provide training and mentoring
  • want to make you part of a newly founded team that has the goal of becoming the leading Southern Africa Eclipse RCP/RAP and OSGi development team
  • want to expose you not only to exciting new software projects, prototyping, and technology research, but also to interesting consultation opportunities, and unfortunately a bit of less interesting maintenance work

Email us at: jobs@richclientgui.com

Tagged with:
Jun 03

This is the third part of my blog series on the Eclipse Commands framework. Please see Part One for an outline of topics covered in the various blogs.

Limiting visibility of Commands

A powerful feature of the Commands framework is that you can declare in the plugin.xml when a Command should be visible (or rather when specific menu contributions should be visible) and when it should be enabled. This is done by using what is called core expressions.


Simple visibleWhen definition

Let us take a simple example first: we want to limit the Annotate eBook command (from the example in Part Two: Quick Review) to only show in the context menu if one item is selected in the view. If no item is selected, or more than one, it must not appear in the menu.

  • First select the popup:org.eclipse.ui.popup.any?after=additions menu contribution extension element
  • Now select the Annotate command element, right-click and choose New -> visibleWhen
  • Set the checkEnabled value to false (setting to true will use the enabled state of the command to determine the visibility)
  • Right-click on the visibleWhen element, and choose New -> with
  • Set the variable attribute to “activeMenuSelection“. “activeMenuSelection” is a known expressions variable that will get resolved when the platform must populate the context menu. Se the list of other known expression variables.
  • Right-click on the activeMenuSelection(with) element and choose New -> count
  • Set the value attribute for count to “1“.

    We have now set up the context-menu contribution to only show the Annotate command when one and only one item in the view is selected. That was not so difficult, was it? I remember spending hours on creating nice selection behaviour helper classes for IActionDelegate-based frameworks, and still not getting the initial visibility or enabling of the actions in the menus right, due to constraints with that approach.

    The menu contributions extension in the plugin.xml now looks like:



       <extension
             point="org.eclipse.ui.menus">
          <menuContribution
                locationURI="menu:file?before=quit">
             <command
                   commandId="com.richclientgui.myreader.commands.OpenEBook"
                   mnemonic="O"
                   style="push">
             </command>
             <command
                   commandId="com.richclientgui.myreader.commands.AnnotateEBook"
                   mnemonic="A"
                   style="push">
             </command>
          </menuContribution>
          <menuContribution
                locationURI="popup:org.eclipse.ui.popup.any?after=additions">
             <command
                   commandId="com.richclientgui.myreader.commands.AnnotateEBook"
                   label="Annotate"
                   mnemonic="A"
                   style="push">
                <visibleWhen
                      checkEnabled="false">
                   <with
                         variable="activeMenuSelection">
                      <count
                            value="1">
                      </count>
                   </with>
                </visibleWhen>
             </command>
          </menuContribution>
       </extension>



    Expression Definitions

    Before I delve more deeply into even more interesting visibleWhen capabilities, first a very nifty tip on core expressions: it is possible to declare a specific expression definition, and then just refer to that definition from your visibleWhen, activeWhen, etc elements.

    We do this with the org.eclipse.core.expressions.definitions extension. To define an expression that checks that only one item is selected:

  • Add the org.eclipse.core.expressions.definitions extension (click Add… on Extensions tab of plugin manifest editor, you might need to uncheck the “Show only extension points from the required plug-ins” checkbox)
  • Give a proper id to your definition, e.g. expression.onlyOneItemSelected
  • Right-click on the expression.onlyOneItemSelected element and choose New -> with
  • Set the variable attribute to “activeMenuSelection“.
  • Right-click on the activeMenuSelection(with) element and choose New -> count
  • Set the value attribute for count to “1“.

    You might have noticed it is the same steps as those followed for a simple visibleWhen definition above.
    For those who rather do it directly in the plugin.xml, here is the org.eclipse.core.expressions.definitions extension declaration:





       <extension
             point="org.eclipse.core.expressions.definitions">
          <definition
                id="expression.onlyOneItemSelected">
             <with
                   variable="activeMenuSelection">
                <count
                      value="1">
                </count>
             </with>
          </definition>
       </extension>


    How do I use the expression definition?

    What do you gain with first defining an expression? Well, you can reuse this definition in multiple places in your plugin.xml if you need the same expression, whether it is for a visibleWhen, activeWhen or enabledWhen declaration.

    To replace our expression for our context menu contribution with the definition, you simply do the following:

  • Select the activeMenuSelection(when) element under the popup:org.eclipse.ui.popup.any?after=additions menu contribution’s visibleWhen element, right-click and select Delete
  • Right-click again on the visibleWhen element and choose New -> reference
  • Set the definitionId attribute to expression.onlyOneItemSelected (i.e. the id of the expression definition you want to use to evaluate whether the menu contribution must be visible or not)

    If you run the application now, it should still behave the same as before we used our own definition, but now we are ready for a much more complex playing field. Underneath is a screenshot of how the extension declarations should look in the Plugin Editor.

    Extensions Commands 4


    To infinity and beyond: the power of expressions

    We have seen a very basic expression up to now. You should have seen a number of other possible items to choose from when you selected New -> with in the steps above. I list them below. These can all be used to build up complex expressions that gets evaluated at runtime to determine whether a specific menu contribution should be visible or not, if used in conjunction with a visibleWhen element.
    Possible Expression Elements

    Element Description
    adapt Use to adapt the object in focus (i.e. the object passed to the expression) to the specified type. See Using adapt for more information.
    and AND the results from evaluating the sub-elements
    count Use to count the number of elements in a collection. The value attribute be an integer or a supported wildcard. See Using count for more information.
    equals Use to check equality of the focussed object with the specified value attribute
    instanceof Use to perform an instanceof check on the object in focus. See Using instanceof for more information.
    iterate Use to iterate over a collection, if the focussed object is of type java.util.Collection. See Using iterate for more information.
    not NOT the results from evaluating the sub-elements
    or OR the results from evaluating the sub-elements
    reference This is the element we use to refer to an expression defined under org.eclipse.core.expressions.definitions. The definitionId is the unique id of the expression definition to use for the evaluation.
    systemTest Use to test a system property, where property is the name of the property to get via System.getProperty, and value is the expected value to test against (as String value).
    test Use this element to test the value of a specific property on the focussed object. See Using test for more information.
    with Use to change the object to inspect or focus on to the object referenced by the variable attribute. See the list of available expression variables.
    resolve Resolve does almost the same as with, but it allows the use of a custom IVariableResolver, and passing the specified args as arguments to the variable resolver. More detail might be topic of a future blog post. I must admit, I have never used this one.

    Note on String values

    The value attribute for the above elements gets specified as some string. Here follows the extract from the Eclipse online help on how that String value might get converted:

    When specifying a value to be tested against any of these expressions, the value is assumed to be a string except for when the following conversions are successful:

  • the string “true” is converted into Boolean.TRUE
  • the string “false” is converted into Boolean.FALSE
  • if the string contains a dot, the interpreter tries to convert the value into a Float object
  • if the string only consists of numbers, the interpreter converts the value into an Integer object
    the conversion into a Boolean, Float, or Integer can be suppressed by surrounding the string with single quotes.


    Using adapt

    Adapt is used to adapt the object in focus (you can see this as the object provided or specified by the parent element) to the type specified its the type attribute. Any sub-elements of the adapt element will be evaluated against the adapted object. Read up about IAdapterFactory and IAdaptable interfaces for more information about adaption.
    If the object can be adapted, the adapt evaluate to true. E.g. we can define an expression for evaluating if something adapts to the ICountable interface.





       <extension
             point="org.eclipse.core.expressions.definitions">
          <definition
                id="isCountable">
             <adapt
                   type="org.eclipse.core.expressions.ICountable">
             </adapt>
          </definition>
       </extension>



    Using instanceof

    This is used to perform an instanceof check on the object in focus. We can for example enhance our Annotate eBook menu contribution in the File menu to only display if at least on of the selected items is an instance of java.lang.String (iterate gets discussed here):





       <extension
             point="org.eclipse.ui.menus">
          <menuContribution
                locationURI="menu:file?before=quit">
             <command
                   commandId="com.richclientgui.myreader.commands.OpenEBook"
                   mnemonic="O"
                   style="push">
             </command>
             <command
                   commandId="com.richclientgui.myreader.commands.AnnotateEBook"
                   mnemonic="A"
                   style="push">
                <visibleWhen
                      checkEnabled="false">
                   <with
                         variable="selection">
                      <iterate
                            ifEmpty="false"
                            operator="or">
                         <instanceof
                               value="java.lang.String">
                         </instanceof>
                      </iterate>
                   </with>
                </visibleWhen>
             </command>
          </menuContribution>



    Using iterate

    Iterate can be used if the object in focus is a java.util.Collection (e.g. when with is used in the parent element and the variable attribute is set to “selection“). It iterates through the collection, and evaluate the sub-elements against each item in the collection.

    The operator attribute can be set to and or or. For and, every item must cause the sub-elements of the expression to evaluate to true, and for or, at least one must evaluate to true.

    The ifEmpty attribute can be set to true or false. If true, then the iterate expression will evaluate to true for empty collections, else to false.

    See the example under the instanceof section.


    Using count

    The count element’s value attribute can take an integer value as parameter if the collection needs to contain the exact number of items. However, the following wildcards are also allowed:

    * Any number of items
    ? Zero or one item
    + One ore more items
    ! No items

    See our first simple visibleWhen example for usage.


    Using test

    Test can be used to evaluate the state (i.e. value) of a specific property of the focussed object. The test expression can evaluate to true, false or not-loaded if the property tester (implemented by a Java class) is not loaded.

    property specifies the name of the property of the object to test
    args specifies additional arguments to pass to the property tester
    value the value we expect the property to be
    forcePluginActivation if this is set to true, the plugin that contributes the property tester class will be loaded to enable the evaluation, if it is not loaded yet. However, this loading will only happen if the evaluation context used allows plugin activation. What does this mean: do not depend that when you set this flag to true, the plugin containing the property tester code will actually be loaded.

    In a future blog I will discuss how to implement your own property testers; quite a powerful feature. For now, let me just point you to some property testers available for your enjoyment. You can follow the links for the detailed code level information, or else have a look at the Propery Testers section in the Command Core Expressions wiki page for a summary.

  • PlatformPropertyTester
  • ResourcePropertyTester
  • FilePropertyTester
  • ProjectPropertyTester
  • ResourceMappingPropertyTester
  • ActivityPropertyTester
  • OpenPerspectivePropertyTester


    Core Expression Variables

    I was planning to list the most common variables available for core expressions here and discuss some of them, but time caught up with me. For now I will point you to:

  • The Variables and the Command Framework section in the Command Core Expressions wiki page.
  • The ISources.java file that list these variables.

    Note: if you use the selection variable, you need to make sure the View that you are expecting a selection from is a SelectionProvider for the platform by registering it as a selection provider, e.g. by calling getSite().setSelectionProvider(viewer).

    Coming soon…

  • What about enabling and disabling Commands? (enabledWhen, activeWhen)
  • More on using object properties to determine visibility and enablement of Commands (propertyTesters)
  • If you don’t like XML: how to tune your Commands from the Java side of things (the programmatic approach)

    References

  • Eclipse.org Commands Framework Article in bugzilla
  • Article on Eclipse Commands Framework, by Marc R. Hoffmann
  • Eclipse.org Wiki on Command Framework
  • Eclipse Commands Tutorial, by Lars Vogel
  • Eclipse.org Wiki on Core Expressions
  • Eclipse.org Wiki on Menu Contributions
  • Eclipse.org Wiki on mapping from old to new menu contribution extension points

    Enough said.

  • Tagged with:
    Jun 01

    When faced with a bulky problem…
    When faced with a bulky problem...

    you have to start digging.
    you have to start digging

    Thanks to Aslam Khan for planting the term “archeology of Java” in a discussion.

    Tagged with:
    Jun 01

    Quick Review: Defining a Command

    In this blog I just want review the basic definition of a command by adding an additional Command to the example application using the steps defined in Part Two of the series on Eclipse RCP Commands.

    We already have an Open eBook command that we made visible in the File menu of the MyReader application. Now we want to another item to the File menu, as well as to a context menu, to allow the user to annotate an eBook. Let us call this the Annotate eBook command. So let us follow the same eight steps we did for the Open eBook command.

    Step 1: Create RCP application

    Done already (I assume you are working from the example in Part Two.)

    Step 2: Add org.eclipse.ui.commands extension to plugin.xml.

    Done already. (see step 2 of previous blog)

    Step 3: Declare Annotate eBook command.

  • right-click the org.eclipse.ui.commands extension, and select New -> Command from the context menu.
  • change the id to something like “com.richclientgui.myreader.commands.AnnotateEBook
  • change the name to “Annotate eBook
  • change description to “Annotates the current eBook

    Our plugin.xml now contains the following entry for the org.eclipse.ui.commands extension:





    <extension
    point="org.eclipse.ui.commands">
    <command
    defaultHandler="com.richclientgui.myreader.handlers.DefaultOpenEBookHandler"
    description="Open an eBook file for reading"
    id="com.richclientgui.myreader.commands.OpenEBook"
    name="Open eBook">
    </command>
    <command
    description="Annotates the current eBook"
    id="com.richclientgui.myreader.commands.AnnotateEBook"
    name="Annotate eBook">
    </command>
    </extension>


    Step 4: Add the org.eclipse.ui.menus extension to plugin.xml.

    Done. (see step 4 of previous blog)

    Step 5: Add the menuContribution element

    We want to make our Annotate eBook command accessible both in the File menu, and in the context menu of the view. We already declared a menuContribution for the File menu (see step 5 of previous blog).
    In order to make the command accessible in any context menu, we add a new menuContribution:

  • Right-click the org.eclipse.ui.menus extension, and select New -> menuContribution from the context menu
  • Change the locationURI to popup:org.eclipse.ui.popup.any?after=additions

    Step 6: Add the Annotate eBook command to the menuContributions.

  • Right-click on the menuContribution created in step 5, and select New -> command from the context menu.
  • Change commandId to the id you provided to your Command definition in step 3.
  • Change mnemonic to “A” to underline the first letter of “Annotate” as your shortcut mnemonic for your command in the menu.
  • Repeat the above for the menu:file?before=quit menuContribution element.But now we have an interesting problem: the client wants the menu item in the File menu to read “Annotate eBook“, but the context menu’s item must read only “Annotate“. If we change the name attribute of the command definition, then it will change in both places. Luckily, the Commands API can help us out here. It is possible to change the presentation of commands for specific menu contributions by “overriding” the text to be used for labels and tooltips. To do this we:
  • Select the command contribution element under the popup:org.eclipse.ui.popup.any?after=additions menu contribution elment,
  • and change the value of the label attribute to “Annotate”.
    Our org.eclipse.ui.menus extension definition in the plugin.xml now looks like:





    <extension
    point="org.eclipse.ui.menus">
    <menuContribution
    locationURI="menu:file?before=quit">
    <command
    commandId="com.richclientgui.myreader.commands.OpenEBook"
    mnemonic="O"
    style="push">
    </command>
    <command
    commandId="com.richclientgui.myreader.commands.AnnotateEBook"
    mnemonic="A"
    style="push">
    </command>
    </menuContribution>
    <menuContribution
    locationURI="popup:org.eclipse.ui.popup.any?after=additions">
    <command
    commandId="com.richclientgui.myreader.commands.AnnotateEBook"
    label="Annotate"
    mnemonic="A"
    style="push">
    </command>
    </menuContribution>
    </extension>


    Step 7: Change command menu-item placement.

    Let’s assume we are happy with the current placement.

    Step 8: Implement a default Handler

    Let us be lazy again and implement a very basic handler that just opens a message dialog. I will go into more detail about org.eclipse.core.commands.Handler and a future blog.

  • Implement a class called DefaultAnnotateEBookHandler that extends AbstractHandler, and only override the execute(…) method to call the JFace MessageDialog class to show some information.
  • Select the AnnotateEBookCommand definition from step 3 and select the DefaultAnnotateEBookHandler class as the defaultHandler’s value.
    The code for DefaultAnnotateEBookHandler looks something like this:





    import org.eclipse.core.commands.AbstractHandler;
    import org.eclipse.core.commands.ExecutionEvent;
    import org.eclipse.core.commands.ExecutionException;
    import org.eclipse.jface.dialogs.MessageDialog;
    import org.eclipse.swt.widgets.Display;

    public class DefaultAnnotateEBookHandler extends AbstractHandler {

    public Object execute(ExecutionEvent event) throws ExecutionException {
    MessageDialog.openInformation(Display.getDefault().getActiveShell(),
    "Annotate", "For now: write in the margins of the real book.");
    return null;
    }

    }


    Where’s that context menu?

    Those of you who have actually been entering the example code, would have found out by now that there is no context showing when running the example. Why not? Well, we have not created a context menu yet for our View. Do that, open the View class created by the New Plug-in Project Wizard in step 1 of my previous blog.
    Change the code to look like this (basically adding the createContextMenu() method):





    public class View extends ViewPart {
    public static final String ID = "MyReader.view";
    private TableViewer viewer;

    //other code not shown...

    public void createPartControl(Composite parent) {
    viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
    | SWT.V_SCROLL);
    viewer.setContentProvider(new ViewContentProvider());
    viewer.setLabelProvider(new ViewLabelProvider());
    viewer.setInput(getViewSite());
    createContextMenu();
    }

    private void createContextMenu(){
    final MenuManager mm = new MenuManager("view.popupmenu");
    mm.setRemoveAllWhenShown(true);
    mm.addMenuListener(new IMenuListener(){
    public void menuAboutToShow(IMenuManager manager) {
    mm.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
    }
    });
    final Menu menu = mm.createContextMenu(viewer.getTable());
    viewer.getTable().setMenu(menu);
    getSite().registerContextMenu(mm, viewer);
    }


    If you run the MyReader application now, you should get the context menu when right-clicking in the view, proudly showing your “Annotate” item.

    Feel free to download the source code for this blog’s example.

    Next up

  • Showing commands only when you want to…

    References

  • Eclipse.org Commands Framework Article in bugzilla
  • Article on Eclipse Commands Framework, by Marc R. Hoffmann
  • Eclipse.org Wiki on Command Framework
  • Eclipse Commands Tutorial, by Lars Vogel

    Enough said.

  • Tagged with:
    May 29

    Some XCode shortcut keys I found very useful:

    Editor keys

    Key Description
    Tab Accept the current completion and jump to after it
    Escape, Control-comma, F5 Shows a pop-up list from which you can select from all the available code sense completions
    Control-period to insert the most likely completion
    Control-Slash / Shift-Control-Slash move between place holder tokens
    Cmd-/ insert comment line
    Ctrl+Left/Right Arrow Jump to previous/next word
    Command-[ and Command-] indent and unindent selected text
    Control-Command Left/Right fold and unfold the function
    Command-Shift-E expand the editor view to full height of the window

    Navigation keys

    Key Description
    Alt-Command-Up Switch between .m and .h file
    Alt-Command-Left / Alt-Command-Right Navigate among open files back and forth.
    Command-Shift-D Show the “Open Quickly” dialog for navigating to defined type or function in your project
    Control-Option-1 Show list of all project files
    Control-Option-2 Show list of members of current file
    Control-Option-3 Show list of include files
    Control-Option-4 Show list of bookmarks
    Control-Option-5 Show list of breakpoints
    Control-Shift-R Show the Console
    Control-Alt-Command-R clear the log
    Shift-Command-C Show the Class browser
    Command-= Jump to the next error in the list of build errors
    Command-Shift-F Display the multiple Find panel
    Command-O Jump to the Project tab
    Command-Shift-B Jump to the Build tab
    Command-Shift-Y Jump to the Debug tab

    Mouse tips

  • Double-click on the square brackets or parentheses to select everything between opening and closing brackets
  • Command-double click on a symbol to see the definition of a symbol
  • Option-double click on a symbol to see the documentation for that symbol

    Thanks to Adeem Basraa for his shortcuts list that helped me find my way around XCode and was a reference for this quick blog.

  • Tagged with:
    May 27

    This is my second blog about the Eclipse Commands framework, but actually the first one containing useful (I hope) information. I’m going to focus on the topic from a practical “using it in development” point of view, trying to keep the examples as simple as possible and the theory limited. For an updated outline please refer to the first blog in the series: Eclipse RCP Commands Part One.

    Short history: the Commands framework has been around partially since Eclipse 3.0, maturing over the versions until it became quite useful in Eclipse 3.3. Some refinements in Eclipse 3.4 makes it even more appealing. I must admit, before Eclipse 3.3 I saw no reason for using Commands, and I stuck to using IActions and IActionDelegates, trying to work around their issues as much as possible (and falling into the rythm of the copy-and-paste anti-pattern in order to contribute an IActionDelegate to multiple places in a UI). No I’m trying to convince all my clients to “renew” their code to use Commands…

    What are Commands

    A command is neither the presentation nor a particular behavior implementation; it is an abstract representation of some semantical behavior.” – Marc R. Hoffmann (see Article on Eclipse Commands Framework)

    That’s the best quote I could find as to what a Command is. What does it boil down to? I assume (hope?) you are all familiar with the Model-View-Controller pattern, used especially when developing UI applications. By abstracting a particular piece of functionality into separate Model, View and Controller objects, the code is must less coupled, allowing more (and easier) reuse, flexibility and extensibility.

    Well, the Command design is not exactly MVC, but it has the same goals in mind. It abstracts the actual business or application semantics (i.e. what is actually meant to happen from business or application functionality perspective) into this thing called a Command. Worries about how it should appear in the UI (menu contributions), or what exactly must happen on a code implementation level to execute the command (handlers) is left for later. In this way we get the same decoupling of presentation and implementation as with MVC, and thus the gain in reusability of Commands and their handlers, and increase in the flexibility and extensibility of the code, thus leading overall to code that is much easier to maintain.

    Add to the above paragraph that code that is easier to maintain leads to huge development cost savings, and you’ll have a convincing argument to offer to your boss for allowing you to refactor away all the old IActionDelegates.

    Ok, but what to we do with Commands?

    Plain and simple: we use it to implement functions that our application can perform and make it available as menu or toolbar items so the user can invoke it.

    On a more practical level

    That is about enough theory for one day. Let’s get down to the bits and the bytes.

    The Example

    Firstly, I want to introduce my patent-pending idea for an application. Image this: you have this cross-platform application (obviously implemented using Eclipse RCP) that can actually read electronic versions of books, that we can call “e-books”. “Wow!” you say. “Amazing”. “What a novel idea”.

    Let us call our bleeding edge application MyReader. You can download the source code for this blog’s version of the example.

    Step 1: Create a RCP application using Eclipse 3.4 (I’m using 3.4.1) and the New Plug-in Project wizard.

  • Name the project MyReader
  • On the next wizard page fill in the details you want, but make sure “Would you like to create a rich client application” is set to “Yes“.
  • On the third wizard page, select the “RCP application with a view” as the template to use.
  • Run the resulting RCP application to make sure it runs, so you don’t blame my examples later for messing up your pristine code.

    Now we have the example application that we are going to enable with Commands. Exciting, isn’t it?

    How to define a Command

    To have a command that is actually accessible in the UI, and able to do something, we need 3 “components”:

  • The Intent: the Command declaration
  • The Presentation: the menu contribution declaration(s)
  • The Behaviour: the Handler that implements the behaviour of the Command

    Declaring the Command (Intent)

    We declare the Command using the org.eclipse.ui.commands extension point. I’m sure you remember this command we declare indicates the meaning or intent of the functionality we want to add to our application or plugin.

    Let us explore this Command declaration in our example, and then I’ll discuss what is going on.
    We need to open an ebook file with our application, so we will define a command to do this.

    Step 2: Add the org.eclipse.ui.commands extension to our plugin.xml

  • Open the PDE-Editor (Plugin Editor), if it is not open already, and select the Extensions tab. (You double-click the plugin.xml or MANIFEST.MF files in the project. However, if you did not know that, you must maybe first implement a “Hello RCP World” application before jumping to Commands…)
  • If, due to random bit-changes caused by unexplained solar activity, you already have the org.eclipse.ui.commands extension in your list of extensions, then do not follow the rest of this step.
  • Click on the “Add…” button.
  • Start typing in “org.eclipse.ui.commands“, and select it from the filtered list when you see it. If it is not available uncheck the “Show only extension points from required plug-ins” option.
  • Select the Finish button. This will add the org.eclipse.ui.commands entry to your plugin.xml file.

    Step 3: Declare the Open File command

  • right-click the org.eclipse.ui.commands extension, and select New -> Command from the context menu.
  • change the id to something like “mydomain.myreader.commands.OpenEBook
  • change the name to “Open eBook
  • change description to “Opens an eBook file for reading
  • for now, ignore the rest

    Steps 2 and 3 updates the plugin.xml file of the plugin project by adding the necessary extension point and declaring a basic command. The plugin.xml file now contains:






       <extension
             point="org.eclipse.ui.commands">
          <command
                description="Open an eBook file for reading"
                id="com.richclientgui.myreader.commands.OpenEBook"
                name="Open eBook">
          </command>
       </extension>


    Congratulations! Your first command.

    “But if I run my app, I don’t see this command. What’s wrong?” Nothing. We still need to define how this command will be visible in the UI, and what the behavior should be when this command is invoked. As mentioned earlier, these are decoupled from the Command declaration.

    However, let us first examine the declaration in the plugin.xml. The org.eclipse.ui.commands extension allows us to declare, among other things, a Command. The Command definition needs the following attributes:

    id a unique id that will be used for referring to this command when declaring the UI contributions and Handlers
    name a user-readable name that will be used for the label in the menu contribution(s), if the menu contribution does not define its own label
    description a user-readable name that will be used for the tooltip in the menu contribution(s), if the contribution does not define its own description

    We are still going to have a look at some of the other attributes available. If you can’t wait, go and see org.eclipse.ui.commands for more detailed information about the extension point definition. Go on, don’t mind me.

    Note: here we had a look at how to declare commands using the extension point in the plugin.xml file. In a later blog I plan to discuss how to do it programmatically. I will update this section with a link to that blog as soon as it is available.

    Basic menu contribution (Presentation)

    It is time to get his command to be presented in the UI of the application. I assume you have already done some nice UI design work sessions with your potential end-users and you are ready to build the ultimate user friendly intuitive graphical user interface for your application. For our example we are just going to use the UI-design-by-coincidence approach and just add our stuff and see how it looks.

    In order to contribute an item that will invoke a Command to the UI, we need to add the org.eclipse.ui.menus extension to our plugin.xml, and declare a MenuContribution element followed by a Command element.

    We first declare where (i.e. the main menubar or toolbar, or a view or editor specific menu and/or toolbar, or a context menu) the command should be added via the MenuContribution. Then we declare the visual representation of our Command using the MenuContribution’s Command element.

    Step 4:Add the org.eclipse.ui.menus extension to plugin.xml

  • Click on the Add… button in the Plugin Editor.
  • Select the org.eclipse.ui.menus extension from the list of available extensions. If it is not available uncheck the “Show only extension points from required plug-ins” option.
  • Select the Finish button. This will add the org.eclipse.ui.menus extension to the plugin.xml file.

    Step 5: Add the MenuContribution element

  • Right-click the org.eclipse.ui.menus extension, and select New -> menuContribution from the context menu
  • Change the locationURI to menu:file?after=additions (don’t worry, we’ll discuss it just now)

    Step 6: Add the Command to the MenuContribution

  • Right-click on the menuContribution created in step 5, and select New -> command from the context menu.
  • Change commandId to the id you provided to your Command definition in step 3.
  • Change mnemonic to “O” to underline the first letter of the “Open” as your shortcut mnemonic for your command in the menu.

    I’m sure you are eager to run your MyReader app now. Go ahead, please. Do you see it? A grayed-out Open eBook menu-item just underneath Exit in the File menu.
    First Menu Contribution with grayed-out Open eBook Command

    That is not quite what we intended. We’ll get there, though. First a discussion on what we actually did.

    We first needed to add the org.eclipse.ui.menus extension to our plugin, and then we declared that we want to contribute an item to a menu via the MenuContribution element. We only had to specify one attribute: the locationURI. More on that in the next section.

    We then declared that we are actually contributing a Command item as part of our MenuContribution. This is not the actual definition of a Command, but just an element indicating that we wish to represent the command with the identifier specified in commandId as an item in the menu or toolbar that we are declaring this MenuContribution for. Thus by specifying the locationURI “menu:file?after=additions” and the commandId “com.richclientgui.myreader.commands.OpenEBook” we are saying that we want the OpenEBook command to display in the standard File menu after the additions placeholder.

    The mnemonic attribute indicates what character should be underlined and act as a shortcut key for selecting the menu item, if that menu is currently open. Other additional attributes can be specified to manage the presentation of the Command in the menu, e.g. the icon, label (overriding the value set in the Command’s name attribute), tooltip (overriding the value set in the Command’s description attribute), etc. This gives us the flexibility to present the same Command slightly different depending on where it gets contributed, something that is not possible with IActions and IActionDelegates.

    LocationURI

    The locationURI is an interesting attribute: it allows the developer to use a URI string to specify where a specific contribution (whether it is a command item, a submenu or some other widget that can be contributed) must be added. It is of the form:
    [scheme]:[id]?[placement arguments]

    scheme The scheme indicates the type of the target component of the contribution, and can be one of:

  • menu : either main menu or view menu
  • toolbar : either main toolbar or view toolbar
  • popup : context menu
  • id The unique identifier of the menu, toolbar or context (popup) menu where the contribution must be added. See the list below for standard platform identifiers that can be used.
    placement The arguments helps to define the placement of the contribution items in relation to another item or placeholder (i.e. GroupMarker) in the target menu. It consists of either the word “before” or “after” followed by an equal sign (=) and then the identifier of a menu contribution item. The word “additions” can also be used in place of an identifier. Contributions added to “additions” will typically be placed last in a menu.

    Talking in detail about the locationURI and menu contribution placement can be a long blog entry on its own, so I want to come to this subject in more detail later in the series.

    Note: I usually declare my view’s identifier as the same as the fully qualified Java class name of the ViewPart implementation class, and then use the convention viewID.menu, viewID.toolbar and viewID.popup as identifiers for its various menus. E.g. a View implemented in the class com.richclientgui.myreader.BookView will have the Id com.richclientgui.myreader.BookView and the menu IDs com.richclientgui.myreader.BookView.menu, com.richclientgui.myreader.BookView.toolbar and com.richclientgui.myreader.BookView.popup.

    Platform Menu IDs

    Some standard identifiers are available for commonly used menus and toolbars:

    ID Description
    org.eclipse.ui.main.menu the main Eclipse application menubar
    org.eclipse.ui.main.toolbar the main Eclipse application toolbar
    org.eclipse.ui.popup.any contributions using this identifier will be visible in all context menus of the application (well, that’s not the full truth, but that is a topic for another blog)
    menu:file three guesses what menu this one point to…
    menu:help I’m not even going to say its a menu, and you only get one guess
    menu:window Ok, you start to get the picture
    helpEnd name of group-marker at end of Help menu
    quit id of Exit action

    See IIDEActionConstants and IWorkbenchActionConstants for more useful identifiers.

    I can’t wait to move that Open eBook item to the top of the menu…

    Step 7: Change Command menu-item placement

  • Select the menuContribution element we specified in step 6.
  • Change the locationURI to be menu:file?before=quit

    Running our latest version gives us a still grayed-out item, but at least where we want it.

    Open eBook Command in right place

    And our plugin.xml has grown a bit:






       <extension
             point="org.eclipse.ui.commands">
          <command
                description="Open an eBook file for reading"
                id="com.richclientgui.myreader.commands.OpenEBook"
                name="Open eBook">
          </command>
       </extension>
       <extension
             point="org.eclipse.ui.menus">
          <menuContribution
                locationURI="menu:file?before=quit">
             <command
                   commandId="com.richclientgui.myreader.commands.OpenEBook"
                   mnemonic="O"
                   style="push">
             </command>
          </menuContribution>
       </extension>


    Now to implement the behaviour.

    Simple Handler (Behaviour)

    After all this build-up, it is quite simple to actually add behaviour to a Command. You need to

  • implement a class that extends org.eclipse.core.commands.AbstractHandler,
  • and update your Command’s defaultHandler attribute that you left empty in step 3.

    Step 8: Implement a default Handler

  • Implement a class called DefaultOpenEBookHandler that extends AbstractHandler, and only override the execute(…) method. I just added a call to the JFace MessageDialog class to show some information. I will discuss these Handler classes more in a future blog in the series.
  • Select the OpenEBookCommand definition from step 3 and select the DefaultOpenEBookHandler class as the defaultHandler’s value.

    Here is my DefaultOpenEBookHandler class:






    package com.richclientgui.myreader.handlers;

    import org.eclipse.core.commands.AbstractHandler;
    import org.eclipse.core.commands.ExecutionEvent;
    import org.eclipse.core.commands.ExecutionException;
    import org.eclipse.jface.dialogs.MessageDialog;
    import org.eclipse.swt.widgets.Display;

    public class DefaultOpenEBookHandler extends AbstractHandler {

      public Object execute(ExecutionEvent eventthrows ExecutionException {
        MessageDialog.openInformation(Display.getDefault().getActiveShell(),
            "O no!""I'm not ready yet. Go read the hardcopy book.");
        return null;
      }

    }


    If you run the application now, you will actually see that the command item in the menu is enabled, and you should see a dialog with a message if you select the item.
    Open eBook Command shows dialog

    The Sum of the Parts

    We saw a basic introduction of how to:

  • declare a Command
  • contribute that command to the main menu-bar
  • define a class that encapsulated the behaviour of the Command

    Each of these components on their own does not add value to an application, but together it forms a powerful yet flexible and very maintainable Commands framework, far superior to using IActions and IActionDelegates because of the separation between the intent, presentation and behaviour.

    Summary of Steps

    Step 1 Create sample RCP application
    Step 2 Add the org.eclipse.ui.commands extension to our plugin.xml
    Step 3 Declare the Open File command
    Step 4 Add the org.eclipse.ui.menus extension to plugin.xml
    Step 5 Add the MenuContribution element
    Step 6 Add the Command to the MenuContribution
    Step 7 Change Command menu-item placement
    Step 8 Implement a default Handler

    You can download the source code for this blog’s version of the example.

    Next Episode

    Do not miss out on the next exciting episode on Eclipse RCP Commands. There I’ll be tackling mind-blowing topics, like

  • how to show commands only when you want to
  • how to disable commands
  • dynamic menu contributions
  • handling the Handlers
    (Time and weather permitting.)

    References

  • Eclipse.org Commands Framework Article in bugzilla
  • Article on Eclipse Commands Framework, by Marc R. Hoffmann
  • Eclipse.org Wiki on Command Framework
  • Eclipse Commands Tutorial, by Lars Vogel

    Enough said for now.

  • Tagged with:
    preload preload preload