/* * JasperReports - Free Java Reporting Library. * Copyright (C) 2001 - 2009 Jaspersoft Corporation. All rights reserved. * http://www.jaspersoft.com * * Unless you have purchased a commercial license agreement from Jaspersoft, * the following license terms apply: * * This program is part of JasperReports. * * JasperReports is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * JasperReports is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with JasperReports. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.jasperreports.engine.util; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.NotSerializableException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.HashMap; import java.util.Map; import net.sf.jasperreports.engine.JRRuntimeException; import org.w3c.tools.codec.Base64Decoder; import org.w3c.tools.codec.Base64Encoder; import org.w3c.tools.codec.Base64FormatException; /** * Utility class used to serialize/deserialize value objects to/from String values. * <p> * Specific logic is used to convert to and from Strings values of the following types: * <ul> * <li><code>java.lang.String</code></li> * <li><code>java.lang.Character</code></li> * <li><code>java.lang.Boolean</code></li> * <li><code>java.lang.Byte</code></li> * <li><code>java.lang.Short</code></li> * <li><code>java.lang.Integer</code></li> * <li><code>java.lang.Long</code></li> * <li><code>java.lang.Float</code></li> * <li><code>java.lang.Double</code></li> * <li><code>java.math.BigInteger</code></li> * <li><code>java.math.BigDecimal</code></li> * <li><code>java.util.Date</code></li> * <li><code>java.sql.Timestamp</code></li> * <li><code>java.sql.Time</code></li> * </ul> * </p> * <p> * Object of other types are serialized and the resulting binary data is converted into a String * using the BASE64 encoding. * </p> * * @author Lucian Chirita (lucianc@users.sourceforge.net) * @version $Id: JRValueStringUtils.java 3712 2010-04-08 09:53:09Z teodord $ */ public final class JRValueStringUtils { protected static interface ValueSerializer { String serialize(Object value); Object deserialize(String data); } private static final Map serializers; private static final ValueSerializer defaultSerializer; static { serializers = getSerializers(); defaultSerializer = new DefaultSerializer(); } /** * Converts a value into a String representation. * * @param valueClass the type of the value * @param value the value * @return the String representation of the value */ public static String serialize(String valueClass, Object value) { String data; if (value == null) { data = null; } else { ValueSerializer serializer = getSerializer(valueClass); data = serializer.serialize(value); } return data; } /** * Converts a String back into a value. * * @param valueClass the type of the value * @param data the String representation of the value * @return the value */ public static Object deserialize(String valueClass, String data) { Object value; if (data == null) { value = null; } else { ValueSerializer serializer = getSerializer(valueClass); value = serializer.deserialize(data); } return value; } protected static ValueSerializer getSerializer(String valueClass) { ValueSerializer serializer = (ValueSerializer) serializers.get(valueClass); if (serializer == null) { serializer = defaultSerializer; } return serializer; } private static Map getSerializers() { Map map = new HashMap(); map.put(java.lang.String.class.getName(), new StringSerializer()); map.put(java.lang.Character.class.getName(), new CharacterSerializer()); map.put(java.lang.Boolean.class.getName(), new BooleanSerializer()); map.put(java.lang.Byte.class.getName(), new ByteSerializer()); map.put(java.lang.Short.class.getName(), new ShortSerializer()); map.put(java.lang.Integer.class.getName(), new IntegerSerializer()); map.put(java.lang.Long.class.getName(), new LongSerializer()); map.put(java.lang.Float.class.getName(), new FloatSerializer()); map.put(java.lang.Double.class.getName(), new DoubleSerializer()); map.put(java.math.BigInteger.class.getName(), new BigIntegerSerializer()); map.put(java.math.BigDecimal.class.getName(), new BigDecimalSerializer()); map.put(java.util.Date.class.getName(), new DateSerializer()); map.put(java.sql.Timestamp.class.getName(), new TimestampSerializer()); map.put(java.sql.Time.class.getName(), new TimeSerializer()); return map; } protected static class StringSerializer implements ValueSerializer { public Object deserialize(String data) { return data; } public String serialize(Object value) { return (String) value; } } protected static class CharacterSerializer implements ValueSerializer { public Object deserialize(String data) { if (data.length() != 1) { throw new JRRuntimeException("Character data \"" + data + "\" should be exactly one character long"); } return new Character(data.charAt(0)); } public String serialize(Object value) { return String.valueOf(new char[]{((Character) value).charValue()}); } } protected static class BooleanSerializer implements ValueSerializer { public Object deserialize(String data) { if (data.equals("true")) { return Boolean.TRUE; } if (data.equals("false")) { return Boolean.FALSE; } throw new JRRuntimeException("Unkown boolean data \"" + data + "\""); } public String serialize(Object value) { return ((Boolean) value).booleanValue() ? "true" : "false"; } } protected static class ByteSerializer implements ValueSerializer { public Object deserialize(String data) { try { return Byte.valueOf(data); } catch (NumberFormatException e) { throw new JRRuntimeException("Error parsing Byte data \"" + data + "\"", e); } } public String serialize(Object value) { return ((Byte) value).toString(); } } protected static class ShortSerializer implements ValueSerializer { public Object deserialize(String data) { try { return Short.valueOf(data); } catch (NumberFormatException e) { throw new JRRuntimeException("Error parsing Short data \"" + data + "\"", e); } } public String serialize(Object value) { return ((Short) value).toString(); } } protected static class IntegerSerializer implements ValueSerializer { public Object deserialize(String data) { try { return Integer.valueOf(data); } catch (NumberFormatException e) { throw new JRRuntimeException("Error parsing Integer data \"" + data + "\"", e); } } public String serialize(Object value) { return ((Integer) value).toString(); } } protected static class LongSerializer implements ValueSerializer { public Object deserialize(String data) { try { return Long.valueOf(data); } catch (NumberFormatException e) { throw new JRRuntimeException("Error parsing Long data \"" + data + "\"", e); } } public String serialize(Object value) { return ((Long) value).toString(); } } protected static class FloatSerializer implements ValueSerializer { public Object deserialize(String data) { try { return Float.valueOf(data); } catch (NumberFormatException e) { throw new JRRuntimeException("Error parsing Float data \"" + data + "\"", e); } } public String serialize(Object value) { return ((Float) value).toString(); } } protected static class DoubleSerializer implements ValueSerializer { public Object deserialize(String data) { try { return Double.valueOf(data); } catch (NumberFormatException e) { throw new JRRuntimeException("Error parsing Double data \"" + data + "\"", e); } } public String serialize(Object value) { return ((Double) value).toString(); } } protected static class BigIntegerSerializer implements ValueSerializer { public Object deserialize(String data) { try { return new java.math.BigInteger(data); } catch (NumberFormatException e) { throw new JRRuntimeException("Error parsing BigInteger data \"" + data + "\"", e); } } public String serialize(Object value) { return ((java.math.BigInteger) value).toString(); } } protected static class BigDecimalSerializer implements ValueSerializer { public Object deserialize(String data) { try { return new java.math.BigDecimal(data); } catch (NumberFormatException e) { throw new JRRuntimeException("Error parsing BigDecimal data \"" + data + "\"", e); } } public String serialize(Object value) { return ((java.math.BigDecimal) value).toString(); } } protected static class DateSerializer implements ValueSerializer { public Object deserialize(String data) { try { long time = Long.parseLong(data); return new java.util.Date(time); } catch (NumberFormatException e) { throw new JRRuntimeException("Error parsing Date data \"" + data + "\"", e); } } public String serialize(Object value) { return Long.toString(((java.util.Date) value).getTime()); } } protected static class TimestampSerializer implements ValueSerializer { public Object deserialize(String data) { try { return java.sql.Timestamp.valueOf(data); } catch (IllegalArgumentException e) { throw new JRRuntimeException("Error parsing Timestamp data \"" + data + "\"", e); } } public String serialize(Object value) { java.sql.Timestamp timestamp = (java.sql.Timestamp) value; return timestamp.toString(); } } protected static class TimeSerializer implements ValueSerializer { public Object deserialize(String data) { try { return java.sql.Time.valueOf(data); } catch (IllegalArgumentException e) { throw new JRRuntimeException("Error parsing Time data \"" + data + "\"", e); } } public String serialize(Object value) { java.sql.Time timestamp = (java.sql.Time) value; return timestamp.toString(); } } protected static class DefaultSerializer implements ValueSerializer { public Object deserialize(String data) { try { ByteArrayInputStream dataIn = new ByteArrayInputStream(data.getBytes()); ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); Base64Decoder dec = new Base64Decoder(dataIn, bytesOut); dec.process(); ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytesOut.toByteArray()); ObjectInputStream objectIn = new ObjectInputStream(bytesIn); return objectIn.readObject(); } catch (IOException e) { throw new JRRuntimeException(e); } catch (ClassNotFoundException e) { throw new JRRuntimeException(e); } catch (Base64FormatException e) { throw new JRRuntimeException(e); } } public String serialize(Object value) { try { ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); ObjectOutputStream objectOut = new ObjectOutputStream(bytesOut); objectOut.writeObject(value); objectOut.close(); ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytesOut.toByteArray()); ByteArrayOutputStream dataOut = new ByteArrayOutputStream(); Base64Encoder enc = new Base64Encoder(bytesIn, dataOut); enc.process(); return new String(dataOut.toByteArray(), "UTF-8"); } catch (NotSerializableException e) { throw new JRRuntimeException("Value is not serializable", e); } catch (IOException e) { throw new JRRuntimeException(e); } } } private JRValueStringUtils() { } }