Wednesday, October 16, 2013

Using Command Parameter Value Convertes with Eclipse e4

This post describes how value converters for command parameters can be used in e4.

In e4, commands can have parameters. Each parameter has a value. When you specify theses values in the application model they are all strings.

Suppose you want to pass an Integer value for a command parameter. In your handler you would like to get the value injected as an Integer instance so that you do not need to perform the conversion in the handlers @CanExecute or @Execute method.

The necessary conversion can be done by the e4 framework before the handler is invoked. Take the following approach.

Implement the converter

Create a new class that inherits from org.eclipse.core.commands.AbstractParameterValueConverter. Implement the abstract methods. These are:

Object convertToObject(String parameterValue) and String convertToString(Object parameterValue)

In the convertToObject method convert the string value of the command parameter to an instance of the type you require. For String to Integer conversion this could be done by simple calling Integer.valueOf(parameterValue). The signature of the method declares to throw ParameterValueConversionException in case the conversion fails. Create an instance of this exception and throw it in case the parameter value cannot be converted. Unfortunately, this exception is currently (Kepler 4.3.1)  swallowed in the eclipse e4 framework so you won't have any idea why things are not working. You might want to log the problem for this reason right in the converter.

Now comes the tricky part. The convertToString method does not do the reverse of the convertToObject method (I thought so at first). It is called with the string value and needs to return a string. For simple String to Integer conversion you can just return the same string that is passed to the method. You might want to treat a null value different and return the string "null" for example.

Register the  converter

In the bundle that supplies the value converter extend the org.eclipse.ui.commands extension point and add a commandParameterType.

The commandParameterType has three properties: id, type and converter.

Choose an id that is specific to your bundle name. For the type enter the class name of the objects you want to convert the string value to, e.g. java.lang.Interger. The converter property takes the fully qualified class name of the class that is called to convert the value (the one you implemented before). The class must be in a package that is exported by the bundle.

Specify the TypeID for the Command Parameter

The last step is to specify the TypeID  for the command parameter in the application model. Each command parameter has a property TypeID that usually does not need to be filled with a value. If you want to make use of the converter just registered enter the ID of the commandParameterType you registered through the extension point above. Do not enter the type of the objects you want to convert to (e.g. java.lang.Integer).

Now the command parameter values should be converted automatically. Make sure to adjust the signature of your handler methods so that they are found and called.

For debugging purposed you can set a breakpoint in org.eclipse.core.commands.ParameterizedCommand.generateCommand(Command, Map) and of course in your converter class.


Sunday, April 15, 2012

IBM ED Search for Android - Part 4

Change Indicators

A result of a search or the list of persons in a bluegroup might change over time. If you trigger a reload of the search result new persons might be added, others might be removed.

To better understand these changes the app uses change indicators. These are narrow colored lines to the left of the person picture. New persons in a search result will have a green line, persons removed will have a red line and persons where the information in the directory has changed since the last time it was loaded will have a yellow line.



It should be pointed out that persons that are no longer part of the search result will not be deleted from the device. Instead they are marked with the red change indicator. This has the following advantages:
  • If you still want to have that person record available in the app you can choose to star the person and it will be available under All Starred Persons
  • You can see who has been removed from a bluegroup
The change indicators are displayed in the person search result until they are actively confirmed. To confirm them trigger the action with the check mark icon from the action bar. After confirming the changes all indicators are removed and the persons that are no longer part of the search result (the ones that had the red change indicator) are actually deleted.

In case the change indicators are not confirmed and the search result is reloaded again new change indicators will be added to the existing ones.

Therefor, it is possible that more than one change indicator will be shown for a person. When a person was added to a bluegroup for example and later the information about that person changed in the directory a green and yellow change indicator will be shown. Likewise, when the person was first added and then later removed a green and red change indicator will appear.



Note that persons marked with a red change indicator might have left the company and are no longer in the directory. When you try to load the person details for such a person the app will display a short message that the person could not be found in the directory.

You can also apply a filter for change indicators to restrict the results shown to only new, changed or deleted persons. A future post will cover filtering.


Saturday, April 14, 2012

IBM ED Search for Android - Part 3

Shortcuts to starred search results

When the app is launched the list of starred search results is immediately visible. Touching one the entries in the list opens the search result view.

Yet, there is a quicker way to access your most often needed search result(s). This could be the list of members of a bluegroup you frequently need to access in order to call someone.

Android has the concept of shortcuts that can be placed directly on the launcher's home screen. Such a shortcut is able to launch into a specific activity in the app.

You can create a shortcut on the launcher's screen for any starred search result. Tapping the shortcut will immediately load the search result and save a little bit of time when looking up contacts.

To create a shortcut a search result must be starred and thus be available for offline use.

Each launcher has a different but similar method to create a shortcut. Usually, you can either use the menu or long press the launcher's home screen background to create a shortcut. On Ice Cream Sandwich (Android 4.x) shortcuts can also be created from the Widgets section in the app drawer.



