/*
* JBoss, Home of Professional Open Source
* Copyright 2010, 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.cdk.templatecompiler;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.isNull;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
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.assertSame;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import javax.faces.event.ActionEvent;
import javax.faces.render.RenderKitFactory;
import javax.faces.validator.Validator;
import org.easymock.EasyMock;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.richfaces.cdk.As;
import org.richfaces.cdk.CdkTestBase;
import org.richfaces.cdk.CdkTestRunner;
import org.richfaces.cdk.FileManager;
import org.richfaces.cdk.Mock;
import org.richfaces.cdk.Source;
import org.richfaces.cdk.Sources;
import org.richfaces.cdk.model.ClassName;
import org.richfaces.cdk.model.ComponentLibrary;
import org.richfaces.cdk.model.EventName;
import org.richfaces.cdk.model.FacesId;
import org.richfaces.cdk.model.MethodSignature;
import org.richfaces.cdk.model.PropertyBase;
import org.richfaces.cdk.model.RenderKitModel;
import org.richfaces.cdk.model.RendererModel;
import org.richfaces.cdk.templatecompiler.model.Template;
import org.richfaces.cdk.xmlconfig.JAXB;
import org.richfaces.cdk.xmlconfig.JAXBBinding;
import org.xml.sax.InputSource;
import org.xml.sax.ext.EntityResolver2;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
/**
* @author Nick Belaevski
*
*/
@RunWith(CdkTestRunner.class)
public class RendererTemplateParserTest extends CdkTestBase {
@Inject
@As(JAXBBinding.class)
private JAXB binding;
@Inject
private ComponentLibrary library;
@Inject
private RendererTemplateParser parser;
@Mock
private EntityResolver2 resolver;
@Mock
@Source(Sources.RENDERER_TEMPLATES)
private FileManager templatesSource;
private void assertNoDefaultValue(PropertyBase property) {
assertNull(property.getDefaultValue());
}
private void assertNoEventNames(PropertyBase property) {
Set<EventName> eventNames = property.getEventNames();
assertNotNull(eventNames);
assertTrue(eventNames.isEmpty());
}
private void assertNoSignature(PropertyBase property) {
MethodSignature signature = property.getSignature();
assertNull(signature);
}
private void assertNotRequired(PropertyBase property) {
assertFalse(property.isRequired());
}
@Test
public void basicComponentTest() throws Exception {
Template template = parser.parseTemplate(getJavaFile("org/richfaces/cdk/templatecompiler/basic.template.xml"));
assertNotNull(template);
parser.mergeTemplateIntoModel(template, null);
RenderKitModel renderKit = getRenderkitFromModel(RenderKitFactory.HTML_BASIC_RENDER_KIT);
RendererModel renderer = getFirstRendererFromRenderkit(renderKit);
assertEquals(new ClassName("org.richfaces.renderkit.html.BasicRendererImpl"), renderer.getRendererClass());
assertFalse(renderer.isRendersChildren());
}
/**
* Checks that method signature satisfies the following declaration: <code>java.lang.String action()</code>
*
* @param actionProperty
*/
private void checkDummyComponentAction(PropertyBase actionProperty) {
assertNotNull(actionProperty);
assertNoEventNames(actionProperty);
assertNotNull(actionProperty.getSignature());
assertEquals(0, actionProperty.getSignature().getParameters().size());
assertEquals(String.class.getName(), actionProperty.getSignature().getReturnType().toString());
}
/**
* Checks that method signature satisfies the following declaration:
* <code>void actionListener(javax.faces.event.ActionEvent)</code>
*
* @param actionListenerProperty
*/
private void checkDummyComponentActionListener(PropertyBase actionListenerProperty) {
assertNotNull(actionListenerProperty);
assertNoEventNames(actionListenerProperty);
assertEquals(Lists.newArrayList(new ClassName(ActionEvent.class)), actionListenerProperty.getSignature()
.getParameters());
}
/**
* Checks that method signature satisfies the following declaration:
* <code>float coolMethod(int, java.lang.String, javax.faces.validator.Validator)</code>
*
* @param coolMethodProperty
*/
private void checkDummyComponentCoolMethod(PropertyBase coolMethodProperty) {
assertNotNull(coolMethodProperty);
assertNoEventNames(coolMethodProperty);
ArrayList<ClassName> expectedSignature = Lists.newArrayList(new ClassName(int.class), new ClassName(String.class),
new ClassName(Validator.class));
assertEquals(expectedSignature, coolMethodProperty.getSignature().getParameters());
}
private void checkDummyComponentImportedAttribute(PropertyBase importedAttribute, Class<?> type) {
assertNotNull(importedAttribute);
assertNoEventNames(importedAttribute);
assertNoSignature(importedAttribute);
assertNoDefaultValue(importedAttribute);
assertFalse(importedAttribute.isRequired());
assertEquals(type.getName(), importedAttribute.getType().getName());
}
/**
* @param integerAttribute
*/
private void checkDummyComponentIntegerAttribute(PropertyBase integerAttribute) {
assertNotNull(integerAttribute);
assertNoEventNames(integerAttribute);
assertNoSignature(integerAttribute);
assertNotRequired(integerAttribute);
assertEquals(new ClassName(Integer.class), integerAttribute.getType());
assertEquals("-1", integerAttribute.getDefaultValue());
}
/**
* Checks the following conditions for attribute:<br />
* - signature is empty<br />
* - There's a single "change" event name that is not a default event<br />
*
* @param onchangeAttr
*/
private void checkDummyComponentOnchange(PropertyBase onchangeAttr) {
assertNotNull(onchangeAttr);
assertNoSignature(onchangeAttr);
Set<EventName> changeEvents = onchangeAttr.getEventNames();
assertNotNull(changeEvents);
EventName changeEventName;
Iterator<EventName> changeEventsIterator = changeEvents.iterator();
assertTrue(changeEventsIterator.hasNext());
changeEventName = changeEventsIterator.next();
assertEquals("change", changeEventName.getName());
assertFalse(changeEventName.isDefaultEvent());
assertFalse(changeEventsIterator.hasNext());
}
/**
* Checks the following conditions for attribute:<br />
*
* - signature is empty<br />
* - First event name is "click" and it's not a default event<br />
* - Second event name is "action" and it is a default event<br />
*
* @param onclickAttr
*/
private void checkDummyComponentOnclick(PropertyBase onclickAttr) {
assertNotNull(onclickAttr);
assertNoSignature(onclickAttr);
Set<EventName> clickEvents = onclickAttr.getEventNames();
assertNotNull(clickEvents);
EventName clickEventName;
Iterator<EventName> clickEventsIterator = clickEvents.iterator();
assertTrue(clickEventsIterator.hasNext());
clickEventName = clickEventsIterator.next();
assertEquals("click", clickEventName.getName());
assertFalse(clickEventName.isDefaultEvent());
assertTrue(clickEventsIterator.hasNext());
clickEventName = clickEventsIterator.next();
assertEquals("action", clickEventName.getName());
assertTrue(clickEventName.isDefaultEvent());
assertFalse(clickEventsIterator.hasNext());
}
/**
* @param requiredAttribute
*/
private void checkDummyComponentRequiredAttribute(PropertyBase requiredAttribute) {
assertNotNull(requiredAttribute);
assertNoEventNames(requiredAttribute);
assertNoSignature(requiredAttribute);
assertNoDefaultValue(requiredAttribute);
assertTrue(requiredAttribute.isRequired());
assertEquals("That's a required attribute", requiredAttribute.getDescription());
assertEquals("Required Attribute", requiredAttribute.getDisplayName());
}
@Test
// TODO - fix import-attributes.
public void dummyComponentTest() throws Exception {
expect(resolver.getExternalSubset(EasyMock.<String>eq("cdk:root"), (String) anyObject())).andStubReturn(null);
expect(
resolver.resolveEntity((String) isNull(),
eq("urn:resource:org/richfaces/cdk/templatecompiler/dummy-attributes.xml")))
.andStubReturn(
new InputSource(this.getClass().getResourceAsStream(
"/org/richfaces/cdk/templatecompiler/dummy-attributes.xml")));
expect(resolver.getExternalSubset(EasyMock.<String>eq("cdk:properties"), (String) isNull())).andStubReturn(null);
expect(resolver.resolveEntity((String) isNull(), eq("urn:attributes:dummy-template-props.xml"))).andStubReturn(
new InputSource(this.getClass().getResourceAsStream("/META-INF/cdk/attributes/dummy-template-props.xml")));
expect(resolver.getExternalSubset(EasyMock.<String>eq("cdk:properties"), (String) isNull())).andStubReturn(null);
replay(resolver, templatesSource);
Template template = parser.parseTemplate(getJavaFile("org/richfaces/cdk/templatecompiler/dummy.template.xml"));
assertNotNull(template);
parser.mergeTemplateIntoModel(template, null);
verify(resolver, templatesSource);
RenderKitModel renderKit = getRenderkitFromModel("org.richfaces.CUSTOM_RENDERKIT");
RendererModel renderer = getFirstRendererFromRenderkit(renderKit);
assertEquals(new ClassName("org.richfaces.renderkit.html.DummyRendererImpl"), renderer.getRendererClass());
assertTrue(renderer.isRendersChildren());
assertEquals(FacesId.parseId("org.richfaces.Dummy"), renderer.getFamily());
assertSame(template, renderer.getTemplate());
Collection<PropertyBase> attributes = renderer.getAttributes();
assertNotNull(attributes);
checkDummyComponentOnclick(getAttribute(attributes, "onclick"));
checkDummyComponentOnchange(getAttribute(attributes, "onchange"));
checkDummyComponentAction(getAttribute(attributes, "action"));
checkDummyComponentActionListener(getAttribute(attributes, "actionListener"));
checkDummyComponentCoolMethod(getAttribute(attributes, "coolMethod"));
checkDummyComponentIntegerAttribute(getAttribute(attributes, "integerAttribute"));
checkDummyComponentRequiredAttribute(getAttribute(attributes, "requiredAttribute"));
checkDummyComponentImportedAttribute(getAttribute(attributes, "anotherImportedStringProperty"), String.class);
checkDummyComponentImportedAttribute(getAttribute(attributes, "anotherImportedProperty"), Object.class);
checkDummyComponentImportedAttribute(getAttribute(attributes, "importedBooleanProperty"), boolean.class);
checkDummyComponentImportedAttribute(getAttribute(attributes, "importedIntegerProperty"), Integer.class);
assertEquals(11, attributes.size());
}
private PropertyBase getAttribute(Collection<PropertyBase> attributes, String string) {
for (PropertyBase property : attributes) {
if (string.equals(property.getName())) {
return property;
}
}
return null;
}
private RendererModel getFirstRendererFromRenderkit(RenderKitModel renderKit) {
Collection<RendererModel> renderers = renderKit.getRenderers();
assertNotNull(renderers);
Iterator<RendererModel> renderersIterator = renderers.iterator();
assertTrue(renderersIterator.hasNext());
RendererModel renderer = renderersIterator.next();
assertNotNull(renderer);
return renderer;
}
private RenderKitModel getRenderkitFromModel(String renderkitId) {
RenderKitModel renderKit = library.getRenderKit(new FacesId(renderkitId));
assertNotNull(renderKit);
return renderKit;
}
}