jdk/src/share/classes/java/beans/MetaData.java
changeset 3439 4a7dc61594ac
parent 1844 ac2cf8242428
child 3473 b9abeee84734
--- a/jdk/src/share/classes/java/beans/MetaData.java	Wed Apr 29 20:03:09 2009 +0400
+++ b/jdk/src/share/classes/java/beans/MetaData.java	Wed Apr 29 20:55:13 2009 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -333,31 +333,6 @@
         return (oldC.size() == newC.size()) && oldC.containsAll(newC);
     }
 
-    static Object getPrivateField(final Object instance, final String name) {
-        return AccessController.doPrivileged(
-                new PrivilegedAction() {
-                    public Object run() {
-                        Class type = instance.getClass();
-                        while ( true ) {
-                            try {
-                                Field field = type.getDeclaredField(name);
-                                field.setAccessible(true);
-                                return field.get( instance );
-                            }
-                            catch (NoSuchFieldException exception) {
-                                type = type.getSuperclass();
-                                if (type == null) {
-                                    throw new IllegalStateException("Could not find field " + name, exception);
-                                }
-                            }
-                            catch (Exception exception) {
-                                throw new IllegalStateException("Could not get value " + type.getName() + '.' + name, exception);
-                            }
-                        }
-                    }
-                } );
-    }
-
     static final class EmptyList_PersistenceDelegate extends java_util_Collections {
         protected Expression instantiate(Object oldInstance, Encoder out) {
             return new Expression(oldInstance, Collections.class, "emptyList", null);
@@ -498,7 +473,7 @@
 
     static final class CheckedCollection_PersistenceDelegate extends java_util_Collections {
         protected Expression instantiate(Object oldInstance, Encoder out) {
-            Object type = getPrivateField(oldInstance, "type");
+            Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type");
             List list = new ArrayList((Collection) oldInstance);
             return new Expression(oldInstance, Collections.class, "checkedCollection", new Object[]{list, type});
         }
@@ -506,7 +481,7 @@
 
     static final class CheckedList_PersistenceDelegate extends java_util_Collections {
         protected Expression instantiate(Object oldInstance, Encoder out) {
-            Object type = getPrivateField(oldInstance, "type");
+            Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type");
             List list = new LinkedList((Collection) oldInstance);
             return new Expression(oldInstance, Collections.class, "checkedList", new Object[]{list, type});
         }
@@ -514,7 +489,7 @@
 
     static final class CheckedRandomAccessList_PersistenceDelegate extends java_util_Collections {
         protected Expression instantiate(Object oldInstance, Encoder out) {
-            Object type = getPrivateField(oldInstance, "type");
+            Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type");
             List list = new ArrayList((Collection) oldInstance);
             return new Expression(oldInstance, Collections.class, "checkedList", new Object[]{list, type});
         }
@@ -522,7 +497,7 @@
 
     static final class CheckedSet_PersistenceDelegate extends java_util_Collections {
         protected Expression instantiate(Object oldInstance, Encoder out) {
-            Object type = getPrivateField(oldInstance, "type");
+            Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type");
             Set set = new HashSet((Set) oldInstance);
             return new Expression(oldInstance, Collections.class, "checkedSet", new Object[]{set, type});
         }
@@ -530,7 +505,7 @@
 
     static final class CheckedSortedSet_PersistenceDelegate extends java_util_Collections {
         protected Expression instantiate(Object oldInstance, Encoder out) {
-            Object type = getPrivateField(oldInstance, "type");
+            Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type");
             SortedSet set = new TreeSet((SortedSet) oldInstance);
             return new Expression(oldInstance, Collections.class, "checkedSortedSet", new Object[]{set, type});
         }
@@ -538,8 +513,8 @@
 
     static final class CheckedMap_PersistenceDelegate extends java_util_Collections {
         protected Expression instantiate(Object oldInstance, Encoder out) {
-            Object keyType = getPrivateField(oldInstance, "keyType");
-            Object valueType = getPrivateField(oldInstance, "valueType");
+            Object keyType   = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.keyType");
+            Object valueType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.valueType");
             Map map = new HashMap((Map) oldInstance);
             return new Expression(oldInstance, Collections.class, "checkedMap", new Object[]{map, keyType, valueType});
         }
@@ -547,8 +522,8 @@
 
     static final class CheckedSortedMap_PersistenceDelegate extends java_util_Collections {
         protected Expression instantiate(Object oldInstance, Encoder out) {
-            Object keyType = getPrivateField(oldInstance, "keyType");
-            Object valueType = getPrivateField(oldInstance, "valueType");
+            Object keyType   = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.keyType");
+            Object valueType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.valueType");
             SortedMap map = new TreeMap((SortedMap) oldInstance);
             return new Expression(oldInstance, Collections.class, "checkedSortedMap", new Object[]{map, keyType, valueType});
         }
@@ -570,7 +545,7 @@
     }
 
     private static Object getType(Object instance) {
-        return java_util_Collections.getPrivateField(instance, "keyType");
+        return MetaData.getPrivateFieldValue(instance, "java.util.EnumMap.keyType");
     }
 }
 
@@ -589,7 +564,7 @@
     }
 
     private static Object getType(Object instance) {
-        return java_util_Collections.getPrivateField(instance, "elementType");
+        return MetaData.getPrivateFieldValue(instance, "java.util.EnumSet.elementType");
     }
 }
 
@@ -1280,7 +1255,7 @@
 
     private Integer getAxis(Object object) {
         Box box = (Box) object;
-        return (Integer) java_util_Collections.getPrivateField(box.getLayout(), "axis");
+        return (Integer) MetaData.getPrivateFieldValue(box.getLayout(), "javax.swing.BoxLayout.axis");
     }
 }
 
@@ -1363,6 +1338,7 @@
 }
 
 class MetaData {
+    private static final Map<String,Field> fields = Collections.synchronizedMap(new WeakHashMap<String, Field>());
     private static Hashtable internalPersistenceDelegates = new Hashtable();
 
     private static PersistenceDelegate nullPersistenceDelegate = new NullPersistenceDelegate();
@@ -1501,4 +1477,35 @@
             return null;
         }
     }
+
+    static Object getPrivateFieldValue(Object instance, String name) {
+        Field field = fields.get(name);
+        if (field == null) {
+            int index = name.lastIndexOf('.');
+            final String className = name.substring(0, index);
+            final String fieldName = name.substring(1 + index);
+            field = AccessController.doPrivileged(new PrivilegedAction<Field>() {
+                public Field run() {
+                    try {
+                        Field field = Class.forName(className).getDeclaredField(fieldName);
+                        field.setAccessible(true);
+                        return field;
+                    }
+                    catch (ClassNotFoundException exception) {
+                        throw new IllegalStateException("Could not find class", exception);
+                    }
+                    catch (NoSuchFieldException exception) {
+                        throw new IllegalStateException("Could not find field", exception);
+                    }
+                }
+            });
+            fields.put(name, field);
+        }
+        try {
+            return field.get(instance);
+        }
+        catch (IllegalAccessException exception) {
+            throw new IllegalStateException("Could not get value of the field", exception);
+        }
+    }
 }