JBoss Rich Faces SVN: r16233 - in root/cdk/trunk/plugins/generator/src/main: java/org/richfaces/cdk/templatecompiler and 2 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: nbelaevski
Date: 2010-01-03 18:35:42 -0500 (Sun, 03 Jan 2010)
New Revision: 16233
Modified:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaField.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/RendererClassVisitor.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/WriteAttributesSetStatement.java
root/cdk/trunk/plugins/generator/src/main/resources/META-INF/templates/java/class.ftl
root/cdk/trunk/plugins/generator/src/main/resources/META-INF/templates/java/macros/write-attribute.ftl
root/cdk/trunk/plugins/generator/src/main/resources/META-INF/templates/java/write-attributes-set.ftl
Log:
https://jira.jboss.org/jira/browse/RF-7732
Modified: root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaField.java
===================================================================
--- root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaField.java 2010-01-03 23:33:55 UTC (rev 16232)
+++ root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/builder/model/JavaField.java 2010-01-03 23:35:42 UTC (rev 16233)
@@ -21,6 +21,7 @@
package org.richfaces.builder.model;
+
/**
* Class field abstraction
*
@@ -28,8 +29,11 @@
*/
public class JavaField extends JavaLanguageElement {
private Class<?> type;
+
private Object value;
+ private Class<?>[] genericArguments;
+
public JavaField(Class<?> type, String name) {
this(type, name, null);
}
@@ -51,4 +55,40 @@
public void setValue(Object value) {
this.value = value;
}
+
+ /**
+ * @return the genericArguments
+ */
+ public Class<?>[] getGenericArguments() {
+ return genericArguments;
+ }
+
+ /**
+ * @param genericArguments the genericArguments to set
+ */
+ public void setGenericArguments(Class<?>[] genericArguments) {
+ this.genericArguments = genericArguments;
+ }
+
+ public String getGenericSignature() {
+ StringBuilder result = new StringBuilder();
+
+ if (genericArguments != null) {
+ for (Class<?> genericArgument : genericArguments) {
+ if (result.length() == 0) {
+ result.append('<');
+ } else {
+ result.append(", ");
+ }
+
+ result.append(genericArgument.getName());
+ }
+ }
+
+ if (result.length() != 0) {
+ result.append('>');
+ }
+
+ return result.toString();
+ }
}
Modified: root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/RendererClassVisitor.java
===================================================================
--- root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/RendererClassVisitor.java 2010-01-03 23:33:55 UTC (rev 16232)
+++ root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/RendererClassVisitor.java 2010-01-03 23:35:42 UTC (rev 16233)
@@ -41,6 +41,7 @@
import org.richfaces.builder.model.Argument;
import org.richfaces.builder.model.JavaClass;
+import org.richfaces.builder.model.JavaField;
import org.richfaces.builder.model.JavaMethod;
import org.richfaces.builder.model.JavaModifier;
import org.richfaces.builder.model.JavaPackage;
@@ -56,6 +57,7 @@
import org.richfaces.cdk.parser.el.ELParserUtils;
import org.richfaces.cdk.parser.el.ELVisitor;
import org.richfaces.cdk.parser.el.ParsingException;
+import org.richfaces.cdk.parser.el.StringUtils;
import org.richfaces.cdk.parser.el.Type;
import org.richfaces.cdk.parser.el.types.TypesFactory;
import org.richfaces.cdk.templatecompiler.model.AnyElement;
@@ -112,12 +114,17 @@
*/
static final String RENDERER_UTILS_VARIABLE = "utils";
- static final String RENDERER_UTILS_CLASS_NAME = "org.ajax4jsf.renderkit.RendererUtils";
+ /**
+ *
+ */
+ private static final String PASS_THROUGH_ATTRIBUTES_FIELD_NAME = "PASS_THROUGH_ATTRIBUTES";
+ private static final String RENDERER_UTILS_CLASS_NAME = "org.ajax4jsf.renderkit.RendererUtils";
+
private static final Logger LOG = LoggerFactory.getLogger();
private static final String XHTML_EL_NAMESPACE = "http://richfaces.org/cdk/xhtml-el";
-
+
private static final Set<String> DEFAULT_NAMESPACES = new HashSet<String>();
static {
@@ -139,6 +146,7 @@
private boolean isAddedMethodForCheckingEmptiness;
private Type lastCompiledExpressionType;
+ private int passThroughCounter;
public RendererClassVisitor(CompositeInterface compositeInterface, ClassLoader classLoader, JAXBBinding jaxbBinding) {
this.compositeInterface = compositeInterface;
@@ -260,6 +268,82 @@
return result;
}
+ private String createPassThroughAttributeCode(String attributeName, String[] eventNames) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("new org.richfaces.renderkit.ComponentAttribute(");
+
+ sb.append('"');
+ sb.append(StringUtils.getEscapedString(attributeName));
+ sb.append('"');
+
+ boolean isFirstEventName = true;
+ if (eventNames != null && eventNames.length != 0) {
+ sb.append(", ");
+ sb.append("new String[] {");
+
+ for (String eventName : eventNames) {
+ if (isFirstEventName) {
+ isFirstEventName = false;
+ } else {
+ sb.append(", ");
+ }
+
+ sb.append('"');
+ sb.append(StringUtils.getEscapedString(eventName));
+ sb.append('"');
+ }
+
+ sb.append("}");
+ }
+
+ sb.append(")");
+
+ return sb.toString();
+ }
+
+ private JavaField createPassThroughField(Map<String, Attribute> attributesMap) {
+ String fieldName = PASS_THROUGH_ATTRIBUTES_FIELD_NAME;
+ if (passThroughCounter >= 0) {
+ fieldName += ("_" + passThroughCounter);
+ }
+ passThroughCounter++;
+
+ // TODO generic arguments
+ JavaField passThroughField = new JavaField(Map.class, fieldName);
+ passThroughField.addModifier(JavaModifier.PRIVATE);
+ passThroughField.addModifier(JavaModifier.STATIC);
+ passThroughField.addModifier(JavaModifier.FINAL);
+
+ //TODO - refactor and remove class loading!
+ //TODO - get rid of FQNs for classes via imports
+ try {
+ passThroughField.setGenericArguments(new Class<?>[] { String.class,
+ Class.forName("org.richfaces.renderkit.ComponentAttribute", false, classLoader) });
+ } catch (ClassNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ StringBuilder fieldValue = new StringBuilder("org.richfaces.renderkit.ComponentAttribute.createMap(");
+ boolean isFirstArgument = true;
+ for (Map.Entry<String, Attribute> entry : attributesMap.entrySet()) {
+ if (isFirstArgument) {
+ isFirstArgument = false;
+ } else {
+ fieldValue.append(", ");
+ }
+
+ // TODO behaviors data
+ fieldValue.append(createPassThroughAttributeCode(entry.getKey(), null));
+ }
+
+ fieldValue.append(")");
+
+ passThroughField.setValue(fieldValue.toString());
+
+ return passThroughField;
+ }
+
private void createMethodContext() {
this.currentStatement = new MethodBody();
this.localsTypesMap = new HashMap<String, Type>();
@@ -383,6 +467,7 @@
if (!isDefaultNamespace(elementName.getNamespaceURI())) {
// TODO: add support
+ return;
}
currentStatement.addStatement(new StartElementStatement(elementName.getLocalPart()));
@@ -391,7 +476,7 @@
Set<String> writtenAttributes = new HashSet<String>();
boolean shouldEncodePassThrough = false;
String[] passThroughExclusions = null;
-
+
for (Map.Entry<QName, Object> attribute : elementAttributes.entrySet()) {
QName attributeName = attribute.getKey();
Object attributeValue = attribute.getValue();
@@ -419,23 +504,25 @@
Element attributesElement = attributesSchema.getElements().get(elementName.getLocalPart());
if (attributesElement != null) {
// make a copy of original set
- TreeMap<String, Attribute> actualAttributesMap = new TreeMap<String, Attribute>(
- attributesElement.getAttributes());
+ TreeMap<String, Attribute> actualAttributesMap = new TreeMap<String, Attribute>(attributesElement
+ .getAttributes());
if (passThroughExclusions != null) {
for (String passThroughExclusion : passThroughExclusions) {
actualAttributesMap.remove(passThroughExclusion);
}
}
-
+
for (String writtenAttribute : writtenAttributes) {
actualAttributesMap.remove(writtenAttribute);
}
-
+
if (!actualAttributesMap.isEmpty()) {
+ JavaField passThroughField = createPassThroughField(actualAttributesMap);
+ generatedClass.addField(passThroughField);
+
// TODO: optimize batch attributes encoding
- currentStatement.addStatement(new WriteAttributesSetStatement(actualAttributesMap
- .keySet()));
+ currentStatement.addStatement(new WriteAttributesSetStatement(passThroughField.getName()));
}
}
}
@@ -652,6 +739,7 @@
*/
public void preProcess() {
initializeJavaClass();
+ passThroughCounter = -1;
}
/**
Modified: root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/WriteAttributesSetStatement.java
===================================================================
--- root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/WriteAttributesSetStatement.java 2010-01-03 23:33:55 UTC (rev 16232)
+++ root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/WriteAttributesSetStatement.java 2010-01-03 23:35:42 UTC (rev 16233)
@@ -21,24 +21,23 @@
*/
package org.richfaces.cdk.templatecompiler;
-import java.util.Set;
/**
* @author Nick Belaevski
*/
public class WriteAttributesSetStatement extends AbstractTemplateMethodBodyStatement {
- private Set<String> attributesSet;
+ private String passThroughFieldName;
- public WriteAttributesSetStatement(Set<String> attributesSet) {
+ public WriteAttributesSetStatement(String passThroughFieldName) {
super("write-attributes-set");
- this.attributesSet = attributesSet;
+ this.passThroughFieldName = passThroughFieldName;
}
/**
- * @return the attributesSet
+ * @return the passThroughFieldName
*/
- public Set<String> getAttributesSet() {
- return attributesSet;
+ public String getPassThroughFieldName() {
+ return passThroughFieldName;
}
}
Modified: root/cdk/trunk/plugins/generator/src/main/resources/META-INF/templates/java/class.ftl
===================================================================
--- root/cdk/trunk/plugins/generator/src/main/resources/META-INF/templates/java/class.ftl 2010-01-03 23:33:55 UTC (rev 16232)
+++ root/cdk/trunk/plugins/generator/src/main/resources/META-INF/templates/java/class.ftl 2010-01-03 23:35:42 UTC (rev 16233)
@@ -6,7 +6,7 @@
<@renderCommonJavaElementStuff element=modelItem />class ${modelItem.name} <#if modelItem.superClass.name != 'java.lang.Object'>extends ${modelItem.superClass.name} </#if>{
<#list modelItem.fields as field>
- <@renderCommonJavaElementStuff element=field />${field.type.simpleName} ${field.name}<#if field.value??> = ${field.value}</#if>;
+ <@renderCommonJavaElementStuff element=field />${field.type.simpleName}${field.genericSignature} ${field.name}<#if field.value??> = ${field.value}</#if>;
</#list>
<#list modelItem.methods as method>
Modified: root/cdk/trunk/plugins/generator/src/main/resources/META-INF/templates/java/macros/write-attribute.ftl
===================================================================
--- root/cdk/trunk/plugins/generator/src/main/resources/META-INF/templates/java/macros/write-attribute.ftl 2010-01-03 23:33:55 UTC (rev 16232)
+++ root/cdk/trunk/plugins/generator/src/main/resources/META-INF/templates/java/macros/write-attribute.ftl 2010-01-03 23:35:42 UTC (rev 16233)
@@ -1,3 +1,3 @@
<#macro writeAttributeMacro attributeName attributeValue>
- ${rendererUtilsVariable}.writeAttribute(${responseWriterVariable}, "${attributeName}", ${attributeValue});
+org.richfaces.renderkit.RenderKitUtils.renderAttribute(${facesContextVariable}, "${attributeName}", ${attributeValue});
</#macro>
\ No newline at end of file
Modified: root/cdk/trunk/plugins/generator/src/main/resources/META-INF/templates/java/write-attributes-set.ftl
===================================================================
--- root/cdk/trunk/plugins/generator/src/main/resources/META-INF/templates/java/write-attributes-set.ftl 2010-01-03 23:33:55 UTC (rev 16232)
+++ root/cdk/trunk/plugins/generator/src/main/resources/META-INF/templates/java/write-attributes-set.ftl 2010-01-03 23:35:42 UTC (rev 16233)
@@ -1,7 +1,4 @@
<#import './macros/write-attribute.ftl' as writeAttributeTemplate />
-//passThroughWithExclusions start
-<#list modelItem.attributesSet as attributeName>
- <@writeAttributeTemplate.writeAttributeMacro attributeName="${attributeName}" attributeValue="${componentVariable}.getAttributes().get(\"${attributeName}\")" />
-</#list>
-//passThroughWithExclusions end
\ No newline at end of file
+org.richfaces.renderkit.RenderKitUtils.renderPassThroughAttributesOptimized(${facesContextVariable}, ${componentVariable},
+ ${modelItem.passThroughFieldName});
\ No newline at end of file
14 years, 11 months
JBoss Rich Faces SVN: r16232 - root/framework/trunk/commons/src/main/java/org/richfaces/renderkit.
by richfaces-svn-commits@lists.jboss.org
Author: nbelaevski
Date: 2010-01-03 18:33:55 -0500 (Sun, 03 Jan 2010)
New Revision: 16232
Added:
root/framework/trunk/commons/src/main/java/org/richfaces/renderkit/RenderKitUtils.java
Modified:
root/framework/trunk/commons/src/main/java/org/richfaces/renderkit/ComponentAttribute.java
Log:
https://jira.jboss.org/jira/browse/RF-8233
Modified: root/framework/trunk/commons/src/main/java/org/richfaces/renderkit/ComponentAttribute.java
===================================================================
--- root/framework/trunk/commons/src/main/java/org/richfaces/renderkit/ComponentAttribute.java 2009-12-30 18:06:28 UTC (rev 16231)
+++ root/framework/trunk/commons/src/main/java/org/richfaces/renderkit/ComponentAttribute.java 2010-01-03 23:33:55 UTC (rev 16232)
@@ -1,4 +1,3 @@
-package org.richfaces.renderkit;
/*
* JBoss, Home of Professional Open Source
* Copyright 2009, Red Hat, Inc. and individual contributors
@@ -21,15 +20,22 @@
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
+package org.richfaces.renderkit;
+
+import java.util.Map;
+import java.util.TreeMap;
+
/**
* @author Nick Belaevski
*/
-public class ComponentAttribute {
+public class ComponentAttribute implements Comparable<ComponentAttribute> {
private final String name;
private final String[] eventNames;
+ //TODO handling for aliases: "styleClass" -> "class"
+
public ComponentAttribute(String name) {
this(name, null);
}
@@ -40,6 +46,16 @@
this.eventNames = eventNames;
}
+ public static final Map<String, ComponentAttribute> createMap(ComponentAttribute... attributes) {
+ Map<String,ComponentAttribute> result = new TreeMap<String, ComponentAttribute>();
+
+ for (ComponentAttribute componentAttribute : attributes) {
+ result.put(componentAttribute.getName(), componentAttribute);
+ }
+
+ return result;
+ }
+
/**
* @return the name
*/
@@ -53,4 +69,8 @@
public String[] getEventNames() {
return eventNames;
}
+
+ public int compareTo(ComponentAttribute o) {
+ return getName().compareTo(o.getName());
+ }
}
Added: root/framework/trunk/commons/src/main/java/org/richfaces/renderkit/RenderKitUtils.java
===================================================================
--- root/framework/trunk/commons/src/main/java/org/richfaces/renderkit/RenderKitUtils.java (rev 0)
+++ root/framework/trunk/commons/src/main/java/org/richfaces/renderkit/RenderKitUtils.java 2010-01-03 23:33:55 UTC (rev 16232)
@@ -0,0 +1,201 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.renderkit;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIComponentBase;
+import javax.faces.component.behavior.ClientBehavior;
+import javax.faces.component.behavior.ClientBehaviorHolder;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public final class RenderKitUtils {
+
+ // TODO - check what's in MyFaces
+ private static final String ATTRIBUTES_THAT_ARE_SET = UIComponentBase.class.getName() + ".attributesThatAreSet";
+
+ private static final String[] BOOLEAN_ATTRIBUTE_NAMES = { "checked", "compact", "declare", "defer", "disabled",
+ "ismap", "multiple", "nohref", "noshade", "nowrap", "readonly", "selected" };
+
+ private static final String[] URI_ATTRIBUTE_NAMES = { "action", "background", "cite", "classid", "codebase",
+ "data", "href", "longdesc", "profile", "src", "usemap" };
+
+ private RenderKitUtils() {
+ // utility constructor
+ }
+
+ private static Map<String, List<ClientBehavior>> getClientBehaviorsMap(UIComponent component) {
+ Map<String, List<ClientBehavior>> result = null;
+ if (component instanceof ClientBehaviorHolder) {
+ ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) component;
+
+ result = clientBehaviorHolder.getClientBehaviors();
+ }
+
+ return result;
+ }
+
+ private static Object createBehaviorsChain(Object inlineHandlerValue, List<ClientBehavior> behaviors) {
+ // TODO implement properly
+ return inlineHandlerValue;
+ }
+
+ private static boolean shouldRenderAttribute(String attributeName, Object attributeValue) {
+ if (attributeValue instanceof String) {
+ return true;
+ } else if (attributeValue instanceof Boolean && Boolean.FALSE.equals(attributeValue)) {
+ return false;
+ } else if (attributeValue instanceof Integer && (Integer) attributeValue == Integer.MIN_VALUE) {
+ return false;
+ } else if (attributeValue instanceof Double && (Double) attributeValue == Double.MIN_VALUE) {
+ return false;
+ } else if (attributeValue instanceof Character && (Character) attributeValue == Character.MIN_VALUE) {
+ return false;
+ } else if (attributeValue instanceof Float && (Float) attributeValue == Float.MIN_VALUE) {
+ return false;
+ } else if (attributeValue instanceof Short && (Short) attributeValue == Short.MIN_VALUE) {
+ return false;
+ } else if (attributeValue instanceof Byte && (Byte) attributeValue == Byte.MIN_VALUE) {
+ return false;
+ } else if (attributeValue instanceof Long && (Long) attributeValue == Long.MIN_VALUE) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public static void renderAttribute(FacesContext facesContext, String attributeName, Object attributeValue)
+ throws IOException {
+
+ if (!shouldRenderAttribute(attributeName, attributeValue)) {
+ return;
+ }
+
+ ResponseWriter writer = facesContext.getResponseWriter();
+
+ if (Arrays.binarySearch(URI_ATTRIBUTE_NAMES, attributeName) >= 0) {
+ writer.writeURIAttribute(attributeName, attributeValue, attributeName);
+ } else if (Arrays.binarySearch(BOOLEAN_ATTRIBUTE_NAMES, attributeName) >= 0) {
+ boolean booleanAttributeValue = Boolean.valueOf(String.valueOf(attributeValue));
+ if (booleanAttributeValue) {
+ writer.writeAttribute(attributeName, attributeName, attributeName);
+ }
+ } else {
+ writer.writeAttribute(attributeName, attributeValue, attributeName);
+ }
+ }
+
+ public static void renderAttributeAndBehaviors(FacesContext facesContext, UIComponent component,
+ ComponentAttribute componentAttribute) throws IOException {
+
+ if (facesContext == null) {
+ throw new NullPointerException("facesContext");
+ }
+
+ if (component == null) {
+ throw new NullPointerException("component");
+ }
+
+ if (componentAttribute == null) {
+ throw new NullPointerException("componentAttribute");
+ }
+
+ String attributeName = componentAttribute.getName();
+ Object attributeValue = component.getAttributes().get(attributeName);
+
+ Map<String, List<ClientBehavior>> behaviorsMap = getClientBehaviorsMap(component);
+ if (behaviorsMap != null) {
+ String[] eventNames = componentAttribute.getEventNames();
+ if (eventNames != null) {
+ for (String eventName : eventNames) {
+ List<ClientBehavior> behaviorsList = behaviorsMap.get(eventName);
+ if (behaviorsList != null) {
+ attributeValue = createBehaviorsChain(attributeValue, behaviorsList);
+
+ break;
+ }
+ }
+ }
+ }
+
+ renderAttribute(facesContext, attributeName, attributeValue);
+ }
+
+ public static void renderPassThroughAttributesOptimized(FacesContext context, UIComponent component,
+ Map<String, ComponentAttribute> knownAttributesMap) throws IOException {
+
+ Set<String> handledAttributes = new HashSet<String>(knownAttributesMap.size());
+ Object attributesThatAreSetObject = component.getAttributes().get(ATTRIBUTES_THAT_ARE_SET);
+ if (attributesThatAreSetObject instanceof Collection<?>) {
+ Collection<?> attributesThatAreSet = (Collection<?>) attributesThatAreSetObject;
+ for (Object attributeNameObject : attributesThatAreSet) {
+ if (attributeNameObject == null) {
+ continue;
+ }
+
+ String attributeName = attributeNameObject.toString();
+
+ ComponentAttribute knownAttribute = knownAttributesMap.get(attributeName);
+ if (knownAttribute != null) {
+ handledAttributes.add(attributeName);
+
+ // TODO check for disabled component
+ renderAttributeAndBehaviors(context, component, knownAttribute);
+ }
+ }
+
+ // render attributes that haven't been processed yet - there can be behaviors
+ for (Map.Entry<String, ComponentAttribute> knownAttributesMapEntry : knownAttributesMap.entrySet()) {
+ ComponentAttribute knownAttribute = knownAttributesMapEntry.getValue();
+
+ if (handledAttributes.contains(knownAttribute.getName())) {
+ continue;
+ }
+
+ renderAttributeAndBehaviors(context, component, knownAttribute);
+ }
+ } else {
+ // switch to unoptimized mode
+ renderPassThroughAttributes(context, component, knownAttributesMap);
+ }
+ }
+
+ public static void renderPassThroughAttributes(FacesContext context, UIComponent component,
+ Map<String, ComponentAttribute> knownAttributesMap) throws IOException {
+
+ for (ComponentAttribute knownAttribute : knownAttributesMap.values()) {
+ renderAttributeAndBehaviors(context, component, knownAttribute);
+ }
+ }
+}
14 years, 11 months