Bob Balfe: plugin_customization.ini and Eclipse preferences

Bob has, once again, written a very nice post on his blog. This time it’s on plugin preferences and how the plugin_customization.ini file fits in and where Eclipse preferences are stored. As this is common cause of concern and questions from plugin developers and admins I wanted to point to the post.

Bob Balfe: plugin_customization.ini and Eclipse preferences

I’m on The Taking Notes Podcast episode 122

On Friday Bruce and Julian let me on The Taking Notes podcast to talk about plug-in development and how to get started with plug-in development. We also talked a bit about the RedWiki we’re writing. I think it’s a pretty decent discussion about the topic and I hope it’s a pleasant listen.

“Let’s talk Eclipse plugins! It’s not just an Eclipse thing, plugins can be used to extend the functionality of your Lotus Notes client.

Mikkel Heisterberg has been instrumental in helping developers wade through the murky waters of Lotus Notes sidebar app and plugin development for several years, through Lotusphere and user group presentations, blog articles, and onsite training. Bruce and Julian talked to him about how this plugin technology can be used and what’s going to be in the new IBM Redbook he’s been working on.”

The podcast may be found in iTunes or directly using the following link: Taking Notes Episode 122: 2010.09.24 – Sidebar, Plugins, and Notes Client Extensions with Mikkel Heisterberg

So there’s no stuff out there on plug-in development?

Well I just did a quick search on developerWorks and it gave me a lot of info. Among others were the below articles that I think look very interesting. Especially those two first ones look like something that would be of interest to a lot of people venturing into this area.

Google saves the day for Notes plugin developers

Alan Cooke (member of the Redbooks team) just pinged me on Sametime and pointed me to a greate piece of news. As you might remember Google acquired Instantiations a while back. Instantiations developed a couple of developer tools for GUI building, code analysis and UI testing. Today all our prayers had been heard and Google is making all the tools from Instantiations free!!!. How sweet is that?!

The article referenced above describes the different tools and screenshots.

The reason this is important to you as a Lotus guy or gal is that WindowBuilder Pro for SWT makes it very easy to quickly mock up or build the GUI for your SWT based plugins. You simply drag’n’drop components onto the screen to build the UI. Think of the XPages UI but for SWT components. Very nice.

So how do you get the tools? Simply head over to the respective Google page to learn more and/or install. The direct links are:

Did I mention that all the tools are now free?!?

Once you go the tool page you’ll see a link to the “Download” page in the menu on the left. The page has links to update sites for easy installation. The tools work with Eclipse 3.4, 3.5 and 3.6.

P.S.: There is also a GWT designer tool (Google Web Toolkit) available (tool page is here). The tool is very nice if you develop GWT applications.

Why I’m not using the Lotus Expeditor Toolkit

Every time I get questions on developing plugins for the Lotus Notes 8 platform I mention that I really can’t comment too much on Lotus Expeditor Toolkit installation and usage questions. The reason is that I do not use the toolkit when developing for Lotus Notes. Since I get the question so much I thought I would take it to the blog as well.

The main reason I started developing for Lotus Notes without the Lotus Expeditor Toolkit was due to two reasons:

  1. Because I kept receiving new betas of the Lotus Notes client from IBM Lotus and because XPD toolkit wouldn’t work with these betas
  2. I wanted to use newer Eclipse versions than what the XPD toolkit supported

It’s not that I don’t find the toolkit valuable but for the work I do it isn’t a requirement.

I understand why you might want to use Lotus Expeditor Toolkit as it may be considered easier (if you’re not so Eclispe savy), because you have to! or because you need to switch target platform often (Notes -> Symphony -> Sametime).

Eclipse Fall Training Series

“The Eclipse Foundation and Eclipse member companies are pleased to announce the fall 2010 training class series. The training is an excellent opportunity for software developers and architects to learn more about Eclipse Rich Client Platform (RCP), BIRT and Modeling technologies. Eclipse experts will lead the sessions, providing practical experience through classroom instruction and hands-on labs. Virtual and on-site classes have been scheduled in several countries from September 20 to November 5, 2010. “

Eclipse Fall Training Series

How to extend Notes 8: New version of the demo application

I just posted an update to the demo application for my Extending Notes 8 series of posts. The demo application is discussed in more detail in my previous post (How to extend Notes 8: LiveText demo application). The issue was that I had a button to create a demo e-mail in the UI which made the plugin depend on the Notes Java UI API which was added in Notes 8.5.1 and hence meant that the demo application wasn’t installable on previous Notes versions… 😦

To remedy that I built an new version where the button using the offending API is added from an Eclipse plugin fragment and using a custom extension point (if you’re running Notes 8.5.1+). More on that approach at a later date. For now you may install the new version using the updated widget descriptor (extension.xml) (simply drag the link to your MyWidgets sidebar plugin).

If you do an update – which there’s absolutely no reason to if it already works for you – the only way to tell is by verifying that the version number at the bottom of the sidebar application is changed to 1.0.1.

That’s all for this post. All the posts in the series may be found under the extending_notes8 tag.

How to extend Notes 8: LiveText demo application

The day before yesterday I posted the first summary post in my Extending Notes 8 series with a complete end-to-end approach to dynamically adding LiveTex recognizers. As part of that post I uploaded a demo application (plugin) but I didn’t add a screenshot so I thought I’d remedy that.

As you can see the plugin has a small welcome text and two buttons. You’ll also see a textbox to hold any exception (not that I’m expecting any) that might be raised as part of adding the recognizer and content type. You may use the two buttons to easily create a demo e-mail for use with the added LiveText stuff. The left button creates the e-mail in the UI (using the new handy Java UI classes) and the right one simply sends the e-mail to you in the backend. The latter is very handy for testing as the e-mail needs to be in read mode for the LiveText sub-system to kick in.

