A site about Talend
The API that you need to know when you're building your own components is poorly documented. Despite this, there are many features available that will help you to build your components. We'll start off with some of the more common calls that you will need to make and explain exactly what they do. The best way to get the full technical documentation is to access this through Talend Studio - Help->Help Contents->Developer Guide->API Reference. You may also access the documentation from here (Talend API Reference).
If you're not already familiar with Java Emitter Templates (JET), then now is probably a good time to read our article on Java Emitter Templates (JET).
The programming style shown here is not necessarily my own. For the examples shown, I have kept the the style that has been used for the standard Talend Components. Within these, there are variations in style. I have chosen a style that seems most common.
In the examples shown here, we usually refer to un-qualified Class names. Remember that if you use un-qualified names (which is usual), you must import these. For more information on this and Java Emitter Templates (JET) in general, refer to the documentation on Java Emitter Templates (JET).
The following code-fragment shows some basic imports.
<%@ jet imports=" org.talend.designer.codegen.config.CodeGeneratorArgument org.talend.core.model.process.INode " %>
Java Emitter Templates (JET) require an argument to be passed to the template. An Object of the Class org.talend.designer.codegen.config.CodeGeneratorArgument
provides this argument. Most components provide a reference to argument
, as shown below.
CodeGeneratorArgument codeGenArgument = (CodeGeneratorArgument) argument;
This Class makes Job-level information available including jobName
, jobVersion
and argument
(INode). For more documentation on this Class, read the Talend API Reference.
From codeGenArgument
we can now create an instance of org.talend.core.model.process.INode
; which will provide information about the unique instance of our component.
It is usual for us to want to extract the unique component name from this Object. This is usually referred to as cid
(Component ID). If, for example, we had a component named tMyComponent
we might expect to see the value tMyComponent_1
returned for the first instance of the component. The nomenclature is confusing as we are using the get-method CodeGenArgument.getArgument
to get an Object of type INode
from argument
.
INode node = (INode) codeGenArgument.getArgument(); String cid = node.getUniqueName();
This Class makes other key information available to us including information on the component's metadata and connections. We'll look at these shortly.
The following code provides an example of what we have learned so far. This is basic code that you might expect to see in any Java Emitter Templates (JET) file.
<%@ jet imports=" org.talend.designer.codegen.config.CodeGeneratorArgument org.talend.core.model.process.INode " %> <% CodeGeneratorArgument codeGenArgument = (CodeGeneratorArgument) argument; INode node = (INode)codeGenArgument.getArgument(); String cid = node.getUniqueName(); %>
The Class org.talend.core.model.process.ElementParameterParser
allows us to extract our component's parameter values from node
. Let's take a look at a simple example, from the component tJava.
<%=ElementParameterParser.getValue(node, "__CODE__") %>
The first observation worth noting with this method, is that a String is always returned, regardless of any inferred data type when you defined your parameters in the Component Descriptor File. i.e. all parameters are or type String.
The following code-fragment shows the specification of the getValue
method.
public static java.lang.String getValue(IElement node, java.lang.String text)
When you get a parameter value, the parameter name must be specified with both a prefix and suffix of __
, for example, __CODE__
where CODE
is a parameter supported by the component tJava.
In the case of tJava, the parameter CODE
is used to specify some user-defined Java code; which is simply emitted by the Java Emitter Template as instructed by the directive <%=
. For more information on this JET Expression Scripting Element, read our tutorial on Java Emitter Templates (JET).
As can be seen from the example above, the value specified by the parameter CODE
is simply emitted to form part of the Job's Java code. It is more common for a parameter's value to be assigned to a variable, for use within the template.
The following example is taken from the component tContextDump.
boolean hidePassword = ("true").equals(ElementParameterParser.getValue(node,"__HIDE_PASSWORD__"));
The component tContextDump allows you to write the values of Context Variables to the console, for debugging purposes; however, given their sensitivity, it allows you to specify that any variable that represent a password (Talend Data Type id_Password
) will be obscured.
The parameter HIDE_PASSWORD
is defined as a Checkbox as described in Component.xsd - PARAMETER FIELD Values. A Checkbox value always represents true or false; however, as we discovered earlier, parameters are always returned by ElementParameterParser.getValue
as String. The boolean variable hidePassword
is assigned a value based on whether or not the value "true"
has been returned.
If you're writing an input, output, or processing component, then you'll need to handle metadata. Metadata describes the data structures that flow through your component.
To work with metadata, the first thing we will do is to add the Interface org.talend.core.model.metadata.IMetadataTable
to our imports. As components may support multiple metadatas, these are made available to us as java.util.List
, so we will import this too, as shown below.
<%@ jet imports=" org.talend.designer.codegen.config.CodeGeneratorArgument org.talend.core.model.process.INode org.talend.core.model.metadata.IMetadataTable java.util.List " %>
Metadata is made available by the get-method Inode.getMetaDataList
. This list is assigned to an Object of type List<IMetadataTable>
, as shown below.
List<IMetadataTable> metadatas = node.getMetadataList();
Most components that work with metadata, work with a single metadata. For the purpose of this documentation, we'll look at this typical code. If you're realy to write components that support multiple metadatas, you'll probably already have a good understanding of how metadata works.
The following shows a typical code fragment, to get and handle a single metadata. Later, we'll look at what can be done with metadata once it has been made available to your code.
if((metadatas != null) && (metadatas.size() > 0)) { IMetadataTable metadata = metadatas.get(0); if(metadata != null) {
This code is fairly self-explanatory. If metadata is available, it will be assigned to the variable metadata
and, in this instance, the component only supports a single metadata. If valid metadata has been returned, some component-specific processing may now be performed.
If you're writing an input, output, or processing component, then you'll need to handle connections. This represents the types of connections that you have between your components, as defined by the attribute CTYPE
; which is described in our article on the Component Descriptor File.
To work with connections, the first thing we will do is to add the Interface org.talend.core.model.process.IConnection
to our imports. As components may support multiple connections, these are made available to us as java.util.List
, so we will import this too, if we haven't already done so.
<%@ jet imports=" org.talend.designer.codegen.config.CodeGeneratorArgument org.talend.core.model.process.INode org.talend.core.model.metadata.IMetadataTable java.util.List org.talend.core.model.process.IConnection " %>
It is important to understand that IConnection
represents a type of connection rather than a specific instance of two components being connected. We may, for example, allow data to FLOW
from our component to one or more other components. One instance of IConnection
will represent this connection type. We will need to drill in this to see the actual flow of data between components.
Connections are made available by a number of get-methods, for example, Inode.getOutgoingConnections
, depending on what you are trying to achive. This list is assigned to an Object of type (usually) List< ? extends IConnection>
, as shown below.
List< ? extends IConnection> conns = node.getOutgoingConnections();comments powered by Disqus