/* * $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()); } }