Monday, August 4, 2008

ALUI Best Practice - Don't Hardcode ObjectIDs: Use UUIDs Instead

In ALUI, there are 2 ways to identify uniquely an object:

  • ClassID (the type of object) + ObjectID (The ID of the object within the classID family)
  • Global UUID (unique ID throughout the environment)

The ClassID/ObjectID combination is used throughout the Portal API to query/open/manage the ALUI objects, as well as navigate to communities and pages. The ALUI ADAPTIVE TAGS are no exception: you will notice that they require ObjectID / ClassID to perform their tasks, like for example the opener tag:

<pt:standard.openerlink pt:objectid="219" pt:classid="514" pt:mode="2" target="myWindow">view community page</pt:standard.openerlink>

The main problem is not in the fact the ObjectID / ClassID is a bad way to identify an object, but in the fact that the ObjectID WILL NOT NECESSARILY (very improbable actually) be the same when you migrate objects from one environment to another. And that's where it can hurt...

Indeed good practice is to test out your creation in DEV / TEST / STAGING etc... and then migrate it using the ALUI migration tool. Since objectIDs will be different after migration in the new environment, all the objectIDs used in Adaptive Tags will have to be changed...hassle indeed.

Fortunately, UUID does NOT change with migration (or very improbable) from environments to environments. So that would seem a good option if you need to hardcode IDs, especially in Adaptive Tags, and I'd recommend that option everywhere you can.

In order to make it possible, I built a Adaptive Tags that does just this: Transform a UUID into its corresponding ClassID/ObjectID pair. All you need to do is use that Adaptive Tag before using the opener link tag for example. The object and class IDs are stored in shared memory (adaptive tag framework) with the specified scope and can be reused with any other tags that require objectID / ClassID.

<pt:taglibname.convertuuidtoid pt:uuid="{UUID}" pt:objectid="objectIDKey1" pt:classid="classIDKey1" pt:scope="portlet request" />

<pt:standard.openerlink pt:objectid="$objectIDKey1" pt:classid="$classIDKey1" pt:mode="2" target="myWindow">view community page</pt:standard.openerlink>

What's even better is that you can use this tag even for your remote portlet applications, like any other tags.

The code to change a UUID to the ObjectID / ClassID pair is fairly simple. Just get the Migration manager and call the convert method UUIDToObjectID to get the job done. I created a helper method that package it altogether:

public Object[] getClassObjectID(String uuid){
        Object[] oClassIDObjectID = null;
        if (null != uuid) {
            try {
                IPTMigrationManager oPTMigrationMgr = (IPTMigrationManager) oPTSession
                        .OpenGlobalObject(
                                PT_GLOBALOBJECTS.PT_GLOBAL_MIGRATION_MANAGER,
                                false);
                oClassIDObjectID = oPTMigrationMgr.UUIDToObjectID(uuid);
            } catch (Exception exc) {
                oClassIDObjectID = null;
            }
        }
        return oClassIDObjectID;
    }

The first item in the returned array is the ClassID (oClassIDObjectID[0]), the second item is the object ID (oClassIDObjectID[1]).

You can download the code on my newly created subversion project (http://alui-toolbox.googlecode.com) on Google code (I'll be updating/maintaining this as I see fit - feel free to suggest at will :)):

svn checkout http://alui-toolbox.googlecode.com/svn/trunk/ alui-toolbox-read-only

No more mocking around with IDs during migration :)

Hope that helps!

5 comments:

  1. http://blog.thebdgway.com/2006/09/uuid-object-opener-coolest-ali-taglib.html

    ReplyDelete
  2. Nice chris...indeed i never saw that post on your blog :)
    Yeah the code is strictly similar.

    This tag is a bit different though, as it is not rewriting an existing tags (like the opener), but acting as an adapater for all the tags that requires Object IDs...

    ReplyDelete
  3. Do you have any idea of checking the current community ID in publisher? How to egt the current community ID in publisher and display content based onit.

    ReplyDelete
  4. you can only get the community ID with an ALUI Adaptive Tag...Then using the "Choose / When / Otherwise" tags (http://download.oracle.com/docs/cd/E13174_01/alui/devdoc/docs60/References/API_Libraries/6.1MP1/index.html), you can compare the current community ID to a particular community ID and display the right content.
    The main issue is that you will have to create your own PT tag to get the current community ID since it is not part of the out of the box tags (i created such a tag if you are interested)

    ReplyDelete
  5. Where do ALUI store the UUID for objects, like authentication source, user group etc?

    ReplyDelete