"How to create TOS components" Tutorial : Part 5

Component Creation - Part 5

In "real life" applications, most of your components will have parameters, used to pass some configuration settings needed for the tasks accomplished by the component itself.
Those parameters are defined in the XML descriptor file which we introduced in lesson 3.

Defining parameters in the XML descriptor

There are two sections in the component's xml file that define parameters, these are the "PARAMETERS" and "ADVANCED PARAMETERS" section.
They basically work in the same way, but the first one is normally used to define key parameters and the second one for those parameters you optionally want to set when using the component. They are visible in the "basic settings" and "advanced settings" tabs of the component.

Open your xml descriptor tTutorial1_java.xml file and add two parameters :

    <DEFAULT>"hello world"</DEFAULT>

Notice we added an element in the parameter section and we also added an entire new section "advanced parameters".
Those xml lines allowed us to add two parameters to the tTutorial1 component, let's see in detail how the parameters have been defined.

    A parameter must define at least two pieces of information : a (unique) NAME="xxxx" and a parmaeter type FILED="yyyy", which defaults to "TEXT" if not specified.

We also used some other settings :
REQUIRED specifies if the job can be started (if set to false) even if no value is specified for the parameter.
NUM_ROW Is used to sort graphically the parameters in the component settings tabs
DEFAULT can provide an initial default value for the component.

There are a few other settings available, we will discover them later on in the tutorial.

Add the new xml code into your tTutorial1_java.xml file if you didn't already and push the component to the palette to see the changes.
Note that if you had tTutorial1 in a job, already open when you pushed the updated component, you will not be able to see the new parameters until you RELOAD the component, this can be achieved by running the job.

Once you successfully installed the updates, you will notice the two new parameters displayed with some "funny" labels, such as !!!MYPAR1.NAME!!!
This is because we did not specify any label for them, but we are quickly going to fix this issue, just open the tTutorial1_messages.properties file and add the following two lines :

MYPAR1.NAME=Say something
MYPAR2.NAME=Console output?

    Parameter labels are defined in the _messages.properties file in the format Parname.NAME=xyz

You can try to push again the component and see the changes, remember you will also need to reload the component by executing the job that contains it.

Using the parameters

Now that we have two parameters, it would be nice to be able to use them in our component.
As explained we can get them from the template code in the javajet template.
We will try to printout in the console MYPAR1 if MYPAR2 checkbox is set.
As you can see, we are going to use them in different ways : The first one will just be a constant passed to the java output code, instead the second one will be used to conditionally generate some java output code (the System.out.println command will be added only if the checkbox is set to "true").

To read the parameter values in the javajet code, we us the ElementParameterParser (static) method getValue.
This method requires in input the node (which we introduced in the previous lesson) and the paramreter name.
Notice that the parameter name is not exactly the one we defined in the xml file.

    Parameters are retrieved in the javajet code using the ElementParameterParser.getValue(node, parname) static method, where parname is defined witht he format __NAME__ (double underscore before and after the name defined in the xml file)

[...jet imports ...]
CodeGeneratorArgument codeGenArgument = (CodeGeneratorArgument) argument;
INode node = (INode)codeGenArgument.getArgument();
String cid = node.getUniqueName();
String sentence = ElementParameterParser.getValue(node, "__MYPAR1__");
String consoleout = ElementParameterParser.getValue(node, "__MYPAR2__");
[.. java output code ...]

Update the _begin.javajet template file similarly to the code shown above, this will add two String variables in the template part,we will use them to "customize" the java output code.

Next step will be to add some code before the "for" cycle :

[...jet imports ...]
CodeGeneratorArgument codeGenArgument = (CodeGeneratorArgument) argument;
INode node = (INode)codeGenArgument.getArgument();
String cid = node.getUniqueName();
String sentence = ElementParameterParser.getValue(node, "__MYPAR1__");
String consoleout = ElementParameterParser.getValue(node, "__MYPAR2__");

 if (consoleout.equals("true"))
 System.out.println(<%=sentence %>);
[.. other java output code ...]

See that if statement defined in the template part? It is used to add conditionaally some java output code, notice how we enter and exit from the template opening and closing the % tags.
You can try to install the updates and execute your test job, play around with the basic and advanced parameter and see how they affect the component, also check that the java output code of the job is different when you set the "console outout?" checkbox.

Passing constants or variables in parameters

The code we wrote : System.out.println(<%=sentence %>); assumes that the parameter is passed within quotes, we could have used the following code instead : System.out.println("<%=sentence %>"); and skip the quotes when entering the value of the parameter.
It would work just the same, however this is generally not a good idea because Talend allows the usage of variables (such as context.myvar1) in parameters, so we cannot assume they are always string constants.

A simple exercise for you now :
Add another parameter whose label will be "Iterations", it will appear before MYPAR1 and will work as the upper limit of the myvar control variable in the for loop.
You will then pass a numerical constant OR a context valriable (or a globalMap.get() value if you prefer).

On completing your exercise you should end up with something like this, if you get lost, here you can download the solution.

I strongly suggest you try to do the exercise first and feel free to experiment!
Note that in this case I did not use quotes passing the parameter, since I am expecting a numerical value (even the context valriable was defined as "int").
Alternatively you can pass a String and use java standard functions to parse it to an inteeger.

In the next lesson we will introduce the Connectors and we will see how we can pass data (records) from a component to another.

Part 4  Part 6