/* * Copyright(c) 2005 Center for E-Commerce Infrastructure Development, The * University of Hong Kong (HKU). All Rights Reserved. * * This software is licensed under the GNU GENERAL PUBLIC LICENSE Version 2.0 [1] * * [1] http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt */ package hk.hku.cecid.piazza.commons.dao; import hk.hku.cecid.piazza.commons.util.Convertor; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.lang.reflect.Method; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.Set; /** * The AbstractDVO, which implements the DVO interface, is simply a * convenient abstract class for managing the data of a DVO. It implemented * the methods of the DVO interface, provides some convenient methods and is * backed by a Hashtable. * * @author Hugo Y. K. Lam * */ public abstract class AbstractDVO implements DVO { private Hashtable data; private Set dirtyFields = Collections.synchronizedSet(new HashSet()); /** * Creates a new instance of AbstractDVO. */ protected AbstractDVO() { this(null); } /** * Creates a new instance of AbstractDVO. * * @param data the source data of this DVO. */ protected AbstractDVO(Hashtable data) { setData(data); } /** * Sets the source data of this DVO. * * @param data the source data of this DVO. */ public void setData(Hashtable data) { if (data != null) { this.data = data; } else { this.data = new Hashtable(); } } /** * Gets the source data of this DVO. * * @return the source data of this DVO. */ public Hashtable getData() { return data; } /** * Gets the keys which reference the dirty values. * * @return the keys referencing the dirty values. */ public String[] getDirties() { return (String[])dirtyFields.toArray(new String[]{}); } /** * Sets a single value to this DVO with a key as its reference. * * @param key the key referencing the value to be set. * @param value the value object to be set to this DVO. * @return the previous value of the specified key in this hashtable, or * null if it did not have one. */ public Object put(Object key, Object value) { if (key != null) { dirtyFields.add(key); if (value == null) { return data.remove(key); } else { return data.put(key, value); } } else { return null; } } /** * Gets a value object back from this DVO by its key. * * @param key the key referencing the value to be retrieved. * @return the value object retrieved by the specified key. */ public Object get(Object key) { if (key == null) { return null; } else { return data.get(key); } } /** * Removes a value object from this DVO. * * @param key the key referencing the value to be removed. * @return the value to which the key had been mapped in this DVO, or * null if the key did not have a mapping. * */ public Object remove(Object key) { if (key == null) { return null; } else { return data.remove(key); } } /** * Sets a String value to this DVO. * * @param key the key referencing the String value. * @param value the String value to be set. */ public void setString(Object key, Object value) { if (value != null) { value = value.toString(); } put(key, value); } /** * Gets a String value from this DVO by its key reference. * * @param key the key referencing the String value. * @return the String value retrieved by the specified key. */ public String getString(Object key) { Object obj = get(key); if (obj == null) { return null; } else { return obj.toString(); } } /** * Retrieves the value by the specified key in this AbstractDVO as an * int. * * @param key the key referencing the value to be retrieved. * @return the value retrieved by the specified key or Integer.MIN_VALUE if * the underlying value is null. */ public int getInt(Object key) { Object num = get(key); if (num instanceof String) { return Integer.parseInt((String)num); } else if (num instanceof Integer) { return ((Integer)num).intValue(); } else if (num instanceof Number) { return ((Number)num).intValue(); } else { return Integer.MIN_VALUE; } } /** * Sets an Integer value to this DVO. * * @param key the key referencing the Integer value. * @param value the Integer value to be set. */ public void setInt(Object key, int value) { put(key, new Integer(value)); } /** * Retrieves the value by the specified key in this AbstractDVO as a * long. * * @param key the key referencing the value to be retrieved. * @return the value retrieved by the specified key or Long.MIN_VALUE if * the underlying value is null. */ public long getLong(Object key) { Object num = get(key); if (num instanceof String) { return Long.parseLong((String)num); } else if (num instanceof Long) { return ((Long)num).longValue(); } else if (num instanceof Number) { return ((Number)num).longValue(); } else { return Long.MIN_VALUE; } } /** * Sets a Long value to this DVO. * * @param key the key referencing the Long value. * @param value the Long value to be set. */ public void setLong(Object key, long value) { put(key, new Long(value)); } /** * Retrieves the value by the specified key in this AbstractDVO as a * double. * * @param key the key referencing the value to be retrieved. * @return the value retrieved by the specified key. */ public double getDouble(Object key) { Object num = get(key); if (num instanceof String) { return Double.parseDouble((String)num); } else if (num instanceof Number) { return ((Number)num).doubleValue(); } else { return Double.NaN; } } /** * Sets a Double value to this DVO. * * @param key the key referencing the Double value. * @param value the Double value to be set. */ public void setDouble(Object key, double value) { put(key, new Double(value)); } /** * Retrieves the value by the specified key in this AbstractDVO as an * boolean. * * @param key the key referencing the value to be retrieved. * @return the value retrieved by the specified key. */ public boolean getBoolean(Object key) { Object obj = get(key); if (obj instanceof String) { return Boolean.parseBoolean((String)obj); } else if (obj instanceof Boolean) { return ((Boolean)obj).booleanValue(); } else { return false; } } /** * Sets a Boolean value to this DVO. * * @param key the key referencing the Boolean value. * @param value the Boolean value to be set. */ public void setBoolean(Object key, boolean value) { put(key, new Boolean(value)); } /** * Gets an Object from this DVO by its referencing key. If the value * object is not of the Class specified, it will try to create an instance * of the Class with the Object as the parameter. * * @param key The key referencing the String value. * @param c the Class of the returning Object. * @return the Object retrieved by its referencing key. If the value object * is not of the Class specified, it will be an instance of the * Class with the Object as the parameter. Null if the mentioned * cannot be achieved. * @deprecated as Convertor.convertObject(Object, Class) is deprecated. */ public Object getObject(Object key, Class c) { return Convertor.convertObject(get(key), c); } /** * Retrieves the value by the specified key in this AbstractDVO as a * java.util.Date. * * @param key the key referencing the value to be retrieved. * @return the value retrieved by the specified key. */ public java.util.Date getDate(Object key) { return (java.util.Date)getTimestamp(key); } /** * Sets a java.util.Date and java.sql.Date value to this DVO. * * * @param key the key referencing the Date value. * @param obj the Date value to be set. */ public void setDate(Object key, Object obj) { if (obj == null) return; if (obj instanceof java.util.Date) put(key, new java.sql.Timestamp(((java.util.Date)obj).getTime())); else if (obj instanceof java.sql.Date) put(key, new java.sql.Timestamp(((java.sql.Date)obj).getTime())); else put(key, (java.sql.Timestamp)obj); } /** * Retrieves the value by the specified key in this AbstractDVO as a * java.sql.Date. * * @param key the key referencing the value to be retrieved. * @return the value retrieved by the specified key. * @deprecated replaced by getDate() */ public java.sql.Date getSQLDate(Object key) { return (java.sql.Date) getObject(key, java.sql.Date.class); } /** * Retrieves the value by the specified key in this AbstractDVO as a * java.sql.Timestamp. * It can transform java.sql.Date, java.util.Date and Oracle DATE and TIMESTAMP. * * @param key the key referencing the value to be retrieved. * @return the value retrieved by the specified key. */ public java.sql.Timestamp getTimestamp(Object key) { Object obj = get(key); if (obj == null) return null; if (obj instanceof java.sql.Timestamp) return (java.sql.Timestamp)obj; else if (obj instanceof java.sql.Date) { return new java.sql.Timestamp(((java.sql.Date)obj).getTime()); } else if (obj instanceof java.util.Date) { return new java.sql.Timestamp(((java.util.Date)obj).getTime()); } else if (obj.getClass().getName().equals("oracle.sql.DATE") || obj.getClass().getName().equals("oracle.sql.TIMESTAMP")) { try { Method m = obj.getClass().getDeclaredMethod("timestampValue", new Class[0]); return (java.sql.Timestamp)m.invoke(obj, new Object[0]); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } return null; } /** * Indicates whether the given object is equal to this one. * The objects are equal if and only if the given object is an * AbstractDVO object and the values contained in that object * match with this one's. * * @param obj the object to be compared. * @return true if the given object is equal to this one. * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object obj) { if (obj instanceof AbstractDVO) { AbstractDVO daoData = (AbstractDVO)obj; if (data.size() == daoData.data.size()) { Enumeration enumeration = data.keys(); while (enumeration.hasMoreElements()) { Object key = enumeration.nextElement(); Object value = data.get(key); Object value2 = daoData.data.get(key); if (value2 == null || !value.equals(value2)) { return false; } } return true; } } return false; } /** * Returns a string representation of this AbstractDVO object in the * form of a set of entries. * * @return a string representation of this AbstractDVO. */ public String toString() { String s = this.getClass() + ":\n"; Enumeration enumeration = data.keys(); while (enumeration.hasMoreElements()) { Object key = enumeration.nextElement(); s += key + "=" + data.get(key) + "\n"; } return s; } }