TDIing out loud, ok SDIing as well

Ramblings on the paradigm-shift that is TDI.

Monday, August 1, 2011

work.FullName.toUpperCase() - What's wrong with this picture?

The fact that TDI lets you use '.' to reference attributes (work.FullName) coupled with JavaScript engine's (limited) automatic type conversion are a constant source of confusion. Although I feel a long rant coming on, I will resist and save some content on this subject for future blogs. For now, suffice to say that using dot notation to reference an attribute gets you just that: a com.ibm.di.entry.Attribute.

Quick refresher alert: Attributes are named containers of values. So for example, work.mail is a container named 'mail' that can in turn hold zero or more values. The values themselves can be any kind of Java object: String, Date, java.sql.Blob - even another attribute, as is the case when working with hierarchical data in TDI (for example, parsing xml, rdf, json, ...).

The JS Engine in TDI sometimes converts the attribute being referenced to a string representation of its value, as with this snippet:

"My name is " + work.FullName >> My name is Slim Shady

Since the Attribute is part of a String concatenation, TDI's JSEngine conveniently returns its value as a Java String instead of the attribute itself. But that's about as far as auto-conversion goes. In most cases when you send an Attribute to do a String's job, the Attribute's toString() method is used. This results in a string value that starts with the attribute name, then a colon and its value.

work.FullName >> "FullName": "Slim Shady"

The toString() method for both the Entry and Attribute classes give you this JSON-like result (of course, you use the JSON Parser for real JSON) and this may not be what you want.

Even worse is when you start calling String functions directly from your dot-referenced Attribute:
work.FullName.toUpperCase() >> com.ibm.jscript.InterpretException: Script interpreter error, line=1, col=12: Error calling method 'toUpperCase()' on an object of type 'com.ibm.di.entry.Attribute'

So what's a poor TDI'er to do? As usual, there is more than one way to flay this feline:

work.getString("FullName").toUpperCase() >> SLIM SHADY
work.FullName.getValue().toUpperCase() >> SLIM SHADY
work["FullName"].getValue().toUpperCase() >> SLIM SHADY
(work.FullName + "").toUpperCase() >> SLIM SHADY

The clue here is to reference the value of the attribute, not the attribute itself. Sometimes you'll want a String representation and will use methods like entry.getString(attributeName) or attribute.getValue(). In those situations where you need the actual Java class used to store the value then you use attribute.getValue(index), where index is is an integer value denoting which value you want: from zero to attribute.size() - 1.

For the sake of completeness, note that calling entry.getObject(attributeName) will return the Java object used to store the first value of the named attribute.

And if any of this is still unclear, please drop a note in the forum and I'll will strive to clarify without further pontification :)

Forum: https://groups.google.com/forum/#!forum/ibm.software.network.directory-integrator