Title: [2302] branches/v-1.4.x: Merge fix for XSTR-762 into branch.

Diff

Modified: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java (2301 => 2302)


--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java	2014-10-30 12:58:59 UTC (rev 2301)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java	2014-10-30 13:18:10 UTC (rev 2302)
@@ -53,7 +53,7 @@
     public AbstractReflectionConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
         this.mapper = mapper;
         this.reflectionProvider = reflectionProvider;
-        init();
+        serializationMethodInvoker = new SerializationMethodInvoker();
     }
     
     protected boolean canAccess(Class type) {
@@ -558,12 +558,8 @@
         serializationMethodInvoker.flushCache();
     }
 
-    protected void init() {
+    protected Object readResolve() {
         serializationMethodInvoker = new SerializationMethodInvoker();
-    }
-
-    private Object readResolve() {
-        init();
         return this;
     }
 

Modified: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/CGLIBEnhancedConverter.java (2301 => 2302)


--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/CGLIBEnhancedConverter.java	2014-10-30 12:58:59 UTC (rev 2301)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/CGLIBEnhancedConverter.java	2014-10-30 13:18:10 UTC (rev 2302)
@@ -438,8 +438,8 @@
         return typeHierarchy;
     }
 
-    private Object readResolve() {
-        init();
+    protected Object readResolve() {
+        super.readResolve();
         fieldCache = new HashMap();
         return this;
     }

Modified: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializationMethodInvoker.java (2301 => 2302)


--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializationMethodInvoker.java	2014-10-30 12:58:59 UTC (rev 2301)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializationMethodInvoker.java	2014-10-30 13:18:10 UTC (rev 2302)
@@ -6,7 +6,7 @@
  * The software in this package is published under the terms of the BSD
  * style license a copy of which has been included with this distribution in
  * the LICENSE.txt file.
- * 
+ *
  * Created on 23. August 2004 by Joe Walnes
  */
 package com.thoughtworks.xstream.converters.reflection;
@@ -19,6 +19,7 @@
 import java.io.ObjectOutputStream;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
@@ -28,7 +29,7 @@
 /**
  * Convenience wrapper to invoke special serialization methods on objects (and perform
  * reflection caching).
- * 
+ *
  * @author Joe Walnes
  * @author Jörg Schaible
  */
@@ -39,17 +40,22 @@
         }
     }).getClass().getDeclaredMethods()[0];
     private static final Object[] EMPTY_ARGS = new Object[0];
-    private static final FastField[] OBJECT_TYPE_FIELDS = new FastField[]{
+    private static final Class[] EMPTY_CLASSES = new Class[0];
+    private static final FastField[] OBJECT_TYPE_FIELDS = {
         new FastField(Object.class, "readResolve"), 
         new FastField(Object.class, "writeReplace"), 
         new FastField(Object.class, "readObject"), 
         new FastField(Object.class, "writeObject")
     };
-    private Map cache = Collections.synchronizedMap(new HashMap());
+    private Map declaredCache = Collections.synchronizedMap(new HashMap());
+    private Map resRepCache = Collections.synchronizedMap(new HashMap());
     {
         for(int i = 0; i < OBJECT_TYPE_FIELDS.length; ++i) {
-            cache.put(OBJECT_TYPE_FIELDS[i], NO_METHOD);
+            declaredCache.put(OBJECT_TYPE_FIELDS[i], NO_METHOD);
         }
+        for(int i = 0; i < 2; ++i) {
+            resRepCache.put(OBJECT_TYPE_FIELDS[i], NO_METHOD);
+        }
     }
 
     /**
@@ -59,17 +65,18 @@
         if (result == null) {
             return null;
         } else {
-            Method readResolveMethod = getMethod(result.getClass(), "readResolve", null, true);
+            final Class resultType = result.getClass();
+            final Method readResolveMethod = getRRMethod(resultType, "readResolve");
             if (readResolveMethod != null) {
                 try {
                     return readResolveMethod.invoke(result, EMPTY_ARGS);
                 } catch (IllegalAccessException e) {
                     throw new ObjectAccessException("Could not call "
-                        + result.getClass().getName()
+                        + resultType.getName()
                         + ".readResolve()", e);
                 } catch (InvocationTargetException e) {
                     throw new ObjectAccessException("Could not call "
-                        + result.getClass().getName()
+                        + resultType.getName()
                         + ".readResolve()", e.getTargetException());
                 }
             } else {
@@ -82,17 +89,18 @@
         if (object == null) {
             return null;
         } else {
-            Method writeReplaceMethod = getMethod(object.getClass(), "writeReplace", null, true);
+            final Class objectType = object.getClass();
+            final Method writeReplaceMethod = getRRMethod(objectType, "writeReplace");
             if (writeReplaceMethod != null) {
                 try {
                     return writeReplaceMethod.invoke(object, EMPTY_ARGS);
                 } catch (IllegalAccessException e) {
                     throw new ObjectAccessException("Could not call "
-                        + object.getClass().getName()
+                        + objectType.getName()
                         + ".writeReplace()", e);
                 } catch (InvocationTargetException e) {
                     throw new ObjectAccessException("Could not call "
-                        + object.getClass().getName()
+                        + objectType.getName()
                         + ".writeReplace()", e.getTargetException());
                 }
             } else {
@@ -157,8 +165,7 @@
             return null;
         }
         FastField method = new FastField(type, name);
-        Method result = (Method)cache.get(method);
-
+        Method result = (Method)declaredCache.get(method);
         if (result == null) {
             try {
                 result = type.getDeclaredMethod(name, parameterTypes);
@@ -168,12 +175,33 @@
             } catch (NoSuchMethodException e) {
                 result = getMethod(type.getSuperclass(), name, parameterTypes);
             }
-            cache.put(method, result);
+            declaredCache.put(method, result);
         }
         return result;
     }
 
+    private Method getRRMethod(final Class type, final String name) {
+        final FastField method = new FastField(type, name);
+        Method result = (Method)resRepCache.get(method);
+        if (result == null) {
+            result = getMethod(type, name, EMPTY_CLASSES, true);
+            if (result != null && result.getDeclaringClass() != type) {
+                if ((result.getModifiers() & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0) {
+                    if ((result.getModifiers() & Modifier.PRIVATE) > 0
+                            || type.getPackage() != result.getDeclaringClass().getPackage()) {
+                        result = NO_METHOD;
+                    }
+                }
+            } else if (result == null) {
+                result = NO_METHOD;
+            }
+            resRepCache.put(method, result);
+        }
+        return result == NO_METHOD ? null : result;
+    }
+
     public void flushCache() {
-        cache.keySet().retainAll(Arrays.asList(OBJECT_TYPE_FIELDS));
+        declaredCache.keySet().retainAll(Arrays.asList(OBJECT_TYPE_FIELDS));
+        resRepCache.keySet().retainAll(Arrays.asList(OBJECT_TYPE_FIELDS));
     }
 }

Modified: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/mapper/AbstractAttributeAliasingMapper.java (2301 => 2302)


--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/mapper/AbstractAttributeAliasingMapper.java	2014-10-30 12:58:59 UTC (rev 2301)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/mapper/AbstractAttributeAliasingMapper.java	2014-10-30 13:18:10 UTC (rev 2302)
@@ -34,7 +34,7 @@
         nameToAlias.put(attributeName, alias);
     }
 
-    private Object readResolve() {
+    Object readResolve() {
         nameToAlias = new HashMap();
         for (final Iterator iter = aliasToName.keySet().iterator(); iter.hasNext();) {
             final Object alias = iter.next();

Modified: branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/AbstractReferenceTest.java (2301 => 2302)


--- branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/AbstractReferenceTest.java	2014-10-30 12:58:59 UTC (rev 2301)
+++ branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/AbstractReferenceTest.java	2014-10-30 13:18:10 UTC (rev 2302)
@@ -397,7 +397,7 @@
             return true;
         }
 
-        private Object writeReplace() {
+        protected Object writeReplace() {
             if (getClass() == TreeData.class) {
                 return this;
             }

Modified: branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/SerializationCallbackOrderTest.java (2301 => 2302)


--- branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/SerializationCallbackOrderTest.java	2014-10-30 12:58:59 UTC (rev 2301)
+++ branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/SerializationCallbackOrderTest.java	2014-10-30 13:18:10 UTC (rev 2302)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2005 Joe Walnes.
- * Copyright (C) 2006, 2007 XStream Committers.
+ * Copyright (C) 2006, 2007, 2014 XStream Committers.
  * All rights reserved.
  *
  * The software in this package is published under the terms of the BSD
@@ -32,58 +32,203 @@
     }
    
 
-    // --- Sample class hiearchy
+    // --- Sample class hierarchy
 
-    public static class Base implements Serializable{
+    public static class PrivateBase implements Serializable{
 
         private void writeObject(ObjectOutputStream out) throws IOException {
-            log.actual("Base.writeObject() start");
+            log.actual("PrivateBase.writeObject() start");
             out.defaultWriteObject();
-            log.actual("Base.writeObject() end");
+            log.actual("PrivateBase.writeObject() end");
         }
 
         private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-            log.actual("Base.readObject() start");
+            log.actual("PrivateBase.readObject() start");
             in.defaultReadObject();
-            log.actual("Base.readObject() end");
+            log.actual("PrivateBase.readObject() end");
         }
 
         private Object writeReplace() {
-            log.actual("Base.writeReplace()");
+            log.actual("PrivateBase.writeReplace()");
             return this;
         }
 
         private Object readResolve() {
-            log.actual("Base.readResolve()");
+            log.actual("PrivateBase.readResolve()");
             return this;
         }
     }
 
-    public static class Child extends Base implements Serializable{
+    public static class PrivateChildOwnRR extends PrivateBase implements Serializable{
 
         private void writeObject(ObjectOutputStream out) throws IOException {
-            log.actual("Child.writeObject() start");
+            log.actual("PrivateChildOwnRR.writeObject() start");
             out.defaultWriteObject();
-            log.actual("Child.writeObject() end");
+            log.actual("PrivateChildOwnRR.writeObject() end");
         }
 
         private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-            log.actual("Child.readObject() start");
+            log.actual("PrivateChildOwnRR.readObject() start");
             in.defaultReadObject();
-            log.actual("Child.readObject() end");
+            log.actual("PrivateChildOwnRR.readObject() end");
         }
 
         private Object writeReplace() {
-            log.actual("Child.writeReplace()");
+            log.actual("PrivateChildOwnRR.writeReplace()");
             return this;
         }
 
         private Object readResolve() {
-            log.actual("Child.readResolve()");
+            log.actual("PrivateChildOwnRR.readResolve()");
             return this;
         }
     }
 
+    public static class PrivateChildNoRR extends PrivateBase implements Serializable{
+
+        private void writeObject(ObjectOutputStream out) throws IOException {
+            log.actual("PrivateChildNoRR.writeObject() start");
+            out.defaultWriteObject();
+            log.actual("PrivateChildNoRR.writeObject() end");
+        }
+
+        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+            log.actual("PrivateChildNoRR.readObject() start");
+            in.defaultReadObject();
+            log.actual("PrivateChildNoRR.readObject() end");
+        }
+    }
+    
+    public static class ProtectedBase implements Serializable{
+
+        private void writeObject(ObjectOutputStream out) throws IOException {
+            log.actual("ProtectedBase.writeObject() start");
+            out.defaultWriteObject();
+            log.actual("ProtectedBase.writeObject() end");
+        }
+
+        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+            log.actual("ProtectedBase.readObject() start");
+            in.defaultReadObject();
+            log.actual("ProtectedBase.readObject() end");
+        }
+
+        protected Object writeReplace() {
+            log.actual("ProtectedBase.writeReplace()");
+            return this;
+        }
+
+        protected Object readResolve() {
+            log.actual("ProtectedBase.readResolve()");
+            return this;
+        }
+    }
+
+    public static class ProtectedChildOwnRR extends ProtectedBase implements Serializable{
+
+        private void writeObject(ObjectOutputStream out) throws IOException {
+            log.actual("ProtectedChildOwnRR.writeObject() start");
+            out.defaultWriteObject();
+            log.actual("ProtectedChildOwnRR.writeObject() end");
+        }
+
+        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+            log.actual("ProtectedChildOwnRR.readObject() start");
+            in.defaultReadObject();
+            log.actual("ProtectedChildOwnRR.readObject() end");
+        }
+
+        protected Object writeReplace() {
+            log.actual("ProtectedChildOwnRR.writeReplace()");
+            return this;
+        }
+
+        protected Object readResolve() {
+            log.actual("ProtectedChildOwnRR.readResolve()");
+            return this;
+        }
+    }
+
+    public static class ProtectedChildInheritedRR extends ProtectedBase implements Serializable{
+
+        private void writeObject(ObjectOutputStream out) throws IOException {
+            log.actual("ProtectedChildInheritedRR.writeObject() start");
+            out.defaultWriteObject();
+            log.actual("ProtectedChildInheritedRR.writeObject() end");
+        }
+
+        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+            log.actual("ProtectedChildInheritedRR.readObject() start");
+            in.defaultReadObject();
+            log.actual("ProtectedChildInheritedRR.readObject() end");
+        }
+    }
+    
+    public static class PackageBase implements Serializable{
+
+        private void writeObject(ObjectOutputStream out) throws IOException {
+            log.actual("PackageBase.writeObject() start");
+            out.defaultWriteObject();
+            log.actual("PackageBase.writeObject() end");
+        }
+
+        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+            log.actual("PackageBase.readObject() start");
+            in.defaultReadObject();
+            log.actual("PackageBase.readObject() end");
+        }
+
+        Object writeReplace() {
+            log.actual("PackageBase.writeReplace()");
+            return this;
+        }
+
+        Object readResolve() {
+            log.actual("PackageBase.readResolve()");
+            return this;
+        }
+    }
+
+    public static class PackageChildOwnRR extends PackageBase implements Serializable{
+
+        private void writeObject(ObjectOutputStream out) throws IOException {
+            log.actual("PackageChildOwnRR.writeObject() start");
+            out.defaultWriteObject();
+            log.actual("PackageChildOwnRR.writeObject() end");
+        }
+
+        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+            log.actual("PackageChildOwnRR.readObject() start");
+            in.defaultReadObject();
+            log.actual("PackageChildOwnRR.readObject() end");
+        }
+
+        Object writeReplace() {
+            log.actual("PackageChildOwnRR.writeReplace()");
+            return this;
+        }
+
+        Object readResolve() {
+            log.actual("PackageChildOwnRR.readResolve()");
+            return this;
+        }
+    }
+
+    public static class PackageChildInheritedRR extends PackageBase implements Serializable{
+
+        private void writeObject(ObjectOutputStream out) throws IOException {
+            log.actual("PackageChildInheritedRR.writeObject() start");
+            out.defaultWriteObject();
+            log.actual("PackageChildInheritedRR.writeObject() end");
+        }
+
+        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+            log.actual("PackageChildInheritedRR.readObject() start");
+            in.defaultReadObject();
+            log.actual("PackageChildInheritedRR.readObject() end");
+        }
+    }
+
     // --- Convenience wrappers around Java Object Serialization
 
     private byte[] javaSerialize(Object object) throws IOException {
@@ -101,47 +246,195 @@
 
     // --- Tests
 
-    public void testJavaSerialization() throws IOException {
+    public void testJavaSerializationOwnPrivateRR() throws IOException {
         // expectations
-        log.expect("Child.writeReplace()");
-        log.expect("Base.writeObject() start");
-        log.expect("Base.writeObject() end");
-        log.expect("Child.writeObject() start");
-        log.expect("Child.writeObject() end");
+        log.expect("PrivateChildOwnRR.writeReplace()");
+        log.expect("PrivateBase.writeObject() start");
+        log.expect("PrivateBase.writeObject() end");
+        log.expect("PrivateChildOwnRR.writeObject() start");
+        log.expect("PrivateChildOwnRR.writeObject() end");
 
         // execute
-        javaSerialize(new Child());
+        javaSerialize(new PrivateChildOwnRR());
 
         // verify
         log.verify();
     }
 
-    public void testXStreamSerialization() {
+    public void testJavaSerializationNoRR() throws IOException {
         // expectations
-        log.expect("Child.writeReplace()");
-        log.expect("Base.writeObject() start");
-        log.expect("Base.writeObject() end");
-        log.expect("Child.writeObject() start");
-        log.expect("Child.writeObject() end");
+        log.expect("PrivateBase.writeObject() start");
+        log.expect("PrivateBase.writeObject() end");
+        log.expect("PrivateChildNoRR.writeObject() start");
+        log.expect("PrivateChildNoRR.writeObject() end");
 
         // execute
-        xstream.toXML(new Child());
+        javaSerialize(new PrivateChildNoRR());
 
         // verify
         log.verify();
     }
 
-    public void testJavaDeserialization() throws IOException, ClassNotFoundException {
+    public void testJavaSerializationOwnProtectedRR() throws IOException {
+        // expectations
+        log.expect("ProtectedChildOwnRR.writeReplace()");
+        log.expect("ProtectedBase.writeObject() start");
+        log.expect("ProtectedBase.writeObject() end");
+        log.expect("ProtectedChildOwnRR.writeObject() start");
+        log.expect("ProtectedChildOwnRR.writeObject() end");
+
+        // execute
+        javaSerialize(new ProtectedChildOwnRR());
+
+        // verify
+        log.verify();
+    }
+
+    public void testJavaSerializationInheritedRR() throws IOException {
+        // expectations
+        log.expect("ProtectedBase.writeReplace()");
+        log.expect("ProtectedBase.writeObject() start");
+        log.expect("ProtectedBase.writeObject() end");
+        log.expect("ProtectedChildInheritedRR.writeObject() start");
+        log.expect("ProtectedChildInheritedRR.writeObject() end");
+
+        // execute
+        javaSerialize(new ProtectedChildInheritedRR());
+
+        // verify
+        log.verify();
+    }
+
+    public void testJavaSerializationOwnPackageRR() throws IOException {
+        // expectations
+        log.expect("PackageChildOwnRR.writeReplace()");
+        log.expect("PackageBase.writeObject() start");
+        log.expect("PackageBase.writeObject() end");
+        log.expect("PackageChildOwnRR.writeObject() start");
+        log.expect("PackageChildOwnRR.writeObject() end");
+
+        // execute
+        javaSerialize(new PackageChildOwnRR());
+
+        // verify
+        log.verify();
+    }
+
+    public void testJavaSerializationInheritedPackageRR() throws IOException {
+        // expectations
+        log.expect("PackageBase.writeReplace()");
+        log.expect("PackageBase.writeObject() start");
+        log.expect("PackageBase.writeObject() end");
+        log.expect("PackageChildInheritedRR.writeObject() start");
+        log.expect("PackageChildInheritedRR.writeObject() end");
+
+        // execute
+        javaSerialize(new PackageChildInheritedRR());
+
+        // verify
+        log.verify();
+    }
+
+    public void testXStreamSerializationOwnPrivateRR() {
+        // expectations
+        log.expect("PrivateChildOwnRR.writeReplace()");
+        log.expect("PrivateBase.writeObject() start");
+        log.expect("PrivateBase.writeObject() end");
+        log.expect("PrivateChildOwnRR.writeObject() start");
+        log.expect("PrivateChildOwnRR.writeObject() end");
+
+        // execute
+        xstream.toXML(new PrivateChildOwnRR());
+
+        // verify
+        log.verify();
+    }
+
+    public void testXStreamSerializationNoRR() {
+        // expectations
+        log.expect("PrivateBase.writeObject() start");
+        log.expect("PrivateBase.writeObject() end");
+        log.expect("PrivateChildNoRR.writeObject() start");
+        log.expect("PrivateChildNoRR.writeObject() end");
+
+        // execute
+        xstream.toXML(new PrivateChildNoRR());
+
+        // verify
+        log.verify();
+    }
+
+    public void testXStreamSerializationOwnProtectedRR() {
+        // expectations
+        log.expect("ProtectedChildOwnRR.writeReplace()");
+        log.expect("ProtectedBase.writeObject() start");
+        log.expect("ProtectedBase.writeObject() end");
+        log.expect("ProtectedChildOwnRR.writeObject() start");
+        log.expect("ProtectedChildOwnRR.writeObject() end");
+
+        // execute
+        xstream.toXML(new ProtectedChildOwnRR());
+
+        // verify
+        log.verify();
+    }
+
+    public void testXStreamSerializationOwnInheritedRR() {
+        // expectations
+        log.expect("ProtectedBase.writeReplace()");
+        log.expect("ProtectedBase.writeObject() start");
+        log.expect("ProtectedBase.writeObject() end");
+        log.expect("ProtectedChildInheritedRR.writeObject() start");
+        log.expect("ProtectedChildInheritedRR.writeObject() end");
+
+        // execute
+        xstream.toXML(new ProtectedChildInheritedRR());
+
+        // verify
+        log.verify();
+    }
+
+    public void testXStreamSerializationOwnPackageRR() {
+        // expectations
+        log.expect("PackageChildOwnRR.writeReplace()");
+        log.expect("PackageBase.writeObject() start");
+        log.expect("PackageBase.writeObject() end");
+        log.expect("PackageChildOwnRR.writeObject() start");
+        log.expect("PackageChildOwnRR.writeObject() end");
+
+        // execute
+        xstream.toXML(new PackageChildOwnRR());
+
+        // verify
+        log.verify();
+    }
+
+    public void testXStreamSerializationOwnInheritedPackageRR() {
+        // expectations
+        log.expect("PackageBase.writeReplace()");
+        log.expect("PackageBase.writeObject() start");
+        log.expect("PackageBase.writeObject() end");
+        log.expect("PackageChildInheritedRR.writeObject() start");
+        log.expect("PackageChildInheritedRR.writeObject() end");
+
+        // execute
+        xstream.toXML(new PackageChildInheritedRR());
+
+        // verify
+        log.verify();
+    }
+
+    public void testJavaDeserializationOwnPrivateRR() throws IOException, ClassNotFoundException {
         // setup
-        byte[] data = "" Child());
+        byte[] data = "" PrivateChildOwnRR());
         log.reset();
 
         // expectations
-        log.expect("Base.readObject() start");
-        log.expect("Base.readObject() end");
-        log.expect("Child.readObject() start");
-        log.expect("Child.readObject() end");
-        log.expect("Child.readResolve()");
+        log.expect("PrivateBase.readObject() start");
+        log.expect("PrivateBase.readObject() end");
+        log.expect("PrivateChildOwnRR.readObject() start");
+        log.expect("PrivateChildOwnRR.readObject() end");
+        log.expect("PrivateChildOwnRR.readResolve()");
 
         // execute
         javaDeserialize(data);
@@ -150,26 +443,213 @@
         log.verify();
     }
 
-    public void testXStreamDeserialization() {
+    public void testJavaDeserializationNoRR() throws IOException, ClassNotFoundException {
         // setup
-        String data = "" Child());
+        byte[] data = "" PrivateChildNoRR());
         log.reset();
 
         // expectations
-        log.expect("Base.readObject() start");
-        log.expect("Base.readObject() end");
-        log.expect("Child.readObject() start");
-        log.expect("Child.readObject() end");
-        log.expect("Child.readResolve()");
+        log.expect("PrivateBase.readObject() start");
+        log.expect("PrivateBase.readObject() end");
+        log.expect("PrivateChildNoRR.readObject() start");
+        log.expect("PrivateChildNoRR.readObject() end");
 
         // execute
+        javaDeserialize(data);
+
+        // verify
+        log.verify();
+    }
+
+    public void testJavaDeserializationOwnProtectedRR() throws IOException, ClassNotFoundException {
+        // setup
+        byte[] data = "" ProtectedChildOwnRR());
+        log.reset();
+
+        // expectations
+        log.expect("ProtectedBase.readObject() start");
+        log.expect("ProtectedBase.readObject() end");
+        log.expect("ProtectedChildOwnRR.readObject() start");
+        log.expect("ProtectedChildOwnRR.readObject() end");
+        log.expect("ProtectedChildOwnRR.readResolve()");
+
+        // execute
+        javaDeserialize(data);
+
+        // verify
+        log.verify();
+    }
+
+    public void testJavaDeserializationInheritedRR() throws IOException, ClassNotFoundException {
+        // setup
+        byte[] data = "" ProtectedChildInheritedRR());
+        log.reset();
+
+        // expectations
+        log.expect("ProtectedBase.readObject() start");
+        log.expect("ProtectedBase.readObject() end");
+        log.expect("ProtectedChildInheritedRR.readObject() start");
+        log.expect("ProtectedChildInheritedRR.readObject() end");
+        log.expect("ProtectedBase.readResolve()");
+
+        // execute
+        javaDeserialize(data);
+
+        // verify
+        log.verify();
+    }
+
+    public void testJavaDeserializationOwnPackageRR() throws IOException, ClassNotFoundException {
+        // setup
+        byte[] data = "" PackageChildOwnRR());
+        log.reset();
+
+        // expectations
+        log.expect("PackageBase.readObject() start");
+        log.expect("PackageBase.readObject() end");
+        log.expect("PackageChildOwnRR.readObject() start");
+        log.expect("PackageChildOwnRR.readObject() end");
+        log.expect("PackageChildOwnRR.readResolve()");
+
+        // execute
+        javaDeserialize(data);
+
+        // verify
+        log.verify();
+    }
+
+    public void testJavaDeserializationInheritedPackageRR() throws IOException, ClassNotFoundException {
+        // setup
+        byte[] data = "" PackageChildInheritedRR());
+        log.reset();
+
+        // expectations
+        log.expect("PackageBase.readObject() start");
+        log.expect("PackageBase.readObject() end");
+        log.expect("PackageChildInheritedRR.readObject() start");
+        log.expect("PackageChildInheritedRR.readObject() end");
+        log.expect("PackageBase.readResolve()");
+
+        // execute
+        javaDeserialize(data);
+
+        // verify
+        log.verify();
+    }
+
+    public void testXStreamDeserializationOwnPrivateRR() {
+        // setup
+        String data = "" PrivateChildOwnRR());
+        log.reset();
+
+        // expectations
+        log.expect("PrivateBase.readObject() start");
+        log.expect("PrivateBase.readObject() end");
+        log.expect("PrivateChildOwnRR.readObject() start");
+        log.expect("PrivateChildOwnRR.readObject() end");
+        log.expect("PrivateChildOwnRR.readResolve()");
+
+        // execute
         xstream.fromXML(data);
 
         // verify
         log.verify();
     }
 
+    public void testXStreamDeserializationNoRR() {
+        // setup
+        String data = "" PrivateChildNoRR());
+        log.reset();
 
+        // expectations
+        log.expect("PrivateBase.readObject() start");
+        log.expect("PrivateBase.readObject() end");
+        log.expect("PrivateChildNoRR.readObject() start");
+        log.expect("PrivateChildNoRR.readObject() end");
+
+        // execute
+        xstream.fromXML(data);
+
+        // verify
+        log.verify();
+    }
+
+    public void testXStreamDeserializationOwnProtectedRR() {
+        // setup
+        String data = "" ProtectedChildOwnRR());
+        log.reset();
+
+        // expectations
+        log.expect("ProtectedBase.readObject() start");
+        log.expect("ProtectedBase.readObject() end");
+        log.expect("ProtectedChildOwnRR.readObject() start");
+        log.expect("ProtectedChildOwnRR.readObject() end");
+        log.expect("ProtectedChildOwnRR.readResolve()");
+
+        // execute
+        xstream.fromXML(data);
+
+        // verify
+        log.verify();
+    }
+
+    public void testXStreamDeserializationInheritedRR() {
+        // setup
+        String data = "" ProtectedChildInheritedRR());
+        log.reset();
+
+        // expectations
+        log.expect("ProtectedBase.readObject() start");
+        log.expect("ProtectedBase.readObject() end");
+        log.expect("ProtectedChildInheritedRR.readObject() start");
+        log.expect("ProtectedChildInheritedRR.readObject() end");
+        log.expect("ProtectedBase.readResolve()");
+
+        // execute
+        xstream.fromXML(data);
+
+        // verify
+        log.verify();
+    }
+
+    public void testXStreamDeserializationOwnPackageRR() {
+        // setup
+        String data = "" PackageChildOwnRR());
+        log.reset();
+
+        // expectations
+        log.expect("PackageBase.readObject() start");
+        log.expect("PackageBase.readObject() end");
+        log.expect("PackageChildOwnRR.readObject() start");
+        log.expect("PackageChildOwnRR.readObject() end");
+        log.expect("PackageChildOwnRR.readResolve()");
+
+        // execute
+        xstream.fromXML(data);
+
+        // verify
+        log.verify();
+    }
+
+    public void testXStreamDeserializationInheritedPackageRR() {
+        // setup
+        String data = "" PackageChildInheritedRR());
+        log.reset();
+
+        // expectations
+        log.expect("PackageBase.readObject() start");
+        log.expect("PackageBase.readObject() end");
+        log.expect("PackageChildInheritedRR.readObject() start");
+        log.expect("PackageChildInheritedRR.readObject() end");
+        log.expect("PackageBase.readResolve()");
+
+        // execute
+        xstream.fromXML(data);
+
+        // verify
+        log.verify();
+    }
+
     public static class ParentNotTransient implements Serializable {
 
         public int somethingNotTransient;

Modified: branches/v-1.4.x/xstream-distribution/src/content/changes.html (2301 => 2302)


--- branches/v-1.4.x/xstream-distribution/src/content/changes.html	2014-10-30 12:58:59 UTC (rev 2301)
+++ branches/v-1.4.x/xstream-distribution/src/content/changes.html	2014-10-30 13:18:10 UTC (rev 2302)
@@ -35,6 +35,7 @@
     <h2>Minor changes</h2>
     
     <ul>
+    	<li>XSTR-762: Private method readResolve() called on base classes.</li>
     	<li>XSTR-755: ExternalizableConverter does not respect writeReplace and readResolve.</li>
     	<li>XSTR-757: Deserialized TreeSet does not honor remove(Object) return value contract.</li>
     	<li>Fix: DateConverter ignores provided locale.</li>
@@ -46,6 +47,8 @@
     <h2>API changes</h2>
     
     <ul>
+    	<li>c.t.x.converters.reflection.AbstractReflectionConverter.readResolve() is protected now.</li>
+    	<li>c.t.x.mapper.AbstractAttributeAliasingMapper.readResolve() is protected now.</li>
     	<li>Deprecated c.t.x.converters.extended.StackTraceElementFactory, it is an internal helper class.</li>
     	<li>Deprecated c.t.x.io.AttributeNameIterator, it is an internal helper class.</li>
     	<li>Deprecated c.t.x.XStream.useXStream11XmlFriendlyMapper(), corresponding

To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Reply via email to