So start to create a shortcut for the IBM ED Search app by dragging the widget to the launcher's home screen.


As soon as the widget is dropped the IBM ED Search app will open an activity to choose the starred search result for which the shortcut is to be created.

On this screen the name of the shortcut can be changed. By default, the value for the name is the same as it is shown in the list of starred search result.

There is also an option to force reloading of the search result when it is opened using the shortcut.



Customize the name if you like and decide whether the result should be reloaded and then tap on one of the entries in the list. This will create the shortcut.


For different kind of search results different icon overlays are used. A shortcut for the members of a bluegroup will have a different icon than the result for a management chain query.


Deleting a shortcut from the launcher will not in any way delete the app or the data that is stored for it.

Thursday, April 12, 2012

IBM ED Search for Android - Part 2

This second blog post will focus on the Person Details Screen

When you touch a person entry in a search result the person details screen / view will open showing more information about the person you selected. When the details screen is opened for the first time for a person the app will try to download additional information about the person (department, secretary, etc.). Once this information has been downloaded it will be persisted and will be available offline. Notice how the number of entries in the details list grows when new data is downloaded.

In case the details screen is opened and no connectivity to the directory server can be established only the information that is already loaded will be available. The next time the details screen is opened or when you trigger the reload action the app will again try to download all details.

The details screen shows the person's bluepage picture, the name, job description and a list of details. The entries in the list of details show icons that can be touched to trigger an action associated with the detail.






For example, clicking the icon to the right hand side of the department detail will trigger a search for all persons in that department. Touching the icon on the email address detail will open the email application with the email address filled in as recipient. For the primary email address there is an action to start a Sametime chat with the person. From the manager detail you can either open the details for the person's direct manager or you can search for the complete management chain. You can also dial a telephone number this way or start google maps to display the work location or start the google maps navigation.






Additional actions are available at the bottom of the screen in the action bar. You can start or reload all the information about a person for example. Reloading will also try to reload the person picture. Remember that you can long press an icon on the action bar to show a tool tip that further explains what the action will do.

Since not all available actions for a person are shown in the action bar check out the additional actions available when you press the menu button or the action overflow (depending on whether your Android device has a menu button or not). Currently these actions are "Bluepages" and "IBM Connections" which will launch the browser and open up the associated person profile in either Bluepages or IBM Connections.

Once you navigate away from the person details screen (e.g. by triggering a search for the members of the same department or the secretary information) the app will either show a list of search results in the former case or navigate directly to another person details screen in the later case. Using the back button you will return to the person details screen of the person you began with.

You can always hit the icon on the left of the upper action bar to return to the home screen to conduct a new search. If you do so the history will be cleared and the back button will no longer bring you back to the previous screen.

Long pressing / touching an entry in the details list opens up a context menu where you can choose to copy the text of the detail to the clipboard. This can be handy to copy the address for example.

Sunday, April 8, 2012

IBM ED Search for Android - Part 1

I've decided to write a series of blog posts about my Android App "IBM ED Search" to explain basic usage and some more advanced topics.

The series will use version 2.0 that will be released real soon now.

In this first post I will focus on the very basics of the application.

Let's begin...

Initial Steps and the Search UI


Version 2 makes use of the excellent Actionbar Sherlock library that makes the Android Ice Cream Sandwich Action Bar available on earlier Android versions. The UI looks and feels very similar on devices running Android 2.2 up to the latest version 4.0.

After starting the app for the first time the home screen is shown. The action bar is located at the top and includes a small magnifying glass icon on the right hand side.
A short introduction is shown below the action bar when the app is started for the first time and as long as no searches have been "starred".



In order to search the directory an https connection to the IBM Intranet must be available. Lacking a VPN connection you will need to be on the Intranet WLAN to conduct any searches.

Tapping the icon on the right hand side of the action bar will reveal the search field directly in the action bar. You can now enter the search term you want to search for.



When the search field is shown another icon is appears  to the right of the search field. Tap it to choose the search category/type. A menu will open up to let you choose among different search types like searching for people's name, serial number, bluegroup by names and some more. Pick the search type from the menu and the search field will display a hint in grey on how the search value must be formatted.



The keyboard will show a search button instead of the "Enter" key. Tap it to begin the search.

When all is well and the directory server can be reached the search result will be displayed on a new screen. All matching persons or bluegroups (depending on what type of search was chosen) will be displayed in a list.

The People Search Result Screen

The action bar now shows the search type (e.g. Name) and the search term (e.g. Hofmann, Thomas) and the number of results in brackets.

The list on this screen will include important information about the persons that match the search term, like name, email address, telephone number and job role. In addition, the bluepages person image is displayed on the left hand side.
Person pictures are not loaded along with the search result. Depending on the preferences the application will either load some, all or none of the person pictures belonging to the persons in the result after the result is already displayed.

Tap the "Load Pictures" icon in the action bar on the bottom of the search results screen to trigger the loading of missing pictures (tap and hold the action icons to see a tooltip about what they do). A progress bar at the top of the screen will report download progress.



