openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ppod...@apache.org
Subject svn commit: r953717 - /openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/JavaVersions.java
Date Fri, 11 Jun 2010 15:14:24 GMT
Author: ppoddar
Date: Fri Jun 11 15:14:24 2010
New Revision: 953717

URL: http://svn.apache.org/viewvc?rev=953717&view=rev
Log:
OPENJPA-1686: Support when a parameterized type has parameterized type arguments

Modified:
    openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/JavaVersions.java

Modified: openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/JavaVersions.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/JavaVersions.java?rev=953717&r1=953716&r2=953717&view=diff
==============================================================================
--- openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/JavaVersions.java
(original)
+++ openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/JavaVersions.java
Fri Jun 11 15:14:24 2010
@@ -23,9 +23,11 @@ import java.lang.reflect.Method;
 import java.security.AccessController;
 
 /**
- * Utilities for dealing with different Java spec versions.
+ * Utilities for dealing with different Java specification versions.
  *
  * @author Abe White
+ * @author Pinaki Poddar
+ * 
  * @nojavadoc
  */
 public class JavaVersions {
@@ -35,15 +37,17 @@ public class JavaVersions {
      */
     public static final int VERSION;
 
-    private static final Class[] EMPTY_CLASSES = new Class[0];
+    private static final Class<?>[] EMPTY_CLASSES = new Class[0];
 
-    private static Class PARAM_TYPE = null;
-    private static Class ENUM_TYPE = null;
-    private static Class ANNO_TYPE = null;
+    private static Class<?> PARAM_TYPE = null;
+    private static Class<?> ENUM_TYPE  = null;
+    private static Class<?> ANNO_TYPE  = null;
     private static Method GET_STACK = null;
     private static Method SET_STACK = null;
     private static Method GET_CAUSE = null;
     private static Method INIT_CAUSE = null;
+    private static Object[] NO_ARGS  = null;
+    private static Class<?>[] NO_CLASS_ARGS = null;
 
     static {
         String specVersion = AccessController.doPrivileged(
@@ -63,8 +67,7 @@ public class JavaVersions {
 
         if (VERSION >= 5) {
             try {
-                PARAM_TYPE = Class.forName
-                    ("java.lang.reflect.ParameterizedType");
+                PARAM_TYPE = Class.forName("java.lang.reflect.ParameterizedType");
                 ENUM_TYPE = Class.forName("java.lang.Enum");
                 ANNO_TYPE = Class.forName("java.lang.annotation.Annotation");
             } catch (Throwable t) {
@@ -73,15 +76,11 @@ public class JavaVersions {
 
         if (VERSION >= 4) {
             try {
-                Class stack = Class.forName("[Ljava.lang.StackTraceElement;");
-                GET_STACK = Throwable.class.getMethod("getStackTrace",
-                    (Class[]) null);
-                SET_STACK = Throwable.class.getMethod("setStackTrace",
-                    new Class[]{ stack });
-                GET_CAUSE = Throwable.class.getMethod("getCause",
-                    (Class[]) null);
-                INIT_CAUSE = Throwable.class.getMethod("initCause",
-                    new Class[]{ Throwable.class });
+                Class<?> stack = Class.forName("[Ljava.lang.StackTraceElement;");
+                GET_STACK = Throwable.class.getMethod("getStackTrace", NO_CLASS_ARGS);
+                SET_STACK = Throwable.class.getMethod("setStackTrace", new Class[]{ stack
});
+                GET_CAUSE = Throwable.class.getMethod("getCause", NO_CLASS_ARGS);
+                INIT_CAUSE = Throwable.class.getMethod("initCause", new Class[]{ Throwable.class
});
             } catch (Throwable t) {
             }
         }
@@ -94,7 +93,7 @@ public class JavaVersions {
      * @return the JDK-version-specific version of the class
      * @see #getVersionSpecificClass(String)
      */
-    public static Class getVersionSpecificClass(Class base) {
+    public static Class<?> getVersionSpecificClass(Class<?> base) {
         try {
             return getVersionSpecificClass(base.getName());
         } catch (ClassNotFoundException e) {
@@ -125,14 +124,13 @@ public class JavaVersions {
      * @param base the base name of the class to load
      * @return the subclass appropriate for the current Java version
      */
-    public static Class getVersionSpecificClass(String base)
+    public static Class<?> getVersionSpecificClass(String base)
         throws ClassNotFoundException {
         for (int i = VERSION; i >= 1; i--) {
             try {
                 return Class.forName(base + i);
             } catch (Throwable e) {
-                // throwables might occur with bytecode that we
-                // cannot understand
+                // throwables might occur with bytecode that we cannot understand
             }
         }
         return Class.forName(base);
@@ -141,29 +139,28 @@ public class JavaVersions {
     /**
      * Return true if the given type is an annotation.
      */
-    public static boolean isAnnotation(Class cls) {
+    public static boolean isAnnotation(Class<?> cls) {
         return ANNO_TYPE != null && ANNO_TYPE.isAssignableFrom(cls);
     }
 
     /**
      * Return true if the given type is an enumeration.
      */
-    public static boolean isEnumeration(Class cls) {
+    public static boolean isEnumeration(Class<?> cls) {
         return ENUM_TYPE != null && ENUM_TYPE.isAssignableFrom(cls);
     }
 
     /**
      * Collects the parameterized type declarations for a given field.
      */
-    public static Class[] getParameterizedTypes(Field f) {
+    public static Class<?>[] getParameterizedTypes(Field f) {
         if (f == null)
             return null;
         if (VERSION < 5)
             return EMPTY_CLASSES;
 
         try {
-            Object type = Field.class.getMethod("getGenericType",
-                (Class[]) null).invoke(f, (Object[]) null);
+            Object type = invokeGetter(f, "getGenericType");
             return collectParameterizedTypes(type, f.getType());
         } catch (Exception e) {
             return EMPTY_CLASSES;
@@ -173,15 +170,14 @@ public class JavaVersions {
     /**
      * Collects the parameterized return type declarations for a given method.
      */
-    public static Class[] getParameterizedTypes(Method meth) {
+    public static Class<?>[] getParameterizedTypes(Method meth) {
         if (meth == null)
             return null;
         if (VERSION < 5)
             return EMPTY_CLASSES;
 
         try {
-            Object type = Method.class.getMethod("getGenericReturnType",
-                (Class[]) null).invoke(meth, (Object[]) null);
+            Object type = invokeGetter(meth, "getGenericReturnType");
             return collectParameterizedTypes(type, meth.getReturnType());
         } catch (Exception e) {
             return EMPTY_CLASSES;
@@ -191,28 +187,46 @@ public class JavaVersions {
     /**
      * Return all parameterized classes for the given type.
      */
-    private static Class[] collectParameterizedTypes(Object type, Class<?> cls)
-        throws Exception {
-        if (PARAM_TYPE == null || !PARAM_TYPE.isInstance(type)) {
-            if (cls.getSuperclass() != Object.class) {
-                return collectParameterizedTypes(cls.getGenericSuperclass(), cls.getSuperclass());
+    private static Class<?>[] collectParameterizedTypes(Object type, Class<?>
cls) throws Exception {
+        if (isParameterizedType(type)) {
+            Object[] args = (Object[]) invokeGetter(type, "getActualTypeArguments");
+            Class<?>[] clss = new Class[args.length];
+            for (int i = 0; i < args.length; i++) {
+                Class<?> c = extractClass(args[i]);
+                if (c == null) {
+                    return EMPTY_CLASSES;
+                }
+                clss[i] = c;
             }
+            return clss;
+        } else if (cls.getSuperclass() != Object.class) {
+            return collectParameterizedTypes(cls.getGenericSuperclass(), cls.getSuperclass());
+        } else {
             return EMPTY_CLASSES;
         }
-
-        Object[] args = (Object[]) PARAM_TYPE.getMethod
-            ("getActualTypeArguments", (Class[]) null).invoke(type,
-            (Object[]) null);
-        if (args.length == 0)
-            return EMPTY_CLASSES;
-
-        Class[] clss = new Class[args.length];
-        for (int i = 0; i < args.length; i++) {
-            if (!(args[i] instanceof Class))
-                return EMPTY_CLASSES;
-            clss[i] = (Class) args[i];
-        }
-        return clss;
+    }
+    
+    /**
+     * Extracts the class from the given argument, if possible. Null otherwise.
+     */
+    static Class<?> extractClass(Object o) throws Exception {
+        if (o == null)
+            return null;
+        if (o instanceof Class)
+            return (Class<?>)o;
+        
+        if (isParameterizedType(o)) {
+            return extractClass(invokeGetter(o, "getRawType"));
+        }
+        return null;
+    }
+    
+    static Object invokeGetter(Object target, String method) throws Exception {
+        return target.getClass().getMethod(method, NO_CLASS_ARGS).invoke(target, NO_ARGS);
+    }
+    
+    static boolean isParameterizedType(Object cls) {
+        return PARAM_TYPE != null && PARAM_TYPE.isInstance(cls);
     }
 
     /**
@@ -220,12 +234,11 @@ public class JavaVersions {
      * false if it cannot be done, possibly due to an unsupported Java version.
      */
     public static boolean transferStackTrace(Throwable from, Throwable to) {
-        if (GET_STACK == null || SET_STACK == null || from == null
-            || to == null)
+        if (GET_STACK == null || SET_STACK == null || from == null || to == null)
             return false;
 
         try {
-            Object stack = GET_STACK.invoke(from, (Object[]) null);
+            Object stack = GET_STACK.invoke(from, NO_ARGS);
             SET_STACK.invoke(to, new Object[]{ stack });
             return true;
         } catch (Throwable t) {
@@ -241,7 +254,7 @@ public class JavaVersions {
             return null;
 
         try {
-            return (Throwable) GET_CAUSE.invoke(ex, (Object[]) null);
+            return (Throwable) GET_CAUSE.invoke(ex, NO_ARGS);
         } catch (Throwable t) {
             return null;
         }



Mime
View raw message