001: package jimm.datavision.source;
002:
003: import jimm.datavision.*;
004: import jimm.datavision.source.sql.SQLQuery;
005: import jimm.util.XMLWriter;
006: import java.sql.Types;
007:
008: /**
009: * Represents a data column. Not all data sources' columns will be
010: * contained within tables. For those that don't, their columns'
011: * <code>getTable</code> method will return <code>null</code>.
012: *
013: * @author Jim Menard, <a href="mailto:jimm@io.com">jimm@io.com</a>
014: * @see Table
015: * @see DataSource
016: */
017: public class Column implements Identity, Nameable, Selectable,
018: Draggable, Writeable {
019:
020: public static final String DEFAULT_DATE_PARSE_FORMAT = "yyyy-MM-dd";
021:
022: protected Object id;
023: protected String name;
024: protected int type;
025: protected String dateParseFormat;
026:
027: public static int typeFromString(String str) {
028: if (str == null || str.length() == 0)
029: return Types.VARCHAR;
030:
031: str = str.toLowerCase();
032: if (str.equals("number"))
033: return Types.NUMERIC;
034: if (str.equals("date"))
035: return Types.DATE;
036: return Types.VARCHAR;
037: }
038:
039: public static String typeToString(int type) {
040: switch (type) {
041: case Types.BIGINT:
042: case Types.BIT:
043: case Types.DECIMAL:
044: case Types.DOUBLE:
045: case Types.INTEGER:
046: case Types.NUMERIC:
047: case Types.REAL:
048: case Types.SMALLINT:
049: case Types.TINYINT:
050: return "number";
051: case Types.DATE:
052: case Types.TIME:
053: case Types.TIMESTAMP:
054: return "date";
055: default:
056: return "string";
057: }
058: }
059:
060: public Column(Object id, String name, int type) {
061: this .id = id;
062: this .name = name;
063: this .type = type;
064: }
065:
066: /**
067: * Returns <code>true</code> if the other object is a column with the
068: * same id.
069: *
070: * @param obj any <code>Object</code>
071: * @return <code>true</code> if the other object is a column with the
072: * same id.
073: */
074: public boolean equals(Object obj) {
075: if (obj == null || !(obj instanceof Column))
076: return false;
077: if (this == obj)
078: return true;
079: return id.equals(((Column) obj).getId());
080: }
081:
082: public int hashCode() {
083: return id.hashCode();
084: }
085:
086: /**
087: * Returns the table id. This is a string of the form
088: * "table_name.column_name".
089: *
090: * @return the id string
091: */
092: public Object getId() {
093: return id;
094: }
095:
096: /**
097: * Returns the column's name. The name may not be unique. To retrieve
098: * a unique name (for example, "table.column"), use <code>fullName</code>.
099: *
100: * @return the column's name
101: * @see #fullName
102: */
103: public String getName() {
104: return name;
105: }
106:
107: /** A column's name is immutable. */
108: public void setName(String name) {
109: }
110:
111: /**
112: * Returns the date parse format, useful for data sources that read text
113: * strings and convert them into date objects. If no format has been
114: * defined, returns <code>DEFAULT_DATE_PARSE_FORMAT</code>
115: *
116: * @return the date parse format string (if not defined, returns
117: * <code>DEFAULT_DATE_PARSE_FORMAT</code>)
118: */
119: public String getDateParseFormat() {
120: return dateParseFormat == null ? DEFAULT_DATE_PARSE_FORMAT
121: : dateParseFormat;
122: }
123:
124: /**
125: * Sets the date parse format, useful for data sources that read text
126: * strings and convert them into date objects. Called from
127: * <code>ReportReader.column</code>, for example.
128: *
129: * @param format the date parse format string
130: */
131: public void setDateParseFormat(String format) {
132: dateParseFormat = format;
133: }
134:
135: /**
136: * Returns the table to which this column belongs, if any.
137: *
138: * @return the table, or <code>null</code> if there is none
139: */
140: public Table getTable() {
141: return null;
142: }
143:
144: /**
145: * Returns the full named of this column: the id as a string. The column's
146: * name may not be unique, but the full name should be unique.
147: * <p>
148: * For SQL columns, this is a string of the form "table_name.column_name".
149: * To retrieve just the column name, use <code>getName</code>.
150: *
151: * @return the full name; this is the same as the id as a string
152: * @see #getName
153: */
154: public String fullName() {
155: return id.toString();
156: }
157:
158: /**
159: * Returns the type constant (a <code>java.sql.Types</code> value).
160: *
161: * @return a <code>java.sql.Types</code> value
162: * @see java.sql.Types
163: */
164: public int getType() {
165: return type;
166: }
167:
168: public Object getValue(Report report) {
169: return report.columnValue(this );
170: }
171:
172: public String fieldTypeString() {
173: return "column";
174: }
175:
176: public String getSelectString(SQLQuery query) {
177: return query.quoted(fullName());
178: }
179:
180: public String getSortString(SQLQuery query) {
181: return getSelectString(query);
182: }
183:
184: public String dragString() {
185: return "column:" + fullName();
186: }
187:
188: public String getDisplayName() {
189: return fullName();
190: }
191:
192: public Selectable reloadInstance(DataSource dataSource) {
193: return dataSource.findColumn(getId());
194: }
195:
196: /**
197: * Returns <code>true</code> if this column is some numeric type
198: * (double, int, etc.)
199: *
200: * @return <code>true</code> if this column is some numeric type
201: * (double, int, etc.)
202: */
203: public boolean isNumeric() {
204: return type == Types.BIGINT || type == Types.BIT
205: || type == Types.DECIMAL || type == Types.DOUBLE
206: || type == Types.FLOAT || type == Types.INTEGER
207: || type == Types.NUMERIC || type == Types.REAL
208: || type == Types.SMALLINT || type == Types.TINYINT;
209: }
210:
211: /**
212: * Returns <code>true</code> if this column is some date type.
213: *
214: * @return <code>true</code> if this column is some date type
215: */
216: public boolean isDate() {
217: return type == Types.DATE || type == Types.TIME
218: || type == Types.TIMESTAMP;
219: }
220:
221: /**
222: * Returns <code>true</code> if this column is some character type.
223: *
224: * @return <code>true</code> if this column is some character type
225: */
226: public boolean isString() {
227: return !isNumeric() && !isDate();
228: }
229:
230: /**
231: * Returns a string representation of this column. Calls
232: * <code>fullName</code>.
233: *
234: * @see #fullName
235: */
236: public String toString() {
237: return fullName();
238: }
239:
240: public void writeXML(XMLWriter out) {
241: out.startElement("column");
242: out.attr("name", getName());
243: out.attr("type", typeToString(type));
244: if (dateParseFormat != null)
245: out.attr("date-format", dateParseFormat);
246: out.endElement();
247: }
248:
249: }
|