Use the "Star" icon to "star" a search result. What this means is that you want to keep the search result's content for offline usage. Once starred, it will appear in the list on the home screen and can be recalled even without a connection to the directory server.

Touching and holding an entry in the search result will open a context menu where you can choose different actions in the context of the entry like, dialing the phone number of the person, sending an email or conducting a search for e.g. the management chain of the person in that entry. The menu is rather long. Make sure you scroll down to see every possible action.



Tap the back key to return to the home screen. As an alternative you can also tap the application icon on the top left hand side of the action bar. This will always bring you back to the home screen no matter how deep inside the application you were navigating.

Back on the home screen the introduction text is now replaced by the list of starred search results. Tap it to return to the list of persons that were included in the search result.



The context menu of an person entry in a search result also allows you to star persons. All persons starred will appear on the home screen under the "Starred Persons" list entry (which will always be the first entry). This way you can pick the ones you want to have available for offline usage and quick access.



Friday, April 16, 2010

Equinox Aspects to the Rescue - Patching non-intrusive

For my current project I implemented synchronization between Rational Team Concert (RTC) and Rational Clear Quest (CQ) using the Clear Quest Connector.

The development team uses RTC as its primary tool to work with defects and work item whereas the test team and the customer is using the CQ web client.

Due to a limitation in the CQ Connector all comments in a defect made in RTC are synched to CQ with the user ID of the CQ Connector. As a consequence, the users of the CQ web client are unable to determine who has made a comment.

I created an enhancement request which unfortunately won't be implemented.

So I thought I should roll my own solution to this problem.

Being a fan of AOP and AspectJ, I thought I could use Equinox Aspects to intercept the call where the comment is saved and simply prepend the username. In fact it was just as easy. I only needed to figure out how to use AspectJ with Equinox Aspects in my eclipse installation. The following two guides helped me:

The first thing to do was find a place in the code where I could easily apply my change. I downloaded the RTC SDK and loaded the bundles into a fresh workspace using the target definition supplied in the SDK so that I could browse and search the codebase using eclipse's features like determining call hierarchies etc.

I was looking for a (central) place that would be sufficient to intercept for all comments added. I quickly found such a place in the code in the model class com.ibm.team.workitem.common.internal.model.Comments.

The method I picked looks like this:

public IComment createComment(IContributorHandle creator, XMLString content) {
  Comment comment= ModelFactory.eINSTANCE.createComment();
  Utils.initNew(comment);
  comment.setCreator(creator);
  comment.setContent(content.getXMLText());
  return comment;
}

Looking at the call hierarchy for this method reveals that it is called from various places in the Eclipse UI and also on the server side (the REST services).



Everything I need for the modification is right there - the content of the comment and the creator. I created the following pointcut to match the code:

public pointcut createCommentMethodToIntercept(IContributorHandle creator, XMLString content, IComments comments) :
 
    execution(public IComment Comments.createComment(IContributorHandle, XMLString))
    && args(creator, content)
    && target(comments);

I am extracting the creator, the content and the comments object here.

The actual modification is done using an around advice:

@SuppressWarnings("restriction")
IComment around(IContributorHandle creator, XMLString content, IComments comments) : createCommentMethodToIntercept(creator, content, comments) {
  try {
    Comments concreteComments = (Comments) comments;
    if(shouldApply(getWorkItemType(concreteComments))) {
      ContributorImpl contributorImpl = (ContributorImpl) creator.getFullState();
      String userId = contributorImpl.getName();
      String xmlText = content.getXMLText();
      System.out.println("Original content: " + xmlText);
      content = XMLString.createFromXMLText(userId + ": " + xmlText);
      System.out.println("Replaced content: " + content.getXMLText());
    }
  } catch(ClassCastException e) {
    e.printStackTrace();
  }
  return proceed(creator, content, comments);
}

Since the modification should only affect defects that are synched to ClearQuest I am calling the getWorkItemType method which makes use of the comments object:

private String getWorkItemType(Comments comments) {
  WorkItem workItem = comments.fWorkItem;
  String workItemType = workItem.getWorkItemType();
  System.out.println("WorkItem type: " + workItemType);
  return workItemType;
}

The shoulApply method just checks a system property for a list of work item types that should be affected.

The aspect is then applied to the bundle containing the Comments class which is com.ibm.team.workitem.common by specifying the following line in the manifest file of the plug-in containing the aspect:

Eclipse-SupplementBundle: com.ibm.team.workitem.common

Basically, this is all that needs to be done.

Now, when I add a comment to a defect that gets synched to ClearQuest my name is prepended to the comment:




Of course, Equinox Aspects must be installed correctly and running the weaving hook for the aspect to be applied at runtime.

On the server side RTC also employs OSGI and bundles through a servlet bridge. Unfortunately, I wasn't able to get the aspect applied there.

Saturday, March 7, 2009

Apache and Subversion and LDAP again

I just noticed that Jeremy Whitlock updated his article on Subversion with Apache and LDAP. This might be interessting to you in case you came here for my post on the same subject.