/*
* $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.model;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.junit.Test;
import org.richfaces.cdk.model.ClassName;
import org.richfaces.cdk.model.FacesId;
import org.richfaces.cdk.xmlconfig.JaxbTestBase;
import com.google.common.collect.Iterables;
/**
* <p class="changed_added_4_0">
* </p>
*
* @author asmirnov@exadel.com
*
*/
public class TemplateParserTest extends JaxbTestBase {
public static final String TEMPLATE_PROLOG = "<cdk:root xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:cdk=\"http://jboss.org/schema/richfaces/cdk/core\" xmlns:c=\"http://jboss.org/schema/richfaces/cdk/jstl/core\" xmlns:cc=\"http://jboss.org/schema/richfaces/cdk/jsf/composite\"><cc:interface>";
private static final Object DEFAULT_ATTRIBUTE_TYPE = new ClassName(Object.class);
private static final String TEMPLATE_EPILOG = "</cc:implementation></cdk:root>";
private static final String TEMPLATE_MIDDLE = "</cc:interface><cc:implementation>";
@Test
public void testAttributes() throws Exception {
Template template = unmarshal(
Template.class,
TEMPLATE_PROLOG
+ "<cdk:renders-children>true</cdk:renders-children>"
+ "<cc:attribute name=\"onclick\" />"
+ "<cc:attribute name=\"mode\" default=\"ajax\" />"
+ "<cc:attribute name=\"action\" method-signature=\"void action()\" />"
+ "<cc:attribute name=\"changeListener\" method-signature=\"void changeListener(ValueChangeEvent)\" targets=\"changes changes1\" />"
+ "<cc:attribute name=\"disabled\" type=\"boolean\" />"
+ "<cc:attribute name=\"delay\" type=\"java.lang.Integer\" />"
+ "<cc:attribute name=\"id\" required=\"true\" />"
+ "<cc:attribute name=\"experts\" shortDescription=\"For use by experts\" displayName=\"Expert attribute\" expert=\"true\" />"
+ "<cc:attribute name=\"preferred\" shortDescription=\"It's a preferred attribute\" displayName=\"Preferred attribute\" preferred=\"true\" />"
+ "<cc:attribute name=\"onchange\">" + "<cc:clientBehavior event=\"change\" />"
+ "<cc:clientBehavior event=\"valueChange\" default=\"true\" />" + "</cc:attribute>" + TEMPLATE_MIDDLE
+ TEMPLATE_EPILOG);
CompositeInterface interfaceSection = template.getInterface();
assertNotNull(interfaceSection);
List<Attribute> attributes = interfaceSection.getAttributes();
assertNotNull(attributes);
assertEquals(10, attributes.size());
Attribute attribute;
attribute = attributes.get(0);
assertNotNull(attribute);
assertEquals("onclick", attribute.getName());
assertNull(attribute.getDefaultValue());
assertNull(attribute.getMethodSignature());
assertEquals(DEFAULT_ATTRIBUTE_TYPE, attribute.getType());
assertNull(attribute.getTargets());
assertNull(attribute.getRequired());
assertNull(attribute.getExpert());
assertNull(attribute.getPreferred());
attribute = attributes.get(1);
assertNotNull(attribute);
assertEquals("mode", attribute.getName());
assertEquals("ajax", attribute.getDefaultValue());
assertNull(attribute.getMethodSignature());
assertEquals(DEFAULT_ATTRIBUTE_TYPE, attribute.getType());
assertNull(attribute.getTargets());
assertNull(attribute.getRequired());
assertNull(attribute.getExpert());
assertNull(attribute.getPreferred());
attribute = attributes.get(2);
assertNotNull(attribute);
assertEquals("action", attribute.getName());
assertNull(attribute.getDefaultValue());
assertEquals("void action()", attribute.getMethodSignature());
assertEquals(DEFAULT_ATTRIBUTE_TYPE, attribute.getType());
assertNull(attribute.getTargets());
assertNull(attribute.getRequired());
assertNull(attribute.getExpert());
assertNull(attribute.getPreferred());
attribute = attributes.get(3);
assertNotNull(attribute);
assertEquals("changeListener", attribute.getName());
assertNull(attribute.getDefaultValue());
assertEquals("void changeListener(ValueChangeEvent)", attribute.getMethodSignature());
assertEquals(DEFAULT_ATTRIBUTE_TYPE, attribute.getType());
assertEquals("changes changes1", attribute.getTargets());
assertNull(attribute.getRequired());
assertNull(attribute.getExpert());
assertNull(attribute.getPreferred());
attribute = attributes.get(4);
assertNotNull(attribute);
assertEquals("disabled", attribute.getName());
assertNull(attribute.getDefaultValue());
assertNull(attribute.getMethodSignature());
assertEquals(ClassName.parseName("boolean"), attribute.getType());
assertNull(attribute.getTargets());
assertNull(attribute.getRequired());
assertNull(attribute.getExpert());
assertNull(attribute.getPreferred());
attribute = attributes.get(5);
assertNotNull(attribute);
assertEquals("delay", attribute.getName());
assertNull(attribute.getDefaultValue());
assertNull(attribute.getMethodSignature());
assertEquals(ClassName.parseName("java.lang.Integer"), attribute.getType());
assertNull(attribute.getTargets());
assertNull(attribute.getRequired());
assertNull(attribute.getExpert());
assertNull(attribute.getPreferred());
attribute = attributes.get(6);
assertNotNull(attribute);
assertEquals("id", attribute.getName());
assertNull(attribute.getDefaultValue());
assertNull(attribute.getMethodSignature());
assertEquals(DEFAULT_ATTRIBUTE_TYPE, attribute.getType());
assertNull(attribute.getTargets());
assertTrue(attribute.getRequired());
assertNull(attribute.getExpert());
assertNull(attribute.getPreferred());
attribute = attributes.get(7);
assertNotNull(attribute);
assertNull(attribute.getRequired());
assertEquals("experts", attribute.getName());
assertNull(attribute.getDefaultValue());
assertNull(attribute.getMethodSignature());
assertEquals(DEFAULT_ATTRIBUTE_TYPE, attribute.getType());
assertNull(attribute.getTargets());
assertEquals("For use by experts", attribute.getShortDescription());
assertEquals("Expert attribute", attribute.getDisplayName());
assertTrue(attribute.getExpert());
assertNull(attribute.getPreferred());
attribute = attributes.get(8);
assertNotNull(attribute);
assertNull(attribute.getRequired());
assertNull(attribute.getExpert());
assertEquals("preferred", attribute.getName());
assertNull(attribute.getDefaultValue());
assertNull(attribute.getMethodSignature());
assertEquals(DEFAULT_ATTRIBUTE_TYPE, attribute.getType());
assertEquals("It's a preferred attribute", attribute.getShortDescription());
assertEquals("Preferred attribute", attribute.getDisplayName());
assertTrue(attribute.getPreferred());
attribute = attributes.get(9);
assertNotNull(attribute);
assertEquals("onchange", attribute.getName());
List<ClientBehavior> clientBehaviors = attribute.getClientBehaviors();
assertNotNull(clientBehaviors);
assertEquals(2, clientBehaviors.size());
ClientBehavior clientBehavior;
clientBehavior = clientBehaviors.get(0);
assertNotNull(clientBehavior);
assertEquals("change", clientBehavior.getEvent());
assertFalse(clientBehavior.isDefaultEvent());
clientBehavior = clientBehaviors.get(1);
assertNotNull(clientBehavior);
assertEquals("valueChange", clientBehavior.getEvent());
assertTrue(clientBehavior.isDefaultEvent());
assertEquals(Boolean.TRUE, interfaceSection.getRendersChildren());
}
@Test
public void testImpl() throws Exception {
Template template = unmarshal(
Template.class,
TEMPLATE_PROLOG
+ TEMPLATE_MIDDLE
+ "<cdk:call expression=\"#{cc.clientId}\"/><table width=\"200\"><tbody><cdk:call expression=\"#{cc.fooMethod(clientId)}\"/></tbody></table>Header<div class='bar'>foo</div>"
+ TEMPLATE_EPILOG);
CompositeImplementation implementation = template.getImplementation();
assertNotNull(implementation);
List<Object> children = implementation.getChildren();
assertNotNull(children);
assertEquals(4, children.size());
assertEquals(CdkCallElement.class, children.get(0).getClass());
assertEquals(AnyElement.class, children.get(1).getClass());
assertEquals(String.class, children.get(2).getClass());
}
@Test
public void testInterface() throws Exception {
Template template = unmarshal(Template.class, TEMPLATE_PROLOG
+ "<cdk:class>org.richfaces.renderkit.html.TreeRenderer</cdk:class>"
+ "<cdk:superclass>org.richfaces.renderkit.TreeRendererBase</cdk:superclass>"
+ "<cdk:component-family>org.richfaces.TreeFamily</cdk:component-family>"
+ "<cdk:renderer-type>org.richfaces.TreeRenderer</cdk:renderer-type>"
+ "<cdk:renderkit-id>RF4_XHTML</cdk:renderkit-id>" + "<cdk:renders-children>false</cdk:renders-children>"
+ "<cdk:import package=\"com.foo\" names=\"Bar Fooz\" />"
+ "<cdk:import package=\"net.foo\" names=\"Field\" static=\"true\" />"
+ "<cdk:import package=\"org.foo\" names=\"*\" />" + TEMPLATE_MIDDLE + TEMPLATE_EPILOG);
CompositeInterface interfaceSection = template.getInterface();
assertNotNull(interfaceSection);
assertEquals(ClassName.parseName("org.richfaces.renderkit.html.TreeRenderer"), interfaceSection.getJavaClass());
assertEquals(ClassName.parseName("org.richfaces.renderkit.TreeRendererBase"), interfaceSection.getBaseClass());
assertEquals(FacesId.parseId("org.richfaces.TreeFamily"), interfaceSection.getComponentFamily());
assertEquals(FacesId.parseId("org.richfaces.TreeRenderer"), interfaceSection.getRendererType());
assertEquals("RF4_XHTML", interfaceSection.getRenderKitId());
assertEquals(Boolean.FALSE, interfaceSection.getRendersChildren());
List<ClassImport> classImports = interfaceSection.getClassImports();
ClassImport importElement;
Iterator<ClassImport> children = classImports.iterator();
importElement = children.next();
assertEquals("com.foo", importElement.getPackage());
assertEquals(Arrays.asList("Bar", "Fooz"), importElement.getNames());
assertFalse(importElement.isStatic());
importElement = children.next();
assertEquals("net.foo", importElement.getPackage());
assertEquals(Arrays.asList("Field"), importElement.getNames());
assertTrue(importElement.isStatic());
importElement = children.next();
assertEquals("org.foo", importElement.getPackage());
assertEquals(Arrays.asList("*"), importElement.getNames());
assertFalse(importElement.isStatic());
assertFalse(children.hasNext());
}
@Test
public void testJstlCoreElements() throws Exception {
Template template = unmarshal(Template.class, TEMPLATE_PROLOG + TEMPLATE_MIDDLE + "start"
+ "<c:if test=\"#{someTest}\">if content</c:if>" + "<c:choose>"
+ "<c:when test=\"#{anotherTest}\">when content</c:when>" + "<c:when test=\"#{coolTest}\">"
+ "<c:if test=\"#{nestedIfTest}\">nested if content</c:if>" + "</c:when>"
+ "<c:otherwise>otherwise content</c:otherwise>" + "</c:choose>"
+ "<c:forEach items=\"#{someCollection}\" var=\"iterationVar\">" + "forEach content" + "</c:forEach>"
+ "finish" + TEMPLATE_EPILOG);
CompositeImplementation implementation = template.getImplementation();
assertNotNull(implementation);
List<Object> children = implementation.getChildren();
assertNotNull(children);
assertEquals(5, children.size());
assertEquals("start", children.get(0));
assertEquals(CdkIfElement.class, children.get(1).getClass());
CdkIfElement ifElement = (CdkIfElement) children.get(1);
assertEquals("#{someTest}", ifElement.getTest());
List<Object> ifChildren = ifElement.getChildren();
assertNotNull(ifChildren);
assertEquals(1, ifChildren.size());
assertEquals("if content", ifChildren.get(0));
assertEquals(CdkChooseElement.class, children.get(2).getClass());
CdkChooseElement chooseElement = (CdkChooseElement) children.get(2);
List<Object> chooseChildren = chooseElement.getChildren();
assertNotNull(chooseChildren);
assertEquals(3, chooseChildren.size());
assertEquals(CdkWhenElement.class, chooseChildren.get(0).getClass());
CdkWhenElement firstWhen = (CdkWhenElement) chooseChildren.get(0);
assertEquals("#{anotherTest}", firstWhen.getTest());
List<Object> childrenOfFirstWhen = firstWhen.getChildren();
assertNotNull(childrenOfFirstWhen);
assertEquals(1, childrenOfFirstWhen.size());
assertEquals("when content", childrenOfFirstWhen.get(0));
assertEquals(CdkWhenElement.class, chooseChildren.get(1).getClass());
CdkWhenElement secondWhen = (CdkWhenElement) chooseChildren.get(1);
assertEquals("#{coolTest}", secondWhen.getTest());
List<Object> childrenOfSecondWhen = secondWhen.getChildren();
assertNotNull(childrenOfSecondWhen);
assertEquals(1, childrenOfSecondWhen.size());
assertEquals(CdkIfElement.class, childrenOfSecondWhen.get(0).getClass());
CdkIfElement nestedIf = (CdkIfElement) childrenOfSecondWhen.get(0);
assertEquals("#{nestedIfTest}", nestedIf.getTest());
List<Object> childrenOfNestedIf = nestedIf.getChildren();
assertNotNull(childrenOfNestedIf);
assertEquals(1, childrenOfNestedIf.size());
assertEquals("nested if content", childrenOfNestedIf.get(0));
assertEquals(CdkOtherwiseElement.class, chooseChildren.get(2).getClass());
CdkOtherwiseElement otherwiseElement = (CdkOtherwiseElement) chooseChildren.get(2);
List<Object> childrenOfOtherwiseElement = otherwiseElement.getChildren();
assertNotNull(childrenOfOtherwiseElement);
assertEquals(1, childrenOfOtherwiseElement.size());
assertEquals("otherwise content", childrenOfOtherwiseElement.get(0));
assertEquals(CdkForEachElement.class, children.get(3).getClass());
CdkForEachElement forEachElement = (CdkForEachElement) children.get(3);
assertEquals("#{someCollection}", forEachElement.getItems());
assertEquals("iterationVar", forEachElement.getVar());
List<Object> forEachChildren = forEachElement.getChildren();
assertNotNull(forEachChildren);
assertEquals(1, forEachChildren.size());
assertEquals("forEach content", forEachChildren.get(0));
assertEquals("finish", children.get(4));
}
@Test
public void testObject() throws Exception {
Template template = unmarshal(Template.class, TEMPLATE_PROLOG + TEMPLATE_MIDDLE
+ "<cdk:object name=\"rowCount\" type=\"int\" value=\"#{getRowCount(context)}\" />"
+ "<cdk:object name=\"bodyExpression\" type=\"java.lang.String\">" + "\"test expression\" +\n\"second line\""
+ "</cdk:object>" +
TEMPLATE_EPILOG);
CompositeImplementation implementation = template.getImplementation();
assertNotNull(implementation);
List<Object> children = implementation.getChildren();
assertNotNull(children);
assertEquals(2, children.size());
assertEquals(CdkObjectElement.class, children.get(0).getClass());
CdkObjectElement firstObject = (CdkObjectElement) children.get(0);
assertNotNull(firstObject);
assertEquals("rowCount", firstObject.getName());
assertEquals("int", firstObject.getType());
assertEquals("#{getRowCount(context)}", firstObject.getValue());
assertEquals(CdkObjectElement.class, children.get(1).getClass());
CdkObjectElement secondObject = (CdkObjectElement) children.get(1);
assertNotNull(secondObject);
assertEquals("bodyExpression", secondObject.getName());
assertEquals("java.lang.String", secondObject.getType());
assertEquals("\"test expression\" +\n\"second line\"", secondObject.getBodyValue());
}
@Test
public void testResourceDependencies() throws Exception {
Template template = unmarshal(Template.class, TEMPLATE_PROLOG + "<cdk:resource-dependency name=\"jquery.js\" />"
+ "<cdk:resource-dependency name=\"richfaces.css\" library=\"org.richfaces\" />"
+ "<cdk:resource-dependency name=\"richfaces.js\" library=\"org.richfaces\" target=\"body\" /> "
+ TEMPLATE_MIDDLE + TEMPLATE_EPILOG);
CompositeInterface interfaceSection = template.getInterface();
assertNotNull(interfaceSection);
assertNull(interfaceSection.getRendersChildren());
List<ResourceDependency> resourceDependencies = interfaceSection.getResourceDependencies();
assertNotNull(resourceDependencies);
assertEquals(3, resourceDependencies.size());
ResourceDependency resourceDependency;
resourceDependency = resourceDependencies.get(0);
assertNotNull(resourceDependency);
assertEquals("jquery.js", resourceDependency.getName());
assertEquals("", resourceDependency.getLibrary());
assertEquals("", resourceDependency.getTarget());
resourceDependency = resourceDependencies.get(1);
assertNotNull(resourceDependency);
assertEquals("richfaces.css", resourceDependency.getName());
assertEquals("org.richfaces", resourceDependency.getLibrary());
assertEquals("", resourceDependency.getTarget());
resourceDependency = resourceDependencies.get(2);
assertNotNull(resourceDependency);
assertEquals("richfaces.js", resourceDependency.getName());
assertEquals("org.richfaces", resourceDependency.getLibrary());
assertEquals("body", resourceDependency.getTarget());
}
@Test
public void testTemplate() throws Exception {
Template template = unmarshal(Template.class, TEMPLATE_PROLOG + TEMPLATE_MIDDLE + TEMPLATE_EPILOG);
assertNotNull(template.getInterface());
assertNotNull(template.getImplementation());
}
@Test
public void testScriptObject() throws Exception {
Template template = unmarshal(Template.class, TEMPLATE_PROLOG + TEMPLATE_MIDDLE
+ "<cdk:scriptObject name=\"hash\" base=\"#{getBaseOptions(context)}\">"
+ "<cdk:scriptOption name=\"name\" value=\"#{value}\" />"
+ "<cdk:scriptOption name=\"delay\" value=\"#{delay}\" defaultValue=\"100\" />"
+ "<cdk:scriptOption name=\"rowClasses\" value=\"#{rowClasses}\" wrapper=\"asArray\" />"
+ "<cdk:scriptOption attributes=\"min max\" />" + "<cdk:scriptOption variables=\"allowHeader allowFooter\" />"
+ "</cdk:scriptObject>" +
TEMPLATE_EPILOG);
CompositeImplementation implementation = template.getImplementation();
assertNotNull(implementation);
CdkScriptObjectElement scriptObject = (CdkScriptObjectElement) Iterables.getOnlyElement(implementation.getChildren());
assertEquals("hash", scriptObject.getName());
assertEquals("#{getBaseOptions(context)}", scriptObject.getBase());
CdkScriptOptionElement scriptOption;
Iterator<Object> children = scriptObject.getChildren().iterator();
scriptOption = (CdkScriptOptionElement) children.next();
assertEquals("name", scriptOption.getName());
assertEquals("#{value}", scriptOption.getValue());
scriptOption = (CdkScriptOptionElement) children.next();
assertEquals("delay", scriptOption.getName());
assertEquals("#{delay}", scriptOption.getValue());
assertEquals("100", scriptOption.getDefaultValue());
scriptOption = (CdkScriptOptionElement) children.next();
assertEquals("rowClasses", scriptOption.getName());
assertEquals("#{rowClasses}", scriptOption.getValue());
assertEquals("asArray", scriptOption.getWrapper());
scriptOption = (CdkScriptOptionElement) children.next();
assertEquals(Arrays.asList("min", "max"), scriptOption.getAttributes());
scriptOption = (CdkScriptOptionElement) children.next();
assertEquals(Arrays.asList("allowHeader", "allowFooter"), scriptOption.getVariables());
assertFalse(children.hasNext());
}
}