package prefuse.data.column; import java.util.Arrays; import java.util.Date; import prefuse.data.DataReadOnlyException; import prefuse.data.DataTypeException; import prefuse.util.TimeLib; /** * Column implementation for storing Date values. * * @author <a href="http://jheer.org">jeffrey heer</a> */ public class DateColumn extends AbstractColumn { private long[] m_values; private int m_size; /** * Create a new empty DateColumn. */ public DateColumn() { this(Date.class, 0, 10, 0L); } /** * Create a new DateColumn. * @param nrows the initial size of the column */ public DateColumn(int nrows) { this(Date.class, nrows, nrows, 0L); } /** * Create a new DateColumn. * @param type the exact data type (must be an instance or * subclass of java.util.Date) * @param nrows the initial size of the column */ public DateColumn(Class type, int nrows) { this(type, nrows, nrows, 0L); } /** * Create a new DateColumn. * @param type the exact data type (must be an instance or * subclass of java.util.Date) * @param nrows the initial size of the column * @param capacity the initial capacity of the column * @param defaultValue the default value for the column */ public DateColumn(Class type, int nrows, int capacity, long defaultValue) { super(type, TimeLib.getDate(type, defaultValue)); if ( !Date.class.isAssignableFrom(type) ) { throw new IllegalArgumentException("Column type must be an " + "instance or subclass of java.util.Date."); } if ( capacity < nrows ) { throw new IllegalArgumentException( "Capacity value can not be less than the row count."); } m_values = new long[capacity]; Arrays.fill(m_values, defaultValue); m_size = nrows; } // ------------------------------------------------------------------------ // Column Metadata /** * @see prefuse.data.column.Column#getRowCount() */ public int getRowCount() { return m_size; } /** * @see prefuse.data.column.Column#setMaximumRow(int) */ public void setMaximumRow(int nrows) { if ( nrows > m_values.length ) { int capacity = Math.max((3*m_values.length)/2 + 1, nrows); long[] values = new long[capacity]; System.arraycopy(m_values, 0, values, 0, m_size); Arrays.fill(values, m_size, capacity, ((Date)m_defaultValue).getTime()); m_values = values; } m_size = nrows; } /** * Indicates if the set method can be called without * an exception being thrown for the given type. * @param type the Class of the data type to check * @return true if the type is supported by this column, false otherwise */ public boolean canSet(Class type) { if ( type == null ) return false; if ( Number.class.isAssignableFrom(type) || String.class.isAssignableFrom(type) ) { return true; } else { return m_columnType.isAssignableFrom(type); } } // ------------------------------------------------------------------------ // Data Access Methods /** * @see prefuse.data.column.Column#get(int) */ public Object get(int row) { return TimeLib.getDate(m_columnType, getLong(row)); } /** * @see prefuse.data.column.Column#set(java.lang.Object, int) */ public void set(Object val, int row) throws DataTypeException { if ( m_readOnly ) { throw new DataReadOnlyException(); } else if ( val != null ) { if ( val instanceof Date ) { setLong(((Date)val).getTime(), row); } else if ( val instanceof Number ) { setLong(((Number)val).longValue(), row); } else if ( val instanceof String ) { setString((String)val, row); } else { throw new DataTypeException(val.getClass()); } } else { throw new DataTypeException("Column does not accept null values"); } } // ------------------------------------------------------------------------ // Data Type Convenience Methods /** * @see prefuse.data.column.AbstractColumn#getLong(int) */ public long getLong(int row) throws DataTypeException { if ( row < 0 || row > m_size ) { throw new IllegalArgumentException("Row index out of bounds: "+row); } return m_values[row]; } /** * @see prefuse.data.column.AbstractColumn#setLong(long, int) */ public void setLong(long val, int row) throws DataTypeException { if ( m_readOnly ) { throw new DataReadOnlyException(); } else if ( row < 0 || row >= m_size ) { throw new IllegalArgumentException("Row index out of bounds: "+row); } // get the previous value long prev = m_values[row]; // exit early if no change if ( prev == val ) return; // set the new value m_values[row] = val; // fire a change event fireColumnEvent(row, prev); } // ------------------------------------------------------------------------ /** * @see prefuse.data.column.Column#getDouble(int) */ public double getDouble(int row) throws DataTypeException { return getLong(row); } } // end of class DateColumn