<< How to extend Notes 8: using LiveText with capture groups | Home | How to extend Notes 8: dynamic extensions using Java >>

How to extend Notes 8: capture group LiveText recognizers with a Java action

I get so many question on how to extend Notes 8 that I finally decided to create a series of blog posts on how to do it. All the posts in the series may be found under the extending_notes8 tag. In all of the examples I assume a working knowledge of Eclipse and Java programming and how to work with extension points.

For this post I'll build on the "How to extend Notes 8: coupling LiveText to a Java action" and "How to extend Notes 8: using LiveText with capture groups" posts and show how to act on your own custom recognizer from a Java action when you have multiple capture groups.

Please note: I'll assume that you read the "How to extend Notes 8: using LiveText with capture groups" post and have it working as we'll build on that example in this post. Unfortunately as we act on the content type id you need to find the id of the content type on your system. I'll show you how.

Enough with preparations - now on to the code!

So far we have our custom recognizer and our custom content type but instead of a web widget we really want to use our Java action as the recipient of the LiveText selection. We couple the Java action to the content type using an extension point in plugin.xml based on the content type id. Let me show you how to find the content type id.

  1. Start by opening the management UI for widgets, content types and recognizers. You do this by choosing "Manage Widgets, Content and Recognizers" from the part menu in the My Widgets sidebar panel as show below.
  2. Now switch to the "Content Types" panel and make a note of the ID for the "Demo Product Number" content type. Here the id is "DemoProductNumber.1410710777" as highlighted below.
  3. Now comes the trick. Notes adds "DCCT." in front of the id shown so the real id is "DCCT.DemoProductNumber.1410710777". Make a note of your own id and read on...

As previously the first piece of the puzzle is the extension point. Add an org.eclipse.ui.popupMenus extension as previous and specify the id you noted above as the content type id. Mine is shown below - notice how I use the id prefixed with "DCCT.".

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
   <extension  point="org.eclipse.ui.popupMenus">
      <objectContribution id="com.lekkimworld.livetxt.objectContr1" 
         objectClass="com.ibm.rcp.content.IDocumentContent">
         <visibility>
            <and>
               <objectState name="content.type" 
               value="DCCT.DemoProductNumber.1410710777"/>
               <objectState name="contents" value="" />
            </and>
         </visibility>
         <action class="com.lekkimworld.livetext.MyAction"
            enablesFor="*" 
            id="com.lekkimworld.livetxt.action1" 
            label="Do stuff!" />
      </objectContribution>   
   </extension>
</plugin>

Now create your Java action class - again implemening org.eclipse.ui.IObjectActionDelegate - and specify the correct class name in the extension point.

Again when it comes to grabbing the contents of the recognized LiveText it comes down to you selectionChanged-method of your Java action. As our recognizer uses capture groups we have a few choices for the properties we can grasp from the document. As always the entire recognized product number will be in the "contents" property but we also have "pf" and a "pn" property available that holds the product family and the part number. The example code below shows how to get at these.

public void selectionChanged(IAction action, ISelection selection) {
   IDocumentContent doc = null;
   
   // cast/adapt selection
   if (selection instanceof StructuredSelection) {
      Object sel = ((StructuredSelection)selection).getFirstElement();
      if (sel instanceof IDocumentContent) {
         doc = (IDocumentContent)sel;
      }
   } else if (selection instanceof IDocumentContent) {
      doc = (IDocumentContent)selection;
   } else {
      // try and adapt
      IAdapterManager amgr = Platform.getAdapterManager();
      doc = (IDocumentContent)amgr.getAdapter(selection, 
          IDocumentContent.class);
   }
   if (null == doc) {
      this.selection = null;
      return;
   }
   
   // get all recognized content
   this.prodNumber = doc.getProperties().getProperty("contents");
   this.prodFamily = doc.getProperties().getProperty("pf");
   this.partNumber = doc.getProperties().getProperty("pn");
}

Now when you install the extension and hence put the pieces together you should see two actions for the product number LiveText recognition as shown below. The top one is our Java action and the bottom one is our web widget from previously.

That's what is required to act on custom recognizers. As you can probably gather from the above it doesn't work letting users do their own recognizers and then wanting to act on them from Java due to two reasons - 1) never trust a user to give it the right name as instructed :-) and 2) the id of the content type will change from machine as it is generated when the user creates the content type. It is possible however if you create the content type and the recognizer for users and install then using an extension.xml file as the extension.xml sets the id's. That's probably also the way you'd want it.

There is however an even better solution... Dynamically add the content type and recognizer to the client from Java for a single, combined solution. Stay tuned...




Add a comment Send a TrackBack