Author: nbelaevski
Date: 2009-12-16 10:48:23 -0500 (Wed, 16 Dec 2009)
New Revision: 16152
Added:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/ComplexType.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/NullType.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/PlainClassType.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/ReferencedType.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/TypesFactory.java
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/UnsupportedType.java
Log:
https://jira.jboss.org/jira/browse/RF-7732
Fixed NPE in CDK
Fixed CheckStyle errors in CDK
Added:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/ComplexType.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/ComplexType.java
(rev 0)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/ComplexType.java 2009-12-16
15:48:23 UTC (rev 16152)
@@ -0,0 +1,233 @@
+/*
+ * 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.parser.el.types;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.richfaces.cdk.parser.el.Type;
+import org.richfaces.cdk.util.ArrayUtils;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class ComplexType implements Type {
+
+ private Type clearComponentType;
+
+ private Type[] typeArguments;
+
+ private Class<?> cachedRawType;
+
+ private int arrayDepth;
+
+ public ComplexType(Type clearComponentType, Type[] typeArguments, int arrayDepth) {
+ super();
+ this.clearComponentType = clearComponentType;
+ this.typeArguments = typeArguments;
+ this.arrayDepth = arrayDepth;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.richfaces.cdk.parser.el.Type#getImportsList()
+ */
+ @Override
+ public Collection<Class<?>> getImportsList() {
+ Set<Class<?>> result = new LinkedHashSet<Class<?>>();
+
+ result.addAll(clearComponentType.getImportsList());
+ for (Type typeArgument : typeArguments) {
+ result.addAll(typeArgument.getImportsList());
+ }
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.richfaces.cdk.parser.el.Type#isNullType()
+ */
+ @Override
+ public boolean isNullType() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.richfaces.cdk.parser.el.Type#getTypeArguments()
+ */
+ @Override
+ public Type[] getTypeArguments() {
+ return typeArguments;
+ }
+
+ @Override
+ public Type getContainerType() {
+ if (arrayDepth != 0) {
+ return new ComplexType(clearComponentType, typeArguments, arrayDepth - 1);
+ } else {
+ if (!ArrayUtils.isEmpty(typeArguments)) {
+ return typeArguments[typeArguments.length - 1];
+ } else {
+ return TypesFactory.getType(Object.class);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.richfaces.cdk.parser.el.Type#getCode()
+ */
+ @Override
+ public String getCode() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(clearComponentType.getCode());
+
+ if (!ArrayUtils.isEmpty(typeArguments)) {
+ sb.append("<");
+ for (int i = 0; i < typeArguments.length; i++) {
+ Type typeArgument = typeArguments[i];
+
+ if (i != 0) {
+ sb.append(", ");
+ }
+
+ sb.append(typeArgument.getCode());
+ }
+
+ sb.append(">");
+ }
+
+ for (int i = 0; i < arrayDepth; i++) {
+ sb.append("[]");
+ }
+
+ return sb.toString();
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + arrayDepth;
+ result = prime * result + ((clearComponentType == null) ? 0 :
clearComponentType.hashCode());
+ result = prime * result + Arrays.hashCode(typeArguments);
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ ComplexType other = (ComplexType) obj;
+ if (arrayDepth != other.arrayDepth) {
+ return false;
+ }
+ if (clearComponentType == null) {
+ if (other.clearComponentType != null) {
+ return false;
+ }
+ } else if (!clearComponentType.equals(other.clearComponentType)) {
+ return false;
+ }
+ if (!Arrays.equals(typeArguments, other.typeArguments)) {
+ return false;
+ }
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getRawType()
+ */
+ @Override
+ public Class<?> getRawType() {
+ if (cachedRawType == null) {
+ Class<?> rawType = clearComponentType.getRawType();
+ if (rawType != null) {
+ if (arrayDepth != 0) {
+ int[] dimensions = new int[arrayDepth];
+ //TODO: more efficient way to create array class
+ cachedRawType = Array.newInstance(rawType, dimensions).getClass();
+ } else {
+ cachedRawType = rawType;
+ }
+ }
+ }
+
+ return cachedRawType;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#isArray()
+ */
+ @Override
+ public boolean isArray() {
+ return arrayDepth != 0;
+ }
+
+ /* (non-Javadoc)
+ * @see
org.richfaces.cdk.parser.el.Type#isAssignableFrom(org.richfaces.cdk.parser.el.Type)
+ */
+ @Override
+ public boolean isAssignableFrom(Type anotherType) {
+ Class<?> thisWrapperClass = TypesFactory.getWrapperClass(getRawType());
+ Class<?> anotherWrapperClass =
TypesFactory.getWrapperClass(anotherType.getRawType());
+
+ if (thisWrapperClass.isAssignableFrom(anotherWrapperClass)) {
+ Type[] thisTypeArguments = getTypeArguments();
+ if (ArrayUtils.isEmpty(thisTypeArguments)) {
+ return true;
+ }
+
+ Type[] anotherTypeArguments = anotherType.getTypeArguments();
+ if (ArrayUtils.isEmpty(anotherTypeArguments)) {
+ return true;
+ }
+
+ return Arrays.equals(thisTypeArguments, anotherTypeArguments);
+ } else {
+ return false;
+ }
+ }
+}
Added:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/NullType.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/NullType.java
(rev 0)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/NullType.java 2009-12-16
15:48:23 UTC (rev 16152)
@@ -0,0 +1,116 @@
+/*
+ * 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.parser.el.types;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.richfaces.cdk.parser.el.Type;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public final class NullType implements Type {
+
+ public static final Type INSTANCE = new NullType();
+
+ /**
+ *
+ */
+ private NullType() {
+ //this class is a singleton, thus has private ctor
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getCode()
+ */
+ @Override
+ public String getCode() {
+ throw new UnsupportedOperationException();
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getImportsIterator()
+ */
+ @Override
+ public Collection<Class<?>> getImportsList() {
+ return Collections.emptyList();
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#isNullType()
+ */
+ @Override
+ public boolean isNullType() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getRawType()
+ */
+ @Override
+ public Class<?> getRawType() {
+ //TODO review
+ return Object.class;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getTypeArguments()
+ */
+ @Override
+ public Type[] getTypeArguments() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return getClass().getName();
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getContainerType()
+ */
+ @Override
+ public Type getContainerType() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#isArray()
+ */
+ @Override
+ public boolean isArray() {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see
org.richfaces.cdk.parser.el.Type#isAssignableFrom(org.richfaces.cdk.parser.el.Type)
+ */
+ @Override
+ public boolean isAssignableFrom(Type anotherType) {
+ return true;
+ }
+}
\ No newline at end of file
Added:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/PlainClassType.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/PlainClassType.java
(rev 0)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/PlainClassType.java 2009-12-16
15:48:23 UTC (rev 16152)
@@ -0,0 +1,162 @@
+/*
+ * 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.parser.el.types;
+
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.richfaces.cdk.parser.el.Type;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class PlainClassType implements Type {
+
+ private Class<?> clazz;
+
+ public PlainClassType(Class<?> clazz) {
+ super();
+
+ if (clazz.isArray()) {
+ throw new IllegalArgumentException("Array classes are not
supported");
+ }
+
+ this.clazz = clazz;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getCode()
+ */
+ @Override
+ public String getCode() {
+ return clazz.getSimpleName();
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getImportsIterator()
+ */
+ @Override
+ public Collection<Class<?>> getImportsList() {
+ return Arrays.<Class<?>>asList(clazz);
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#isNullType()
+ */
+ @Override
+ public boolean isNullType() {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getRawType()
+ */
+ @Override
+ public Class<?> getRawType() {
+ return clazz;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getTypeArguments()
+ */
+ @Override
+ public Type[] getTypeArguments() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((clazz == null) ? 0 : clazz.hashCode());
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ PlainClassType other = (PlainClassType) obj;
+ if (clazz == null) {
+ if (other.clazz != null) {
+ return false;
+ }
+ } else if (!clazz.equals(other.clazz)) {
+ return false;
+ }
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return MessageFormat.format("{0}: {1}", getClass().getName(),
clazz.toString());
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getCompositeType()
+ */
+ @Override
+ public Type getContainerType() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#isArray()
+ */
+ @Override
+ public boolean isArray() {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see
org.richfaces.cdk.parser.el.Type#isAssignableFrom(org.richfaces.cdk.parser.el.Type)
+ */
+ @Override
+ public boolean isAssignableFrom(Type anotherType) {
+ if (anotherType.isNullType()) {
+ return !clazz.isPrimitive();
+ } else {
+ Class<?> thisWrapperClass = TypesFactory.getWrapperClass(clazz);
+ Class<?> anotherWrapperClass =
TypesFactory.getWrapperClass(anotherType.getRawType());
+
+ return thisWrapperClass.isAssignableFrom(anotherWrapperClass);
+ }
+ }
+}
Added:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/ReferencedType.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/ReferencedType.java
(rev 0)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/ReferencedType.java 2009-12-16
15:48:23 UTC (rev 16152)
@@ -0,0 +1,171 @@
+/*
+ * 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.parser.el.types;
+
+import java.text.MessageFormat;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.richfaces.cdk.parser.el.Type;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class ReferencedType implements Type {
+
+ private String referencedClassName;
+
+ private Class<?> knownType;
+
+ public ReferencedType(String className) {
+ this(className, Object.class);
+ }
+
+ public ReferencedType(String className, Class<?> knownType) {
+ super();
+
+ this.referencedClassName = className;
+ this.knownType = knownType;
+ }
+
+ /**
+ * @return the referencedClassName
+ */
+ String getReferencedClassName() {
+ return referencedClassName;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getCode()
+ */
+ @Override
+ public String getCode() {
+ return referencedClassName;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getImportsList()
+ */
+ @Override
+ public Collection<Class<?>> getImportsList() {
+ return Collections.emptyList();
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getRawType()
+ */
+ @Override
+ public Class<?> getRawType() {
+ return knownType;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#isNullType()
+ */
+ @Override
+ public boolean isNullType() {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getTypeArguments()
+ */
+ @Override
+ public Type[] getTypeArguments() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((referencedClassName == null) ? 0 :
referencedClassName.hashCode());
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ ReferencedType other = (ReferencedType) obj;
+ if (referencedClassName == null) {
+ if (other.referencedClassName != null) {
+ return false;
+ }
+ } else if (!referencedClassName.equals(other.referencedClassName)) {
+ return false;
+ }
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return MessageFormat.format("{0}: {1}", getClass().getName(),
getCode());
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getCompositeType()
+ */
+ @Override
+ public Type getContainerType() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#isArray()
+ */
+ @Override
+ public boolean isArray() {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see
org.richfaces.cdk.parser.el.Type#isAssignableFrom(org.richfaces.cdk.parser.el.Type)
+ */
+ @Override
+ public boolean isAssignableFrom(Type anotherType) {
+ if (anotherType instanceof ReferencedType) {
+ ReferencedType anotherReferencedType = (ReferencedType) anotherType;
+
+ return
getReferencedClassName().equals(anotherReferencedType.getReferencedClassName());
+ }
+
+ return false;
+ }
+}
Added:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/TypesFactory.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/TypesFactory.java
(rev 0)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/TypesFactory.java 2009-12-16
15:48:23 UTC (rev 16152)
@@ -0,0 +1,293 @@
+/*
+ * 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.parser.el.types;
+
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.behavior.Behavior;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+
+import org.richfaces.cdk.parser.el.Type;
+import org.richfaces.cdk.util.ArrayUtils;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public final class TypesFactory {
+
+ private static final Map<java.lang.reflect.Type, Type> REFLECTION_TYPES_CACHE =
+ Collections.synchronizedMap(new HashMap<java.lang.reflect.Type, Type>());
+
+ private static final Map<String, Type> REFERENCED_TYPES_CACHE =
+ Collections.synchronizedMap(new HashMap<String, Type>());
+
+ private static final Map<Class<?>, Class<?>>
PRIMITIVE_TO_WRAPPER_CLASSES_MAP;
+ private static final Map<String, Class<?>> PRIMITIVE_CLASSES_MAP;
+
+ static {
+ Map<Class<?>, Class<?>> primitiveToWrapperClassesMap = new
HashMap<Class<?>, Class<?>>();
+ primitiveToWrapperClassesMap.put(Boolean.TYPE, Boolean.class);
+ primitiveToWrapperClassesMap.put(Float.TYPE, Float.class);
+ primitiveToWrapperClassesMap.put(Long.TYPE, Long.class);
+ primitiveToWrapperClassesMap.put(Integer.TYPE, Integer.class);
+ primitiveToWrapperClassesMap.put(Short.TYPE, Short.class);
+ primitiveToWrapperClassesMap.put(Byte.TYPE, Byte.class);
+ primitiveToWrapperClassesMap.put(Double.TYPE, Double.class);
+ primitiveToWrapperClassesMap.put(Character.TYPE, Character.class);
+
+ PRIMITIVE_TO_WRAPPER_CLASSES_MAP =
Collections.unmodifiableMap(primitiveToWrapperClassesMap);
+
+ Map<String, Class<?>> primitiveClassesMap = new HashMap<String,
Class<?>>();
+ for (Class<?> primitiveClass : PRIMITIVE_TO_WRAPPER_CLASSES_MAP.keySet())
{
+ primitiveClassesMap.put(primitiveClass.getName(), primitiveClass);
+ }
+
+ PRIMITIVE_CLASSES_MAP = Collections.unmodifiableMap(primitiveClassesMap);
+ }
+
+ private static final Pattern CLASS_SIGNATURE_PATTERN = Pattern.compile("^"
+
+ "\\s*([^\\[<]+)\\s*" + //class name
+ "(?:<\\s*(.*)\\s*>)?\\s*" + //generic signature
+ "((?:\\[\\s*\\]\\s*)+)?\\s*" + //array signature
+ "$");
+
+ private static final int CLASS_NAME_GROUP_IDX = 1;
+
+ private static final int TYPE_ARGUMENTS_GROUP_IDX = 2;
+
+ private static final int ARRAY_SIGNATURE_GROUP_IDX = 3;
+
+ private static final int ARRAY_SIGNATURE_LENGTH = "[]".length();
+
+ private static final String[] GUESS_PACKAGES;
+
+ static {
+ Class<?>[] guessPackagesClasses = {
+ UIComponent.class,
+ Behavior.class,
+ Converter.class,
+ FacesContext.class,
+ Collection.class,
+ Object.class
+ };
+
+ GUESS_PACKAGES = new String[guessPackagesClasses.length];
+ int i = 0;
+ for (Class<?> guessPackageClass : guessPackagesClasses) {
+ GUESS_PACKAGES[i++] = guessPackageClass.getPackage().getName();
+ }
+ }
+
+ private TypesFactory() {
+ }
+
+ private static Type getPlainClassType(Class<?> plainClass) {
+ Type plainClassType = REFLECTION_TYPES_CACHE.get(plainClass);
+ if (plainClassType == null) {
+ plainClassType = new PlainClassType(plainClass);
+ REFLECTION_TYPES_CACHE.put(plainClass, plainClassType);
+ }
+
+ return plainClassType;
+ }
+
+ private static Type getReferencedType(String referencedClassName) {
+ Type type = REFERENCED_TYPES_CACHE.get(referencedClassName);
+ if (type == null) {
+ type = new ReferencedType(referencedClassName);
+ REFERENCED_TYPES_CACHE.put(referencedClassName, type);
+ }
+
+ return type;
+ }
+
+ private static Class<?> tryLoadClas(String type, ClassLoader classLoader)
throws ClassNotFoundException {
+ int dotIndex = type.indexOf('.');
+ if (dotIndex < 0) {
+ //guess type
+ for (String guessPackage : GUESS_PACKAGES) {
+ try {
+ return Class.forName(guessPackage + "." + type, false,
classLoader);
+ } catch (ClassNotFoundException e) {
+ //ignore
+ } catch (LinkageError e) {
+ // TODO: handle exception
+ }
+ }
+ }
+
+ Class<?> result = PRIMITIVE_CLASSES_MAP.get(type);
+ if (result == null) {
+ result = Class.forName(type, true, classLoader);
+ }
+
+ return result;
+ }
+
+ static Type[] parseTypeArgumentsString(String typeArguments, ClassLoader classLoader)
{
+ if (typeArguments == null) {
+ return null;
+ }
+
+ String[] typeArgumentsSplit = typeArguments.trim().split(",");
+
+ Type[] types = new Type[typeArgumentsSplit.length];
+ for (int i = 0; i < typeArgumentsSplit.length; i++) {
+ types[i] = getType(typeArgumentsSplit[i], classLoader);
+ }
+
+ return types;
+ }
+
+ public static Type getType(String typeString, ClassLoader classLoader) {
+ Matcher matcher = CLASS_SIGNATURE_PATTERN.matcher(typeString);
+ boolean matchResult = matcher.matches();
+ if (!matchResult) {
+ //TODO review
+ throw new IllegalArgumentException("Cannot parse type signature: "
+ typeString);
+ }
+
+ String className = matcher.group(CLASS_NAME_GROUP_IDX).trim();
+
+ String typeArgumentsString = matcher.group(TYPE_ARGUMENTS_GROUP_IDX);
+ Type[] typeArguments = parseTypeArgumentsString(typeArgumentsString,
classLoader);
+
+ String arraySignature = matcher.group(ARRAY_SIGNATURE_GROUP_IDX);
+ int arrayDepth = 0;
+ if (arraySignature != null) {
+ arrayDepth = arraySignature.replaceAll("\\s+",
"").length() / ARRAY_SIGNATURE_LENGTH;
+ }
+
+ Type baseType;
+ try {
+ //NB: loadedClass can have name that differs from className!
+ Class<?> loadedClas = tryLoadClas(className, classLoader);
+
+ baseType = getType(loadedClas);
+ } catch (ClassNotFoundException e) {
+ baseType = getReferencedType(className);
+ }
+
+ if (arrayDepth != 0 || !ArrayUtils.isEmpty(typeArguments)) {
+ return new ComplexType(baseType, typeArguments, arrayDepth);
+ } else {
+ return baseType;
+ }
+ }
+
+ static Type createType(java.lang.reflect.Type reflectionType) {
+ java.lang.reflect.Type[] actualTypeArguments = null;
+ Class<?> rawType = null;
+ int arrayDepth = 0;
+
+ java.lang.reflect.Type localReflectionType = reflectionType;
+
+ while (localReflectionType instanceof GenericArrayType) {
+ localReflectionType = ((GenericArrayType)
localReflectionType).getGenericComponentType();
+ arrayDepth++;
+ }
+
+ if (localReflectionType instanceof ParameterizedType) {
+ ParameterizedType parameterizedType = (ParameterizedType)
localReflectionType;
+
+ actualTypeArguments = parameterizedType.getActualTypeArguments();
+ rawType = (Class<?>) parameterizedType.getRawType();
+ } else if (localReflectionType instanceof Class<?>) {
+ rawType = (Class<?>) localReflectionType;
+ }
+
+ if (rawType != null) {
+ while (rawType.isArray()) {
+ arrayDepth++;
+ rawType = rawType.getComponentType();
+ }
+
+ Type[] typeArguments = null;
+ if (!ArrayUtils.isEmpty(actualTypeArguments)) {
+ typeArguments = getTypesArray(actualTypeArguments);
+ }
+
+ Type clearComponentType = getPlainClassType(rawType);
+ if (!ArrayUtils.isEmpty(typeArguments) || arrayDepth != 0) {
+ return new ComplexType(clearComponentType, typeArguments, arrayDepth);
+ } else {
+ return clearComponentType;
+ }
+ } else {
+ return new UnsupportedType(reflectionType);
+ }
+ }
+
+ public static Type getType(java.lang.reflect.Type reflectionType) {
+ Type result = REFLECTION_TYPES_CACHE.get(reflectionType);
+ if (result == null) {
+ result = createType(reflectionType);
+ REFLECTION_TYPES_CACHE.put(reflectionType, result);
+ }
+
+ return result;
+ }
+
+ public static Type[] getTypesArray(java.lang.reflect.Type[] reflectionTypes) {
+ Type[] types = new Type[reflectionTypes.length];
+ for (int i = 0; i < reflectionTypes.length; i++) {
+ types[i] = getType(reflectionTypes[i]);
+ }
+
+ return types;
+ }
+
+ public static Type getNullType() {
+ return NullType.INSTANCE;
+ }
+
+ public static void clearCaches() {
+ REFLECTION_TYPES_CACHE.clear();
+ REFERENCED_TYPES_CACHE.clear();
+ }
+
+ /**
+ * Returns wrapper classes for passed-in class. If type is primitive, then
corresponding
+ * wrapper class is returned (e.g. boolean -> Boolean), otherwise does nothing and
returns
+ * passed-in class.
+ *
+ * @return wrapper for primitive types, or passed-in class
+ */
+ static Class<?> getWrapperClass(Class<?> inClazz) {
+ if (inClazz.isPrimitive()) {
+ return PRIMITIVE_TO_WRAPPER_CLASSES_MAP.get(inClazz);
+ } else {
+ return inClazz;
+ }
+ }
+
+}
Added:
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/UnsupportedType.java
===================================================================
---
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/UnsupportedType.java
(rev 0)
+++
root/cdk/trunk/plugins/generator/src/main/java/org/richfaces/cdk/parser/el/types/UnsupportedType.java 2009-12-16
15:48:23 UTC (rev 16152)
@@ -0,0 +1,145 @@
+/*
+ * 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.parser.el.types;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.richfaces.cdk.parser.el.Type;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+//TODO replace with referenced type?
+public class UnsupportedType implements Type {
+
+ private java.lang.reflect.Type reflectionType;
+
+ /**
+ * @param reflectionType
+ */
+ public UnsupportedType(java.lang.reflect.Type reflectionType) {
+ this.reflectionType = reflectionType;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getCode()
+ */
+ @Override
+ public String getCode() {
+ return reflectionType.toString();
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getContainerType()
+ */
+ @Override
+ public Type getContainerType() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getImportsList()
+ */
+ @Override
+ public Collection<Class<?>> getImportsList() {
+ return Collections.emptyList();
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getRawType()
+ */
+ @Override
+ public Class<?> getRawType() {
+ return Object.class;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#getTypeArguments()
+ */
+ @Override
+ public Type[] getTypeArguments() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#isArray()
+ */
+ @Override
+ public boolean isArray() {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see
org.richfaces.cdk.parser.el.Type#isAssignableFrom(org.richfaces.cdk.parser.el.Type)
+ */
+ @Override
+ public boolean isAssignableFrom(Type anotherType) {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.richfaces.cdk.parser.el.Type#isNullType()
+ */
+ @Override
+ public boolean isNullType() {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((reflectionType == null) ? 0 :
reflectionType.hashCode());
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ UnsupportedType other = (UnsupportedType) obj;
+ if (reflectionType == null) {
+ if (other.reflectionType != null) {
+ return false;
+ }
+ } else if (!reflectionType.equals(other.reflectionType)) {
+ return false;
+ }
+ return true;
+ }
+
+}