Christopher Bucchere

UUID Object Opener, The Coolest ALI Taglib Yet

Written by Christopher Bucchere | Sep 12, 2006 3:52:00 PM

Anyone who's ever done a major Plumtree/ALUI deployment knows of this problem: You create a portlet or community (or any other object) in Dev and then you migrate it to Test and on to Production. The problem is that you've also written some code in your navigation portlet or in another portlet that depends on an ObjectID (e.g. you've used a pt:standard:opener tag) and now, in each environment, your ObjectID has changed and you're basically hosed.

Pre-G6, I came up with a solution described (somewhat hastily) in this post, but it requires a lot of leg work and -- worse yet -- manual configuration in each environment.

Enter G6 and the magic of taglibs. (Am I beginning to sound like a broken record? Yes, I know, you can't fix every problem with a taglib, just 95% of them, right?) With this new taglib I wrote today, I extend AOpenerLinkTag and simply convert a UUID to an ObjectID and ClassID so that you can use the same taglib invocation in every environment. I don't want to toot my own horn too much here, but honestly, this is pretty much the most useful taglib I've ever encountered, and once again, it took under 30 minutes to write.

Before I dive into the source, let me back up and say that I had to bend the rules a bit. OOTB, there are two subclasses of ATagAttribute: RequiredTagAttribute and OptionalTagAttribute. I added a third: MutableTagAttribute. It looks and smells like a tag attribute, but under the covers it's not. Instead of grabbing its value out of the tag invocation, it allows you to set/change the value at runtime inside the taglib code. Granted, this is a little weird, but it's what I needed to do in order to subclass AOpenerLinkTag and keep it happy dappy.

MutableTagAttribute.java:

package com.bdgportal.alui.taglibs;

import com.plumtree.portaluiinfrastructure.tags.metadata.*;

public class MutableTagAttribute extends ATagAttribute {

private String value;

public MutableTagAttribute(String name, String desc, AttributeType type) {
super(name, desc, type);
}

public String GetDefaultValue() {
return value;
}

public void SetDefaultValue(String value) {
this.value = value;
}

public boolean GetIsRequired() {
return false;
}
}

Now that we have a tag attribute that we can change on-the-fly, writing the taglib was a snap.

UUIDObjectOpener.java:

package com.bdgportal.alui.taglibs;

import com.plumtree.portaluiinfrastructure.tags.*;
import com.plumtree.portaluiinfrastructure.tags.metadata.*;
import com.plumtree.xpshared.htmlelements.*;
import com.plumtree.taglib.standard.basetags.*;
import com.plumtree.server.*;

public class UUIDObjectOpener extends AOpenerLinkTag
{
public static final RequiredTagAttribute UUID;
private MutableTagAttribute OBJECT_ID;
private MutableTagAttribute CLASS_ID;

public UUIDObjectOpener() {
OBJECT_ID = new MutableTagAttribute("objectid", "Not used -- do not set a value for this!", AttributeType.INT);
CLASS_ID = new MutableTagAttribute("classid", "Not used -- do not set a value for this!", AttributeType.INT);
}

public ATagAttribute GetObjectIDAttribute()
{
return OBJECT_ID;
}

public ATagAttribute GetClassIDAttribute()
{
return CLASS_ID;
}

public static final ITagMetaData TAG;

static
{
TAG = new TagMetaData("uuidobjectopener", "Opens an object based on its UUID.");
UUID = new RequiredTagAttribute("uuid", "The UUID for the object you want to open.", AttributeType.STRING);
}

public HTMLElement DisplayTag()
{
Object[] objectAndClassId = ((IPTMigrationManager)(((IPTSession)GetEnvironment().GetUserSession()).OpenGlobalObject(PT_GLOBALOBJECTS.PT_GLOBAL_MIGRATION_MANAGER,
false))).UUIDToObjectID(GetTagAttributeAsString(UUID));

OBJECT_ID.SetDefaultValue(objectAndClassId[PT_MIGRATION_OBJECT_COLS.PT_MOC_OBJECTID].toString());
CLASS_ID.SetDefaultValue(objectAndClassId[PT_MIGRATION_OBJECT_COLS.PT_MOC_CLASSID].toString());
return super.DisplayTag();
}

public ATag Create()
{
return new UUIDObjectOpener();
}
}

To deploy this code, see the excellent section on edocs about creating custom Adaptive Tags.

To use this code in a portlet, do the following.

myportlet.htm:

<span xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
<pt:mytaglibns.uuidobjectopener pt:uuid="{00000-0000-0000-000000}" pt:mode="2">Open My
Object</pt:mytablibns.uuidobjectopener>
</span>

I did actually test this taglib and it worked swimmingly. Of course you need to substitute a real UUID for all those Os.

In closing, here's a little shameless plug: I've been asked by BEA to give a short, 20-minute talk at BEA World on my favorite subject (duh, taglibs) at the ALUI Developer User Group on Monday, September 18th in Moscone Center, San Francisco. It will happen some time between 1 and 5:30 PM. The ALUI User Groups are free for conference attendees. I hope to see you there or at the bdg booth. Please come on up and introduce yourself -- I always like to meet members of this great community in person.

Enjoy!

Comments

Comments are listed in date ascending order (oldest first)

  • Will there be any performance issues using this tag as it involves additional operations of getting Object ID and Class ID from the UUID?

    Posted by: psudhir_it on February 6, 2007 at 10:15 PM

  • From what I can tell, the tag makes a single SQL query (something like select objectid, classid from ptmigration where uuid = ?) which should be a pretty darn fast query, especially since there's probably an index on uuid.

    The portal is making database calls left and right when you're displaying a portal page, so making one more database call to generate an opener link shouldn't really be a performance factor. Nonetheless, it's definitely something to think about and I'm glad you brought it up.

    Posted by: bucchere on February 7, 2007 at 5:53 PM

  • Hi Chris! Am attempting to move this over to .NET; can you tell me which reference I need to add to resolve com.plumtree.taglib.standard and the AOpenerLinkTag? I'm not sure how to convert this Java fragment, which appears to have two seperate definitions of TAG: public static final ITagMetaData TAG; static { TAG = new TagMetaData("uuidobjectopener", "... UUID."); ...can you tell me what it means, and any tips on converting to C# ? Should have an opportunity to throw some load at this later on; will post my results here. My customer is already sensitive to performance problems caused by header portlets making DB calls; so I will also be looking into the caching possibilities. Cheers, Rob

    Posted by: rwagner on October 10, 2007 at 11:04 AM

  • Here is another option. The little known server.pt?uuID={XYZ-UUID} syntax. We use this in our public site which is not gatewayed to deep link into portal content without the need for an adaptive tag. We also use this to establish fqdns in apache that redirect to portal pages. For example in apache setup a fqdn of docs.bea.com which points to portal.bea.com/portal/server.pt?uuID={XYZ-UUID}.

    Posted by: ryanyoder on February 11, 2008 at 6:18 AM

  • Wow, very cool! I totally didn't know that syntax even existed. If it's supported, it ought to be documented, because it's quite handy.

    One gotcha is that you need to pass mode=2 if you want to open the object in view mode because the default is edit mode, e.g.: /portal/server.pt?uuID={46514C0F-0187-4340-AA24-84E41C00C60F}&mode=2

    Posted by: bucchere on February 11, 2008 at 6:31 AM