Complex validation, conversion, and formatting logic in a Talend Open Studio tMap is difficult to maintain. Don't cram lengthy and repeated Java expressions in a field mapping. Use a Talend Routine to encapsulate the logic and apply it in a concise syntax across all your tMaps. Java Varargs -- a Java 5 language feature -- will make these Routines general by accepting different call signatures (# of arguments).
If you want to form a comma-separated list in a tMap, you can use the standard Java concatenation operator like this in a tMap expression:
row1.last_name + ", " + row2.first_name
To add additional rows, you would add additional +'s.
An alternative tMap expression uses a Routine. Package the concatenation in a method call so that the syntax becomes
comma(row1.last_name, row2.first_name) // produces "Doe, John"
While the code reduction isn't huge for a comma-separated, this is a solution that scales for a more complex example. Suppose you would like to create an HTML list.
"<ul class=\"myclass\"><li>" + row1.last_name + "</li><li>" + row1.first_name + "</li></ul>"
It becomes difficult to troubleshoot the longer expression with escaped characters in the text box of a tMap. A Routine-based alternative is
htmlList("myclass", "ul", row1.last_name, row2.first_name)
Java Varargs
Varargs is a relatively new language feature to Java (Java 5). It allows a method to specify a varying number of arguments while retaining the ability to have required parameters. Here is the code for the comma() example
public static String comma(Object..._objects) {
StringBuffer sb = new StringBuffer();
boolean firstPass = true;
if( _objects != null ) {
for( Object obj : _objects) {
if( !firstPass ) {
sb.append(",");
} else {
firstPass = false;
}
if( obj == null ) {
sb.append("");
}
else {
sb.append( obj.toString() );
}
}
}
return sb.toString();
}
Note the special "Object..." syntax. This forms an array of objects that can be iterated over using the "new" foreach loop. comma() can be called with any number of arguments (the name example uses 2 arguments, first_name and last_name). The code snippet can be cut-and-pasted into a new Talend Open Studio Routine.
More Complex Example
The htmlList() example has required parameters "styleClass" and "listType". These are presented in the declaration first, followed up by the array of objects that makes up the data to be presented.
public static String htmlList(String _styleClass, String _listType,
Object..._objects) {
if( _listType == null ||
!(_listType.equals("ul") || _listType.equals("ol")) ) {
throw new IllegalArgumentException("listType must be 'ul' or 'ol'");
}
StringBuffer sb = new StringBuffer();
if( _styleClass != null && _styleClass.length() > 0 ) {
sb.append("<" + _listType + " class=\"" + _styleClass + "\">" );
}
else {
sb.append("<" + _listType + ">");
}
if( _objects != null ) {
for( Object obj : _objects) {
sb.append("<li>" + ((obj==null)?"":obj.toString()) + "</li>");
}
}
sb.append("</" + _listType + ">");
return sb.toString();
}
The parameters are required, although this code will accept an empty styleClass. Passing an empty listType is permitted by the declaration but a runtime exception will be thrown by the program in this case. As with the comma() example, htmlList() can be cut-and-pasted into a new Routine. The same Routine as was used for comma() can be used for htmlList().
Overly-complex data transformations can often be handled in dedicated components. But if you're working with a tMap, keep it lean with Routines.
BRules Note
BRules 1.2 -- available on the Talend Exchange -- will have a generalized version of comma() called join(). Additional HTML methods will be added.
No comments:
Post a Comment