001: /*
002: * argun 1.0
003: * Web 2.0 delivery framework
004: * Copyright (C) 2007 Hammurapi Group
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2 of the License, or (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * URL: http://www.hammurapi.biz
021: * e-Mail: support@hammurapi.biz
022: */
023: package biz.hammurapi.web.mda.db.model;
024:
025: import java.sql.DatabaseMetaData;
026: import java.sql.ResultSet;
027: import java.sql.ResultSetMetaData;
028: import java.sql.SQLException;
029: import java.util.ArrayList;
030: import java.util.HashMap;
031: import java.util.HashSet;
032: import java.util.Iterator;
033: import java.util.List;
034: import java.util.Map;
035: import java.util.Properties;
036: import java.util.Set;
037: import java.util.StringTokenizer;
038:
039: import org.apache.xpath.CachedXPathAPI;
040: import org.w3c.dom.Element;
041:
042: import biz.hammurapi.config.ConfigurationException;
043: import biz.hammurapi.sql.DataAccessObject;
044: import biz.hammurapi.sql.SQLProcessor;
045: import biz.hammurapi.util.CollectionVisitable;
046: import biz.hammurapi.util.Visitable;
047: import biz.hammurapi.util.Visitor;
048: import biz.hammurapi.web.ActionsBase;
049: import biz.hammurapi.web.interaction.InteractionInstance;
050: import biz.hammurapi.web.interaction.InteractionInstance.StepInstance;
051: import biz.hammurapi.web.metadata.DbmTableImpl;
052: import biz.hammurapi.web.metadata.MetadataEngine;
053: import biz.hammurapi.xml.dom.AbstractDomObject;
054: import biz.hammurapi.xml.dom.CompositeDomSerializer;
055:
056: /**
057: * This class represents database table for the purposes of MDA transformations. The class combines metadata retrieved from JDBC
058: * interfaces with info from DBM_TABLE table.
059: * @author Pavel
060: *
061: */
062: public class Table extends DbmTableImpl implements Visitable,
063: DataAccessObject {
064:
065: private List tableColumns = new ArrayList();
066:
067: private List indices = new ArrayList();
068: private List exportedKeys = new ArrayList();
069: private List importedKeys = new ArrayList();
070: private List primaryKeys = new ArrayList();
071:
072: public Table() {
073: super ();
074: }
075:
076: public Table(boolean force) {
077: super (force);
078: }
079:
080: public Table(Element holder, boolean force)
081: throws ConfigurationException {
082: super (holder, force);
083: }
084:
085: public Table(Element holder, Properties nameMap,
086: CachedXPathAPI cxpa, boolean force)
087: throws ConfigurationException {
088: super (holder, nameMap, cxpa, force);
089: }
090:
091: public Table(ResultSet rs) throws SQLException {
092: super (rs);
093: }
094:
095: public List getColumns() {
096: return tableColumns;
097: }
098:
099: public List getImportedKeys() {
100: return importedKeys;
101: }
102:
103: public List getIndices() {
104: return indices;
105: }
106:
107: public List getExportedKeys() {
108: return exportedKeys;
109: }
110:
111: public List getPrimaryKeys() {
112: return primaryKeys;
113: }
114:
115: public boolean accept(Visitor visitor) {
116: if (!visitor.visit(this )) {
117: return false;
118: }
119:
120: new CollectionVisitable(tableColumns, false).accept(visitor);
121: new CollectionVisitable(indices, false).accept(visitor);
122: new CollectionVisitable(importedKeys, false).accept(visitor);
123: new CollectionVisitable(exportedKeys, false).accept(visitor);
124: //new CollectionVisitable(primaryKeys, false).accept(visitor);
125:
126: return true;
127: }
128:
129: /**
130: * Loads columns, indices, keys
131: */
132: public void setSQLProcessor(SQLProcessor processor)
133: throws SQLException {
134: MetadataEngine engine = new MetadataEngine(processor);
135: engine.getDbmColumnByTable(getId(), tableColumns, Column.class);
136: Iterator it = tableColumns.iterator();
137: while (it.hasNext()) {
138: Column column = (Column) it.next();
139: column.setOwner(this );
140: }
141: }
142:
143: void loadMetaData(DatabaseMetaData metaData) throws SQLException {
144: Catalog catalog = owner.getOwner();
145: ResultSet rs = metaData.getTables(catalog.getName(), owner
146: .getName(), getName(), null);
147: if (rs.next()) {
148: ResultSetMetaData rsmd = rs.getMetaData();
149: for (int i = 1; i <= rsmd.getColumnCount(); ++i) {
150: this .metaData.put(rsmd.getColumnName(i), rs
151: .getObject(i));
152: }
153: }
154: rs.close();
155:
156: Iterator it = tableColumns.iterator();
157: while (it.hasNext()) {
158: Column column = (Column) it.next();
159: if (!column.loadMetaData(metaData)) { // Don't use columns not found in the DB (orphans).
160: it.remove();
161: }
162: }
163:
164: ResultSet pkSet = metaData.getPrimaryKeys(catalog.getName(),
165: owner.getName(), getName());
166: ResultSetMetaData pkSetMeta = pkSet.getMetaData();
167: Set pkSetColumns = new HashSet();
168: for (int i = 1, l = pkSetMeta.getColumnCount(); i <= l; ++i) {
169: pkSetColumns.add(pkSetMeta.getColumnName(i));
170: }
171: while (pkSet.next()) {
172: Map metaMap = new HashMap();
173: Iterator pit = pkSetColumns.iterator();
174: while (pit.hasNext()) {
175: String cName = (String) pit.next();
176: metaMap.put(cName, pkSet.getString(cName));
177: }
178: primaryKeys.add(metaMap);
179: }
180: pkSet.close();
181: }
182:
183: private Schema owner;
184:
185: public Schema getOwner() {
186: return owner;
187: }
188:
189: void setOwner(Schema owner) {
190: this .owner = owner;
191: }
192:
193: private Map metaData = new HashMap();
194:
195: public Object getMetaValue(String name) {
196: return metaData.get(name);
197: }
198:
199: public void toDom(Element holder) {
200: super .toDom(holder);
201: CompositeDomSerializer ds = CompositeDomSerializer
202: .getThreadInstance();
203: if (metaData != null) {
204: ds.toDomSerializable(metaData).toDom(
205: AbstractDomObject.addElement(holder, "meta-data"));
206: }
207:
208: AbstractDomObject.addTextElement(holder, "java-name",
209: getJavaName());
210: AbstractDomObject.addTextElement(holder, "label", getLabel());
211:
212: Schema schema = getOwner();
213: if (schema.getName() != null
214: && schema.getName().trim().length() > 0) {
215: holder.setAttribute("schema", schema.getName());
216: }
217:
218: Catalog catalog = schema.getOwner();
219: if (catalog.getName() != null
220: && catalog.getName().trim().length() > 0) {
221: holder.setAttribute("catalog", catalog.getName());
222: }
223:
224: holder.setAttribute("sql-processor", catalog.getSqlProcessor());
225:
226: ds.toDomSerializable(tableColumns).toDom(
227: AbstractDomObject.addElement(holder, "columns"));
228: ds.toDomSerializable(exportedKeys).toDom(
229: AbstractDomObject.addElement(holder, "exported-keys"));
230: ds.toDomSerializable(importedKeys).toDom(
231: AbstractDomObject.addElement(holder, "imported-keys"));
232: ds.toDomSerializable(indices).toDom(
233: AbstractDomObject.addElement(holder, "indices"));
234: ds.toDomSerializable(primaryKeys).toDom(
235: AbstractDomObject.addElement(holder, "primary-keys"));
236:
237: }
238:
239: // TODO - Method to set JDBC metadata stuff.
240:
241: public String getJavaName() {
242: String ret = super .getJavaName();
243: return ret == null || ret.trim().length() == 0 ? getOwner()
244: .getOwner().getOwner().getGenerationPolicy()
245: .generateColumnName(getName()) : ret;
246: }
247:
248: public String getLabel() {
249: String ret = super .getLabel();
250: return ret == null || ret.trim().length() == 0 ? getOwner()
251: .getOwner().getOwner().getGenerationPolicy()
252: .generateLabel(getJavaName()) : ret;
253: }
254:
255: private InteractionInstance interactionInstance;
256:
257: public void setInteractionInstance(
258: InteractionInstance interactionInstance) {
259: this .interactionInstance = interactionInstance;
260: }
261:
262: public InteractionInstance getInteractionInstance() {
263: return interactionInstance;
264: }
265:
266: /**
267: * @param viewName
268: * @return true if given view was selected for generation in the interaction.
269: * @throws SQLException
270: */
271: public boolean hasView(String viewName) throws SQLException {
272: if (interactionInstance != null) {
273: Iterator it = interactionInstance.getStepsByDefinitionName(
274: "Select views").iterator();
275: while (it.hasNext()) {
276: StepInstance step = (StepInstance) it.next();
277: if ("completed".equals(step.getStatus())) {
278: String views = (String) step.getProperty("views");
279: if (views != null) {
280: StringTokenizer st = new StringTokenizer(views,
281: ",");
282: while (st.hasMoreTokens()) {
283: if (viewName.equals(st.nextToken().trim())) {
284: return true;
285: }
286: }
287: }
288: }
289: }
290: }
291: return false;
292: }
293:
294: /**
295: * @param viewName
296: * @return Ordered list of columns for given view.
297: * @throws SQLException
298: */
299: public List getViewColumns(String viewName) throws SQLException {
300: List ret = new ArrayList();
301: if (interactionInstance != null) {
302: Iterator it = interactionInstance.getStepsByDefinitionName(
303: "Order columns").iterator();
304: while (it.hasNext()) {
305: StepInstance step = (StepInstance) it.next();
306: if ("completed".equals(step.getStatus())
307: && viewName
308: .equals(step.getProperty("viewName"))) {
309: String columns = (String) step
310: .getProperty("columns");
311: if (columns != null) {
312: StringTokenizer st = new StringTokenizer(
313: columns, ",");
314: while (st.hasMoreTokens()) {
315: int cId = Integer.parseInt(st.nextToken()
316: .trim());
317: Iterator cit = tableColumns.iterator();
318: while (cit.hasNext()) {
319: Column c = (Column) cit.next();
320: if (c.getId() == cId) {
321: ret.add(c);
322: break;
323: }
324: }
325: }
326: }
327: }
328: }
329: }
330:
331: return ret;
332: }
333:
334: public String getFullName() {
335: String ownerName = getOwner() == null ? null : owner.getName();
336: return ActionsBase.isBlank(ownerName) ? getName() : ownerName
337: + "." + getName();
338: }
339: }
|