You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by si...@apache.org on 2011/11/03 18:19:21 UTC
svn commit: r1197229 - in
/labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans:
BeanMemberInfo.java MethodInfo.java ParameterInfo.java
Author: simoneg
Date: Thu Nov 3 17:19:21 2011
New Revision: 1197229
URL: http://svn.apache.org/viewvc?rev=1197229&view=rev
Log:
Support for inspection of methods
Added:
labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeanMemberInfo.java
labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/MethodInfo.java
labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/ParameterInfo.java
Added: labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeanMemberInfo.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeanMemberInfo.java?rev=1197229&view=auto
==============================================================================
--- labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeanMemberInfo.java (added)
+++ labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/BeanMemberInfo.java Thu Nov 3 17:19:21 2011
@@ -0,0 +1,303 @@
+package org.apache.magma.beans;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.magma.basics.utils.GenericClass;
+import org.apache.magma.basics.utils.GenericClass.MethodDef;
+
+
+/**
+ * Holds informations about a member of a bean.
+ *
+ * Members are either public fields, properties (exposed by getters and setters), instance methods and static methods.
+ *
+ * Each kind of member is represented by the proper subclassm like {@link PropertyInfo} for properties.
+ *
+ * Bean is inspected inside {@link BeanData} constructor. Many aspects will enhance either this class
+ * or subclasses adding specific fields and specific parsing of bean classes.
+ *
+ * @author Simone Gianni <si...@apache.org>
+ *
+ */
+public abstract class BeanMemberInfo {
+
+ /**
+ * Name of the member, could be field name, property name or method name.
+ */
+ protected String name;
+
+ /**
+ * Type of the member, in case of fields is a real type, in case of properties is usually the return type of the getter,
+ * in case of methods is the return type of the method, and in this case could be {@link Void}.
+ */
+ @SuppressWarnings("rawtypes")
+ protected Class type;
+
+ /**
+ * Class of the bean this member is found on
+ */
+ @SuppressWarnings("rawtypes")
+ protected Class beanClass;
+
+ /**
+ * Whether the {@link #type} represents a collection (this includes {@link List}, {@link Set} and arrays, but not maps or tables).
+ */
+ protected boolean isCollection;
+
+ /**
+ * The type of elements contained in the collection (could be Object if it's not possible to deduce it) if {@link #isCollection} is true.
+ */
+ @SuppressWarnings("rawtypes")
+ protected Class collectionClass;
+
+ /**
+ * Whether the {@link #type} represents a map (this includes {@link Map} and tables).
+ */
+ protected boolean isMap;
+
+ /**
+ * The type of keys in the map (could be Object if it's not possible to deduce it)
+ */
+ @SuppressWarnings("rawtypes")
+ protected Class mapKeyClass;
+
+ /**
+ * The type of values in the map (could be Object if it's not possible to deduce it)
+ */
+ @SuppressWarnings("rawtypes")
+ protected Class mapValueClass;
+
+ /**
+ * If the type is a basic type, that is a primitive type, a wrapper, one of java.math numbers, or Date.
+ */
+ protected boolean isBasicType;
+
+ /**
+ * If the type is an enum.
+ */
+ protected boolean isEnum;
+
+ /**
+ * If the type is itself another bean
+ */
+ protected boolean isBean;
+
+ /**
+ * Initializes this instance
+ * @param beanClass The class this member is found in
+ */
+ public BeanMemberInfo(@SuppressWarnings("rawtypes") Class beanClass) {
+ this.beanClass = beanClass;
+ }
+
+ /**
+ * @return the name of the member, could be field name, property name or method name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @return the type of the member, in case of fields is a real type, in case of properties is usually the return type of the getter,
+ * in case of methods is the return type of the method, and in this case could be {@link Void}.
+ */
+ @SuppressWarnings("rawtypes")
+ public Class getType() {
+ return type;
+ }
+
+ /**
+ * Initializes {@link #type} the the given type (if provided), if a method is provided tries to determine generics based on that method return type.
+ * @param type The type of this member, see {@link #type}. May be null if a method is provided, in that case return type of the method is used.
+ * @param method A method (the getter in case of properties, the method itself for method members, null for fields) to use to try determine
+ * generics informations if needed
+ */
+ @SuppressWarnings("rawtypes")
+ protected void initType(Class type, GenericClass generic) {
+ if (type == null) {
+ type = generic.getBaseClass();
+ }
+ this.type = type;
+
+ if (this.type != null) {
+ this.isCollection = Collection.class.isAssignableFrom(this.type);
+ this.isMap = Map.class.isAssignableFrom(this.type);
+ if (this.isCollection) {
+ if (generic != null) {
+ if (!generic.getBaseClass().equals(this.type))
+ generic = GenericClass.forClass(this.type);
+ // It must have an add method
+ List<MethodDef> methods = generic.findMethods("add", new Class<?>[] {null});
+ // It must have a single parameter of the type of the collection
+ this.collectionClass = methods.get(0).getParameterTypes()[0].getBaseClass();
+ }
+ } else if (this.isMap) {
+ if (generic != null) {
+ if (!generic.getBaseClass().equals(this.type))
+ generic = GenericClass.forClass(this.type);
+ // It must have a put method
+ List<MethodDef> methods = generic.findMethods("put", new Class<?>[] {null, null});
+ // It must have a single parameter of the type of the collection
+ MethodDef putmethod = methods.get(0);
+ GenericClass[] parameterTypes = putmethod.getParameterTypes();
+ this.mapKeyClass = parameterTypes[0].getBaseClass();
+ this.mapValueClass = parameterTypes[1].getBaseClass();
+ }
+ } else {
+ this.isBasicType = isBasicType(this.type);
+ this.isEnum = isEnum(this.type);
+ this.isBean = isBean(this.type);
+ }
+ }
+
+ }
+
+ /**
+ * @return true if the type is a basic type, that is a primitive type, a wrapper, one of java.math numbers or Date.
+ */
+ public boolean isBasicType() {
+ return this.isBasicType;
+ }
+
+ /**
+ * @return true if the type is an {@link Enum}.
+ */
+ public boolean isEnum() {
+ return this.isEnum;
+ }
+
+ /**
+ * Static access to determination of basic types.
+ * @param c The class to check
+ * @return true if it can be considered a basic type
+ */
+ public static boolean isBasicType(Class c) {
+ return c.isPrimitive() ||
+ (Number.class.isAssignableFrom(c) && (c.getName().startsWith("java.lang") || c.getName().startsWith("java.math"))) ||
+ String.class.equals(c) ||
+ Date.class.isAssignableFrom(c);
+ }
+
+ /**
+ * Static access to determination of enum type
+ * @param c The class to check
+ * @return true if it can be considered an enum type
+ */
+ public static boolean isEnum(Class c) {
+ return Enum.class.isAssignableFrom(c);
+ }
+
+ /**
+ * @return true if type is itself a bean
+ */
+ public boolean isBean() {
+ return isBean;
+ }
+
+ /**
+ * Static access to determination of bean type
+ * @param c The class to check
+ * @return true is the given class is itself a bean (in the Magma sense)
+ */
+ public static boolean isBean(Class c) {
+ return MagmaBeanSupport.class.isAssignableFrom(c);
+ }
+
+ /**
+ * @return Whether the type returned by {@link #getType()} represents a collection (this includes {@link List}, {@link Set} and arrays, but not maps or tables).
+ */
+ public boolean isCollection() {
+ return isCollection;
+ }
+
+ /**
+ * @param isCollection Whether the {@link #type} represents a collection.
+ */
+ public void setCollection(boolean isCollection) {
+ this.isCollection = isCollection;
+ }
+
+ /**
+ * @return The type of elements contained in the collection (could be Object if it's not possible to deduce it)
+ */
+ @SuppressWarnings("rawtypes")
+ public Class getCollectionClass() {
+ return collectionClass;
+ }
+
+ /**
+ * @param collectionClass The type of elements contained in the collection (could be Object if it's not possible to deduce it)
+ */
+ @SuppressWarnings("rawtypes")
+ public void setCollectionClass(Class collectionClass) {
+ this.collectionClass = collectionClass;
+ }
+
+ /**
+ * @return Class of the bean this member is found on
+ */
+ @SuppressWarnings("rawtypes")
+ public Class getBeanClass() {
+ return beanClass;
+ }
+
+ /**
+ * @param beanClass Class of the bean this member is found on
+ */
+ @SuppressWarnings("rawtypes")
+ public void setBeanClass(Class beanClass) {
+ this.beanClass = beanClass;
+ }
+
+ /**
+ * @return Whether the type returned by {@link #getType()} represents a map (this includes {@link Map} and tables).
+ */
+ public boolean isMap() {
+ return isMap;
+ }
+
+ /**
+ * @return the Class of the keys in the map if {@link #isMap} and if it's possible to determine its generics.
+ */
+ @SuppressWarnings("rawtypes")
+ public Class getMapKeyClass() {
+ return mapKeyClass;
+ }
+
+ /**
+ * @return the Class of the values in the map if {@link #isMap} and if it's possible to determine its generics.
+ */
+ @SuppressWarnings("rawtypes")
+ public Class getMapValueClass() {
+ return mapValueClass;
+ }
+
+ /**
+ * Checks if the given {@link Class} is a good fit for the type of this member.
+ *
+ * The basic check relies on {@link Class#isAssignableFrom(Class)}.
+ *
+ * @param clazz The class of the argument we are planning to assign to this member
+ * @return true if a value of the given type will fit in the type of this member
+ */
+ public boolean matchesType(Class clazz) {
+ return this.type.isAssignableFrom(clazz);
+ }
+
+
+ public boolean isVoid() {
+ return this.type.equals(Void.TYPE);
+ }
+
+
+ @Override
+ public String toString() {
+ return this.getClass().getSimpleName() + " " + this.getType() + " " + this.getName();
+ }
+
+}
Added: labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/MethodInfo.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/MethodInfo.java?rev=1197229&view=auto
==============================================================================
--- labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/MethodInfo.java (added)
+++ labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/MethodInfo.java Thu Nov 3 17:19:21 2011
@@ -0,0 +1,74 @@
+package org.apache.magma.beans;
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.magma.basics.MagmaException;
+import org.apache.magma.basics.utils.GenericClass;
+
+public class MethodInfo extends BeanMemberInfo {
+
+ private Method method;
+ private ParameterInfo[] parameters = new ParameterInfo[0];
+ private Class[] exceptions = new Class[0];
+ private boolean isStatic = false;
+
+ @SuppressWarnings("rawtypes")
+ public MethodInfo(Class beanClass) {
+ super(beanClass);
+ }
+
+ public void init(Method method, Class beanClass) {
+ super.initType(null, GenericClass.forReturnType(method));
+
+ this.name = method.getName();
+ this.method = method;
+ this.isStatic = Modifier.isStatic(method.getModifiers());
+
+ Class<?>[] params = method.getParameterTypes();
+ if (params.length > 0) {
+ List<ParameterInfo> paramInfos = new ArrayList<ParameterInfo>(params.length);
+ for (int i = 0; i < params.length; i++) {
+ paramInfos.add(new ParameterInfo(this.beanClass, method, i));
+ }
+ this.parameters = paramInfos.toArray(this.parameters);
+ }
+
+ this.exceptions = method.getExceptionTypes();
+ }
+
+ public ParameterInfo[] getParameters() {
+ return parameters;
+ }
+
+ public Class[] getExceptions() {
+ return exceptions;
+ }
+
+ public boolean isStatic() {
+ return isStatic;
+ }
+
+ public Object invoke(Object target, Object... parameters) {
+ try {
+ return method.invoke(target, parameters);
+ } catch (Exception e) {
+ throw new MagmaException(e, "Error invoking method ({0}) {1}.{2}({3})", target, this.getBeanClass(), this.name, parameters);
+ }
+ }
+
+ public boolean matchesParameters(Class[] paramTypes) {
+ if (this.parameters.length != paramTypes.length) return false;
+ for (int i = 0; i < this.parameters.length; i++) {
+ if (paramTypes[i] == null) continue;
+ if (!this.parameters[i].matchesType(paramTypes[i])) return false;
+ }
+ return true;
+ }
+
+}
Added: labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/ParameterInfo.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/ParameterInfo.java?rev=1197229&view=auto
==============================================================================
--- labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/ParameterInfo.java (added)
+++ labs/magma/trunk/foundation-beans/src/main/java/org/apache/magma/beans/ParameterInfo.java Thu Nov 3 17:19:21 2011
@@ -0,0 +1,22 @@
+package org.apache.magma.beans;
+
+import java.lang.reflect.Method;
+
+import org.apache.magma.basics.utils.GenericClass;
+
+public class ParameterInfo extends BeanMemberInfo {
+
+ public ParameterInfo(Class beanClass, Method method, int i) {
+ super(beanClass);
+
+ GenericClass gc = GenericClass.forParameter(method, i);
+ super.initType(null, gc);
+
+ String simpleName = super.getType().getSimpleName();
+ if (simpleName.endsWith("[]")) {
+ simpleName = simpleName.substring(0, simpleName.length() - 2) + "Arr";
+ }
+ this.name = "p" + i + "_" + simpleName;
+ }
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org