I’ve put a compiled version of the plugin on my update site and tthe plugin may be installed by dragging this extension.xml file to your MyWidgets sidebar panel (policy permitting).

That’s all for this post. All the posts in the series may be found under the extending_notes8 tag.

How to extend Notes 8: case insensitive LiveText patterns

When you start to do a lot of LiveText recognizers you find yourself wanting to do more advanced stuff with your regular expressions. For instance you might want to do case insensitive patterns or use some of the others regular expression modifiers. This post will show you how to do this.

By default the regular expressions you specify for your recognizers are case sensitive. This is normally fine unless you really want it to be case insensitive. Since the LiveText engine is in Java you may use the supported Java modifiers for your regular expressions. Normally the modifiers are specified when you “compile the pattern” in Java (java.util.regex.Pattern.compile(pattern, modifiers)) but as you don’t have access to this process you can’t do that.

There is however another way…

You can embed some modifiers in the pattern such as Pattern.MULTILINE, Pattern.UNICODE_CASE, Pattern.DOTALL and most of all Pattern.CASE_INSENSITIVE! You embed the modifier in the start of the pattern. So instead of doing a case insensitive pattern like this (to recognizer “lotus” and “Lotus”):

[Ll]otus

you do

(?i)lotus

Cool isn’t it?

The following modifiers are supported in Java though not all makes sense for LiveText:

  • Pattern.CASE_INSENSITIVE = (?i)
  • Pattern.MULTILINE = (?m)
  • Pattern.DOTALL = (?s)
  • Pattern.UNICODE_CASE = (?u)

Please bear in mind that it probably only makes sense to use DOTALL and CASE_INSENSITIVE.

That’s all for this post. All the posts in the series may be found under the extending_notes8 tag.

How to extend Notes 8: dynamic LiveText recognizers using Java

As I briefly described in my last post (“How to extend Notes 8: dynamic extensions using Java“) it’s possible to create new extensions to Lotus Notes using Java and hence inject functionality into the client dynamically. It’s very cool functionality and it allows you to inject anything from content types and recognizers to sidebar panels.

In this post I’ll build on three previous posts and show you how to use dynamic extensions in Lotus Notes in combination with a Java action that uses multiple capture groups for an end-to-end solution that may be deployed as a single Java extension (aka plugin). The result is a plugin that may be deployed to a client workstations which allows you to act on text recognized by the LiveText sub-system but where you have the power of Java for processing.

All the posts in the series may be found under the extending_notes8 tag.

We need three pieces of information:

  1. The code to dynamically inject our custom recognizer and content type into Lotus Notes without the need for an extension.xml file. This is what the LiveText sub-system uses to highlight the text for us.
  2. The Java action to act on the LiveText selection.
  3. The plugin.xml file to bind it all together.

The first piece is the code that injects the custom recognizer and content type under a known id. This code may be run in lots of ways but to make it easy for this example I choose a sidebar panel. Below is the createPartControl-method from that class.

public void createPartControl(final Composite parent) {
  try {
    // define XML
    final String extensionXml = ...;

    // get extension registry and load extension
    // into registry
    final IExtensionRegistry reg = Platform.getExtensionRegistry();
    InputStream ins = new ByteArrayInputStream(extensionXml.getBytes());
    Bundle bundle = Activator.getDefault().getBundle();
    IContributor contr = ContributorFactoryOSGi.createContributor(bundle);
    reg.addContribution(ins, contr, false, null, null, null);

  } catch (Throwable t) {
    t.printStackTrace();
  }
}

The above code injects the recognizer and content type with an id of DCCT.ExampleContentType.1234567890 into the client.

The next part we need is the action class (again implementing org.eclipse.ui.IObjectActionDelegate) to act on the LiveText selection. Most of the code you’ve seen before in a previous post but again it goes and get the text from the underlying document as document properties.

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.contents = null;
      this.prodFamily = null;
      this.partNumber = null;
      return;
   }

   // get data from document property
   this.contents = doc.getProperties().getProperty("contents");
   this.prodFamily = doc.getProperties().getProperty("pf");
   this.partNumber = doc.getProperties().getProperty("pn");
}

The last piece is the plugin.xml to put it all together using the org.eclipse.ui.popupMenus extension point. Notice how we use the content type id we know (bold text below) from our dynamically deployed content type.

<extension
  point="org.eclipse.ui.popupMenus">
  <objectContribution
    id="com.lekkimworld.extnotes8.dynext.objCtr1"
    objectClass="com.ibm.rcp.content.IDocumentContent">
    <visibility>
      <and>
        <objectState
          name="content.type"
          value="DCCT.ExampleContentType.1234567890">
        </objectState>
        <objectState
          name="contents"
          value="*">
        </objectState>
      </and>
    </visibility>
    <action
      class="com.lekkimworld.extnotes8.dynext.MyAction"
      enablesFor="*"
      id="com.lekkimworld.extnotes8.dynext.action1"
      label="Do me!">
    </action>
  </objectContribution>
</extension>

The result when deployed to a Lotus Notes client is something like the screenshot below where you get a Java action to act on a LiveText recognition. Only change this time is that all the functionality is provided from your plugin. No separate extension.xml is necessary for the recognizer or the content type.

That’s how it’s done. I’ve uploaded an Eclipse project to the blog so you can download it and install it in your Eclipse as a demo. You can download the project here.