001: /*
002: * ============================================================================
003: * GNU Lesser General Public License
004: * ============================================================================
005: *
006: * JasperReports - Free Java report-generating library.
007: * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
008: *
009: * This library is free software; you can redistribute it and/or
010: * modify it under the terms of the GNU Lesser General Public
011: * License as published by the Free Software Foundation; either
012: * version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: * Lesser General Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
022: *
023: * JasperSoft Corporation
024: * 303 Second Street, Suite 450 North
025: * San Francisco, CA 94107
026: * http://www.jaspersoft.com
027: */
028: package net.sf.jasperreports.engine.util;
029:
030: import java.io.ByteArrayInputStream;
031: import java.io.ByteArrayOutputStream;
032: import java.io.IOException;
033: import java.io.NotSerializableException;
034: import java.io.ObjectInputStream;
035: import java.io.ObjectOutputStream;
036: import java.util.HashMap;
037: import java.util.Map;
038:
039: import org.w3c.tools.codec.Base64Decoder;
040: import org.w3c.tools.codec.Base64Encoder;
041: import org.w3c.tools.codec.Base64FormatException;
042:
043: import net.sf.jasperreports.engine.JRRuntimeException;
044:
045: /**
046: * Utility class used to serialize/deserialize value objects to/from String values.
047: * <p>
048: * Specific logic is used to convert to and from Strings values of the following types:
049: * <ul>
050: * <li><code>java.lang.String</code></li>
051: * <li><code>java.lang.Character</code></li>
052: * <li><code>java.lang.Boolean</code></li>
053: * <li><code>java.lang.Byte</code></li>
054: * <li><code>java.lang.Short</code></li>
055: * <li><code>java.lang.Integer</code></li>
056: * <li><code>java.lang.Long</code></li>
057: * <li><code>java.lang.Float</code></li>
058: * <li><code>java.lang.Double</code></li>
059: * <li><code>java.math.BigInteger</code></li>
060: * <li><code>java.math.BigDecimal</code></li>
061: * <li><code>java.util.Date</code></li>
062: * <li><code>java.sql.Timestamp</code></li>
063: * <li><code>java.sql.Time</code></li>
064: * </ul>
065: * </p>
066: * <p>
067: * Object of other types are serialized and the resulting binary data is converted into a String
068: * using the BASE64 encoding.
069: * </p>
070: *
071: * @author Lucian Chirita (lucianc@users.sourceforge.net)
072: * @version $Id: JRValueStringUtils.java 1355 2006-08-04 14:31:54Z lucianc $
073: */
074: public class JRValueStringUtils {
075:
076: protected static interface ValueSerializer {
077: String serialize(Object value);
078:
079: Object deserialize(String data);
080: }
081:
082: private static final Map serializers;
083: private static final ValueSerializer defaultSerializer;
084:
085: static {
086: serializers = getSerializers();
087: defaultSerializer = new DefaultSerializer();
088: }
089:
090: /**
091: * Converts a value into a String representation.
092: *
093: * @param valueClass the type of the value
094: * @param value the value
095: * @return the String representation of the value
096: */
097: public static String serialize(String valueClass, Object value) {
098: String data;
099: if (value == null) {
100: data = null;
101: } else {
102: ValueSerializer serializer = getSerializer(valueClass);
103: data = serializer.serialize(value);
104: }
105: return data;
106: }
107:
108: /**
109: * Converts a String back into a value.
110: *
111: * @param valueClass the type of the value
112: * @param data the String representation of the value
113: * @return the value
114: */
115: public static Object deserialize(String valueClass, String data) {
116: Object value;
117: if (data == null) {
118: value = null;
119: } else {
120: ValueSerializer serializer = getSerializer(valueClass);
121: value = serializer.deserialize(data);
122: }
123: return value;
124: }
125:
126: protected static ValueSerializer getSerializer(String valueClass) {
127: ValueSerializer serializer = (ValueSerializer) serializers
128: .get(valueClass);
129: if (serializer == null) {
130: serializer = defaultSerializer;
131: }
132: return serializer;
133: }
134:
135: private static Map getSerializers() {
136: Map map = new HashMap();
137: map.put(java.lang.String.class.getName(),
138: new StringSerializer());
139: map.put(java.lang.Character.class.getName(),
140: new CharacterSerializer());
141: map.put(java.lang.Boolean.class.getName(),
142: new BooleanSerializer());
143: map.put(java.lang.Byte.class.getName(), new ByteSerializer());
144: map.put(java.lang.Short.class.getName(), new ShortSerializer());
145: map.put(java.lang.Integer.class.getName(),
146: new IntegerSerializer());
147: map.put(java.lang.Long.class.getName(), new LongSerializer());
148: map.put(java.lang.Float.class.getName(), new FloatSerializer());
149: map.put(java.lang.Double.class.getName(),
150: new DoubleSerializer());
151: map.put(java.math.BigInteger.class.getName(),
152: new BigIntegerSerializer());
153: map.put(java.math.BigDecimal.class.getName(),
154: new BigDecimalSerializer());
155: map.put(java.util.Date.class.getName(), new DateSerializer());
156: map.put(java.sql.Timestamp.class.getName(),
157: new TimestampSerializer());
158: map.put(java.sql.Time.class.getName(), new TimeSerializer());
159: return map;
160: }
161:
162: protected static class StringSerializer implements ValueSerializer {
163: public Object deserialize(String data) {
164: return data;
165: }
166:
167: public String serialize(Object value) {
168: return (String) value;
169: }
170: }
171:
172: protected static class CharacterSerializer implements
173: ValueSerializer {
174: public Object deserialize(String data) {
175: if (data.length() != 1) {
176: throw new JRRuntimeException("Character data \"" + data
177: + "\" should be exactly one character long");
178: }
179: return new Character(data.charAt(0));
180: }
181:
182: public String serialize(Object value) {
183: return String.valueOf(new char[] { ((Character) value)
184: .charValue() });
185: }
186: }
187:
188: protected static class BooleanSerializer implements ValueSerializer {
189: public Object deserialize(String data) {
190: if (data.equals("true")) {
191: return Boolean.TRUE;
192: }
193: if (data.equals("false")) {
194: return Boolean.FALSE;
195: }
196: throw new JRRuntimeException("Unkown boolean data \""
197: + data + "\"");
198: }
199:
200: public String serialize(Object value) {
201: return ((Boolean) value).booleanValue() ? "true" : "false";
202: }
203: }
204:
205: protected static class ByteSerializer implements ValueSerializer {
206: public Object deserialize(String data) {
207: try {
208: return Byte.valueOf(data);
209: } catch (NumberFormatException e) {
210: throw new JRRuntimeException(
211: "Error parsing Byte data \"" + data + "\"", e);
212: }
213: }
214:
215: public String serialize(Object value) {
216: return ((Byte) value).toString();
217: }
218: }
219:
220: protected static class ShortSerializer implements ValueSerializer {
221: public Object deserialize(String data) {
222: try {
223: return Short.valueOf(data);
224: } catch (NumberFormatException e) {
225: throw new JRRuntimeException(
226: "Error parsing Short data \"" + data + "\"", e);
227: }
228: }
229:
230: public String serialize(Object value) {
231: return ((Short) value).toString();
232: }
233: }
234:
235: protected static class IntegerSerializer implements ValueSerializer {
236: public Object deserialize(String data) {
237: try {
238: return Integer.valueOf(data);
239: } catch (NumberFormatException e) {
240: throw new JRRuntimeException(
241: "Error parsing Integer data \"" + data + "\"",
242: e);
243: }
244: }
245:
246: public String serialize(Object value) {
247: return ((Integer) value).toString();
248: }
249: }
250:
251: protected static class LongSerializer implements ValueSerializer {
252: public Object deserialize(String data) {
253: try {
254: return Long.valueOf(data);
255: } catch (NumberFormatException e) {
256: throw new JRRuntimeException(
257: "Error parsing Long data \"" + data + "\"", e);
258: }
259: }
260:
261: public String serialize(Object value) {
262: return ((Long) value).toString();
263: }
264: }
265:
266: protected static class FloatSerializer implements ValueSerializer {
267: public Object deserialize(String data) {
268: try {
269: return Float.valueOf(data);
270: } catch (NumberFormatException e) {
271: throw new JRRuntimeException(
272: "Error parsing Float data \"" + data + "\"", e);
273: }
274: }
275:
276: public String serialize(Object value) {
277: return ((Float) value).toString();
278: }
279: }
280:
281: protected static class DoubleSerializer implements ValueSerializer {
282: public Object deserialize(String data) {
283: try {
284: return Double.valueOf(data);
285: } catch (NumberFormatException e) {
286: throw new JRRuntimeException(
287: "Error parsing Double data \"" + data + "\"", e);
288: }
289: }
290:
291: public String serialize(Object value) {
292: return ((Double) value).toString();
293: }
294: }
295:
296: protected static class BigIntegerSerializer implements
297: ValueSerializer {
298: public Object deserialize(String data) {
299: try {
300: return new java.math.BigInteger(data);
301: } catch (NumberFormatException e) {
302: throw new JRRuntimeException(
303: "Error parsing BigInteger data \"" + data
304: + "\"", e);
305: }
306: }
307:
308: public String serialize(Object value) {
309: return ((java.math.BigInteger) value).toString();
310: }
311: }
312:
313: protected static class BigDecimalSerializer implements
314: ValueSerializer {
315: public Object deserialize(String data) {
316: try {
317: return new java.math.BigDecimal(data);
318: } catch (NumberFormatException e) {
319: throw new JRRuntimeException(
320: "Error parsing BigDecimal data \"" + data
321: + "\"", e);
322: }
323: }
324:
325: public String serialize(Object value) {
326: return ((java.math.BigDecimal) value).toString();
327: }
328: }
329:
330: protected static class DateSerializer implements ValueSerializer {
331: public Object deserialize(String data) {
332: try {
333: long time = Long.parseLong(data);
334: return new java.util.Date(time);
335: } catch (NumberFormatException e) {
336: throw new JRRuntimeException(
337: "Error parsing Date data \"" + data + "\"", e);
338: }
339: }
340:
341: public String serialize(Object value) {
342: return Long.toString(((java.util.Date) value).getTime());
343: }
344: }
345:
346: protected static class TimestampSerializer implements
347: ValueSerializer {
348: public Object deserialize(String data) {
349: try {
350: return java.sql.Timestamp.valueOf(data);
351: } catch (IllegalArgumentException e) {
352: throw new JRRuntimeException(
353: "Error parsing Timestamp data \"" + data + "\"",
354: e);
355: }
356: }
357:
358: public String serialize(Object value) {
359: java.sql.Timestamp timestamp = (java.sql.Timestamp) value;
360: return timestamp.toString();
361: }
362: }
363:
364: protected static class TimeSerializer implements ValueSerializer {
365: public Object deserialize(String data) {
366: try {
367: return java.sql.Time.valueOf(data);
368: } catch (IllegalArgumentException e) {
369: throw new JRRuntimeException(
370: "Error parsing Time data \"" + data + "\"", e);
371: }
372: }
373:
374: public String serialize(Object value) {
375: java.sql.Time timestamp = (java.sql.Time) value;
376: return timestamp.toString();
377: }
378: }
379:
380: protected static class DefaultSerializer implements ValueSerializer {
381: public Object deserialize(String data) {
382: try {
383: ByteArrayInputStream dataIn = new ByteArrayInputStream(
384: data.getBytes());
385: ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
386: Base64Decoder dec = new Base64Decoder(dataIn, bytesOut);
387: dec.process();
388:
389: ByteArrayInputStream bytesIn = new ByteArrayInputStream(
390: bytesOut.toByteArray());
391: ObjectInputStream objectIn = new ObjectInputStream(
392: bytesIn);
393: return objectIn.readObject();
394: } catch (IOException e) {
395: throw new JRRuntimeException(e);
396: } catch (ClassNotFoundException e) {
397: throw new JRRuntimeException(e);
398: } catch (Base64FormatException e) {
399: throw new JRRuntimeException(e);
400: }
401: }
402:
403: public String serialize(Object value) {
404: try {
405: ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
406: ObjectOutputStream objectOut = new ObjectOutputStream(
407: bytesOut);
408: objectOut.writeObject(value);
409: objectOut.close();
410:
411: ByteArrayInputStream bytesIn = new ByteArrayInputStream(
412: bytesOut.toByteArray());
413: ByteArrayOutputStream dataOut = new ByteArrayOutputStream();
414:
415: Base64Encoder enc = new Base64Encoder(bytesIn, dataOut);
416: enc.process();
417:
418: return new String(dataOut.toByteArray(), "UTF-8");
419: } catch (NotSerializableException e) {
420: throw new JRRuntimeException(
421: "Value is not serializable", e);
422: } catch (IOException e) {
423: throw new JRRuntimeException(e);
424: }
425: }
426: }
427: }
|