}
}
private TagAttributes convertTagAttributes(Tag tag)
{
TagAttribute elementNameTagAttribute = new TagAttributeImpl(
tag.getLocation(), PASS_THROUGH_NAMESPACE , Renderer.PASSTHROUGH_RENDERER_LOCALNAME_KEY,
P_ELEMENTNAME, tag.getLocalName() );
TagAttribute[] sourceTagAttributes = tag.getAttributes().getAll();
// FIXME: Doing a black box test over Mojarra it was found that passthrough
// attributes are added to both passthrough map and normal attribute map. It seems
// in some point the attributes are copied, but the spec doesn't mention where this
// should be. The relevant case happens when the attribute has no associated namespace,
// because in that case the user suppose the attribute will be passed through. If the use
// jsf or passthrough namespace it is clear where it should go.
// 1. Count how many attributes requires to be duplicated
int duplicateCount = 0;
for (int i = 0; i < sourceTagAttributes.length; i++)
{
TagAttribute tagAttribute = sourceTagAttributes[i];
String namespace = tagAttribute.getNamespace();
if (namespace == null)
{
// should not happen, but let it because org.xml.sax.Attributes considers it
duplicateCount++;
}
else if (tagAttribute.getNamespace().length() == 0)
{
// "... If the current attribute's namespace is empty
// let the current attribute be convertedTagAttribute. ..."
duplicateCount++;
}
}
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();
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
convertedTagAttributes[j] = tagAttribute;
j++;
// Duplicate passthrough
convertedTagAttributes[j] = new TagAttributeImpl(tagAttribute.getLocation(),
PASS_THROUGH_NAMESPACE, tagAttribute.getLocalName(),
"p:"+tagAttribute.getLocalName(), tagAttribute.getValue());
}
else if (tagAttribute.getNamespace().length() == 0)
{
// "... If the current attribute's namespace is empty
// let the current attribute be convertedTagAttribute. ..."
convertedTagAttributes[j] = tagAttribute;
j++;
// Duplicate passthrough
convertedTagAttributes[j] = new TagAttributeImpl(tagAttribute.getLocation(),
PASS_THROUGH_NAMESPACE, tagAttribute.getLocalName(),
"p:"+tagAttribute.getLocalName(), tagAttribute.getValue());
}
else if (!tag.getNamespace().equals(tagAttribute.getNamespace()))
{
// "... or different from the argument tag's namespace,
// let the current attribute be convertedTagAttribute. ..."
convertedTagAttributes[j] = tagAttribute;
}
else
{
// "... Otherwise, 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.
convertedNamespace = PASS_THROUGH_NAMESPACE;
qname = "p:"+tagAttribute.getLocalName();
convertedTagAttributes[j] = new TagAttributeImpl(tagAttribute.getLocation(),
convertedNamespace, tagAttribute.getLocalName(), qname, tagAttribute.getValue());
}
if (Renderer.PASSTHROUGH_RENDERER_LOCALNAME_KEY.equals(convertedTagAttributes[j].getLocalName()) && (
PASS_THROUGH_NAMESPACE.equals(convertedTagAttributes[j].getNamespace()) ||