It is important to customize taglib because:
- For JSP taglibs:
- It plays a role in JSP quality rules,
- It is used to compute function points
- For JSF:
- It plays a role in the quality rules: to locate which JSF Input Field is validated or not.
- It is used to compute function points
When you need to customize the management of the taglib, there are two cases:
- the TLD is already supported but associated to different URIs. In this case, you need to edit the file <CAST installation folder>\configuration\J2EE\WEB-INF\cast-tag.extension.xml or the files ".tagextension" located in Technology > J2EE > Platform Setting > CAST Tags Extension Folder to add the uri
- the TLD is not supported at all. In this case, you have to create a file similar <CAST installation folder>\configuration\J2EE\WEB-INF\cast-tag.extension.xml in the directory or a sub-directory specified in Technology > J2EE > Platform Setting > CAST Tags Extension Folder with the extension ".tagextension". This file will be automatically taken into account during the analysis.
The TLD is already supported
The TLD that you want to support already exists in the cast-tag.extension.xml file, but the associated URI doesn't match.
For example, the URI found in the TLD is http://struts.apache.org/tags-bean.
If you look for tags-bean in the file cast-tag.extension.xml you will find or in a ".tagextension" located in a directory or sub-directory specified by Technology > J2EE > Platform Setting > CAST Tags Extension Folder parameter:
<taglib uri="http://jakarta.apache.org/struts/tags-bean" uri1="http://jakarta.apache.org/struts/tags-bean-1.0"> <tag name="define"> <create nameSrc="id" kind="bean" scopeSrc="toScope"> ...
To associate this URI to this definition you need to add this entry with the property urix where 'x' is the next unused number in the list of URI:
<taglib uri="http://jakarta.apache.org/struts/tags-bean" uri1="http://jakarta.apache.org/struts/tags-bean-1.0" uri2="http://struts.apache.org/tags-bean"> <tag name="define"> <create nameSrc="id" kind="bean" scopeSrc="toScope"> ...
Then you need to run the analyzer to create the missing beans.
The TLD is not supported
How it works?
The J2EE Analyser is composed of two analyzer (JSP and Java) to analyze JSP content.
- When a TLD uri is found incast-tag.extensions.xml all tags related to this TLD found in the JSP file will follow these rules:
- If the tag is not defined in the cast-tag.extensions.xml:
- The JSP Analyzer will not interpret any attribute values including EL expressions and they will be replaced by empty strings during the .java file generation process. As a consequence, no internal and external references will be resolved with the value of these attributes from the generated Java file.This is useful if the tag has no useful semantic.
- If the tag is defined in the cast-tag.extensions.xml:
- The JSP Analyzer will interpret the instructions defined to manage this tag and associated attributes (see forthcoming chapters to get more information).
- The JSP analyzer will generate the .java file related to this JSP where the attributes are all blank.
- If the tag is not defined in the cast-tag.extensions.xml:
- When a TLD is not found, all tag attributes values will be passed to the generated .java file. As a consequence, the Java Analyzer will create links from this value to other internal or external objects through a grep. As such you may have false links to validate through the Dynamic Link Manager.This is different from literal strings extracted from Java files because these strings are resolved against J2EE internal objects.
Note that the expression language is interpreted by the JSP Analyzer to resolve the value against JSP bean properties. JSF adds the possibility to specify a method to call from EL. To manage this case, the resolution attribute "jsf-el-method" (means Java method in a JSF managed Bean) is used.
Get the taglib documentation
Without any documentation on the taglib, it is impossible to configure it properly. The documentation allows you to understand what to do with this tag and its attribute, for example: do you have to create a specific JSP Bean property for this attribute?
To get this description, you may find documentation on internet (this is the case for an external framework) or find that the description added in the taglib is sufficiently accurate or ask the customer for the documentation.
Some examples of documentation that you can find on internet:
- Struts taglibs: http://struts.apache.org/1.3.8/struts-taglib/index.html
- JSF 1.1 standard taglibs: http://java.sun.com/javaee/javaserverfaces/1.1/docs/tlddocs/index.html
- ADF Faces Core: http://www.oracle.com/technology/products/jdev/htdocs/partners/addins/exchange/jsf/doc/tagdoc/core/imageIndex.html
What if the taglib uri doesn't exist?
The taglib uri is required by the JSP analyzer to make the association. In the case where the uri is missing, you must add one by patching the TLD:
<taglib> <tlibversion>1.0</tlibversion> <jspversion>1.1</jspversion> <shortname>mfl</shortname> <uri>http://mycompany.com/common.tld</uri> <info>MFL general application custom tags</info> <tag>
JSP specific taglib
Example of the customization of the tag bean:define
You can find the complete description here:
The extract that is important is here:
Specifies the name of the scripting variable (and associated page scope attribute) that will be made available with the value of the specified property.
Specifies the attribute name of the bean whose property is accessed to define a new page scope attribute (if property is also specified) or the attribute name of the bean that is duplicated with the new reference created by this tag (if property is not specified). This attribute is required unless you specify a value attribute or nested body content.
Specifies the name of the property to be accessed on the bean specified by name. This value may be a simple, indexed, or nested property reference expression. If not specified, the bean identified by name is given a new reference identified by id.
Specifies the variable scope searched to retrieve the bean specified by name. If not specified, the default rules applied by PageContext.findAttribute() are applied.
Specifies the variable scope into which the newly defined bean will be created. If not specified, the bean will be created in the page scope.
Specifies the fully qualified class name of the value to be exposed as the id attribute.
The java.lang.String value to which the exposed bean should be set. This attribute is required unless you specify the name attribute or nested body content.
When reading this description, this means that:
- We have to create a JSP Bean whose name is 'id' and with a scope defined by "toScope" or with a scope page when not defined
- This JSP bean is a Java class whose type is:
- The class name defined by the attribute "type" when it existsAlso, when the "name" or "property" attribute is defined then the intrinsic type of the JSP bean to create is the type of the bean "name" or "name.property" when the property is set. When the attribute type is set, it is used to cast the intrinsic class specified by the name and the optional property when they are set.
- or java.lang.String when the attribute "value" is defined
- When the bean property is set, we have to create a link from the created bean ("id") to the JSP Bean or bean property whose scope is defined by the attribute "scope".
1 - Tag is used to customize a tag from the TLD whose name is defined with the attribute "name"
2 - This section defines the creation of the bean to create
- create nameSrc="id" is used to create an object whose name is defined by the value of the attribute "id" and whose type is specified by the attribute "kind" (a JSP bean in this case) and whose scope id is defined by the value of the attribute "toScope". Note that when toScope is not defined the default behavior of JSP is to use the scope page.
- useTypeOfis used to specify the Java type of the bean to create. In this sample, the list is sorted so that we will try to see:
- If the attribute value is defined and in this case we associate this bean with a java.lang.String class. Here the attribute "type" in cast-tag.extensions.xml is used when its value is a literal (java.lang.String in this case).
- If the attribute type is defined, we will associate this bean with a class or interface whose name is defined by the attribute "type". Note that here we used "typeSrc" to specify that the value comes from the value associated to the attribute "type" of the tag.
- If the attribute "name" is defined, then we will associate this bean to the same class as the bean defined in the embedded search expression or the bean property if the attribute "property" is set. The search expression has been written to indicate to the analyzer how to find the JSP bean whose name is specified by the value of the attribute "name" and the scope by the value of the attribute "scope".
- create kind "bean.property" is used to create a bean property associated to the JSP bean that we are creating. Its name is given by the name of the property specified by the value of the attribute "property" of the JSP bean found through the search expression that encloses this tag (i.e. search kind="bean" nameSrc="name" scopeSrc="scope").
3&4 - This section represents the declaration of the Java code so that the generated java file will compile
This step is needed only for taglibs for JSP versions older than version 1.2 (i.e. JSP version 1.0 and 1.1) This must be done so that JSP embedded java code that references a Java variable defined by the tag will compile. For example, if after the tag declaration with an id="b", you have:<% b.m(); %> the variable b must be declared so that it will compile.Note that it is not necessary to do in version 1.2 since these variables are defined directly in the taglib. For example:
<tag> ... <variable> <name-from-attribute>id</name-from-attribute> <variable-class>com.acme.bean.Contact</variable-class> <declare>true</declare> <scope>NESTED</scope> </variable> ... </tag>
- How to find the version of the taglib?
Look at the version defined in the TLD defined as: <jspversion>1.1</jspversion>
- declare name-from-attribute="id" scope="AT_END" typeSrc="type" is used to indicate to the J2EE Analyzer to create a variable whose name is given by the value of "id" attribute value. The scope=AT_END specifies that this variable is defined after the declaration of the tag.To find the value scope, there is only one possibility that consists of looking at the source code of the taglib when it is not defined in the documentation.
- call instanceSrc ...
- It instructs the analyzer to create a call to the method getXXX deduced from the attribute value of the "property" applied on the class whose name is deduced from the attribute value "name". The search is here to find the class associated to the attribute "name" whose scope is "scope" and the type of "name" is a bean.
- This is done to prevent getXXX appearing as unreferenced code
5 - <attribute name="type"...
- This is used to create a link from the JSP page to an object directly. This has been made despite the fact that we already associate the JSP bean to this java type because it is used in some quality rules to know which kind of Java class is used in a JSP page.
- This also avoids sending this class name to the external reference engine and creating a link in the Dynamic Link Manager.
To find more details about the taglib configuration attributes, please refer to the: <CAST installation folder>\<version>\configuration\J2EE\schemas\cast-tag-extensions.xsd schema, an explanation is described for each of them.
JSF specific taglib
It is important to correctly handle the JSF taglib since it used in future JSF quality rules like: "JSF: Avoid invalidated inputs".
Also, this configuration will simulate the server methods invoked by each tag.
As for JSP taglibs, you need to declare in the cast-tag.extensions.xml file, the tag taglib that will refer to the uri used in the tld and then declare the tags as was done for JSP tags.
In addition to JSP tags, when configuring a JSF TLD, you will find three types of components that must be configured with specific attributes:
- Input Field
To illustrate this, let's use the Oracle ADF Faces framework: http://www.oracle.com/technology/products/jdev/htdocs/partners/addins/exchange/jsf/doc/tagdoc/core/imageIndex.html
How to recognize a Validator?
- Usually this tag has a name that begins with "validateXXX"
- The description of the tag indicates that it is carrying out validation
- It is registered in a faces-config.xml file like for example the Double
In the ADF framework, the following tags are Validators:
- validator (http://www.oracle.com/technology/products/jdev/htdocs/partners/addins/exchange/jsf/doc/tagdoc/core/validator.html): the name of the tag and the description allow us to deduce that it is a validator
- validateRegExp (http://www.oracle.com/technology/products/jdev/htdocs/partners/addins/exchange/jsf/doc/tagdoc/core/validateRegExp.html): the name of the tag and the description allow us to deduce that it is a validator
- validateByteLength (http://www.oracle.com/technology/products/jdev/htdocs/partners/addins/exchange/jsf/doc/tagdoc/core/validateByteLength.html): the name of the tag and the description allow us to deduce that it is a Validator
How to configure a Validator?
- ADF Validator (http://www.oracle.com/technology/products/jdev/htdocs/partners/addins/exchange/jsf/doc/tagdoc/core/validator.html):
Its configuration is as follows:
The line attribute name="validatorId" resolveValueAs=... instructs the analyzer to recognize the id as a JSF Validator and create a link from the JSF field with the JSF Validator.
The line search kind="jsf-input-field" instructs the analyzer to find the nearest JSF Input Field that embeds the Validator tag instruction (card in the above sample). Then, the embedded instruction (addAttribute...) will be applied to this JSF Input Field. The line addAttribute name="Validate"... instructs the analyzer to add the property Validate="true" to the JSF Field. This checks that each JSF Field is validated through a quality rule.
The line addAttribute name="Validator"... instructs the analyzer to add the property Validator initialized with the name of the Validator referenced by validatorId. This checks that specific JSF Fields are validated through a specific Validator through quality rules.
- ADF validateRegExp (http://www.oracle.com/technology/products/jdev/htdocs/partners/addins/exchange/jsf/doc/tagdoc/core/validateRegExp.html): Its configuration is as follows:
Here the only differences with the previous sample are that there is no validatorId to solve and the Validator name is directly set.
How to recognize an Input Field?
- Usually these tags have a name that contains "input"
- The description of the tag indicates that it is an input field
How to configure an Input Field?
ADF selectInputText (http://www.oracle.com/technology/products/jdev/htdocs/partners/addins/exchange/jsf/doc/tagdoc/core/selectInputText.html):
Its configuration is as follows:
The first line create nameSrc="id" kind=... instructs the analyzer to create a JSF Input Field object whose name comes from the id attribute value.The second line search kind="jsf-input-field" is used to find this JSF Input Field and apply the embedded instructions (addAttribute...)The two lines addAttribute instruct the analyzer to add the properties Validator and Required to the JSF Field. This checks that each numerical field has the property required and each JSF Field is validated through quality rules.The lines:
- <attribute name="value" resolveValueAs="bean-property"caller-type="jsf-input-field"/>
- <attribute name="converter" resolveValueAs="jsf-converter" caller-type="jsf-input-field" />
- <attribute name="validator" resolveValueAs="jsf-validator;jsf-el-method" caller-type="jsf-input-field" />
instruct the analyzer to create links from the JSF Input Field to:
- the bean property referenced by the attribute "value" value
- the JSF Converter referenced by the attribute "converter" value
- the JSF Validator referenced by the attribute "Validator" value
The line attribute name="action" resolveValueAs="jsf-outcome;jsf-el-method" instructs the analyzer to create a link from the JSP page (this is the default when no caller-type or caller-name is specified) to the JSF outcome or the Java method specified by the JSF Expression Language. This means Function Points can be computed.
The four following lines attribute name="xxxListener"... instruct the analyzer to create links from the JSP pages to the Java method specified by the JSF Expression Language. Function points can thus be computed, but also a check of which components are called by JSP pages for architecture quality rules can be made.
The last two lines attribute name="xxxx" resolveValueAs="url" are used to create links from the JSP page to the url referenced by the attribute value. Function points can thus be computed, but also a check of which components are called by JSP pages for architecture quality rules can be made.
How to recognize a Converter?
- Usually this tag has a name that contains "convert"
- The description of the tag indicates that it is a converter
How to configure a Converter?
ADF convertNumber (http://www.oracle.com/technology/products/jdev/htdocs/partners/addins/exchange/jsf/doc/tagdoc/core/convertNumber.html)
The first line search kind="jsf-input-field" is used to find this JSF Input Field and apply the embedded instructions (addAttribute...)
The two lines addAttribute instruct the analyzer to add the properties Convert and Converter to the JSF Field. This checks if a converter is used and which converter is used for this JSF Input Field.
The other tags need to be configured when there is reference to methods specified by the JSF Expression Language, a URL and also when there are beans to create as for JSP tags.