/* * Value.java * * Created on January 4, 2001, 11:37 AM */ package org.freehep.util; import java.util.Date; /** * A class that can represent any Java object or primitive. Unlike the built-in * primitive proxies (Double, Integer etc) it is mutable. It is used to allow * values to be used without needing overloaded methods for each primitive type, * and without the overhead of object creation/deletion. * * When a value is returned by an Object method it should be assumed to be valid * only until the next method call to that Object. The use of Value should be * avoided in multi-threaded environments. * * @author tonyj * @version $Id: Value.java,v 1.4 2009-06-22 02:18:20 hohenwarter Exp $ */ public class Value { private int intValue; private short shortValue; private long longValue; private float floatValue; private double doubleValue; private boolean boolValue; private byte byteValue; private char charValue; private Object obj; private Class<?> type; public final static Class<?> TYPE_INTEGER = Integer.TYPE; public final static Class<?> TYPE_SHORT = Short.TYPE; public final static Class<?> TYPE_LONG = Long.TYPE; public final static Class<?> TYPE_FLOAT = Float.TYPE; public final static Class<?> TYPE_DOUBLE = Double.TYPE; public final static Class<?> TYPE_BOOLEAN = Boolean.TYPE; public final static Class<?> TYPE_BYTE = Byte.TYPE; public final static Class<?> TYPE_CHAR = Character.TYPE; public final static Class<?> TYPE_STRING = String.class; public final static Class<?> TYPE_DATE = Date.class; public Value() { } public Value(Value v) { setValue(v); } public Value setValue(Value v) { this.type = v.getType(); this.intValue = v.intValue; this.shortValue = v.shortValue; this.longValue = v.longValue; this.floatValue = v.floatValue; this.doubleValue = v.doubleValue; this.boolValue = v.boolValue; this.byteValue = v.byteValue; this.charValue = v.charValue; this.obj = v.obj; return this; } /** * Get the Value's type * * @return The Class of this Value. * */ public Class<?> getType() { return type; } /** * Set the Value's internal value to an integer. * * @param val * The integer value. * @return The Value object with the given internal value. * */ public Value set(int val) { intValue = val; type = TYPE_INTEGER; return this; } /** * Set the Value's internal value to a short. * * @param val * The short value. * @return The Value object with the given internal value. * */ public Value set(short val) { shortValue = val; type = TYPE_SHORT; return this; } /** * Set the Value's internal value to a long. * * @param val * The long value. * @return The Value object with the given internal value. * */ public Value set(long val) { longValue = val; type = TYPE_LONG; return this; } /** * Set the Value's internal value to a float. * * @param val * The float value. * @return The Value object with the given internal value. * */ public Value set(float val) { floatValue = val; type = TYPE_FLOAT; return this; } /** * Set the Value's internal value to a double. * * @param val * The double value. * @return The Value object with the given internal value. * */ public Value set(double val) { doubleValue = val; type = TYPE_DOUBLE; return this; } /** * Set the Value's internal value to a boolean. * * @param val * The boolean value. * @return The Value object with the given internal value. * */ public Value set(boolean val) { boolValue = val; type = TYPE_BOOLEAN; return this; } /** * Set the Value's internal value to a byte. * * @param val * The byte value. * @return The Value object with the given internal value. * */ public Value set(byte val) { byteValue = val; type = TYPE_BYTE; return this; } /** * Set the Value's internal value to a char. * * @param val * The char value. * @return The Value object with the given internal value. * */ public Value set(char val) { charValue = val; type = TYPE_CHAR; return this; } /** * Set the Value's internal value to a String. * * @param val * The String value. * @return The Value object with the given internal value. * */ public Value set(String val) { obj = val; type = TYPE_STRING; return this; } /** * Set the Value's internal value to a Date. * * @param val * The Date value. * @return The Value object with the given internal value. * */ public Value set(Date val) { obj = val; type = TYPE_DATE; return this; } /** * Set the Value's internal value to an Object. * * @param val * The Object value. * @return The Value object with the given internal value. * */ public Value set(Object val) { obj = val; type = obj == null ? Object.class : obj.getClass(); return this; } /** * Get the integer value. * * @return The int value. * @exception ClassCastException * is thrown if this Value has incompatible type. * */ public int getInt() { if (type == TYPE_INTEGER) { return intValue; } else if (type == TYPE_SHORT) { return shortValue; } else if (type == TYPE_BYTE) { return byteValue; } else { throw new ClassCastException( "getInt cannot be called for type " + type.toString()); } } /** * Get the short value. * * @return The short value. * @exception ClassCastException * is thrown if this Value has incompatible type. * */ public short getShort() { if (type == TYPE_SHORT) { return shortValue; } else if (type == TYPE_BYTE) { return byteValue; } else { throw new ClassCastException( "getShort cannot be called for type " + type.toString()); } } /** * Get the long value. * * @return The long value. * @exception ClassCastException * is thrown if this Value has incompatible type. * */ public long getLong() { if (type == TYPE_LONG) { return longValue; } else if (type == TYPE_INTEGER) { return intValue; } else if (type == TYPE_SHORT) { return shortValue; } else if (type == TYPE_BYTE) { return byteValue; } else { throw new ClassCastException( "getLong cannot be called for type " + type.toString()); } } /** * Get the float value. * * @return The float value. * @exception ClassCastException * is thrown if this Value has incompatible type. * */ public float getFloat() { if (type == TYPE_FLOAT) { return floatValue; } else if (type == TYPE_INTEGER) { return intValue; } else if (type == TYPE_SHORT) { return shortValue; } else if (type == TYPE_LONG) { return longValue; } else if (type == TYPE_BYTE) { return byteValue; } else { throw new ClassCastException( "getFloat cannot be called for type " + type.toString()); } } /** * Get the double value. * * @return The double value. * @exception ClassCastException * is thrown if this Value has incompatible type. * */ public double getDouble() { if (type == TYPE_DOUBLE) { return doubleValue; } else if (type == TYPE_INTEGER) { return intValue; } else if (type == TYPE_SHORT) { return shortValue; } else if (type == TYPE_LONG) { return longValue; } else if (type == TYPE_FLOAT) { return floatValue; } else if (type == TYPE_BYTE) { return byteValue; } else if (type == TYPE_DATE) { return ((Date) obj).getTime(); } else { throw new ClassCastException( "getDouble cannot be called for type " + type.toString()); } } /** * Get the boolean value. * * @return The boolean value. * @exception ClassCastException * is thrown if this Value has incompatible type. * */ public boolean getBoolean() { if (type == TYPE_BOOLEAN) { return boolValue; } throw new ClassCastException( "getBoolean cannot be called for type " + type.toString()); } /** * Get the byte value. * * @return The byte value. * @exception ClassCastException * is thrown if this Value has incompatible type. * */ public byte getByte() { if (type == TYPE_BYTE) { return byteValue; } throw new ClassCastException( "getByte cannot be called for type " + type.toString()); } /** * Get the char value. * * @return The char value. * @exception ClassCastException * is thrown if this Value has incompatible type. * */ public char getChar() { if (type == TYPE_CHAR) { return charValue; } throw new ClassCastException( "getChar cannot be called for type " + type.toString()); } /** * Get the String value. * * @return The String representation of the internal value. * */ public String getString() { if (type == TYPE_STRING) { return (String) obj; } else if (type == TYPE_INTEGER) { return String.valueOf(intValue); } else if (type == TYPE_SHORT) { return String.valueOf(shortValue); } else if (type == TYPE_LONG) { return String.valueOf(longValue); } else if (type == TYPE_FLOAT) { return String.valueOf(floatValue); } else if (type == TYPE_DOUBLE) { return String.valueOf(doubleValue); } else if (type == TYPE_BOOLEAN) { return String.valueOf(boolValue); } else if (type == TYPE_BYTE) { return String.valueOf(byteValue); } else if (type == TYPE_CHAR) { return String.valueOf(charValue); } else if (type == TYPE_DATE) { return ((Date) obj).toString(); } else { return obj != null ? obj.toString() : "null"; } } /** * Get the Date value. * * @return The Date value. * @exception ClassCastException * is thrown if this Value has incompatible type. * */ public Date getDate() { if (type == TYPE_DATE) { return (Date) obj; } throw new ClassCastException( "getDate cannot be called for type " + type.toString()); } /** * Get the Object value. * * @return The Object value. * */ public Object getObject() { if (obj != null) { return obj; } else if (type == TYPE_INTEGER) { return Integer.valueOf(intValue); } else if (type == TYPE_SHORT) { return Short.valueOf(shortValue); } else if (type == TYPE_LONG) { return Long.valueOf(longValue); } else if (type == TYPE_FLOAT) { return Float.valueOf(floatValue); } else if (type == TYPE_DOUBLE) { return Double.valueOf(doubleValue); } else if (type == TYPE_BOOLEAN) { return Boolean.valueOf(boolValue); } else if (type == TYPE_BYTE) { return Byte.valueOf(byteValue); } else if (type == TYPE_CHAR) { return Character.valueOf(charValue); } else { return null; } } /** * Get the String value. * * @return The String representation of the internal value. */ @Override public String toString() { return getString(); } /** * Returns an external representation of this value */ public String toExternal() { // FIXME, does not work for arrays... return type.getName() + ":" + getString(); } /** * Set to value from the external representation */ // public Value fromExternal(String external) throws // IllegalArgumentException { // String[] part = external.split(":", 2); // if (part.length != 2) // throw new IllegalArgumentException(getClass()+": External '"+external+ // "'does not contain ':' to separate type from value."); // // if (part[0].equals(TYPE_STRING.getName())) { // return set(part[1]); // } else if (part[0].equals(TYPE_SHORT.getName())) { // return set(Short.parseShort(part[1])); // } else if (part[0].equals(TYPE_LONG.getName())) { // return set(Long.parseLong(part[1])); // } else if (part[0].equals(TYPE_FLOAT.getName())) { // return set(Float.parseFloat(part[1])); // } else if (part[0].equals(TYPE_DOUBLE.getName())) { // return set(Double.parseDouble(part[1])); // } else if (part[0].equals(TYPE_BOOLEAN.getName())) { // return set(Boolean.getBoolean(part[1])); // } else if (part[0].equals(TYPE_BYTE.getName())) { // return set(Byte.parseByte(part[1])); // } else if (part[0].equals(TYPE_CHAR.getName())) { // return set(part[1].charAt(0)); // } else if (part[0].equals(TYPE_INTEGER.getName())) { // return set(Integer.parseInt(part[1])); // } else if (part[0].equals(TYPE_DATE.getName())) { // try { // return set(new SimpleDateFormat().parse(part[1])); // } catch (ParseException e) { // throw new IllegalArgumentException(e.getMessage()); // } // } else if (part[0].equals(Object.class.getName()) && // part[1].equals("null")) { // return set((Object)null); // } else { // // FIXME will not work for arrays, which are encoded as // "[Lpackagename.classname;" // try { // Class<?> cls = Class.forName(part[0]); // Constructor<?> ctor = cls.getDeclaredConstructor(new Class[] { // String.class }); // ctor.setAccessible(true); // return set(ctor.newInstance(new Object[] { part[1] })); // } catch (Exception e) { // throw new IllegalArgumentException(getClass()+": Cannot reconstruct value // from type: "+part[0]+", " // +"and value "+part[1]+", due to "+e.getMessage()); // } // } // } }