{
TagAttribute[] sourceTagAttributes = tag.getAttributes().getAll();
String elementNameTagLocalName = tag.getLocalName();
TagAttribute elementNameTagAttribute = new TagAttributeImpl(
tag.getLocation(), PASS_THROUGH_NAMESPACE , Renderer.PASSTHROUGH_RENDERER_LOCALNAME_KEY,
P_ELEMENTNAME, elementNameTagLocalName );
// 1. Count how many attributes requires to be duplicated
int duplicateCount = 0;
TagAttribute[] convertedTagAttributes = new TagAttribute[
sourceTagAttributes.length+1+duplicateCount];
boolean elementNameTagAttributeSet = false;
int j = 0;
for (int i = 0; i < sourceTagAttributes.length; i++)
{
TagAttribute tagAttribute = sourceTagAttributes[i];
String convertedNamespace;
String qname;
String namespace = tagAttribute.getNamespace();
/*
-= Leonardo Uribe =- After check the javadoc and compare it with the code and try some
examples with the implementation done in the RI, we found that the javadoc of
TagDecorator has some bugs. Below is the description of the implementation done, which
resembles the behavior found on the RI.
"...
For each of argument tag's attributes obtain a reference to a TagAttribute
with the following characteristics. For discussion let such an attribute be
convertedTagAttribute.
* convertedTagAttribute's location: from the argument tag's location.
* If the current attribute's namespace is http://xmlns.jcp.org/jsf,
convertedTagAttribute's qualified name must be the current attribute's
local name and convertedTagAttribute's namespace must be the empty string.
This will have the effect of setting the current attribute as a proper
property on the UIComponent instance represented by this markup.
* If the current attribute's namespace is empty, assume the current
attribute's namespace is http://xmlns.jcp.org/jsf/passthrough.
ConvertedTagAttribute's qualified name is the current attribute's
local name prefixed by "p:". convertedTagAttribute's namespace must be
http://xmlns.jcp.org/jsf/passthrough.
* Otherwise, if the current attribute's namespace is not empty, let
the current attribute be convertedTagAttribute. This will have the
effect of let the attribute be processed by the meta rules defined
by the TagHandler instance associated with the generated target
component.
..."
*/
if (JSF_NAMESPACE.equals(namespace) || JSF_ALIAS_NAMESPACE.equals(namespace))
{
// "... If the current attribute's namespace is http://xmlns.jcp.org/jsf, convertedTagAttribute's
// qualified name must be the current attribute's local name and convertedTagAttribute's
// namespace must be the empty string. This will have the effect of setting the current
// attribute as a proper property on the UIComponent instance represented by this markup.
convertedNamespace = "";
qname = tagAttribute.getLocalName();
convertedTagAttributes[j] = new TagAttributeImpl(tagAttribute.getLocation(),
convertedNamespace, tagAttribute.getLocalName(), qname, tagAttribute.getValue());
}
else if (namespace == null)
{
// should not happen, but let it because org.xml.sax.Attributes considers it
// -= Leonardo Uribe =- after conversation with Frank Caputo, who was the main contributor for
// this feature in JSF 2.2, he said that if the namespace is empty the intention is pass the
// attribute to the passthrough attribute map, so there is an error in the spec documentation.
//convertedTagAttributes[j] = tagAttribute;
convertedNamespace = PASS_THROUGH_NAMESPACE;
qname = "p:"+tagAttribute.getLocalName();
convertedTagAttributes[j] = new TagAttributeImpl(tagAttribute.getLocation(),
convertedNamespace, tagAttribute.getLocalName(), qname, tagAttribute.getValue());
}
else if (tagAttribute.getNamespace().length() == 0)
{
// "... If the current attribute's namespace is empty
// let the current attribute be convertedTagAttribute. ..."
// -= Leonardo Uribe =- after conversation with Frank Caputo, who was the main contributor for
// this feature in JSF 2.2, he said that if the namespace is empty the intention is pass the
// attribute to the passthrough attribute map, so there is an error in the spec documentation.
//convertedTagAttributes[j] = tagAttribute;
convertedNamespace = PASS_THROUGH_NAMESPACE;
qname = "p:"+tagAttribute.getLocalName();
convertedTagAttributes[j] = new TagAttributeImpl(tagAttribute.getLocation(),
convertedNamespace, tagAttribute.getLocalName(), qname, tagAttribute.getValue());
}
else /*if (!tag.getNamespace().equals(tagAttribute.getNamespace()))*/
{
// "... or different from the argument tag's namespace,
// let the current attribute be convertedTagAttribute. ..."