From 4eac7391771198979a21565d0ef60cb427d4f528 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Mon, 29 Apr 2013 16:42:22 +0400 Subject: [PATCH] 8007458: [findbugs] One more beans issue, with ReflectionUtils Reviewed-by: art, alexsch --- .../share/classes/java/beans/MetaData.java | 147 +++++++++--------- .../classes/java/beans/ReflectionUtils.java | 78 ---------- .../share/classes/java/beans/XMLEncoder.java | 16 +- .../java/beans/XMLEncoder/AbstractTest.java | 26 +++- .../java/beans/XMLEncoder/BeanValidator.java | 37 ++--- .../java/beans/XMLEncoder/Test4631471.java | 5 - .../java/beans/XMLEncoder/Test4679556.java | 1 - .../XMLEncoder/java_awt_BorderLayout.java | 6 +- .../beans/XMLEncoder/java_awt_CardLayout.java | 83 ++++++++++ .../XMLEncoder/java_awt_GridBagLayout.java | 101 ++++++++++++ .../javax_swing_DefaultCellEditor.java | 6 + 11 files changed, 321 insertions(+), 185 deletions(-) delete mode 100644 jdk/src/share/classes/java/beans/ReflectionUtils.java create mode 100644 jdk/test/java/beans/XMLEncoder/java_awt_CardLayout.java create mode 100644 jdk/test/java/beans/XMLEncoder/java_awt_GridBagLayout.java diff --git a/jdk/src/share/classes/java/beans/MetaData.java b/jdk/src/share/classes/java/beans/MetaData.java index 3e3f5d11e09..61f51d4bb3f 100644 --- a/jdk/src/share/classes/java/beans/MetaData.java +++ b/jdk/src/share/classes/java/beans/MetaData.java @@ -69,8 +69,9 @@ import java.util.Objects; * @author Philip Milne * @author Steve Langley */ +class MetaData { -class NullPersistenceDelegate extends PersistenceDelegate { +static final class NullPersistenceDelegate extends PersistenceDelegate { // Note this will be called by all classes when they reach the // top of their superclass chain. protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { @@ -87,7 +88,7 @@ class NullPersistenceDelegate extends PersistenceDelegate { * * @author Sergey A. Malenkov */ -class EnumPersistenceDelegate extends PersistenceDelegate { +static final class EnumPersistenceDelegate extends PersistenceDelegate { protected boolean mutatesTo(Object oldInstance, Object newInstance) { return oldInstance == newInstance; } @@ -98,7 +99,7 @@ class EnumPersistenceDelegate extends PersistenceDelegate { } } -class PrimitivePersistenceDelegate extends PersistenceDelegate { +static final class PrimitivePersistenceDelegate extends PersistenceDelegate { protected boolean mutatesTo(Object oldInstance, Object newInstance) { return oldInstance.equals(newInstance); } @@ -109,7 +110,7 @@ class PrimitivePersistenceDelegate extends PersistenceDelegate { } } -class ArrayPersistenceDelegate extends PersistenceDelegate { +static final class ArrayPersistenceDelegate extends PersistenceDelegate { protected boolean mutatesTo(Object oldInstance, Object newInstance) { return (newInstance != null && oldInstance.getClass() == newInstance.getClass() && // Also ensures the subtype is correct. @@ -150,7 +151,7 @@ class ArrayPersistenceDelegate extends PersistenceDelegate { } } -class ProxyPersistenceDelegate extends PersistenceDelegate { +static final class ProxyPersistenceDelegate extends PersistenceDelegate { protected Expression instantiate(Object oldInstance, Encoder out) { Class type = oldInstance.getClass(); java.lang.reflect.Proxy p = (java.lang.reflect.Proxy)oldInstance; @@ -185,7 +186,7 @@ class ProxyPersistenceDelegate extends PersistenceDelegate { } // Strings -class java_lang_String_PersistenceDelegate extends PersistenceDelegate { +static final class java_lang_String_PersistenceDelegate extends PersistenceDelegate { protected Expression instantiate(Object oldInstance, Encoder out) { return null; } public void writeObject(Object oldInstance, Encoder out) { @@ -194,7 +195,7 @@ class java_lang_String_PersistenceDelegate extends PersistenceDelegate { } // Classes -class java_lang_Class_PersistenceDelegate extends PersistenceDelegate { +static final class java_lang_Class_PersistenceDelegate extends PersistenceDelegate { protected boolean mutatesTo(Object oldInstance, Object newInstance) { return oldInstance.equals(newInstance); } @@ -228,7 +229,7 @@ class java_lang_Class_PersistenceDelegate extends PersistenceDelegate { } // Fields -class java_lang_reflect_Field_PersistenceDelegate extends PersistenceDelegate { +static final class java_lang_reflect_Field_PersistenceDelegate extends PersistenceDelegate { protected boolean mutatesTo(Object oldInstance, Object newInstance) { return oldInstance.equals(newInstance); } @@ -243,7 +244,7 @@ class java_lang_reflect_Field_PersistenceDelegate extends PersistenceDelegate { } // Methods -class java_lang_reflect_Method_PersistenceDelegate extends PersistenceDelegate { +static final class java_lang_reflect_Method_PersistenceDelegate extends PersistenceDelegate { protected boolean mutatesTo(Object oldInstance, Object newInstance) { return oldInstance.equals(newInstance); } @@ -267,7 +268,7 @@ class java_lang_reflect_Method_PersistenceDelegate extends PersistenceDelegate { * * @author Sergey A. Malenkov */ -class java_util_Date_PersistenceDelegate extends PersistenceDelegate { +static class java_util_Date_PersistenceDelegate extends PersistenceDelegate { protected boolean mutatesTo(Object oldInstance, Object newInstance) { if (!super.mutatesTo(oldInstance, newInstance)) { return false; @@ -290,7 +291,7 @@ class java_util_Date_PersistenceDelegate extends PersistenceDelegate { * * @author Sergey A. Malenkov */ -final class java_sql_Timestamp_PersistenceDelegate extends java_util_Date_PersistenceDelegate { +static final class java_sql_Timestamp_PersistenceDelegate extends java_util_Date_PersistenceDelegate { private static final Method getNanosMethod = getNanosMethod(); private static Method getNanosMethod() { @@ -354,7 +355,7 @@ delegates to be registered with concrete classes. * * @author Sergey A. Malenkov */ -abstract class java_util_Collections extends PersistenceDelegate { +private static abstract class java_util_Collections extends PersistenceDelegate { protected boolean mutatesTo(Object oldInstance, Object newInstance) { if (!super.mutatesTo(oldInstance, newInstance)) { return false; @@ -367,6 +368,10 @@ abstract class java_util_Collections extends PersistenceDelegate { return (oldC.size() == newC.size()) && oldC.containsAll(newC); } + protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { + // do not initialize these custom collections in default way + } + static final class EmptyList_PersistenceDelegate extends java_util_Collections { protected Expression instantiate(Object oldInstance, Encoder out) { return new Expression(oldInstance, Collections.class, "emptyList", null); @@ -569,7 +574,7 @@ abstract class java_util_Collections extends PersistenceDelegate { * * @author Sergey A. Malenkov */ -class java_util_EnumMap_PersistenceDelegate extends PersistenceDelegate { +static final class java_util_EnumMap_PersistenceDelegate extends PersistenceDelegate { protected boolean mutatesTo(Object oldInstance, Object newInstance) { return super.mutatesTo(oldInstance, newInstance) && (getType(oldInstance) == getType(newInstance)); } @@ -588,7 +593,7 @@ class java_util_EnumMap_PersistenceDelegate extends PersistenceDelegate { * * @author Sergey A. Malenkov */ -class java_util_EnumSet_PersistenceDelegate extends PersistenceDelegate { +static final class java_util_EnumSet_PersistenceDelegate extends PersistenceDelegate { protected boolean mutatesTo(Object oldInstance, Object newInstance) { return super.mutatesTo(oldInstance, newInstance) && (getType(oldInstance) == getType(newInstance)); } @@ -603,7 +608,7 @@ class java_util_EnumSet_PersistenceDelegate extends PersistenceDelegate { } // Collection -class java_util_Collection_PersistenceDelegate extends DefaultPersistenceDelegate { +static class java_util_Collection_PersistenceDelegate extends DefaultPersistenceDelegate { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { java.util.Collection oldO = (java.util.Collection)oldInstance; java.util.Collection newO = (java.util.Collection)newInstance; @@ -618,7 +623,7 @@ class java_util_Collection_PersistenceDelegate extends DefaultPersistenceDelegat } // List -class java_util_List_PersistenceDelegate extends DefaultPersistenceDelegate { +static class java_util_List_PersistenceDelegate extends DefaultPersistenceDelegate { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { java.util.List oldO = (java.util.List)oldInstance; java.util.List newO = (java.util.List)newInstance; @@ -653,7 +658,7 @@ class java_util_List_PersistenceDelegate extends DefaultPersistenceDelegate { // Map -class java_util_Map_PersistenceDelegate extends DefaultPersistenceDelegate { +static class java_util_Map_PersistenceDelegate extends DefaultPersistenceDelegate { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { // System.out.println("Initializing: " + newInstance); java.util.Map oldMap = (java.util.Map)oldInstance; @@ -691,14 +696,14 @@ class java_util_Map_PersistenceDelegate extends DefaultPersistenceDelegate { } } -class java_util_AbstractCollection_PersistenceDelegate extends java_util_Collection_PersistenceDelegate {} -class java_util_AbstractList_PersistenceDelegate extends java_util_List_PersistenceDelegate {} -class java_util_AbstractMap_PersistenceDelegate extends java_util_Map_PersistenceDelegate {} -class java_util_Hashtable_PersistenceDelegate extends java_util_Map_PersistenceDelegate {} +static final class java_util_AbstractCollection_PersistenceDelegate extends java_util_Collection_PersistenceDelegate {} +static final class java_util_AbstractList_PersistenceDelegate extends java_util_List_PersistenceDelegate {} +static final class java_util_AbstractMap_PersistenceDelegate extends java_util_Map_PersistenceDelegate {} +static final class java_util_Hashtable_PersistenceDelegate extends java_util_Map_PersistenceDelegate {} // Beans -class java_beans_beancontext_BeanContextSupport_PersistenceDelegate extends java_util_Collection_PersistenceDelegate {} +static final class java_beans_beancontext_BeanContextSupport_PersistenceDelegate extends java_util_Collection_PersistenceDelegate {} // AWT @@ -709,7 +714,7 @@ class java_beans_beancontext_BeanContextSupport_PersistenceDelegate extends java * * @author Sergey A. Malenkov */ -final class java_awt_Insets_PersistenceDelegate extends PersistenceDelegate { +static final class java_awt_Insets_PersistenceDelegate extends PersistenceDelegate { protected boolean mutatesTo(Object oldInstance, Object newInstance) { return oldInstance.equals(newInstance); } @@ -733,7 +738,7 @@ final class java_awt_Insets_PersistenceDelegate extends PersistenceDelegate { * * @author Sergey A. Malenkov */ -final class java_awt_Font_PersistenceDelegate extends PersistenceDelegate { +static final class java_awt_Font_PersistenceDelegate extends PersistenceDelegate { protected boolean mutatesTo(Object oldInstance, Object newInstance) { return oldInstance.equals(newInstance); } @@ -802,7 +807,7 @@ final class java_awt_Font_PersistenceDelegate extends PersistenceDelegate { * * @author Sergey A. Malenkov */ -final class java_awt_AWTKeyStroke_PersistenceDelegate extends PersistenceDelegate { +static final class java_awt_AWTKeyStroke_PersistenceDelegate extends PersistenceDelegate { protected boolean mutatesTo(Object oldInstance, Object newInstance) { return oldInstance.equals(newInstance); } @@ -843,7 +848,7 @@ final class java_awt_AWTKeyStroke_PersistenceDelegate extends PersistenceDelegat } } -class StaticFieldsPersistenceDelegate extends PersistenceDelegate { +static class StaticFieldsPersistenceDelegate extends PersistenceDelegate { protected void installFields(Encoder out, Class cls) { Field fields[] = cls.getFields(); for(int i = 0; i < fields.length; i++) { @@ -870,13 +875,13 @@ class StaticFieldsPersistenceDelegate extends PersistenceDelegate { } // SystemColor -class java_awt_SystemColor_PersistenceDelegate extends StaticFieldsPersistenceDelegate {} +static final class java_awt_SystemColor_PersistenceDelegate extends StaticFieldsPersistenceDelegate {} // TextAttribute -class java_awt_font_TextAttribute_PersistenceDelegate extends StaticFieldsPersistenceDelegate {} +static final class java_awt_font_TextAttribute_PersistenceDelegate extends StaticFieldsPersistenceDelegate {} // MenuShortcut -class java_awt_MenuShortcut_PersistenceDelegate extends PersistenceDelegate { +static final class java_awt_MenuShortcut_PersistenceDelegate extends PersistenceDelegate { protected boolean mutatesTo(Object oldInstance, Object newInstance) { return oldInstance.equals(newInstance); } @@ -889,7 +894,7 @@ class java_awt_MenuShortcut_PersistenceDelegate extends PersistenceDelegate { } // Component -class java_awt_Component_PersistenceDelegate extends DefaultPersistenceDelegate { +static final class java_awt_Component_PersistenceDelegate extends DefaultPersistenceDelegate { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { super.initialize(type, oldInstance, newInstance, out); java.awt.Component c = (java.awt.Component)oldInstance; @@ -936,7 +941,7 @@ class java_awt_Component_PersistenceDelegate extends DefaultPersistenceDelegate } // Container -class java_awt_Container_PersistenceDelegate extends DefaultPersistenceDelegate { +static final class java_awt_Container_PersistenceDelegate extends DefaultPersistenceDelegate { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { super.initialize(type, oldInstance, newInstance, out); // Ignore the children of a JScrollPane. @@ -971,7 +976,7 @@ class java_awt_Container_PersistenceDelegate extends DefaultPersistenceDelegate } // Choice -class java_awt_Choice_PersistenceDelegate extends DefaultPersistenceDelegate { +static final class java_awt_Choice_PersistenceDelegate extends DefaultPersistenceDelegate { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { super.initialize(type, oldInstance, newInstance, out); java.awt.Choice m = (java.awt.Choice)oldInstance; @@ -983,7 +988,7 @@ class java_awt_Choice_PersistenceDelegate extends DefaultPersistenceDelegate { } // Menu -class java_awt_Menu_PersistenceDelegate extends DefaultPersistenceDelegate { +static final class java_awt_Menu_PersistenceDelegate extends DefaultPersistenceDelegate { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { super.initialize(type, oldInstance, newInstance, out); java.awt.Menu m = (java.awt.Menu)oldInstance; @@ -995,7 +1000,7 @@ class java_awt_Menu_PersistenceDelegate extends DefaultPersistenceDelegate { } // MenuBar -class java_awt_MenuBar_PersistenceDelegate extends DefaultPersistenceDelegate { +static final class java_awt_MenuBar_PersistenceDelegate extends DefaultPersistenceDelegate { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { super.initialize(type, oldInstance, newInstance, out); java.awt.MenuBar m = (java.awt.MenuBar)oldInstance; @@ -1007,7 +1012,7 @@ class java_awt_MenuBar_PersistenceDelegate extends DefaultPersistenceDelegate { } // List -class java_awt_List_PersistenceDelegate extends DefaultPersistenceDelegate { +static final class java_awt_List_PersistenceDelegate extends DefaultPersistenceDelegate { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { super.initialize(type, oldInstance, newInstance, out); java.awt.List m = (java.awt.List)oldInstance; @@ -1022,7 +1027,7 @@ class java_awt_List_PersistenceDelegate extends DefaultPersistenceDelegate { // LayoutManagers // BorderLayout -class java_awt_BorderLayout_PersistenceDelegate extends DefaultPersistenceDelegate { +static final class java_awt_BorderLayout_PersistenceDelegate extends DefaultPersistenceDelegate { private static final String[] CONSTRAINTS = { BorderLayout.NORTH, BorderLayout.SOUTH, @@ -1053,41 +1058,44 @@ class java_awt_BorderLayout_PersistenceDelegate extends DefaultPersistenceDelega } // CardLayout -class java_awt_CardLayout_PersistenceDelegate extends DefaultPersistenceDelegate { +static final class java_awt_CardLayout_PersistenceDelegate extends DefaultPersistenceDelegate { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { super.initialize(type, oldInstance, newInstance, out); - Hashtable tab = (Hashtable)ReflectionUtils.getPrivateField(oldInstance, - java.awt.CardLayout.class, - "tab", - out.getExceptionListener()); - if (tab != null) { - for(Enumeration e = tab.keys(); e.hasMoreElements();) { - Object child = e.nextElement(); - invokeStatement(oldInstance, "addLayoutComponent", - new Object[]{child, (String)tab.get(child)}, out); + if (getVector(newInstance).isEmpty()) { + for (Object card : getVector(oldInstance)) { + Object[] args = {MetaData.getPrivateFieldValue(card, "java.awt.CardLayout$Card.name"), + MetaData.getPrivateFieldValue(card, "java.awt.CardLayout$Card.comp")}; + invokeStatement(oldInstance, "addLayoutComponent", args, out); } } } + protected boolean mutatesTo(Object oldInstance, Object newInstance) { + return super.mutatesTo(oldInstance, newInstance) && getVector(newInstance).isEmpty(); + } + private static Vector getVector(Object instance) { + return (Vector) MetaData.getPrivateFieldValue(instance, "java.awt.CardLayout.vector"); + } } // GridBagLayout -class java_awt_GridBagLayout_PersistenceDelegate extends DefaultPersistenceDelegate { +static final class java_awt_GridBagLayout_PersistenceDelegate extends DefaultPersistenceDelegate { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { super.initialize(type, oldInstance, newInstance, out); - Hashtable comptable = (Hashtable)ReflectionUtils.getPrivateField(oldInstance, - java.awt.GridBagLayout.class, - "comptable", - out.getExceptionListener()); - if (comptable != null) { - for(Enumeration e = comptable.keys(); e.hasMoreElements();) { - Object child = e.nextElement(); - invokeStatement(oldInstance, "addLayoutComponent", - new Object[]{child, comptable.get(child)}, out); + if (getHashtable(newInstance).isEmpty()) { + for (Map.Entry entry : getHashtable(oldInstance).entrySet()) { + Object[] args = {entry.getKey(), entry.getValue()}; + invokeStatement(oldInstance, "addLayoutComponent", args, out); } } } + protected boolean mutatesTo(Object oldInstance, Object newInstance) { + return super.mutatesTo(oldInstance, newInstance) && getHashtable(newInstance).isEmpty(); + } + private static Hashtable getHashtable(Object instance) { + return (Hashtable) MetaData.getPrivateFieldValue(instance, "java.awt.GridBagLayout.comptable"); + } } // Swing @@ -1095,7 +1103,7 @@ class java_awt_GridBagLayout_PersistenceDelegate extends DefaultPersistenceDeleg // JFrame (If we do this for Window instead of JFrame, the setVisible call // will be issued before we have added all the children to the JFrame and // will appear blank). -class javax_swing_JFrame_PersistenceDelegate extends DefaultPersistenceDelegate { +static final class javax_swing_JFrame_PersistenceDelegate extends DefaultPersistenceDelegate { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { super.initialize(type, oldInstance, newInstance, out); java.awt.Window oldC = (java.awt.Window)oldInstance; @@ -1115,7 +1123,7 @@ class javax_swing_JFrame_PersistenceDelegate extends DefaultPersistenceDelegate // Models // DefaultListModel -class javax_swing_DefaultListModel_PersistenceDelegate extends DefaultPersistenceDelegate { +static final class javax_swing_DefaultListModel_PersistenceDelegate extends DefaultPersistenceDelegate { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { // Note, the "size" property will be set here. super.initialize(type, oldInstance, newInstance, out); @@ -1129,7 +1137,7 @@ class javax_swing_DefaultListModel_PersistenceDelegate extends DefaultPersistenc } // DefaultComboBoxModel -class javax_swing_DefaultComboBoxModel_PersistenceDelegate extends DefaultPersistenceDelegate { +static final class javax_swing_DefaultComboBoxModel_PersistenceDelegate extends DefaultPersistenceDelegate { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { super.initialize(type, oldInstance, newInstance, out); javax.swing.DefaultComboBoxModel m = (javax.swing.DefaultComboBoxModel)oldInstance; @@ -1141,7 +1149,7 @@ class javax_swing_DefaultComboBoxModel_PersistenceDelegate extends DefaultPersis // DefaultMutableTreeNode -class javax_swing_tree_DefaultMutableTreeNode_PersistenceDelegate extends DefaultPersistenceDelegate { +static final class javax_swing_tree_DefaultMutableTreeNode_PersistenceDelegate extends DefaultPersistenceDelegate { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { super.initialize(type, oldInstance, newInstance, out); @@ -1157,7 +1165,7 @@ class javax_swing_tree_DefaultMutableTreeNode_PersistenceDelegate extends Defaul } // ToolTipManager -class javax_swing_ToolTipManager_PersistenceDelegate extends PersistenceDelegate { +static final class javax_swing_ToolTipManager_PersistenceDelegate extends PersistenceDelegate { protected Expression instantiate(Object oldInstance, Encoder out) { return new Expression(oldInstance, javax.swing.ToolTipManager.class, "sharedInstance", new Object[]{}); @@ -1165,7 +1173,7 @@ class javax_swing_ToolTipManager_PersistenceDelegate extends PersistenceDelegate } // JTabbedPane -class javax_swing_JTabbedPane_PersistenceDelegate extends DefaultPersistenceDelegate { +static final class javax_swing_JTabbedPane_PersistenceDelegate extends DefaultPersistenceDelegate { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { super.initialize(type, oldInstance, newInstance, out); javax.swing.JTabbedPane p = (javax.swing.JTabbedPane)oldInstance; @@ -1180,7 +1188,7 @@ class javax_swing_JTabbedPane_PersistenceDelegate extends DefaultPersistenceDele } // Box -class javax_swing_Box_PersistenceDelegate extends DefaultPersistenceDelegate { +static final class javax_swing_Box_PersistenceDelegate extends DefaultPersistenceDelegate { protected boolean mutatesTo(Object oldInstance, Object newInstance) { return super.mutatesTo(oldInstance, newInstance) && getAxis(oldInstance).equals(getAxis(newInstance)); } @@ -1201,7 +1209,7 @@ class javax_swing_Box_PersistenceDelegate extends DefaultPersistenceDelegate { // Container will return all of the sub menu items that // need to be added to the menu item. // Not so for JMenu apparently. -class javax_swing_JMenu_PersistenceDelegate extends DefaultPersistenceDelegate { +static final class javax_swing_JMenu_PersistenceDelegate extends DefaultPersistenceDelegate { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { super.initialize(type, oldInstance, newInstance, out); javax.swing.JMenu m = (javax.swing.JMenu)oldInstance; @@ -1219,7 +1227,7 @@ class javax_swing_JMenu_PersistenceDelegate extends DefaultPersistenceDelegate { * * @author Sergey A. Malenkov */ -final class javax_swing_border_MatteBorder_PersistenceDelegate extends PersistenceDelegate { +static final class javax_swing_border_MatteBorder_PersistenceDelegate extends PersistenceDelegate { protected Expression instantiate(Object oldInstance, Encoder out) { MatteBorder border = (MatteBorder) oldInstance; Insets insets = border.getBorderInsets(); @@ -1239,7 +1247,7 @@ final class javax_swing_border_MatteBorder_PersistenceDelegate extends Persisten } /* XXX - doens't seem to work. Debug later. -class javax_swing_JMenu_PersistenceDelegate extends DefaultPersistenceDelegate { +static final class javax_swing_JMenu_PersistenceDelegate extends DefaultPersistenceDelegate { protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { super.initialize(type, oldInstance, newInstance, out); javax.swing.JMenu m = (javax.swing.JMenu)oldInstance; @@ -1261,7 +1269,7 @@ class javax_swing_JMenu_PersistenceDelegate extends DefaultPersistenceDelegate { * * @author Sergey A. Malenkov */ -final class sun_swing_PrintColorUIResource_PersistenceDelegate extends PersistenceDelegate { +static final class sun_swing_PrintColorUIResource_PersistenceDelegate extends PersistenceDelegate { protected boolean mutatesTo(Object oldInstance, Object newInstance) { return oldInstance.equals(newInstance); } @@ -1273,7 +1281,6 @@ final class sun_swing_PrintColorUIResource_PersistenceDelegate extends Persisten } } -class MetaData { private static final Map fields = Collections.synchronizedMap(new WeakHashMap()); private static Hashtable internalPersistenceDelegates = new Hashtable<>(); @@ -1316,7 +1323,7 @@ class MetaData { if (Enum.class.isAssignableFrom(type)) { return enumPersistenceDelegate; } - if (ReflectionUtils.isPrimitive(type)) { + if (null != XMLEncoder.primitiveTypeFor(type)) { return primitivePersistenceDelegate; } // The persistence delegate for arrays is non-trivial; instantiate it lazily. @@ -1350,7 +1357,7 @@ class MetaData { internalPersistenceDelegates.put(typeName, defaultPersistenceDelegate); try { String name = type.getName(); - Class c = Class.forName("java.beans." + name.replace('.', '_') + Class c = Class.forName("java.beans.MetaData$" + name.replace('.', '_') + "_PersistenceDelegate"); pd = (PersistenceDelegate)c.newInstance(); internalPersistenceDelegates.put(typeName, pd); diff --git a/jdk/src/share/classes/java/beans/ReflectionUtils.java b/jdk/src/share/classes/java/beans/ReflectionUtils.java deleted file mode 100644 index 9271827b135..00000000000 --- a/jdk/src/share/classes/java/beans/ReflectionUtils.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2003, 2009, Oracle and/or its affiliates. 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code 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 General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.beans; - -import java.lang.reflect.Field; - -/** - * A utility class for reflectively finding methods, constuctors and fields - * using reflection. - */ -class ReflectionUtils { - - @SuppressWarnings("rawtypes") - public static boolean isPrimitive(Class type) { - return primitiveTypeFor(type) != null; - } - - @SuppressWarnings("rawtypes") - public static Class primitiveTypeFor(Class wrapper) { - if (wrapper == Boolean.class) return Boolean.TYPE; - if (wrapper == Byte.class) return Byte.TYPE; - if (wrapper == Character.class) return Character.TYPE; - if (wrapper == Short.class) return Short.TYPE; - if (wrapper == Integer.class) return Integer.TYPE; - if (wrapper == Long.class) return Long.TYPE; - if (wrapper == Float.class) return Float.TYPE; - if (wrapper == Double.class) return Double.TYPE; - if (wrapper == Void.class) return Void.TYPE; - return null; - } - - /** - * Returns the value of a private field. - * - * @param instance object instance - * @param cls class - * @param name name of the field - * @param el an exception listener to handle exceptions; or null - * @return value of the field; null if not found or an error is encountered - */ - @SuppressWarnings("rawtypes") - public static Object getPrivateField(Object instance, Class cls, - String name, ExceptionListener el) { - try { - Field f = cls.getDeclaredField(name); - f.setAccessible(true); - return f.get(instance); - } - catch (Exception e) { - if (el != null) { - el.exceptionThrown(e); - } - } - return null; - } -} diff --git a/jdk/src/share/classes/java/beans/XMLEncoder.java b/jdk/src/share/classes/java/beans/XMLEncoder.java index 97e1359268a..dfccf7af11b 100644 --- a/jdk/src/share/classes/java/beans/XMLEncoder.java +++ b/jdk/src/share/classes/java/beans/XMLEncoder.java @@ -604,7 +604,7 @@ public class XMLEncoder extends Encoder implements AutoCloseable { return; } - Class primitiveType = ReflectionUtils.primitiveTypeFor(value.getClass()); + Class primitiveType = primitiveTypeFor(value.getClass()); if (primitiveType != null && target == value.getClass() && methodName.equals("new")) { String primitiveTypeName = primitiveType.getName(); @@ -778,4 +778,18 @@ public class XMLEncoder extends Encoder implements AutoCloseable { indentation--; writeln(""); } + + @SuppressWarnings("rawtypes") + static Class primitiveTypeFor(Class wrapper) { + if (wrapper == Boolean.class) return Boolean.TYPE; + if (wrapper == Byte.class) return Byte.TYPE; + if (wrapper == Character.class) return Character.TYPE; + if (wrapper == Short.class) return Short.TYPE; + if (wrapper == Integer.class) return Integer.TYPE; + if (wrapper == Long.class) return Long.TYPE; + if (wrapper == Float.class) return Float.TYPE; + if (wrapper == Double.class) return Double.TYPE; + if (wrapper == Void.class) return Void.TYPE; + return null; + } } diff --git a/jdk/test/java/beans/XMLEncoder/AbstractTest.java b/jdk/test/java/beans/XMLEncoder/AbstractTest.java index 09eb73f2908..3207fee6aff 100644 --- a/jdk/test/java/beans/XMLEncoder/AbstractTest.java +++ b/jdk/test/java/beans/XMLEncoder/AbstractTest.java @@ -30,8 +30,10 @@ import java.io.ByteArrayOutputStream; import java.nio.charset.Charset; +import java.lang.reflect.Field; + abstract class AbstractTest implements ExceptionListener { - private final BeanValidator validator = new BeanValidator(); + final BeanValidator validator = new BeanValidator(); public final void exceptionThrown(Exception exception) { throw new Error("unexpected exception", exception); @@ -59,7 +61,7 @@ abstract class AbstractTest implements ExceptionListener { } /** - * This method should be overriden + * This method should be overridden * if specified encoder should be initialized. * * @param encoder the XML encoder to initialize @@ -68,7 +70,7 @@ abstract class AbstractTest implements ExceptionListener { } /** - * This method should be overriden + * This method should be overridden * if specified decoder should be initialized. * * @param decoder the XML decoder to initialize @@ -77,7 +79,7 @@ abstract class AbstractTest implements ExceptionListener { } /** - * This method should be overriden + * This method should be overridden * for test-specific comparison. * * @param before the object before encoding @@ -134,6 +136,7 @@ abstract class AbstractTest implements ExceptionListener { private byte[] writeObject(Object object) { ByteArrayOutputStream output = new ByteArrayOutputStream(); XMLEncoder encoder = new XMLEncoder(output); + encoder.setExceptionListener(this); initialize(encoder); encoder.writeObject(object); encoder.close(); @@ -143,9 +146,24 @@ abstract class AbstractTest implements ExceptionListener { private Object readObject(byte[] array) { ByteArrayInputStream input = new ByteArrayInputStream(array); XMLDecoder decoder = new XMLDecoder(input); + decoder.setExceptionListener(this); initialize(decoder); Object object = decoder.readObject(); decoder.close(); return object; } + + static Field getField(String name) { + try { + int index = name.lastIndexOf('.'); + String className = name.substring(0, index); + String fieldName = name.substring(1 + index); + Field field = Class.forName(className).getDeclaredField(fieldName); + field.setAccessible(true); + return field; + } + catch (Exception exception) { + throw new Error(exception); + } + } } diff --git a/jdk/test/java/beans/XMLEncoder/BeanValidator.java b/jdk/test/java/beans/XMLEncoder/BeanValidator.java index 78f2faa358f..78e13bc0873 100644 --- a/jdk/test/java/beans/XMLEncoder/BeanValidator.java +++ b/jdk/test/java/beans/XMLEncoder/BeanValidator.java @@ -63,6 +63,15 @@ final class BeanValidator { } Class type = object1.getClass(); if (!type.equals(object2.getClass())) { + // resolve different implementations of the Map.Entry interface + if ((object1 instanceof Map.Entry) && (object2 instanceof Map.Entry)) { + log("!!! special case", "Map.Entry"); + Map.Entry entry1 = (Map.Entry) object1; + Map.Entry entry2 = (Map.Entry) object2; + validate(entry1.getKey(), entry2.getKey()); + validate(entry1.getValue(), entry2.getValue()); + return; + } throw new IllegalStateException("could not compare objects with different types"); } // validate elements of arrays @@ -82,10 +91,14 @@ final class BeanValidator { } return; } + // special case for collections: do not use equals + boolean ignore = Collection.class.isAssignableFrom(type) + || Map.Entry.class.isAssignableFrom(type) + || Map.class.isAssignableFrom(type); // validate objects using equals() // we assume that the method equals(Object) can be called, // if the class declares such method - if (isDefined(type, "equals", Object.class)) { + if (!ignore && isDefined(type, "equals", Object.class)) { if (object1.equals(object2)) { return; } @@ -205,27 +218,7 @@ final class BeanValidator { } private void validate(Map map1, Map map2, boolean sorted) { - if (map1.size() != map2.size()) { - throw new IllegalStateException("could not compare maps with different sizes"); - } - if (sorted) { - Iterator first = map1.entrySet().iterator(); - Iterator second = map2.entrySet().iterator(); - int index = 0; - while (first.hasNext() && second.hasNext()) { - log("validate map entry", Integer.valueOf(index++)); - validate(first.next(), second.next()); - } - if (first.hasNext() || second.hasNext()) { - throw new IllegalStateException("one map contains more entries than another one"); - } - } else { - // assume that equals() can be used for keys - for (Object key : map1.keySet()) { - log("validate map value for key", key); - validate(map1.get(key), map2.get(key)); - } - } + validate(map1.entrySet(), map2.entrySet(), sorted); } private boolean isCyclic(Object object1, Object object2) { diff --git a/jdk/test/java/beans/XMLEncoder/Test4631471.java b/jdk/test/java/beans/XMLEncoder/Test4631471.java index 0b3b107f7c6..ccaae8295ce 100644 --- a/jdk/test/java/beans/XMLEncoder/Test4631471.java +++ b/jdk/test/java/beans/XMLEncoder/Test4631471.java @@ -28,7 +28,6 @@ * @author Sergey Malenkov, Mark Davidson */ -import java.beans.XMLEncoder; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; @@ -78,10 +77,6 @@ public abstract class Test4631471 extends AbstractTest { // do not any validation } - protected final void initialize(XMLEncoder encoder) { - encoder.setExceptionListener(this); - } - public static TreeNode getRoot() { DefaultMutableTreeNode node = new DefaultMutableTreeNode("root"); DefaultMutableTreeNode first = new DefaultMutableTreeNode("first"); diff --git a/jdk/test/java/beans/XMLEncoder/Test4679556.java b/jdk/test/java/beans/XMLEncoder/Test4679556.java index a77836e12ee..3ede5266858 100644 --- a/jdk/test/java/beans/XMLEncoder/Test4679556.java +++ b/jdk/test/java/beans/XMLEncoder/Test4679556.java @@ -103,7 +103,6 @@ public class Test4679556 extends AbstractTest { } protected void initialize(XMLEncoder encoder) { - encoder.setExceptionListener(this); encoder.setPersistenceDelegate(C.class, new DefaultPersistenceDelegate() { protected Expression instantiate(Object oldInstance, Encoder out) { C c = (C) oldInstance; diff --git a/jdk/test/java/beans/XMLEncoder/java_awt_BorderLayout.java b/jdk/test/java/beans/XMLEncoder/java_awt_BorderLayout.java index eed980a83b0..44876d9c912 100644 --- a/jdk/test/java/beans/XMLEncoder/java_awt_BorderLayout.java +++ b/jdk/test/java/beans/XMLEncoder/java_awt_BorderLayout.java @@ -68,11 +68,9 @@ public final class java_awt_BorderLayout extends AbstractTest { @Override protected void validate(BorderLayout before, BorderLayout after) { super.validate(before, after); - - BeanValidator validator = new BeanValidator(); for (String constraint : CONSTRAINTS) { - validator.validate(before.getLayoutComponent(constraint), - after.getLayoutComponent(constraint)); + super.validator.validate(before.getLayoutComponent(constraint), + after.getLayoutComponent(constraint)); } } diff --git a/jdk/test/java/beans/XMLEncoder/java_awt_CardLayout.java b/jdk/test/java/beans/XMLEncoder/java_awt_CardLayout.java new file mode 100644 index 00000000000..aa6a3fc5fe3 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/java_awt_CardLayout.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8007458 + * @summary Tests CardLayout encoding + * @author Sergey Malenkov + */ + +import java.awt.CardLayout; +import java.lang.reflect.Field; +import java.util.Vector; +import javax.swing.JLabel; + +public final class java_awt_CardLayout extends AbstractTest { + private static final Field VECTOR = getField("java.awt.CardLayout.vector"); + private static final Field NAME = getField("java.awt.CardLayout$Card.name"); + private static final Field COMP = getField("java.awt.CardLayout$Card.comp"); + + public static void main(String[] args) throws Exception { + new java_awt_CardLayout().test(true); + } + + @Override + protected CardLayout getObject() { + CardLayout layout = new CardLayout(); + layout.addLayoutComponent(new JLabel("a"), "a"); + layout.addLayoutComponent(new JLabel("b"), "b"); + layout.addLayoutComponent(new JLabel("c"), "c"); + return layout; + } + + @Override + protected CardLayout getAnotherObject() { + CardLayout layout = new CardLayout(); + layout.addLayoutComponent(new JLabel("a"), "a"); + layout.addLayoutComponent(new JLabel("b"), "b"); + layout.addLayoutComponent(new JLabel("c"), "c"); + layout.addLayoutComponent(new JLabel("d"), "d"); + return layout; + } + + @Override + protected void validate(CardLayout before, CardLayout after) { + super.validate(before, after); + try { + Vector a = (Vector) VECTOR.get(after); + Vector b = (Vector) VECTOR.get(before); + int size = a.size(); + if (size != b.size()) { + throw new Error("different content"); + } + for (int i = 0; i < size; i++) { + super.validator.validate(NAME.get(a.get(i)), NAME.get(b.get(i))); + super.validator.validate(COMP.get(a.get(i)), COMP.get(b.get(i))); + } + } + catch (Exception exception) { + throw new Error(exception); + } + } +} diff --git a/jdk/test/java/beans/XMLEncoder/java_awt_GridBagLayout.java b/jdk/test/java/beans/XMLEncoder/java_awt_GridBagLayout.java new file mode 100644 index 00000000000..7011dbd739f --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/java_awt_GridBagLayout.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8007458 + * @summary Tests GridBagLayout encoding + * @author Sergey Malenkov + */ + +import java.awt.Component; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.lang.reflect.Field; +import java.util.Hashtable; +import java.util.Map; +import javax.swing.JLabel; + +public final class java_awt_GridBagLayout extends AbstractTest { + private static final Field HASHTABLE = getField("java.awt.GridBagLayout.comptable"); + + public static void main(String[] args) { + new java_awt_GridBagLayout().test(true); + } + + @Override + protected GridBagLayout getObject() { + GridBagLayout layout = new GridBagLayout(); + update(layout, "1", 1, 1); + update(layout, "2", 2, 2); + update(layout, "3", 3, 3); + return layout; + } + + @Override + protected GridBagLayout getAnotherObject() { + GridBagLayout layout = new GridBagLayout(); + update(layout, "11", 1, 1); + update(layout, "12", 1, 2); + update(layout, "21", 2, 1); + update(layout, "22", 2, 2); + return layout; + } + + @Override + protected void validate(GridBagLayout before, GridBagLayout after) { + super.validate(before, after); + try { + Hashtable a = (Hashtable) HASHTABLE.get(after); + Hashtable b = (Hashtable) HASHTABLE.get(before); + super.validator.validate(a, b); + +// for (int i = 0; i < size; i++) { +// validator.validate(NAME.get(a.get(i)), NAME.get(b.get(i))); +// validator.validate(COMP.get(a.get(i)), COMP.get(b.get(i))); +// } + } + catch (Exception exception) { + throw new Error(exception); + } + + + +// for (String name : names) { +// validator.validate(getConstraints(before, name), getConstraints(after, name)); +// } + } + + private static void update(GridBagLayout layout, String id, int x, int y) { + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = x; + gbc.gridy = y; + layout.addLayoutComponent(new JLabel(id), gbc); + } + +/* + private static GridBagConstraints getConstraints(GridBagLayout layout, String id) { + return (layout == null) ? null : ((MyGridBagLayout) layout).getConstraints(id); + } +*/ +} diff --git a/jdk/test/java/beans/XMLEncoder/javax_swing_DefaultCellEditor.java b/jdk/test/java/beans/XMLEncoder/javax_swing_DefaultCellEditor.java index 037588352c0..476d64db827 100644 --- a/jdk/test/java/beans/XMLEncoder/javax_swing_DefaultCellEditor.java +++ b/jdk/test/java/beans/XMLEncoder/javax_swing_DefaultCellEditor.java @@ -28,6 +28,7 @@ * @author Sergey Malenkov */ +import java.beans.XMLEncoder; import javax.swing.DefaultCellEditor; import javax.swing.JTextField; import javax.swing.text.JTextComponent; @@ -46,6 +47,11 @@ public final class javax_swing_DefaultCellEditor extends AbstractTest