/* * 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.cdk.templatecompiler.parser.el.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.io.Writer; import java.util.List; import java.util.Map; import javax.faces.context.FacesContext; import org.junit.Test; import org.junit.runner.RunWith; import org.richfaces.cdk.CdkClassLoader; import org.richfaces.cdk.CdkTestBase; import org.richfaces.cdk.CdkTestRunner; import org.richfaces.cdk.templatecompiler.el.types.ELPropertyDescriptor; import org.richfaces.cdk.templatecompiler.el.types.ELType; import org.richfaces.cdk.templatecompiler.el.types.TypeParserFactory; import org.richfaces.cdk.templatecompiler.el.types.TypesFactory; import org.richfaces.cdk.templatecompiler.el.types.TypesFactoryImpl; import com.google.inject.Binder; import com.google.inject.Inject; /** * @author Nick Belaevski * */ @RunWith(CdkTestRunner.class) public class TypesFactoryTest extends CdkTestBase { @Inject TypesFactory typesFactory; @Override public void configure(Binder binder) { super.configure(binder); binder.bind(CdkClassLoader.class).toInstance(createClassLoader()); binder.bind(TypeParserFactory.class); binder.bind(TypesFactory.class).to(TypesFactoryImpl.class); } private static final class ParameterizedTypesHolder { @SuppressWarnings("unused") public List<String>[] getArray() { return null; } @SuppressWarnings("unused") public Map<String, Object> getMap() { return null; } @SuppressWarnings("unused") public <Abc> Abc getTypeVariableList() { return null; } @SuppressWarnings("unused") public List<? extends String> getWildcardList() { return null; } } private java.lang.reflect.Type getParameterizedArrayType() throws Exception { return ParameterizedTypesHolder.class.getMethod("getArray").getGenericReturnType(); } private java.lang.reflect.Type getParameterizedMapType() throws Exception { return ParameterizedTypesHolder.class.getMethod("getMap").getGenericReturnType(); } private java.lang.reflect.Type getTypeVariableType() throws Exception { return ParameterizedTypesHolder.class.getMethod("getTypeVariableList").getGenericReturnType(); } private java.lang.reflect.Type getWildcardType() throws Exception { return ParameterizedTypesHolder.class.getMethod("getWildcardList").getGenericReturnType(); } @Test public void testCaching() throws Exception { ELType objectType = typesFactory.getType(Object.class); ELType objectType2 = typesFactory.getType(Object.class); assertNotNull(objectType); assertNotNull(objectType2); assertSame(objectType, objectType2); } @Test public void testGetTypeFromReflectionType() throws Exception { ELType integerType = typesFactory.getType(Integer.TYPE); assertNotNull(integerType); assertEquals(Integer.TYPE.getName(), integerType.getRawName()); assertFalse(integerType.isArray()); assertFalse(integerType.isNullType()); ELType stringType = typesFactory.getType(String.class); assertNotNull(stringType); assertEquals(String.class.getName(), stringType.getRawName()); assertEquals(0, stringType.getTypeArguments().length); assertFalse(stringType.isArray()); assertFalse(stringType.isNullType()); ELType arrayType = typesFactory.getType(String[].class); assertNotNull(arrayType); assertEquals(0, arrayType.getTypeArguments().length); assertTrue(arrayType.isArray()); assertEquals(String.class.getName(), arrayType.getContainerType().getRawName()); assertFalse(arrayType.isNullType()); ELType multiDimArrayType = typesFactory.getType(String[][][].class); assertNotNull(multiDimArrayType); assertEquals(0, multiDimArrayType.getTypeArguments().length); assertTrue(multiDimArrayType.isArray()); // assertEquals(String[][].class, multiDimArrayType.getContainerType().getRawName()); assertFalse(multiDimArrayType.isNullType()); ELType parameterizedMapType = typesFactory.getType(getParameterizedMapType()); assertNotNull(parameterizedMapType); assertFalse(parameterizedMapType.isArray()); assertEquals(Map.class.getName(), parameterizedMapType.getRawName()); ELType[] parameterizedMapTypeArguments = parameterizedMapType.getTypeArguments(); assertNotNull(parameterizedMapTypeArguments); assertEquals(2, parameterizedMapTypeArguments.length); assertEquals(String.class.getName(), parameterizedMapTypeArguments[0].getRawName()); assertEquals(Object.class.getName(), parameterizedMapTypeArguments[1].getRawName()); ELType parameterizedArrayType = typesFactory.getType(getParameterizedArrayType()); assertNotNull(parameterizedArrayType); assertTrue(parameterizedArrayType.isArray()); // assertEquals(List[].class, parameterizedArrayType.getRawName()); ELType[] parameterizedArrayTypeArguments = parameterizedArrayType.getTypeArguments(); assertNotNull(parameterizedArrayTypeArguments); assertEquals(1, parameterizedArrayTypeArguments.length); ELType parameterizedArrayTypeArgument = parameterizedArrayTypeArguments[0]; assertEquals(String.class.getName(), parameterizedArrayTypeArgument.getRawName()); assertFalse(parameterizedArrayTypeArgument.isArray()); ELType typeVariableType = typesFactory.getType(getTypeVariableType()); assertNotNull(typeVariableType); assertEquals("Abc", typeVariableType.getCode()); ELType wildcardTypeHolder = typesFactory.getType(getWildcardType()); assertNotNull(wildcardTypeHolder); assertEquals(List.class.getName(), wildcardTypeHolder.getRawName()); ELType[] wildcardTypeHolderArguments = wildcardTypeHolder.getTypeArguments(); assertNotNull(wildcardTypeHolderArguments); assertEquals(1, wildcardTypeHolderArguments.length); ELType wildcardType = wildcardTypeHolderArguments[0]; assertEquals("? extends java.lang.String", wildcardType.getCode()); } @Test public void testGetTypeFromString() throws Exception { ELType primitiveIntType = typesFactory.getType("int"); assertNotNull(primitiveIntType); assertEquals(Integer.TYPE.getName(), primitiveIntType.getRawName()); ELType guessedMapType = typesFactory.getType("Map"); assertNotNull(guessedMapType); assertEquals(Map.class.getName(), guessedMapType.getRawName()); ELType writerType = typesFactory.getType(java.io.Writer.class.getName()); assertNotNull(writerType); assertEquals(Writer.class.getName(), writerType.getRawName()); assertEquals(0, writerType.getTypeArguments().length); ELType genericMapType = typesFactory.getType("Map<String, Object>"); assertNotNull(genericMapType); assertEquals(Map.class.getName(), genericMapType.getRawName()); ELType[] genericMapTypeArguments = genericMapType.getTypeArguments(); assertNotNull(genericMapTypeArguments); assertFalse(genericMapType.isArray()); assertEquals(2, genericMapTypeArguments.length); ELType genericMapTypeKeyArgument = genericMapTypeArguments[0]; assertEquals(String.class.getName(), genericMapTypeKeyArgument.getRawName()); ELType genericMapTypeValueArgument = genericMapTypeArguments[1]; assertEquals(Object.class.getName(), genericMapTypeValueArgument.getRawName()); ELType arrayType = typesFactory.getType("String[]"); assertNotNull(arrayType); assertTrue(arrayType.isArray()); // assertEquals(String[].class, arrayType.getRawName()); ELType genericArrayType = typesFactory.getType("List<String>[]"); assertNotNull(genericArrayType); assertTrue(genericArrayType.isArray()); // assertEquals(List[].class, genericArrayType.getRawName()); ELType[] genericArrayTypeArguments = genericArrayType.getTypeArguments(); assertNotNull(genericArrayTypeArguments); assertEquals(1, genericArrayTypeArguments.length); ELType genericArrayTypeArgument = genericArrayTypeArguments[0]; assertEquals(String.class.getName(), genericArrayTypeArgument.getRawName()); } @Test public void testReferencedType() throws Exception { String className = "some.not.available.Class"; ELType plainReferencedType = typesFactory.getType(className); assertNotNull(plainReferencedType); assertEquals(className, plainReferencedType.getCode()); String arraySignature = className + "[]"; ELType arrayReferencedType = typesFactory.getType(arraySignature); assertNotNull(arrayReferencedType); assertTrue(arrayReferencedType.isArray()); assertEquals(arraySignature, arrayReferencedType.getCode()); String genericSignature = className + "<String>"; ELType genericReferenceType = typesFactory.getType(genericSignature); assertNotNull(genericReferenceType); assertEquals(genericSignature, genericReferenceType.getCode()); ELType[] genericTypeArguments = genericReferenceType.getTypeArguments(); assertNotNull(genericTypeArguments); assertEquals(1, genericTypeArguments.length); ELType genericTypeArgument = genericTypeArguments[0]; assertEquals(String.class.getName(), genericTypeArgument.getRawName()); } public ELPropertyDescriptor getAndCheckPropertyDescriptor(Class<?> clazz, String propertyName, String getMethodName, Class<?> expectedType, boolean readable, boolean writable) throws Exception { ELPropertyDescriptor checkPropertyDescriptor = getAndCheckPropertyDescriptor(clazz, propertyName, getMethodName, expectedType); assertEquals(writable, checkPropertyDescriptor.isWritable()); assertEquals(readable, checkPropertyDescriptor.isReadable()); return checkPropertyDescriptor; } public ELPropertyDescriptor getAndCheckPropertyDescriptor(Class<?> clazz, String propertyName, String getMethodName, Class<?> expectedType) throws Exception { ELType beanType = typesFactory.getType(clazz); ELPropertyDescriptor propertyDescriptor = typesFactory.getPropertyDescriptor(beanType, propertyName); assertNotNull(propertyDescriptor); assertEquals(getMethodName, propertyDescriptor.getReadMethodName()); assertEquals(expectedType.getName(), propertyDescriptor.getType().getRawName()); return propertyDescriptor; } @Test public void testGetStringProperty() throws Exception { ELPropertyDescriptor propertyDescriptor = getAndCheckPropertyDescriptor(Bean2.class, "string", "getString", String.class, true, true); } @Test public void testGetRawMapProperty() throws Exception { ELPropertyDescriptor propertyDescriptor = getAndCheckPropertyDescriptor(Bean.class, "rawMap", "getRawMap", Map.class, true, true); } @Test public void testGetBooleanProperty() throws Exception { ELPropertyDescriptor propertyDescriptor = getAndCheckPropertyDescriptor(Bean.class, "readOnly", "isReadOnly", Boolean.TYPE, true, true); } @Test public void testGetContextProperty() throws Exception { ELPropertyDescriptor propertyDescriptor = getAndCheckPropertyDescriptor(Bean.class, "context", "getContext", FacesContext.class, true, false); } @Test public void testGetDummyProperty() throws Exception { ELPropertyDescriptor propertyDescriptor = getAndCheckPropertyDescriptor(Bean.class, "nonExistedProperty", "getNonExistedProperty", Object.class, false, false); } public ELType findAndCheckMethod(Class<?> clazz, String methodName, Class<?> expectedType, Class<?>... arguments) throws Exception { ELType beanType = typesFactory.getType(clazz); ELType[] parameters = new ELType[arguments.length]; for (int i = 0; i < arguments.length; i++) { parameters[i] = typesFactory.getType(arguments[i]); } ELType returnType = typesFactory.getMatchingVisibleMethodReturnType(beanType, methodName, parameters); assertNotNull(returnType); assertEquals(expectedType.getName(), returnType.getRawName()); return returnType; } @Test public void testFindCountMethod() throws Exception { findAndCheckMethod(Bean.class, "count", Integer.class, Integer.TYPE); } @Test public void testFindCountMethodWithWrongParameter() throws Exception { findAndCheckMethod(Bean.class, "count", Object.class, String.class); } @Test public void testFindToStringMethod() throws Exception { findAndCheckMethod(Bean.class, "toString", String.class); } @Test public void testFindCollectionMethod() throws Exception { ELType type = findAndCheckMethod(Bean.class, "getComponents", List.class); assertEquals(UIComponent.class.getName(), type.getContainerType().getRawName()); } }