It’s been quiet around here – what have I been up to?

Well it has been very quiet on my front both on the blogging side and on twitter. I’ve not been lazy but just have had a lot of stuff on my plate the last couple of months. It all started with a very productive trip to Japan and following that AusLUG to catch up with friends and speak at that user group. Businesswise Japan was especially great and we have hooked up with a new OnTime partner out there. Axcel Coporation is our new spearhead into the Japanese market and they are making great progress and already have an ontimesuite.com-like website available in Japanese (ontimesuite.jp) complete with trials, support and online buying all in Japanese. Impressive.

We’ve received a lot of very nice press coverage in Japan with the latest piece coming this weekend where Mr. Muneyuki Ohkawa of IBM Lotus Japan wrote a very nice summary of OnTime Group Calendar and how he sees it in the Japanese market (Japanese: ノーツのグループカレンダー – OnTime Group Calendar, Google Translated into English: OnTime Group Calendar – Group Calendar of Notes).

Besides our Japanese venture I also spent quite a lot of time working on opening up the API for OnTime Group Calendar (more information here). Part of opening up the API has been recording videos on the usage as well as writing samples as well as completing the API Explorer I started writing in a session at BLUG. Don’t say you cannot get inspired everywhere! ๐Ÿ™‚ The API Explorer (demo.ontimesuite.com/apiexplorer) is interesting from a number of perspectives. First of all it affords easy access to the API and easily allows you to try out the API without installing it in your own environment. It’s also written as a web application without any hardcoded piece of information. Every endpoint and every operation and argument for the operations are fully dynamic and read from a JSON file allowing up to easily extend and update the API Explorer when we need to. Very nice if I may say so myself.

As if that wasn’t enough I’ve been very busy with the next release of the plugin based UI’s for OnTime Group Calendar programming a sidebar app (Team-At-A-Glance, out in beta currently), adding private group support, adding meeting and allday appointment support to the Notes 2011 UI. I’ve also completed porting the UI’s to use the newer JSON based OnTime API. Oh and of course finalizing the Japanese support in both clients by fully supporting the Imperial Calendar system. It’s all been great fun.

For the next two weeks I’m doing an IBM Connections widget project which I’m looking very much forward to. It is going to be very cool to do some web and JavaScript development and it will give me an opportunity to use my iWidget Test Harness framework which allows me to easily develop and test iWidgets without running a full IBM Connections or Mashup server – oh yeah – wrote that too… ๐Ÿ™‚

Now back to work – happy coding!!

IBM still in the lead

I was pleasantly surprised to again see that IDC for the third year running is ranking IBM as the leader for enterprise social software. As a IBM business partner we too are seeing the increased demand for this transformational software although implementation and realization of the potential is oftentimes hard in smaller companies without the budget to drive adoption with community managers or evangelists. It will be interesting to follow this market and see when and if competitors will catch up. For now – good job IBM!!

Controlling the feature install location

When installing plugins (that is Eclipse features) into Lotus Notes and you’re running a roaming environment you kind of have a problem. The problem is that the only part of the plugins that roam are the plugin settings (i.e. should the Sametime come of front on new IMs) but not the actual code for the plugin. That means that when a user roams to a new machine the plugin isn’t installed and hence the user will experience that the plugin will start installing and prompt for a restart. This is because plugins are installed in what’s termed the “user” location (ie. your workspace directory) and not in a shared location.

An alternative is to install the plugins in the “shared” location instead (on my laptop that would mean that features would go into C:Notes8frameworksharedeclipsefeatures instead of C:Notes8dataworkspaceapplicationseclipsefeatures). The “Controlling the feature install location” article from the Lotus Expeditor info center has a nice description on the 3 possible locations.

To do this you use what’s called the colocation affinity of a feature and specify that in the feature.xml describing the feature (the feature.xml can be found inside the jar-file that makes up a feature). To do this you have two options – 1) edit the existing feature.xml and set the “colocation-affinity”-attribute of the top level “feature”-tag or 2) set it using the GUI editor when you build your feature. Option 2 is for those doing their own plugins and option 1 for those changing the colocation affinity for a 3rd party plugin.

Below is a screenshot of setting the colocation affinity to “com.ibm.rcp.site.anchor.shared.feature” driving the feature to the shared location using the GUI editor in Eclipse.

Please note that installing into the shared location require read/write access in the file system for that location.

The easy way to loop an XPage managed bean

I got harassed by Nathan (hmmm his blog appears to be down just now) yesterday for not contributing to the XPages dicussions out there so I thought I’d better remedy that. A quick tip is to make sure your Managed Bean implements Iterable if it contains a list of “things” and the obvious behaviour would be to loop over these things. If you implement Iterable you simple loop on the object using the “new” for-loop (when in Java) instead of first returning a List or array and then looping that with a for- or while loop.

Below is an example of a Managed Bean (just a Java-element from 8.5.3) that implements Iterable and hence it implements the iterator() method. That method should return an Iterator for the data you want to expose. Here I just return an iterator to the underlying list.

package com.example;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import lotus.domino.Database;
import lotus.domino.Document;
import lotus.domino.Session;
import lotus.domino.View;

import com.ibm.domino.xsp.module.nsf.NotesContext;

public class PeopleLister implements Iterable {
  // declarations
  private List people = new LinkedList();

  public PeopleLister() {
    NotesContext ctx = NotesContext.getCurrent();
    Session session = ctx.getCurrentSession();
    try {
      Database db = session.getDatabase(null, "names.nsf");
      View view = db.getView("People");
      Document doc = view.getFirstDocument();
      while (null != doc) {
        this.people.add(doc.getItemValue("FullName")
          .elementAt(0).toString());
        Document docTemp = view.getNextDocument(doc);
        doc.recycle();
        doc = docTemp;
      }
    } catch (Throwable t) {

    }
  }

