1 /**********************************************************************
2 * JavolutionAdapter.java
3 * created on 13.08.2004 by netseeker
4 * $Source$
5 * $Date$
6 * $Revision$
7 *
8 * ====================================================================
9 *
10 * Copyright 2005-2006 netseeker aka Michael Manske
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 * ====================================================================
24 *
25 * This file is part of the ejoe framework.
26 * For more information on the author, please see
27 * <http://www.manskes.de/>.
28 *
29 *********************************************************************/
30 package de.netseeker.ejoe.adapter;
31
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.OutputStream;
35 import java.math.BigDecimal;
36 import java.math.BigInteger;
37 import java.text.ParseException;
38 import java.text.SimpleDateFormat;
39 import java.util.Date;
40 import java.util.logging.Level;
41 import java.util.logging.Logger;
42
43 import javolution.xml.XmlElement;
44 import javolution.xml.XmlFormat;
45 import javolution.xml.XmlInputStream;
46 import javolution.xml.XmlOutputStream;
47 import sun.misc.BASE64Decoder;
48 import sun.misc.BASE64Encoder;
49 import de.netseeker.ejoe.request.RemotingRequest;
50
51 /***
52 * An adapter for (de)serializing objects via the javolution library
53 *
54 * @author netseeker
55 * @since 0.3.9.1
56 * @see http://javolution.org/
57 */
58 public class JavolutionAdapter extends BaseAdapter
59 {
60 /***
61 *
62 */
63 private static final long serialVersionUID = 1L;
64
65 private static final Logger logger = Logger.getLogger( JavolutionAdapter.class.getName() );
66
67 private static final String DATE_FORMAT = "yyMMddHHmmssZ";
68
69 /***
70 * Creates a new instance of JavolutionAdapter preconfigured with additional custom XmlFormats for
71 * <ul>
72 * <li>java.math.BigDecimal</li>
73 * <li>java.math.BigInteger</li>
74 * </ul>
75 */
76 public JavolutionAdapter()
77 {
78 this( new Class[] {}, new XmlFormat[] {} );
79 }
80
81 /***
82 * Creates a new instance of JavolutionAdapter preconfigured with the provided XmlFormats.
83 *
84 * @param classes array of classes for which custom XmlFormats are provided in the formats parameter
85 * @param formats array of XmlFormats
86 */
87 public JavolutionAdapter(Class[] classes, XmlFormat[] formats)
88 {
89 XmlFormat.setFormat( BigDecimal.class, BigDecimalFormat );
90 XmlFormat.setFormat( BigInteger.class, BigIntegerFormat );
91 XmlFormat.setFormat( Date.class, DateFormat );
92 XmlFormat.setFormat( String[].class, StringArrayFormat );
93 XmlFormat.setFormat( byte[].class, ByteArrayFormat );
94 XmlFormat.setFormat( RemotingRequest.class, RemotingRequestFormat );
95
96 for ( int i = 0; i < classes.length; i++ )
97 {
98 if ( !(XmlFormat.getInstance( classes[i] ).equals( formats[i] )) )
99 {
100 XmlFormat.setFormat( classes[i], formats[i] );
101 }
102 }
103 }
104
105 /*
106 * (non-Javadoc)
107 *
108 * @see de.netseeker.ejoe.adapter.SerializeAdapter#read(java.io.InputStream)
109 */
110 public Object read( InputStream in ) throws Exception
111 {
112 XmlInputStream reader = new XmlInputStream();
113 Object obj = null;
114 try
115 {
116 reader.setInputStream( in );
117 obj = reader.readObject();
118 }
119 finally
120 {
121 reader.close();
122 }
123
124 return obj;
125 }
126
127 /*
128 * (non-Javadoc)
129 *
130 * @see de.netseeker.ejoe.adapter.SerializeAdapter#write(java.lang.Object, java.io.OutputStream)
131 */
132 public void write( Object obj, OutputStream out ) throws Exception
133 {
134 XmlOutputStream writer = new XmlOutputStream();
135 try
136 {
137 writer.setOutputStream( out );
138 writer.writeObject( obj );
139 }
140 finally
141 {
142 writer.close();
143 }
144 }
145
146 /*
147 * (non-Javadoc)
148 *
149 * @see de.netseeker.ejoe.adapter.BaseAdapter#getContentType()
150 */
151 public String getContentType()
152 {
153 return "text/xml";
154 }
155
156 private static final XmlFormat BigDecimalFormat = new XmlFormat( BigDecimal.class )
157 {
158 public void format( Object foo, XmlElement xml )
159 {
160 xml.setAttribute( "value", foo.toString() );
161 }
162
163 public Object parse( XmlElement xml )
164 {
165 BigDecimal foo = new BigDecimal( xml
166 .getAttribute( "value", "-1" ) );
167 return foo;
168 }
169 };
170
171 private static final XmlFormat BigIntegerFormat = new XmlFormat( BigInteger.class )
172 {
173 public void format( Object foo, XmlElement xml )
174 {
175 xml.setAttribute( "value", foo.toString() );
176 }
177
178 public Object parse( XmlElement xml )
179 {
180 BigInteger foo = new BigInteger( xml
181 .getAttribute( "value", "-1" ) );
182 return foo;
183 }
184 };
185
186 private static final XmlFormat DateFormat = new XmlFormat( Date.class )
187 {
188 SimpleDateFormat sdf = new SimpleDateFormat(
189 DATE_FORMAT );
190
191 public void format( Object foo, XmlElement xml )
192 {
193 xml
194 .setAttribute( "value", sdf
195 .format( (Date) foo ) );
196 }
197
198 public Object parse( XmlElement xml )
199 {
200 Date foo = null;
201 try
202 {
203 foo = sdf.parse( xml
204 .getAttribute( "value", "" ) );
205 }
206 catch ( ParseException e )
207 {
208 }
209 return foo;
210 }
211 };
212
213 private static final XmlFormat StringArrayFormat = new XmlFormat( String[].class )
214 {
215 public void format( Object foo, XmlElement xml )
216 {
217 String[] arr = (String[]) foo;
218 int len = arr.length;
219 int prelen = len - 1;
220 StringBuffer sb = new StringBuffer();
221 for ( int i = 0; i < len; i++ )
222 {
223 sb.append( arr[i] );
224 if ( i < prelen ) sb.append( ',' );
225 }
226
227 xml.setAttribute( "value", sb.toString() );
228 }
229
230 public Object parse( XmlElement xml )
231 {
232 return xml.getAttribute( "value", "" ).split( "," );
233 }
234 };
235
236 private static final XmlFormat RemotingRequestFormat = new XmlFormat( RemotingRequest.class )
237 {
238 public void format( Object foo, XmlElement xml )
239 {
240 RemotingRequest r = (RemotingRequest) foo;
241 xml.setAttribute( "clazz", r.getClazz() );
242 xml.setAttribute( "mtd", r.getMethod() );
243 Object[] args = r.getArgs();
244 xml.setAttribute( "entries",
245 new Integer( args.length ) );
246 int i = 0;
247 for ( ; i < args.length; i++ )
248 {
249 xml.add( args[i], "arg" + i );
250 }
251 }
252
253 public Object parse( XmlElement xml )
254 {
255 RemotingRequest r = new RemotingRequest();
256 r.setClazz( xml.getAttribute( "clazz", "" ) );
257 r.setMethod( xml.getAttribute( "mtd", "" ) );
258 int entries = xml.getAttribute( "entries",
259 new Integer( 0 ) )
260 .intValue();
261 if ( entries > 0 )
262 {
263 Object args[] = new Object[entries];
264 for ( int i = 0; i < entries; i++ )
265 {
266 args[i] = xml.get( "arg" + i );
267 }
268 r.setArgs( args );
269 }
270
271 return r;
272 }
273 };
274
275 private static final XmlFormat ByteArrayFormat = new XmlFormat( byte[].class )
276 {
277 public void format( Object foo, XmlElement xml )
278 {
279 byte[] bArray = (byte[]) foo;
280 BASE64Encoder enc = new BASE64Encoder();
281 xml.add( enc.encode( bArray ), "bArray" );
282 }
283
284 public Object parse( XmlElement xml )
285 {
286 String bString = (String) xml.get( "bArray" );
287 BASE64Decoder dec = new BASE64Decoder();
288 byte[] result = null;
289 try
290 {
291 result = dec.decodeBuffer( bString );
292 }
293 catch ( IOException e )
294 {
295 logger
296 .log(
297 Level.SEVERE,
298 "Error occured while deserializing Base64 encoded array of bytes!",
299 e );
300 }
301
302 return result;
303 }
304 };
305 }