package prefuse.data; import java.util.HashMap; import prefuse.util.PrefuseLib; /** *

The Schema class represents a description of a Table's columns, including * column names, data types, and default values. New Table * instances can be created directly from Schema objects through the use of * the {@link #instantiate()} method. If a schema is subsequently changed, * instantiated table instances are not affected, keeping their original * schema.

* *

Schema instances can be locked to prevent further changes. Any attempt * to alter a locked schema will result in a runtime exception being thrown. * If a schema is not locked, clients are free to add new columns and * edit default values.

* * @author jeffrey heer */ public class Schema implements Cloneable { private String[] m_names; private Class[] m_types; private Object[] m_dflts; private HashMap m_lookup; private int m_size; private boolean m_locked; // ------------------------------------------------------------------------ // Constructors /** * Creates a new empty schema. */ public Schema() { this(10); } /** * Creates a new empty schema with a starting capacity for a given number * of columns. * @param ncols the number of columns in this schema */ public Schema(int ncols) { m_names = new String[ncols]; m_types = new Class[ncols]; m_dflts = new Object[ncols]; m_size = 0; m_locked = false; } /** * Create a new schema consisting of the given column names and types. * @param names the column names * @param types the column types (as Class instances) */ public Schema(String[] names, Class[] types) { this(names.length); // check the schema validity if ( names.length != types.length ) { throw new IllegalArgumentException( "Input arrays should be the same length"); } for ( int i=0; iAdd a new interpolated column to this data schema. This actually adds * three columns to the schema: a column for the current value of the * field, and columns for starting and ending values. During animation or * operations spread over a time span, the current value can be * interpolated between the start and end values.

* *

The name for the current value column is the name parameter provided * to the method. The name for the start and end columns will be determined * by the return value of {@link PrefuseLib#getStartField(String)} and * {@link PrefuseLib#getEndField(String)}. The default behavior for these * methods is to append ":start" to the name of a stating value column * and append ":end" to the the name of an ending value column.

* * @param name the name of the interpolated column to add * @param type the data type the columns will contain * @param dflt the default value for each of the columns */ public void addInterpolatedColumn(String name, Class type, Object dflt) { addColumn(name, type, dflt); addColumn(PrefuseLib.getStartField(name), type, dflt); addColumn(PrefuseLib.getEndField(name), type, dflt); } /** * Add an interpolated column with a null default value. * @see #addInterpolatedColumn(String, Class, Object) * @param name the name of the interpolated column to add * @param type the data type the columns will contain */ public void addInterpolatedColumn(String name, Class type) { addInterpolatedColumn(name, type, null); } /** * Get the number of columns in this schema. * @return the number of columns */ public int getColumnCount() { return m_size; } /** * The name of the column at the given position. * @param col the column index * @return the column name */ public String getColumnName(int col) { return m_names[col]; } /** * The column index for the column with the given name. * @param field the column name * @return the column index */ public int getColumnIndex(String field) { if ( m_lookup == null ) initLookup(); Integer idx = (Integer)m_lookup.get(field); return ( idx==null ? -1 : idx.intValue() ); } /** * The type of the column at the given position. * @param col the column index * @return the column type */ public Class getColumnType(int col) { return m_types[col]; } /** * The type of the column with the given name. * @param field the column name * @return the column type */ public Class getColumnType(String field) { int idx = getColumnIndex(field); return ( idx<0 ? null : m_types[idx] ); } /** * The default value of the column at the given position. * @param col the column index * @return the column's default value */ public Object getDefault(int col) { return m_dflts[col]; } /** * The default value of the column with the given name. * @param field the column name * @return the column's default value */ public Object getDefault(String field) { int idx = getColumnIndex(field); return ( idx<0 ? null : m_dflts[idx] ); } /** * Set the default value for the given field. * @param col the column index of the field to set the default for * @param val the new default value */ public void setDefault(int col, Object val) { // check lock status if ( m_locked ) { throw new IllegalStateException( "Can not update default values of a locked Schema."); } m_dflts[col] = val; } /** * Set the default value for the given field. * @param field the name of column to set the default for * @param val the new default value */ public void setDefault(String field, Object val) { // check lock status if ( m_locked ) { throw new IllegalStateException( "Can not update default values of a locked Schema."); } int idx = getColumnIndex(field); m_dflts[idx] = val; } /** * Set the default value for the given field as an int. * @param field the name of column to set the default for * @param val the new default value */ public void setDefault(String field, int val) { setDefault(field, new Integer(val)); } /** * Set the default value for the given field as a long. * @param field the name of column to set the default for * @param val the new default value */ public void setDefault(String field, long val) { setDefault(field, new Long(val)); } /** * Set the default value for the given field as a float. * @param field the name of column to set the default for * @param val the new default value */ public void setDefault(String field, float val) { setDefault(field, new Float(val)); } /** * Set the default value for the given field as a double. * @param field the name of column to set the default for * @param val the new default value */ public void setDefault(String field, double val) { setDefault(field, new Double(val)); } /** * Set the default value for the given field as a boolean. * @param field the name of column to set the default for * @param val the new default value */ public void setDefault(String field, boolean val) { setDefault(field, val ? Boolean.TRUE : Boolean.FALSE); } /** * Set default values for the current, start, and end columns of an * interpolated column. * @param field the field name of the interpolated column * @param val the new default value for all three implicated columns */ public void setInterpolatedDefault(String field, Object val) { setDefault(field, val); setDefault(PrefuseLib.getStartField(field), val); setDefault(PrefuseLib.getEndField(field), val); } /** * Set default values for the current, start, and end columns of an * interpolated column as an int. * @param field the field name of the interpolated column * @param val the new default value for all three implicated columns */ public void setInterpolatedDefault(String field, int val) { setInterpolatedDefault(field, new Integer(val)); } /** * Set default values for the current, start, and end columns of an * interpolated column as a long. * @param field the field name of the interpolated column * @param val the new default value for all three implicated columns */ public void setInterpolatedDefault(String field, long val) { setInterpolatedDefault(field, new Long(val)); } /** * Set default values for the current, start, and end columns of an * interpolated column as a float. * @param field the field name of the interpolated column * @param val the new default value for all three implicated columns */ public void setInterpolatedDefault(String field, float val) { setInterpolatedDefault(field, new Float(val)); } /** * Set default values for the current, start, and end columns of an * interpolated column as a double. * @param field the field name of the interpolated column * @param val the new default value for all three implicated columns */ public void setInterpolatedDefault(String field, double val) { setInterpolatedDefault(field, new Double(val)); } /** * Set default values for the current, start, and end columns of an * interpolated column as a boolean. * @param field the field name of the interpolated column * @param val the new default value for all three implicated columns */ public void setInterpolatedDefault(String field, boolean val) { setInterpolatedDefault(field, val ? Boolean.TRUE : Boolean.FALSE); } // ------------------------------------------------------------------------ // Comparison and Hashing /** * Compares this schema with another one for equality. */ public boolean equals(Object o) { if ( !(o instanceof Schema) ) return false; Schema s = (Schema)o; if ( m_size != s.getColumnCount() ) return false; for ( int i=0; i m_size ) return false; for ( int i=0; i 0 ) sbuf.append(' '); sbuf.append('(').append(m_names[i]).append(", "); sbuf.append(m_types[i].getName()).append(", "); sbuf.append(m_dflts[i]).append(')'); } sbuf.append(']'); return sbuf.toString(); } // ------------------------------------------------------------------------ // Table Operations /** * Instantiate this schema as a new Table instance. * @return a new Table with this schema */ public Table instantiate() { return instantiate(0); } /** * Instantiate this schema as a new Table instance. * @param nrows the number of starting rows in the table * @return a new Table with this schema */ public Table instantiate(int nrows) { Table t = new Table(nrows, m_size); for ( int i=0; i