PowerUp
"How to create TOS components" Tutorial : Part 4

Component Creation - Part 4

We finally reached the point in this tutorial where we are going to write some actual java code in our component.
I hope you went through the previous tutorial lessons and that you are now familiar with the basic concepts we described.
In part 3 we created an empty component and indentified which files are essential for the component to be visible in the palette, today we will focus instead on the additional files that allow the component to actually do something : the javajet template files.

The template tiles

There are three template files, they correspond to the three component sections we discussed in lesson 2, so you should already be familiar with the concepts of begin,main and end section.

    A javajet template file contains two different types of java code : the template code and the java output code. Template code is included in <% %> tags


The concept is similar to the jsp pages,but here you have other java code instead of the html part.If you are familiar with this technology, the whole process should look quite clear to you.

The first file we need to create in the component directory is tTutorial1_begin.javajet.
The component designer can do this for you, but today we are going to manually create it in the file system.
As for jsp pages, on the top part of the file, you import the needed classes, which can vary according to your needs, however there are some "default" ones that are normally placed by the component designed wizard :



<%@ jet
imports="
org.talend.core.model.process.INode
org.talend.core.model.process.ElementParameterParser
org.talend.core.model.metadata.IMetadataTable
org.talend.core.model.metadata.IMetadataColumn
org.talend.core.model.process.IConnection
org.talend.core.model.process.IConnectionCategory
org.talend.designer.codegen.config.CodeGeneratorArgument
org.talend.core.model.metadata.types.JavaTypesManager
org.talend.core.model.metadata.types.JavaType
"
%>



This is a particular section of the jet template, it's the jet imports section, you will need it in all the template files since they are compiled separately.
The classes listed in inports are Talend specific and are documented with javadoc here : http://talendforge.org/tos-2.0.0/api/.

Right after the jet imports, just add some java output code, something that will be executed when you run the job :



System.out.println("I am a component and this is the begin section");



Now in the component designer perspective, refresh the tTutorial1 files (f5) and push again the component to the palette.
Switch back to the Data Integration perspective and drop your component in a blank project, then execute it (f6).
If everything went smoothly, you should see in the console panel the text you printed using java output code, in my case I am a component and this is the begin section.

Good, this one was really basic, so, now, do you remember the exercise we did with the tJavaFles in part 2 of the tutorial? We are going to replicate the same exercise using our component.
Just to quickly refresh your mind : We used all three sections, we opened a cycle in the begin section, did something in the main and finally closed the cycle in the end section.
Your first task is to copy the tTutorial1_begin.javajet file into tTutorial1_main.javajet and tTutorial1_end.javajet then refresh the files in the Component Designer, it just needs to know that now you have all the three sections.

We will leave the jet imports as they are, instead you need to modify the java output code.If you still have the tutorial job we used in part two, you can copy&paste the code of the three sections right after the jet imports, finally you should have something like this :



[... jet imports ...]
System.out.println("I am the begin section");
for (int myvar=0;myvar<10;myvar++)
{

in the _begin



[... jet imports ...]
System.out.println("I am the main section and myvas is "+myvar);

in the _main



[... jet imports ...]
}
System.out.println("I am the end section");

in the _end

Notice that we can open a " { } " block in the begin and close it in the end section, in the same way we did with the tJavaFlex component, even if here the block start and end are in different files.
This is allowed and normal in java output code, because the three javajet templates when executed will actually write java code snippets that fillay end up in the same java code block.

Push again your component to the palette and test it, you should get the exact same result we had with the exercise we did with the tJavaFlex component.

The Unique Name

You should recall we had an issue with the tJafaflex exercise : the variable scope.
This issue is present also here and it's even worse.
Logically a component can be used many times in a job and you cannot predict the name of the variables used in the other components or even how many instances of your component will be present, how they are interconnected etc.
Talend provides a safe way to make variable unique : adding the component instance unique name.

    When designing a component, all the local variables in the java output code must be made unique adding to their name the UNIQUE NAME of the istance of the copmponent.


When adding a component to a job, a parameter called __UNIQUE_NAME__ is automatically generated by Talend and it contains a unique identifier which has the name of the component itself (tTutorial1) followed by an underscore and a progressive number : i.e. tTutorial_1

Check the "View" tab of your component (or of any other component), you will see that the label is set to "__UNIQUE_NAME__", this is precisely the parameter created automatically that will identify the instance of the component.

We already explained in previous lessons that component parameters are visible in the java jet template code, so our next step will be to get that unique name from the javajet template


Open your _begin.javajet section and add the following lines right after the javajet imports :



[ ... javajet imports ... ]
<%
CodeGeneratorArgument codeGenArgument = (CodeGeneratorArgument) argument;
INode node = (INode)codeGenArgument.getArgument();
String cid = node.getUniqueName();
%>
[ ... java output code ... ]



Those lines are normally added automatically by the component designer wizard in each template file and they are used to retrieve the instance unique name.
Each instance in a job is a Node whose interface is INode, using the variable node we can use the method getUniqueName(), finally the variable cid will contain "tTutorial1_1" so we can use it to create variables with unique names.
As an example, we will rename our myvar variable into myvar_tTuturial1_1 or myvar_tTuturial1_xyz where xyz is the progressive number of the tTutorial1 component instance in a job.
The javajet template code is used to generate the java output code, so it is possible to "output" some java code from the template, the easist way is by passing values (variables, methods...) to the java output code via the tags <%= %>, so our java output code will be transformed in :



[ ... javajet imports ... ]
[ ... java template code ... ]

System.out.println("I am the begin section");
for (int myvar_<%=cid %>=0;myvar_<%=cid %> < 10;myvar_<%=cid %>++)
{



The same technique will be used in the main section because we are using the myvar variable, so you will need to copy the same javajet template code (note : "cid" is defined in the begin java jet template code and it is not visible in the other sections because each section is executed separately)
Adapt accordingly your main section and then install again the component, once you are done run the job to veify it still works properly and finally inspect it's java code.
If you search for myvar_tTutorial1_1 (assuming the progressive number of your instance is 1, else adapt it accordingly) you wil notice that the cid variable has been transformed in a string used to generate the java output code.


In the next lesson we will expand this technique by defining parameters, reading them in the javajet code and passing them to the java output code.

Part 3  Part 5