classpath-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cp-patches] FYI: XMLEncoder - less dependencies & bugfix


From: Robert Schuster
Subject: [cp-patches] FYI: XMLEncoder - less dependencies & bugfix
Date: Tue, 24 Jan 2006 18:07:47 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; de-AT; rv:1.7.12) Gecko/20051208

Hi,
I spend some time finding out how the JDK makes it possible that a
PersistenceDelegate registered for AbstractMap is used for all its subclasses.

The funny thing is that the whole behavior depends on three places. Two of them
were implemented already because they are part of the spec. The final component
consists only of one line (calling super.inititialize() in
DefaultPersistenceDelegate.initialize()).

Along the lines I found out that the XMLEncoder gets into an endless recursion
when it serializes a class which is not public. The problem is not specific to
this case the recursion would happen in any when an exception occurs during the
Expression.getValue() call. A simple early "return" fixes that. I have to admit
that the wrong behavior slipped in when I copied most of
Encoder.writeExpression's code into XMLEncoder.writeExpression. Anyway this
fixes PR #25941 .

The ChangeLog entry:

2006-01-24  Robert Schuster  <address@hidden>

        * java/beans/XMLEncoder.java:
        (writeExpression): Added early return (fixes PR #25941).
        * java/beans/Encoder: Removed unused imports.
        (setupDefaultPersistenceDelegates): Removed unneccessary
        PersistenceDelegates for subclasses.
        * java/beans/PersistenceDelegate:
        (initialize): Use local variable as first argument as it was
        intended once.

Index: java/beans/DefaultPersistenceDelegate.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/java/beans/DefaultPersistenceDelegate.java,v
retrieving revision 1.1
diff -u -r1.1 DefaultPersistenceDelegate.java
--- java/beans/DefaultPersistenceDelegate.java  8 Jan 2006 19:31:38 -0000       
1.1
+++ java/beans/DefaultPersistenceDelegate.java  24 Jan 2006 16:42:17 -0000
@@ -157,6 +157,23 @@
   protected void initialize(Class type, Object oldInstance, Object newInstance,
                             Encoder out)
   {
+    // Calling the supertype's implementation of initialize makes it
+    // possible that descendants of classes like AbstractHashMap
+    // or Hashtable are serialized correctly. This mechanism grounds on
+    // two other facts:
+    // * Each class which has not registered a special purpose
+    //   PersistenceDelegate is handled by a DefaultPersistenceDelegate
+    //   instance.
+    // * PersistenceDelegate.initialize() is implemented in a way that it
+    //   calls the initialize method of the superclass' persistence delegate.
+    super.initialize(type, oldInstance, newInstance, out);
+    
+    // Suppresses the writing of property setting statements when this delegate
+    // is not used for the exact instance type. By doing so the following code
+    // is called only once per object.
+    if (type != oldInstance.getClass())
+      return;
+    
     try
       {
         PropertyDescriptor[] propertyDescs = Introspector.getBeanInfo(
Index: java/beans/Encoder.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/beans/Encoder.java,v
retrieving revision 1.1
diff -u -r1.1 Encoder.java
--- java/beans/Encoder.java     8 Jan 2006 19:31:38 -0000       1.1
+++ java/beans/Encoder.java     24 Jan 2006 16:42:17 -0000
@@ -44,15 +44,9 @@
 import gnu.java.beans.encoder.MapPersistenceDelegate;
 import gnu.java.beans.encoder.PrimitivePersistenceDelegate;
 
-import java.util.ArrayList;
+import java.util.AbstractCollection;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.IdentityHashMap;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.Vector;
 
 /**
  * @author Robert Schuster (address@hidden)
@@ -123,31 +117,11 @@
         delegates.put(Object[].class, new ArrayPersistenceDelegate());
 
         pd = new CollectionPersistenceDelegate();
-        delegates.put(ArrayList.class, pd);
-        delegates.put(LinkedList.class, pd);
-        delegates.put(Vector.class, pd);
-        delegates.put(HashSet.class, pd);
-        delegates.put(LinkedHashSet.class, pd);
-        delegates.put(TreeSet.class, pd);
+        delegates.put(AbstractCollection.class, pd);
         
         pd = new MapPersistenceDelegate();
-        delegates.put(HashMap.class, pd);
-        delegates.put(TreeMap.class, pd);
+        delegates.put(java.util.AbstractMap.class, pd);
         delegates.put(java.util.Hashtable.class, pd);
-        delegates.put(java.util.IdentityHashMap.class, pd);
-        
-        delegates.put(java.util.LinkedHashMap.class, pd);
-        delegates.put(java.util.Properties.class, pd);
-
-        delegates.put(java.awt.RenderingHints.class, pd);
-        delegates.put(java.util.WeakHashMap.class, pd);
-        delegates.put(javax.swing.UIDefaults.class, pd);
-        
-        // TODO: These classes need to be implemented first
-        //delegates.put(java.security.AuthProvider.class, pd);
-        //delegates.put(java.util.concurrent.ConcurrentHashMap.class, pd);
-        //delegates.put(java.util.EnumMap.class, pd);
-        //delegates.put(javax.management.openmbean.TabularDataSupport.class, 
pd);
         
         defaultPersistenceDelegate = new DefaultPersistenceDelegate();
         delegates.put(Object.class, defaultPersistenceDelegate);
@@ -199,7 +173,6 @@
       public void exceptionThrown(Exception e)
       {
         System.err.println("exception thrown: " + e);
-        e.printStackTrace();
       }
     };
   }
Index: java/beans/PersistenceDelegate.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/beans/PersistenceDelegate.java,v
retrieving revision 1.1
diff -u -r1.1 PersistenceDelegate.java
--- java/beans/PersistenceDelegate.java 8 Jan 2006 19:31:38 -0000       1.1
+++ java/beans/PersistenceDelegate.java 24 Jan 2006 16:42:17 -0000
@@ -59,9 +59,8 @@
       {
         type = type.getSuperclass();
 
-        PersistenceDelegate pd = out.getPersistenceDelegate(
-          oldInstance.getClass().getSuperclass());
-
+        PersistenceDelegate pd = out.getPersistenceDelegate(type);
+        
         pd.initialize(type, oldInstance, newInstance, out);
       }
   }
Index: java/beans/XMLEncoder.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/beans/XMLEncoder.java,v
retrieving revision 1.1
diff -u -r1.1 XMLEncoder.java
--- java/beans/XMLEncoder.java  8 Jan 2006 19:31:38 -0000       1.1
+++ java/beans/XMLEncoder.java  24 Jan 2006 16:42:17 -0000
@@ -168,6 +168,8 @@
             // an erroneous state to the ScanEngine without behaving different
             // to the JDK.            
             scanEngine.revoke();
+            
+            return;
           }
         
         writeObject(value);

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]