KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > webflow > execution > repository > continuation > SerializedFlowExecutionContinuation


1 /*
2  * Copyright 2002-2006 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.springframework.webflow.execution.repository.continuation;
17
18 import java.io.ByteArrayInputStream JavaDoc;
19 import java.io.ByteArrayOutputStream JavaDoc;
20 import java.io.Externalizable JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.NotSerializableException JavaDoc;
23 import java.io.ObjectInput JavaDoc;
24 import java.io.ObjectInputStream JavaDoc;
25 import java.io.ObjectOutput JavaDoc;
26 import java.io.ObjectOutputStream JavaDoc;
27 import java.util.zip.GZIPInputStream JavaDoc;
28 import java.util.zip.GZIPOutputStream JavaDoc;
29
30 import org.springframework.util.FileCopyUtils;
31 import org.springframework.webflow.execution.FlowExecution;
32
33 /**
34  * A continuation implementation that is based on standard Java serialization,
35  * created by a {@link SerializedFlowExecutionContinuationFactory}.
36  *
37  * @see SerializedFlowExecutionContinuationFactory
38  *
39  * @author Keith Donald
40  * @author Erwin Vervaet
41  */

42 public class SerializedFlowExecutionContinuation extends FlowExecutionContinuation implements Externalizable JavaDoc {
43
44     /**
45      * The serialized flow execution.
46      */

47     private byte[] flowExecutionData;
48
49     /**
50      * Whether or not the flow execution byte array is compressed.
51      */

52     private boolean compressed;
53
54     /**
55      * Default constructor necessary for {@link Externalizable} custom
56      * serialization semantics. Should not be called by application code.
57      */

58     public SerializedFlowExecutionContinuation() {
59     }
60
61     /**
62      * Creates a new serialized flow execution continuation. This will marshall
63      * given flow execution into a serialized continuation form.
64      * @param flowExecution the flow execution
65      * @param compress whether or not the flow execution should be compressed
66      */

67     public SerializedFlowExecutionContinuation(FlowExecution flowExecution, boolean compress)
68             throws ContinuationCreationException {
69         try {
70             flowExecutionData = serialize(flowExecution);
71             if (compress) {
72                 flowExecutionData = compress(flowExecutionData);
73             }
74         }
75         catch (NotSerializableException JavaDoc e) {
76             throw new ContinuationCreationException(flowExecution,
77                     "Could not serialize flow execution; " +
78                     "make sure all objects stored in flow or flash scope are serializable", e);
79         }
80         catch (IOException JavaDoc e) {
81             throw new ContinuationCreationException(flowExecution,
82                     "IOException thrown serializing flow execution -- this should not happen!", e);
83         }
84         this.compressed = compress;
85     }
86
87     /**
88      * Returns whether or not the flow execution data in this continuation is
89      * compressed.
90      */

91     public boolean isCompressed() {
92         return compressed;
93     }
94
95     public FlowExecution unmarshal() throws ContinuationUnmarshalException {
96         try {
97             return deserialize(getFlowExecutionData());
98         }
99         catch (IOException JavaDoc e) {
100             throw new ContinuationUnmarshalException(
101                     "IOException thrown deserializing the flow execution stored in this continuation -- this should not happen!",
102                     e);
103         }
104         catch (ClassNotFoundException JavaDoc e) {
105             throw new ContinuationUnmarshalException(
106                     "ClassNotFoundException thrown deserializing the flow execution stored in this continuation -- "
107                             + "This should not happen! Make sure there are no classloader issues."
108                             + "For example, perhaps the Web Flow system is being loaded by a classloader "
109                             + "that is a parent of the classloader loading application classes?", e);
110         }
111     }
112
113     public byte[] toByteArray() {
114         try {
115             ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc(flowExecutionData.length + 40);
116             ObjectOutputStream JavaDoc oos = new ObjectOutputStream JavaDoc(baos);
117             try {
118                 oos.writeObject(this);
119                 oos.flush();
120             }
121             finally {
122                 oos.close();
123             }
124             return baos.toByteArray();
125         }
126         catch (IOException JavaDoc e) {
127             throw new IllegalStateException JavaDoc();
128         }
129     }
130
131     // implementing Externalizable for custom serialization
132

133     public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc {
134         // write out length first
135
out.writeInt(flowExecutionData.length);
136         // write out contents
137
out.write(flowExecutionData);
138         out.writeBoolean(compressed);
139     }
140
141     public void readExternal(ObjectInput JavaDoc in) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
142         // read length of data array
143
int length = in.readInt();
144         flowExecutionData = new byte[length];
145         // read in contents in full
146
in.readFully(flowExecutionData);
147         compressed = in.readBoolean();
148     }
149     
150     // internal helpers
151

152     /**
153      * Return the flow execution data in its raw byte[] form. Will decompress if
154      * necessary.
155      * @return the byte array
156      * @throws IOException a problem occured with decompression
157      */

158     protected byte[] getFlowExecutionData() throws IOException JavaDoc {
159         if (isCompressed()) {
160             return decompress(flowExecutionData);
161         }
162         else {
163             return flowExecutionData;
164         }
165     }
166
167     /**
168      * Internal helper method to serialize given flow execution. Override if a
169      * custom serialization method is used.
170      * @param flowExecution flow execution to serialize
171      * @return serialized flow flow execution data
172      * @throws IOException when something goes wrong during during serialization
173      */

174     protected byte[] serialize(FlowExecution flowExecution) throws IOException JavaDoc {
175         ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc(1024);
176         ObjectOutputStream JavaDoc oos = new ObjectOutputStream JavaDoc(baos);
177         try {
178             oos.writeObject(flowExecution);
179             oos.flush();
180             return baos.toByteArray();
181         }
182         finally {
183             oos.close();
184         }
185     }
186
187     /**
188      * Internal helper method to deserialize given flow execution data. Override
189      * if a custom serialization method is used.
190      * @param data serialized flow flow execution data
191      * @return deserialized flow execution
192      * @throws IOException when something goes wrong during deserialization
193      * @throws ClassNotFoundException when required classes cannot be loaded
194      */

195     protected FlowExecution deserialize(byte[] data) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
196         ObjectInputStream JavaDoc ois = new ObjectInputStream JavaDoc(new ByteArrayInputStream JavaDoc(data));
197         try {
198             return (FlowExecution)ois.readObject();
199         }
200         finally {
201             ois.close();
202         }
203     }
204
205     /**
206      * Internal helper method to compress given flow execution data using GZIP
207      * compression. Override if custom compression is desired.
208      */

209     protected byte[] compress(byte[] dataToCompress) throws IOException JavaDoc {
210         ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
211         GZIPOutputStream JavaDoc gzipos = new GZIPOutputStream JavaDoc(baos);
212         try {
213             gzipos.write(dataToCompress);
214             gzipos.flush();
215         }
216         finally {
217             gzipos.close();
218         }
219         return baos.toByteArray();
220     }
221
222     /**
223      * Internal helper method to decompress given flow execution data using GZIP
224      * decompression. Override if custom decompression is desired.
225      */

226     protected byte[] decompress(byte[] dataToDecompress) throws IOException JavaDoc {
227         GZIPInputStream JavaDoc gzipin = new GZIPInputStream JavaDoc(new ByteArrayInputStream JavaDoc(dataToDecompress));
228         ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
229         try {
230             FileCopyUtils.copy(gzipin, baos);
231         }
232         finally {
233             gzipin.close();
234         }
235         return baos.toByteArray();
236     }
237 }
Popular Tags