001: package jimm.datavision.source.ncsql;
002:
003: import jimm.datavision.*;
004: import jimm.datavision.source.*;
005: import jimm.util.XMLWriter;
006: import java.util.*;
007:
008: /**
009: * An <code>NCDatabase</code> a data source that acts like a SQL
010: * database data source but can't run reports. It gets its column
011: * descriptions from metadata described in the report XML file.
012: *
013: * @author Jim Menard, <a href="mailto:jimm@io.com">jimm@io.com</a>
014: */
015: public class NCDatabase extends DataSource {
016:
017: protected static final String ORPHANS_TABLE = "no_table";
018:
019: protected TreeMap tables;
020:
021: public NCDatabase(Report report) {
022: super (report, new NCQuery(report));
023: tables = new TreeMap();
024: }
025:
026: public boolean canRunReports() {
027: return false;
028: }
029:
030: public boolean canJoinTables() {
031: return true;
032: }
033:
034: public boolean isSQLGenerated() {
035: return true;
036: }
037:
038: public boolean isConnectionEditable() {
039: return false;
040: }
041:
042: public boolean areRecordsSelectable() {
043: return true;
044: }
045:
046: public boolean areRecordsSortable() {
047: return true;
048: }
049:
050: public boolean canGroupRecords() {
051: return true;
052: }
053:
054: /**
055: * This override not only remembers the column but also hands it to the
056: * query for cacheing.
057: *
058: * @param col a column
059: */
060: public void addColumn(Column col) {
061: // We need to turn the column into a NCColumn and perhaps add an
062: // NCTable, too.
063:
064: // Parse the column's full name, looking for the table name and column
065: // name.
066: String fullName = col.fullName();
067: int lastDotPos = fullName.lastIndexOf('.');
068: String tableName = null;
069: String colName = null;
070: if (lastDotPos == -1) {
071: tableName = ORPHANS_TABLE;
072: colName = fullName;
073: } else {
074: tableName = fullName.substring(0, lastDotPos);
075: colName = fullName.substring(lastDotPos + 1);
076: }
077:
078: // Find the table. Create one if we don't already have one.
079: NCTable table = (NCTable) tables.get(tableName);
080: if (table == null) {
081: table = new NCTable(this , tableName);
082: tables.put(tableName, table);
083: }
084:
085: table.addColumn(new NCColumn(table, colName, col.getType()));
086: }
087:
088: /**
089: * Given an id (a column name), returns the column that has that id. If no
090: * column with the specified id exists, returns <code>null</code>. Uses
091: * <code>Table.findColumn</code>.
092: *
093: * @param id a column id
094: * @return a column, or <code>null</code> if no column with the specified
095: * id exists
096: * @see Table#findColumn
097: */
098: public Column findColumn(Object id) {
099: if (tables == null)
100: return null;
101:
102: for (Iterator iter = tables.values().iterator(); iter.hasNext();) {
103: Column col = ((Table) iter.next()).findColumn(id);
104: if (col != null)
105: return col;
106: }
107: return null;
108: }
109:
110: public Iterator tables() {
111: return tables.values().iterator();
112: }
113:
114: public Iterator tablesUsedInReport() {
115: return ((NCQuery) query).getTablesUsed().iterator();
116: }
117:
118: public Iterator columns() {
119: return new ColumnIterator(tables.values().iterator());
120: }
121:
122: public DataCursor execute() {
123: return null;
124: }
125:
126: /**
127: * Writes this database and all its tables as an XML tag.
128: *
129: * @param out a writer that knows how to write XML
130: */
131: protected void doWriteXML(XMLWriter out) {
132: out.startElement("nc-database");
133: if (metadataURL != null)
134: out.textElement("metadata-url", metadataURL);
135: else
136: for (Iterator iter = columns(); iter.hasNext();)
137: ((Column) iter.next()).writeXML(out);
138: out.endElement();
139: }
140:
141: }
|