Author: alexsmirnov
Date: 2010-07-02 20:20:40 -0400 (Fri, 02 Jul 2010)
New Revision: 17715
Added:
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/AttributesStatementTest.java
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/FreeMarkerTestBase.java
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/WriteAttributeTest.java
Modified:
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/RendererClassVisitor.java
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/model/AnyElement.java
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/model/Template.java
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/statements/AttributesStatement.java
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/statements/CaseStatement.java
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/statements/FreeMarkerTemplateStatementBase.java
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/statements/WriteAttributeStatement.java
root/cdk/branches/RF8755/plugins/generator/src/main/resources/META-INF/templates/java/write-attribute.ftl
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/FreeMarkerTemplateStatementTest1.java
Log:
tests and implementation for attributes.
Modified:
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/RendererClassVisitor.java
===================================================================
---
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/RendererClassVisitor.java 2010-07-02
18:23:59 UTC (rev 17714)
+++
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/RendererClassVisitor.java 2010-07-03
00:20:40 UTC (rev 17715)
@@ -98,33 +98,33 @@
*
*/
// TODO externalize
- static final String RENDER_KIT_UTILS_CLASS_NAME =
"org.richfaces.renderkit.RenderKitUtils";
+ public static final String RENDER_KIT_UTILS_CLASS_NAME =
"org.richfaces.renderkit.RenderKitUtils";
/**
*
*/
- static final String RESPONSE_WRITER_VARIABLE = "responseWriter";
+ public static final String RESPONSE_WRITER_VARIABLE = "responseWriter";
/**
*
*/
- static final String COMPONENT_VARIABLE = "component";
+ public static final String COMPONENT_VARIABLE = "component";
/**
*
*/
- static final String THIS_VARIABLE = "this";
+ public static final String THIS_VARIABLE = "this";
/**
*
*/
- static final String SUPER_VARIABLE = "super";
+ public static final String SUPER_VARIABLE = "super";
/**
*
*/
- static final String FACES_CONTEXT_VARIABLE = "facesContext";
+ public static final String FACES_CONTEXT_VARIABLE = "facesContext";
/**
*
*/
static final String CLIENT_ID_VARIABLE = "clientId";
- static final ImmutableMap<String, Object> ENCODE_METHOD_VARIABLES =
ImmutableMap.<String, Object> builder()
+ public static final ImmutableMap<String, Object> ENCODE_METHOD_VARIABLES =
ImmutableMap.<String, Object> builder()
.put("facesContextVariable",
RendererClassVisitor.FACES_CONTEXT_VARIABLE)
.put("componentVariable", RendererClassVisitor.COMPONENT_VARIABLE)
.put("responseWriterVariable",
RendererClassVisitor.RESPONSE_WRITER_VARIABLE)
@@ -355,7 +355,7 @@
StartElementStatement startElementStatement =
addStatement(StartElementStatement.class);
startElementStatement.setElementName(elementName.getLocalPart());
AttributesStatement attributesStatement =
addStatement(AttributesStatement.class);
- attributesStatement.setAttributes(elementAttributes);
+ attributesStatement.processAttributes(anyElement,attributes);
// Set<String> writtenAttributes = new HashSet<String>();
// boolean shouldEncodePassThrough = false;
// String[] passThroughExclusions = null;
Modified:
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/model/AnyElement.java
===================================================================
---
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/model/AnyElement.java 2010-07-02
18:23:59 UTC (rev 17714)
+++
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/model/AnyElement.java 2010-07-03
00:20:40 UTC (rev 17715)
@@ -22,10 +22,11 @@
*/
package org.richfaces.cdk.templatecompiler.model;
-
+import static org.richfaces.cdk.templatecompiler.QNameComparator.QNAME_COMPARATOR;
import java.util.Map;
import javax.xml.bind.annotation.XmlAnyAttribute;
+import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.namespace.QName;
import org.richfaces.cdk.CdkException;
@@ -40,8 +41,10 @@
public class AnyElement extends ModelFragment {
private QName name;
+ private String passThrough;
+ private String passThroughWithExclusions;
- private Map<QName, Object> attributes = Maps.newHashMap();
+ private Map<QName, Object> attributes = Maps.newTreeMap(QNAME_COMPARATOR);
/**
* <p class="changed_added_4_0"></p>
@@ -63,6 +66,40 @@
/**
* <p class="changed_added_4_0"></p>
+ * @return the passThrough
+ */
+ @XmlAttribute(namespace=Template.CDK_NAMESPACE)
+ public String getPassThrough() {
+ return this.passThrough;
+ }
+
+ /**
+ * <p class="changed_added_4_0"></p>
+ * @param passThrough the passThrough to set
+ */
+ public void setPassThrough(String passThrough) {
+ this.passThrough = passThrough;
+ }
+
+ /**
+ * <p class="changed_added_4_0"></p>
+ * @return the passThroughWithExclusions
+ */
+ @XmlAttribute(namespace=Template.CDK_NAMESPACE)
+ public String getPassThroughWithExclusions() {
+ return this.passThroughWithExclusions;
+ }
+
+ /**
+ * <p class="changed_added_4_0"></p>
+ * @param passThroughWithExclusions the passThroughWithExclusions to set
+ */
+ public void setPassThroughWithExclusions(String passThroughWithExclusions) {
+ this.passThroughWithExclusions = passThroughWithExclusions;
+ }
+
+ /**
+ * <p class="changed_added_4_0"></p>
*
* @return the attributes
*/
Modified:
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/model/Template.java
===================================================================
---
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/model/Template.java 2010-07-02
18:23:59 UTC (rev 17714)
+++
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/model/Template.java 2010-07-03
00:20:40 UTC (rev 17715)
@@ -25,12 +25,15 @@
import java.io.Serializable;
+import javax.xml.XMLConstants;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.namespace.QName;
/**
- * <p class="changed_added_4_0"></p>
- *
+ * <p class="changed_added_4_0">
+ * </p>
+ *
* @author asmirnov(a)exadel.com
*/
@XmlRootElement(name = "root", namespace = Template.CDK_NAMESPACE)
@@ -40,12 +43,14 @@
public static final String CDK_NAMESPACE =
"http://richfaces.org/cdk/core";
+ public static final String CDK_PASS_THROUGH_NAMESPACE =
"http://richfaces.org/cdk/passThrough";
+
public static final String COMPOSITE_NAMESPACE =
"http://richfaces.org/cdk/jsf/composite";
public static final String XHTML_EL_NAMESPACE =
"http://richfaces.org/cdk/xhtml-el";
public static final String XHTML_NAMESPACE =
"http://www.w3.org/1999/xhtml";
-
+
private static final long serialVersionUID = -6900382133123748812L;
private String templatePath;
@@ -63,8 +68,9 @@
}
/**
- * <p class="changed_added_4_0"></p>
- *
+ * <p class="changed_added_4_0">
+ * </p>
+ *
* @return the interface
*/
@XmlElement(name = "interface", namespace = COMPOSITE_NAMESPACE)
@@ -73,17 +79,20 @@
}
/**
- * <p class="changed_added_4_0"></p>
- *
- * @param interface1 the interface to set
+ * <p class="changed_added_4_0">
+ * </p>
+ *
+ * @param interface1
+ * the interface to set
*/
public void setInterface(CompositeInterface interface1) {
this.compositeInterface = interface1;
}
/**
- * <p class="changed_added_4_0"></p>
- *
+ * <p class="changed_added_4_0">
+ * </p>
+ *
* @return the implementation
*/
@XmlElement(name = "implementation", namespace = COMPOSITE_NAMESPACE)
@@ -92,12 +101,22 @@
}
/**
- * <p class="changed_added_4_0"></p>
- *
- * @param implementation the implementation to set
+ * <p class="changed_added_4_0">
+ * </p>
+ *
+ * @param implementation
+ * the implementation to set
*/
public void setImplementation(CompositeImplementation implementation) {
this.compositeImplementation = implementation;
}
+ public static boolean isDefaultNamespace(QName name) {
+ return isDefaultNamespace(name.getNamespaceURI());
+ }
+
+ public static boolean isDefaultNamespace(String namespace) {
+ return XMLConstants.NULL_NS_URI.equals(namespace) ||
XHTML_EL_NAMESPACE.equals(namespace)
+ || XHTML_NAMESPACE.equals(namespace);
+ }
}
Modified:
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/statements/AttributesStatement.java
===================================================================
---
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/statements/AttributesStatement.java 2010-07-02
18:23:59 UTC (rev 17714)
+++
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/statements/AttributesStatement.java 2010-07-03
00:20:40 UTC (rev 17715)
@@ -1,35 +1,222 @@
package org.richfaces.cdk.templatecompiler.statements;
+import java.util.Collection;
import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.regex.Pattern;
import javax.xml.namespace.QName;
+import org.richfaces.cdk.Logger;
+import org.richfaces.cdk.attributes.Attribute;
+import org.richfaces.cdk.attributes.Element;
import org.richfaces.cdk.attributes.Schema;
+import org.richfaces.cdk.attributes.Attribute.Kind;
+import org.richfaces.cdk.model.EventName;
+import org.richfaces.cdk.model.PropertyBase;
import org.richfaces.cdk.templatecompiler.ELParser;
+import org.richfaces.cdk.templatecompiler.RendererClassVisitor;
+import org.richfaces.cdk.templatecompiler.model.AnyElement;
import org.richfaces.cdk.templatecompiler.model.Template;
+import org.richfaces.cdk.util.Pair;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
import com.google.inject.Inject;
import com.google.inject.Provider;
+import com.google.inject.internal.Sets;
import com.google.inject.name.Named;
public class AttributesStatement extends StatementsContainer {
+ private static final Splitter PASS_THGOUGH_SPLITTER =
Splitter.on(Pattern.compile("\\s*,\\s*"));
+
private final Schema attributesSchema;
private final Provider<WriteAttributeStatement> statementProvider;
private final Provider<WriteAttributesSetStatement>
passThroughStatementProvider;
- private final ELParser parser;
+ private final Logger logger;
+ private QName elementName;
@Inject
public AttributesStatement((a)Named(Template.XHTML_EL_NAMESPACE) Schema
attributesSchema,
Provider<WriteAttributeStatement> attributeStatementProvider,
- Provider<WriteAttributesSetStatement> passThroughStatementProvider,
ELParser parser) {
+ Provider<WriteAttributesSetStatement> passThroughStatementProvider, Logger
logger) {
this.attributesSchema = attributesSchema;
this.statementProvider = attributeStatementProvider;
this.passThroughStatementProvider = passThroughStatementProvider;
- this.parser = parser;
+ this.logger = logger;
}
- public void setAttributes(Map<QName, Object> attributes) {
+ /**
+ * <p class="changed_added_4_0">
+ * </p>
+ *
+ * @param attributes
+ * @param componentAttributes
+ */
+ public void processAttributes(AnyElement element, Collection<PropertyBase>
componentAttributes) {
+ Set<String> processedAttributes = Sets.newHashSet();
+ Map<String, String> passThroughAttributes = Maps.newTreeMap();
+ this.elementName = element.getName();
+ for (Map.Entry<QName, Object> entry : element.getAttributes().entrySet())
{
+ QName qName = entry.getKey();
+ if (Template.CDK_NAMESPACE.equals(qName.getNamespaceURI())) {
+ // TODO - CDK attributes should be assigned to AnyElement attribute, log
error.
+ } else {
+ Object value = entry.getValue();
+ String localAttributeName = qName.getLocalPart();
+ if (Template.CDK_PASS_THROUGH_NAMESPACE.equals(qName.getNamespaceURI()))
{
+ // TODO - check empty attribute value.
+ // pass through attribute in format <div
pf:class="styleClass" />
+ passThroughAttributes.put(localAttributeName, value.toString());
+ processedAttributes.add(localAttributeName);
+ } else if (Template.isDefaultNamespace(qName.getNamespaceURI())) {
+ Attribute schemaAttribute = getSchemaAttribute(localAttributeName);
+ setupAttributeStatement(qName, value, schemaAttribute);
+ processedAttributes.add(localAttributeName);
+ } else {
+ setupAttributeStatement(qName, value,
getGenericAttribute(localAttributeName));
+ }
+ }
+ }
+ String passThrough = element.getPassThrough();
+ if (null != passThrough) {
+ // cdk:passThrough="class:styleClass,style , id:clientId"
+ Iterable<String> split = PASS_THGOUGH_SPLITTER.split(passThrough);
+ for (String attribute : split) {
+ String[] split2 = attribute.split(":");
+ String attributeName = split2[0];
+ if (processedAttributes.add(attributeName)) {
+ Attribute schemaAttribute = getSchemaAttribute(attributeName);
+ String componentAttributeName =
+ split2.length > 1 ? split2[1] :
schemaAttribute.getComponentAttributeName();
+ // WriteAttributeStatement writeAttributeStatement =
createAttributeStatement();
+ // processPassThroughAttribute(componentAttributes,
QName.valueOf(attributeName),
+ // writeAttributeStatement, componentAttributeName);
+ passThroughAttributes.put(attributeName, componentAttributeName);
+ }
+ }
+ }
+ String passThroughWithExclusions = element.getPassThroughWithExclusions();
+ if (null != passThroughWithExclusions) {
+ // cdk:passThroughWithExclusions="id,class,style"
+ Map<String, Element> elements = attributesSchema.getElements();
+ String elementLocalName = elementName.getLocalPart();
+ if (Template.isDefaultNamespace(elementName) &&
elements.containsKey(elementLocalName)) {
+ Element schemaElement = elements.get(elementLocalName);
+ Iterable<String> exclusions =
PASS_THGOUGH_SPLITTER.split(passThroughWithExclusions);
+ Iterables.addAll(processedAttributes, exclusions);
+ for (Attribute schemaAttribute : schemaElement.getAttributes().values())
{
+ if(!processedAttributes.contains(schemaAttribute.getName())){
+ passThroughAttributes.put(schemaAttribute.getName(),
schemaAttribute.getComponentAttributeName());
+ }
+ }
+ }
+ }
+ if(!passThroughAttributes.isEmpty()){
+ WriteAttributesSetStatement writeAttributesSetStatement =
passThroughStatementProvider.get();
+ addStatement(writeAttributesSetStatement);
+ // TODO - setup passThrough statement
+ }
+ }
+ private void processPassThroughAttribute(Collection<PropertyBase>
componentAttributes, QName qName,
+ String componentAttributeName) {
+ // Pass through attribute which value represents component attribute.
+ Attribute schemaAttribute = getSchemaAttribute(qName.getLocalPart());
+ // TODO -send statement directly ?
+ String expression =
+ "#{" +
RendererClassVisitor.ENCODE_METHOD_VARIABLES.get("componentVariable") +
".getAttributes().get(\""
+ + componentAttributeName + "\")}";
+ WriteAttributeStatement writeAttributeStatement = setupAttributeStatement(qName,
expression, schemaAttribute);
+ // Check for behavior events.
+ if (Kind.GENERIC.equals(schemaAttribute.getKind())) {
+ try {
+ PropertyBase componentAttribute =
findComponentAttribute(componentAttributeName, componentAttributes);
+ Set<EventName> eventNames = componentAttribute.getEventNames();
+ writeAttributeStatement.setEvents(Iterables.transform(eventNames, new
Function<EventName, String>() {
+ @Override
+ public String apply(EventName from) {
+ return from.getName();
+ }
+ }));
+ } catch (NoSuchElementException e) {
+ // Ignore it, no behavior such attribute defined.
+ logger.warn("Attribute " + componentAttributeName + " was
not defined for renderer");
+ }
+ }
}
+
+ private WriteAttributeStatement createAttributeStatement() {
+ WriteAttributeStatement writeAttributeStatement = statementProvider.get();
+ addStatement(writeAttributeStatement);
+ return writeAttributeStatement;
+ }
+
+ private PropertyBase findComponentAttribute(final String name,
Collection<PropertyBase> componentAttributes)
+ throws NoSuchElementException {
+ return Iterables.find(componentAttributes, new Predicate<PropertyBase>() {
+ @Override
+ public boolean apply(PropertyBase input) {
+ return name.equals(input.getName());
+ }
+ });
+
+ }
+
+ private WriteAttributeStatement setupAttributeStatement(QName qName,Object value,
+ Attribute schemaAttribute) {
+ WriteAttributeStatement writeAttributeStatement = createAttributeStatement();
+ String defaultValue = schemaAttribute.getDefaultValue();
+ switch (schemaAttribute.getKind()) {
+ case GENERIC:
+ writeAttributeStatement.setAttribute(qName, value, defaultValue);
+ break;
+ case URI:
+ writeAttributeStatement.setUriAttribute(qName, value, defaultValue);
+ break;
+ case BOOLEAN:
+ writeAttributeStatement.setBooleanAttribute(qName, value, defaultValue);
+ break;
+ }
+ return writeAttributeStatement;
+ }
+
+ protected Kind getAttributeKind(String attributeName) {
+ return getSchemaAttribute(attributeName).getKind();
+ }
+
+ protected Attribute getSchemaAttribute(String attributeName) {
+ Attribute result;
+ Map<String, Element> elements = attributesSchema.getElements();
+ String elementLocalName = elementName.getLocalPart();
+ if (Template.isDefaultNamespace(elementName) &&
elements.containsKey(elementLocalName)) {
+ Element schemaElement = elements.get(elementLocalName);
+ if (schemaElement.getAttributes().containsKey(attributeName)) {
+ result = schemaElement.getAttributes().get(attributeName);
+ } else {
+ result = getGenericAttribute(attributeName);
+ }
+ } else {
+ result = getGenericAttribute(attributeName);
+ }
+ return result;
+ }
+
+ protected Attribute getGenericAttribute(String name) {
+ Attribute attribute = new Attribute(name);
+ attribute.setKind(Kind.GENERIC);
+ // TODO - check default exceptions like class -> styleClass;
+ if ("class".equals(name)) {
+ attribute.setComponentAttributeName("styleClass");
+
+ } else {
+ attribute.setComponentAttributeName(name);
+ }
+ return attribute;
+ }
}
Modified:
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/statements/CaseStatement.java
===================================================================
---
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/statements/CaseStatement.java 2010-07-02
18:23:59 UTC (rev 17714)
+++
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/statements/CaseStatement.java 2010-07-03
00:20:40 UTC (rev 17715)
@@ -33,9 +33,6 @@
private String[] values;
- public CaseStatement() {
- this(null);
- }
@Inject
public CaseStatement(@TemplateModel FreeMarkerRenderer renderer) {
Modified:
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/statements/FreeMarkerTemplateStatementBase.java
===================================================================
---
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/statements/FreeMarkerTemplateStatementBase.java 2010-07-02
18:23:59 UTC (rev 17714)
+++
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/statements/FreeMarkerTemplateStatementBase.java 2010-07-03
00:20:40 UTC (rev 17715)
@@ -44,7 +44,7 @@
public class FreeMarkerTemplateStatementBase extends StatementsContainer {
protected StatementsContainer parent;
- private final String templateName;
+ private String templateName;
private final FreeMarkerRenderer renderer;
private final Set<JavaImport> imports =
Sets.newTreeSet(JavaImport.COMPARATOR);
private final EnumSet<HelperMethod> requiredMethods =
EnumSet.noneOf(HelperMethod.class);
@@ -73,6 +73,14 @@
}
}
+ /**
+ * <p class="changed_added_4_0">Some templates use modelItem
variable</p>
+ * @return
+ */
+ public Object getModelItem() {
+ return this;
+ }
+
@Override
public Iterable<JavaImport> getRequiredImports() {
parse();
@@ -96,6 +104,10 @@
requiredMethods.add(helperMethod);
}
}
+
+ public void setTemplateName(String templateName) {
+ this.templateName = templateName+".ftl";
+ }
public void addConstant(String type, String name, String code) {
JavaField field = new JavaField(new ReferencedType(type),name);
Modified:
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/statements/WriteAttributeStatement.java
===================================================================
---
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/statements/WriteAttributeStatement.java 2010-07-02
18:23:59 UTC (rev 17714)
+++
root/cdk/branches/RF8755/plugins/generator/src/main/java/org/richfaces/cdk/templatecompiler/statements/WriteAttributeStatement.java 2010-07-03
00:20:40 UTC (rev 17715)
@@ -21,8 +21,19 @@
*/
package org.richfaces.cdk.templatecompiler.statements;
+import java.util.Collection;
+import java.util.Collections;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+
+import org.richfaces.cdk.Logger;
import org.richfaces.cdk.generate.freemarker.FreeMarkerRenderer;
+import org.richfaces.cdk.templatecompiler.ELParser;
import org.richfaces.cdk.templatecompiler.TemplateModel;
+import org.richfaces.cdk.templatecompiler.el.ParsingException;
+import org.richfaces.cdk.templatecompiler.el.types.ELType;
+import org.richfaces.cdk.templatecompiler.el.types.TypesFactory;
import com.google.inject.Inject;
@@ -31,28 +42,89 @@
*/
public class WriteAttributeStatement extends FreeMarkerTemplateStatementBase {
- private String name;
+ private String attributeName;
private TypedTemplateStatement valueExpression;
+ private final ELParser parser;
+ private final Logger log;
+
+ private String defaultValue;
+
+ private Iterable<String> events = Collections.emptyList();
+
+
@Inject
- public WriteAttributeStatement(@TemplateModel FreeMarkerRenderer renderer) {
+ public WriteAttributeStatement(@TemplateModel FreeMarkerRenderer renderer,ELParser
parser,Logger log) {
super(renderer,"write-attribute");
+ this.parser = parser;
+ this.log = log;
}
- public void setAttribute(String name,TypedTemplateStatement expression) {
- this.name = name;
- this.valueExpression = expression;
- addRequiredMethods(HelperMethod.WRITE_ATTRIBUTE);
+ public void setAttribute(QName qName,Object object, String defaultValue) {
+ this.defaultValue = defaultValue;
+ setAttributeName(qName);
+ parseExpression(object, TypesFactory.OBJECT_TYPE);
}
- public String getName() {
- return name;
+ public void setUriAttribute(QName qName, Object value, String defaultValue) {
+ setTemplateName("write-uri-attribute");
+ setAttribute(qName, value, defaultValue);
}
+ public void setBooleanAttribute(QName qName, Object value, String defaultValue) {
+ setTemplateName("write-boolean-attribute");
+ setAttribute(qName, value, defaultValue);
+ }
+
+ private void parseExpression(Object object, ELType objectType) {
+ try {
+ valueExpression = parser.parse(object.toString(), this, objectType);
+ this.addStatement(valueExpression);
+ } catch (ParsingException e) {
+ log.error("Error parsing expression for attribute
"+getAttributeName(), e);
+ }
+ }
+
+ private void setAttributeName(QName qName) {
+ StringBuilder nameBuilder = new StringBuilder();
+ if(!XMLConstants.DEFAULT_NS_PREFIX.equals(qName.getPrefix())){
+ nameBuilder.append(qName.getPrefix()).append(':');
+ }
+ this.attributeName = nameBuilder.append(qName.getLocalPart()).toString();
+ }
+
+ public String getAttributeName() {
+ return attributeName;
+ }
+
public TypedTemplateStatement getValue() {
return valueExpression;
}
+ /**
+ * <p class="changed_added_4_0"></p>
+ * @return the defaultValue
+ */
+ public String getDefaultValue() {
+ return this.defaultValue;
+ }
+
+ /**
+ * <p class="changed_added_4_0"></p>
+ * @param iterable the events to set
+ */
+ public void setEvents(Iterable<String> iterable) {
+ this.events = iterable;
+ }
+
+ /**
+ * <p class="changed_added_4_0"></p>
+ * @return the events
+ */
+ public Iterable<String> getEvents() {
+ return this.events;
+ }
+
}
Modified:
root/cdk/branches/RF8755/plugins/generator/src/main/resources/META-INF/templates/java/write-attribute.ftl
===================================================================
---
root/cdk/branches/RF8755/plugins/generator/src/main/resources/META-INF/templates/java/write-attribute.ftl 2010-07-02
18:23:59 UTC (rev 17714)
+++
root/cdk/branches/RF8755/plugins/generator/src/main/resources/META-INF/templates/java/write-attribute.ftl 2010-07-03
00:20:40 UTC (rev 17715)
@@ -1 +1 @@
-RenderKitUtils.renderAttribute(${facesContextVariable},
"${modelItem.attributeName}", ${modelItem.valueExpression});
\ No newline at end of file
+RenderKitUtils.renderAttribute(${facesContextVariable},
"${modelItem.attributeName}", ${modelItem.value.code});
\ No newline at end of file
Added:
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/AttributesStatementTest.java
===================================================================
---
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/AttributesStatementTest.java
(rev 0)
+++
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/AttributesStatementTest.java 2010-07-03
00:20:40 UTC (rev 17715)
@@ -0,0 +1,178 @@
+/*
+ * $Id$
+ *
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package org.richfaces.cdk.templatecompiler.statements;
+
+import static org.easymock.EasyMock.*;
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.*;
+
+import java.util.Collection;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.easymock.EasyMock;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.richfaces.cdk.CdkTestBase;
+import org.richfaces.cdk.CdkTestRunner;
+import org.richfaces.cdk.Logger;
+import org.richfaces.cdk.Mock;
+import org.richfaces.cdk.MockController;
+import org.richfaces.cdk.attributes.Attribute;
+import org.richfaces.cdk.attributes.Attribute.Kind;
+import org.richfaces.cdk.attributes.Element;
+import org.richfaces.cdk.attributes.Schema;
+import org.richfaces.cdk.generate.freemarker.FreeMarkerRenderer;
+import org.richfaces.cdk.model.EventName;
+import org.richfaces.cdk.model.ModelSet;
+import org.richfaces.cdk.model.PropertyBase;
+import org.richfaces.cdk.model.PropertyModel;
+import org.richfaces.cdk.templatecompiler.ELParser;
+import org.richfaces.cdk.templatecompiler.TemplateModel;
+import org.richfaces.cdk.templatecompiler.el.types.TypesFactory;
+import org.richfaces.cdk.templatecompiler.model.AnyElement;
+import org.richfaces.cdk.templatecompiler.model.Template;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.inject.Binder;
+import com.google.inject.Inject;
+import com.google.inject.name.Names;
+
+/**
+ * <p class="changed_added_4_0"></p>
+ * @author asmirnov(a)exadel.com
+ *
+ */
+(a)RunWith(CdkTestRunner.class)
+public class AttributesStatementTest extends CdkTestBase {
+
+ @Mock
+ private Logger log;
+
+ @Mock
+ private ELParser parser;
+ @Mock
+ private TypedTemplateStatement parsedExpression;
+
+ @Mock
+ @TemplateModel
+ private FreeMarkerRenderer renderer;
+
+ @Inject
+ private AttributesStatement statement;
+
+ @Inject
+ private MockController controller;
+
+
+ @Override
+ public void configure(Binder binder) {
+ super.configure(binder);
+ Schema schema = new Schema();
+ Element element = new Element("div");
+ createSchemaAttribute(element, "class",null,Kind.GENERIC);
+ createSchemaAttribute(element, "href",null,Kind.URI);
+ createSchemaAttribute(element, "disabled",null,Kind.BOOLEAN);
+ schema.addElement(element);
+
binder.bind(Schema.class).annotatedWith(Names.named(Template.XHTML_EL_NAMESPACE)).toInstance(schema);
+ }
+ private void createSchemaAttribute(Element element, String name,String
defaultValue,Kind kind) {
+ Attribute attribute = new Attribute(name);
+ attribute.setDefaultValue(defaultValue);
+ attribute.setComponentAttributeName(name+"Component");
+ attribute.setKind(kind);
+ element.addAttribute(attribute);
+ }
+ /**
+ * Test method for {@link
org.richfaces.cdk.templatecompiler.statements.AttributesStatement#processAttributes(java.util.Map,
java.util.Collection)}.
+ * @throws Exception
+ */
+ @Test
+ public void testProcessSimpleHtmlAttribute() throws Exception {
+ expect(parser.parse(eq("header"), isA(WriteAttributeStatement.class),
same(TypesFactory.OBJECT_TYPE))).andReturn(parsedExpression);
+ parsedExpression.setParent(isA(WriteAttributeStatement.class));expectLastCall();
+ processAttributes("div", "id", "header");
+ assertEquals(1, statement.getStatements().size());
+ assertThat(statement.getStatements().get(0),
instanceOf(WriteAttributeStatement.class));
+ }
+ private void processAttributes(String element, String attribute, String value)
throws Exception {
+ Collection<PropertyBase> componentAttributes =
createComponentAttributes();
+ processAttributes(element, attribute, value, componentAttributes);
+ }
+ private void processAttributes(String element, String attribute, String value,
Collection<PropertyBase> componentAttributes) throws Exception {
+ controller.replay();
+ AnyElement anyElement = new AnyElement();
+ anyElement.setName(QName.valueOf(element));
+ anyElement.getAttributes().putAll(createAttributesMap(attribute, value));
+ statement.processAttributes(anyElement, componentAttributes);
+ controller.verify();
+ }
+
+ /**
+ * Test method for {@link
org.richfaces.cdk.templatecompiler.statements.AttributesStatement#processAttributes(java.util.Map,
java.util.Collection)}.
+ */
+ @Test
+ public void testProcessLiteralAttribute() {
+ fail("Not yet implemented");
+ }
+ /**
+ * Test method for {@link
org.richfaces.cdk.templatecompiler.statements.AttributesStatement#processAttributes(java.util.Map,
java.util.Collection)}.
+ */
+ @Test
+ public void testProcessElAttribute() {
+ fail("Not yet implemented");
+ }
+ /**
+ * Test method for {@link
org.richfaces.cdk.templatecompiler.statements.AttributesStatement#processAttributes(java.util.Map,
java.util.Collection)}.
+ */
+ @Test
+ public void testProcessHtmlAttributeWithBehavior() {
+ fail("Not yet implemented");
+ }
+
+ private Map<QName, Object> createAttributesMap(String name, String value){
+ ImmutableMap<QName,Object> map = ImmutableMap.<QName,
Object>of(QName.valueOf(name),value);
+ return map;
+ }
+
+ private PropertyBase createComponentAttribute(String name,String ...events) {
+ PropertyBase property = new PropertyModel();
+ property.setName(name);
+ for (String event : events) {
+ EventName eventName = new EventName();
+ eventName.setName(event);
+ property.getEventNames().add(eventName);
+ }
+ return property;
+ }
+
+ private Collection<PropertyBase> createComponentAttributes(PropertyBase
...properties) {
+ ModelSet<PropertyBase> attributes = ModelSet.<PropertyBase>create();
+ for (PropertyBase prop : properties) {
+ attributes.add(prop);
+ }
+ return attributes;
+ }
+}
Property changes on:
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/AttributesStatementTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified:
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/FreeMarkerTemplateStatementTest1.java
===================================================================
---
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/FreeMarkerTemplateStatementTest1.java 2010-07-02
18:23:59 UTC (rev 17714)
+++
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/FreeMarkerTemplateStatementTest1.java 2010-07-03
00:20:40 UTC (rev 17715)
@@ -2,7 +2,6 @@
import static org.junit.Assert.*;
-import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -11,25 +10,15 @@
import org.richfaces.cdk.Logger;
import org.richfaces.cdk.MockController;
import org.richfaces.cdk.Stub;
-import org.richfaces.cdk.generate.freemarker.CdkConfiguration;
-import org.richfaces.cdk.generate.freemarker.DefaultImports;
-import org.richfaces.cdk.generate.freemarker.FreeMarkerRenderer;
-import org.richfaces.cdk.generate.freemarker.TemplatesFolder;
-import org.richfaces.cdk.templatecompiler.JavaClassModelWrapper;
-import org.richfaces.cdk.templatecompiler.TemplateModel;
import org.richfaces.cdk.templatecompiler.builder.model.JavaField;
import org.richfaces.cdk.templatecompiler.builder.model.JavaImport;
-import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
-import com.google.inject.Binder;
import com.google.inject.Inject;
-import com.google.inject.TypeLiteral;
-import freemarker.template.ObjectWrapper;
@RunWith(CdkTestRunner.class)
-public class FreeMarkerTemplateStatementTest1 extends CdkTestBase {
+public class FreeMarkerTemplateStatementTest1 extends FreeMarkerTestBase {
private static final String FOO_CODE = "private static final String foo;";
@@ -37,25 +26,10 @@
private Logger log;
@Inject
- @TemplateModel
- private FreeMarkerRenderer renderer;
-
-
-
- @Inject
private MockController controller;
- @Override
- public void configure(Binder binder) {
- super.configure(binder);
- binder.bind(ObjectWrapper.class).to(JavaClassModelWrapper.class);
-
binder.bind(FreeMarkerRenderer.class).annotatedWith(TemplateModel.class).to(CdkConfiguration.class);
-
binder.bind(String.class).annotatedWith(TemplatesFolder.class).toInstance("/META-INF/templates/java");
- binder.bind(new
TypeLiteral<Map<String,String>>(){}).annotatedWith(DefaultImports.class).toInstance(ImmutableMap.of("util","util.ftl"));
- }
-
public FreeMarkerTemplateStatementBase setUpStatement(String template) {
FreeMarkerTemplateStatementBase freeMarkerStatement = new
FreeMarkerTemplateStatementBase(renderer, template);
return freeMarkerStatement;
Added:
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/FreeMarkerTestBase.java
===================================================================
---
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/FreeMarkerTestBase.java
(rev 0)
+++
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/FreeMarkerTestBase.java 2010-07-03
00:20:40 UTC (rev 17715)
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package org.richfaces.cdk.templatecompiler.statements;
+
+import java.util.Map;
+
+import org.richfaces.cdk.CdkTestBase;
+import org.richfaces.cdk.generate.freemarker.CdkConfiguration;
+import org.richfaces.cdk.generate.freemarker.DefaultImports;
+import org.richfaces.cdk.generate.freemarker.FreeMarkerRenderer;
+import org.richfaces.cdk.generate.freemarker.TemplatesFolder;
+import org.richfaces.cdk.templatecompiler.JavaClassModelWrapper;
+import org.richfaces.cdk.templatecompiler.RendererClassVisitor;
+import org.richfaces.cdk.templatecompiler.TemplateModel;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.inject.Binder;
+import com.google.inject.Inject;
+import com.google.inject.TypeLiteral;
+
+import freemarker.template.ObjectWrapper;
+
+/**
+ * <p class="changed_added_4_0"></p>
+ * @author asmirnov(a)exadel.com
+ *
+ */
+public class FreeMarkerTestBase extends CdkTestBase {
+
+ @Inject
+ @TemplateModel
+ protected FreeMarkerRenderer renderer;
+
+ @Override
+ public void configure(Binder binder) {
+ super.configure(binder);
+ binder.bind(ObjectWrapper.class).to(JavaClassModelWrapper.class);
+
binder.bind(FreeMarkerRenderer.class).annotatedWith(TemplateModel.class).to(CdkConfiguration.class);
+
binder.bind(String.class).annotatedWith(TemplatesFolder.class).toInstance("/META-INF/templates/java");
+ binder.bind(new
TypeLiteral<Map<String,String>>(){}).annotatedWith(DefaultImports.class).toInstance(ImmutableMap.of("util","util.ftl"));
+ binder.bind(new TypeLiteral<Map<String, Object>>() {
+ }).toInstance(RendererClassVisitor.ENCODE_METHOD_VARIABLES);
+ }
+
+}
Property changes on:
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/FreeMarkerTestBase.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added:
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/WriteAttributeTest.java
===================================================================
---
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/WriteAttributeTest.java
(rev 0)
+++
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/WriteAttributeTest.java 2010-07-03
00:20:40 UTC (rev 17715)
@@ -0,0 +1,50 @@
+package org.richfaces.cdk.templatecompiler.statements;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
+
+import javax.xml.namespace.QName;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.richfaces.cdk.CdkTestRunner;
+import org.richfaces.cdk.Logger;
+import org.richfaces.cdk.Mock;
+import org.richfaces.cdk.MockController;
+import org.richfaces.cdk.Stub;
+import org.richfaces.cdk.templatecompiler.ELParser;
+import org.richfaces.cdk.templatecompiler.el.types.TypesFactory;
+
+import com.google.inject.Inject;
+
+(a)RunWith(CdkTestRunner.class)
+public class WriteAttributeTest extends FreeMarkerTestBase {
+ private static final String HTTP_EXAMPLE_COM = "http://example.com/";
+
+ @Stub
+ private Logger log;
+
+ @Mock
+ private ELParser parser;
+ @Mock
+ private TypedTemplateStatement parsedExpression;
+
+ @Inject
+ private MockController controller;
+
+ @Inject
+ private WriteAttributeStatement statement;
+
+ @Test
+ public void testWriteLiteral() throws Exception {
+ expect(parser.parse(HTTP_EXAMPLE_COM, statement,
TypesFactory.OBJECT_TYPE)).andReturn(parsedExpression);
+ expect(parsedExpression.getCode()).andStubReturn(HTTP_EXAMPLE_COM);
+ expect(parsedExpression.isLiteral()).andStubReturn(true);
+ parsedExpression.setParent(statement);expectLastCall();
+ controller.replay();
+ statement.setAttribute(QName.valueOf("href"), HTTP_EXAMPLE_COM);
+ String code = statement.getCode();
+ controller.verify();
+
+ }
+}
Property changes on:
root/cdk/branches/RF8755/plugins/generator/src/test/java/org/richfaces/cdk/templatecompiler/statements/WriteAttributeTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain