1   package org.apache.commons.javaflow.bytecode.transformation.tests;
2   
3   import java.io.File;
4   import java.io.FileInputStream;
5   import java.io.FileOutputStream;
6   import java.io.IOException;
7   import java.io.InputStream;
8   import java.io.ObjectInputStream;
9   import java.io.ObjectOutputStream;
10  import java.io.ObjectStreamClass;
11  import java.lang.reflect.Proxy;
12  
13  import junitx.util.PrivateAccessor;
14  
15  import org.apache.commons.javaflow.Continuation;
16  import org.apache.commons.javaflow.bytecode.StackRecorder;
17  import org.apache.commons.javaflow.bytecode.transformation.AbstractTransformerTestCase;
18  import org.apache.commons.javaflow.bytecode.transformation.Invoker;
19  import org.apache.commons.javaflow.bytecode.transformation.rewrite.Simple;
20  import org.apache.commons.javaflow.bytecode.transformation.rewrite.SimpleSerializable;
21  
22  public abstract class AbstractSerializationTestCase extends AbstractTransformerTestCase {
23  
24      private File output;
25  
26  
27      public void testSuspend() throws Exception {
28          final SimpleSerializable r = new SimpleSerializable();
29          assertTrue(r.g == -1);
30          assertTrue(r.l == -1);
31          Continuation c1 = Continuation.startWith(r);
32          assertTrue(r.g == 0);
33          assertTrue(r.l == 0);
34          
35          output = File.createTempFile("continuation", "xml");
36          output.deleteOnExit();
37  
38          saveJDK(c1, output);
39          
40      }
41  
42      public class ObjectInputStreamExt extends ObjectInputStream {
43  
44          private ClassLoader classloader;
45  
46          public ObjectInputStreamExt(InputStream in, ClassLoader loader) throws IOException {
47              super(in);
48              this.classloader = loader;
49          }
50  
51          protected Class resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException {
52  
53          	return Class.forName(classDesc.getName(), true, classloader);
54          }
55  
56          protected Class resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
57              Class[] cinterfaces = new Class[interfaces.length];
58              for (int i = 0; i < interfaces.length; i++) {
59              	cinterfaces[i] = Class.forName(interfaces[i], true, classloader);
60              }
61              
62              try {
63                  return Proxy.getProxyClass(classloader, cinterfaces);
64              } catch (IllegalArgumentException e) {
65                  throw new ClassNotFoundException(null, e);
66              }
67          }
68      }
69      
70      
71      private void saveJDK(final Object c1, final File output) throws IOException {
72      	final ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(output));    	
73      	oos.writeObject(c1); 
74      	oos.close(); 
75      }
76  
77      private Object loadJDK(final File input) throws IOException, ClassNotFoundException {
78      	final ObjectInputStream ois = new ObjectInputStreamExt(new FileInputStream(input), this.getClass().getClassLoader());
79      	final Object o = ois.readObject();
80      	ois.close();
81      	return o;
82      }
83      
84      public void testResume() throws Exception {
85          testSuspend();
86          assertTrue("suspend must succeed to create the output first", output != null);
87  
88          assertEquals(output.length(), 586);
89          
90          final Object o = loadJDK(output);
91          
92          assertTrue(o instanceof Continuation);
93          final Continuation c1 = (Continuation) o;
94          final StackRecorder sr1 = (StackRecorder) PrivateAccessor.getField(c1,"stackRecorder");
95          final Runnable r1 = (Runnable) PrivateAccessor.getField(sr1, "runnable");
96          assertEquals(SimpleSerializable.class.getName(), r1.getClass().getName());
97          
98          final SimpleSerializable ss1 = (SimpleSerializable)r1;
99          assertTrue(ss1.g == 0);
100         assertTrue(ss1.l == 0);
101         final Continuation c2 = Continuation.continueWith(c1);
102         final StackRecorder sr2 = (StackRecorder) PrivateAccessor.getField(c2,"stackRecorder");
103         final Runnable r2 = (Runnable) PrivateAccessor.getField(sr2, "runnable");
104         assertEquals(SimpleSerializable.class.getName(), r2.getClass().getName());
105         final SimpleSerializable ss2 = (SimpleSerializable)r2;
106         assertTrue(ss2.g == 1);
107         assertTrue(ss2.l == 1);
108         assertTrue(r1 == r2);
109     }
110 
111 
112     public void testSerializableCheck() throws Exception {
113         final Runnable r1 = new Simple();
114         Continuation c1 = Continuation.startWith(r1);
115         assertTrue(c1 != null);
116         assertTrue(!c1.isSerializable());
117 
118         final Runnable r2 = new SimpleSerializable();
119         Continuation c2 = Continuation.startWith(r2);
120         assertTrue(c2 != null);
121         assertTrue(c2.isSerializable());
122 
123         final Runnable r3 = new SimpleSerializable();
124         Continuation c3 = Continuation.startWith(new Invoker(r3));
125         assertTrue(c3 != null);
126         assertTrue(c3.isSerializable());
127     }
128 }