  public Iterator iterator() {
    return this.people.iterator();
  }

  public String toString() {
    StringBuilder b =
      new StringBuilder(this.people.size() * 25);
    for (String p : this) {
      if (b.length() > 0) b.append(',').append(' ');
      b.append(p);
    }
    return b.toString();
  }

  public String[] getList() {
    return (String[]) people
      .toArray(new String[people.size()]);
  }
}

With that in mind I can just use the bean as follows from SSJS code (e.g. a Label):

var people = new com.example.PeopleLister();
var result = "";
for (p in people) {
  if (result.length() > 0) result += ", ";
  result += p;
}
return result;

Happy coding!

http://lekkimworld.com/files/prettyprint/prettify.js

prettyPrint();

Using the IBM Connections API from other languages using custom certificates

I was reading up on some stuff in the IBM Connections REST API during the weekend and came across a post titled Using IBM Connections API in different programming languages on how to use the REST API from other languages than JavaScript from within IBM Connections. The approach there is very nice and quite valid but it fails to mention what to do if the SSL certificate of the API endpoint either isn’t trusted or isn’t certified using a “known” root certificate. In this case “known” means to the Java runtime you’re using or the runtime of any other language for that matter. Here I’m only dealing with Java though.

By default the java.net classes will not allow a SSL connections to a server using a unknown/untrusted certificate but there are ways around that. Of course the best is always to make sure that the certificate of the server may be validated by the Java keystore (including intermediate certificates) but for testing – or if you know what you’re doing – simply ignoring the certificate test can be beneficial. Below is some code showing how to configure the SSL runtime to ignore the certificate and hostname checks. The code is a static configuration method and I deem it pretty readable. The code allows *all* certificates but could pretty easily be locked down to be more restrictive if need be.

private void enableSelfSignedCerts() throws Throwable {
  TrustManager[] trustAllCerts = new TrustManager[] {
    new X509TrustManager() {
      public java.security.cert.X509Certificate[]
        getAcceptedIssuers() {
        return null;
      }
      public void checkClientTrusted(X509Certificate[] certs,
          String authType) {
      }
      public void checkServerTrusted(X509Certificate[] certs,
        String authType) {
      }
    }
 };

 SSLContext sc = SSLContext.getInstance("SSL");
 sc.init(null,
         trustAllCerts,
         new java.security.SecureRandom());
  HttpsURLConnection.
    setDefaultSSLSocketFactory(sc.getSocketFactory());

  // Create all-trusting host name verifier
  HostnameVerifier allHostsValid = new HostnameVerifier() {
    public boolean verify(String hostname,
      SSLSession session) {
      return true;
    }
  };

  // Install the all-trusting host verifier
  HttpsURLConnection
    .setDefaultHostnameVerifier(allHostsValid);
}

http://./files/prettyprint/prettify.js

prettyPrint();

IBM moving to electronic support only

Starting June 2012 customers are “requested” to start opening IBM Serbice Requests (SR) using the electronic support portal and from 2013 only electronic entry will be possible for severity 2, 3 and 4. This is in no way a surprise and makes IBM move funds from the probably costly phone based support they are offering now and probably also makes a lot more sense for supplying all the relevant information. This is all well and good so long the quality of the data entry forms are top notch. More information can be found at the announcement.

Joda Time comment

Ulrich Krause has an interesting post (Joda to the rescue) and I just had to comment on as I – probably to no surprise to many – work a lot with dates for the OnTime Suite. Ulrich is using the Joda Time library to compare two dates to see if they are on the same day by first stripping the time component which isn’t easily possible using java.util.Date. My comment is to remember that the Java Date object is just a wrapper about a UTC long so math can do the trick. Below is my comment.

While Joda Time is a great library there is an easier way to accomplish what you are trying to do. Simply remove the time component by doing a simple modulus calculation. I am not trying to be smart about it but we do this quite a lot at OnTime ๐Ÿ™‚ Code could look like so:

Date d = new Date();
long lngTime = d.getTime();
lngTime -= lngTime % TimeUnit.DAYS.toMillis(1);
Date dNoTime = new Date(lngTime);

The latter date object creation isn’t actually necessary for the comparison. An utility function could be like so:

private boolean isSameDay(Date d1, Date d2) {
  long lngTime1 = d1.getTime();
  lngTime1 -= lngTime1 % TimeUnit.DAYS.toMillis(1);

  long lngTime2 = d2.getTime();
  lngTime2 -= lngTime2 % TimeUnit.DAYS.toMillis(1);

  return lngTime1 == lngTime2;
}

Hope it helps and it helps remove the dependency on Joda Time if that’s all you’re using it for.

Day in the Life presentation with Chris Crummey

Chris is an excellent presenter and I had the pleasure of seeing him present again at the keynote at BLUG. The video runs 12 minutes and it’s an excellent overview of the IBM collaboration solutions.

[youtube https://www.youtube.com/watch?v=oCiP0e6rbq8&w=560&h=315]

Jason Fried: Why work doesn’t happen at work

Excellent TED video on why work doesn’t happen at work.

http://video.ted.com/assets/player/swf/EmbedPlayer.swf

“Jason Fried has a radical theory of working: that the office isn’t a good place to do it. At TEDxMidwest, he lays out the main problems (call them the M&Ms) and offers three suggestions to make work work.”

“Jason Fried thinks deeply about collaboration, productivity and the nature of work. He’s the co-founder of 37signals, makers of Basecamp and other web-based collaboration tools, and co-author of “Rework.””