001: /*
002: * sqlc 1
003: * SQL Compiler
004: * Copyright (C) 2003 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/products/sqlc/index.html
021: * e-Mail: support@hammurapi.biz
022: */
023: package biz.hammurapi.sql.metadata;
024:
025: import java.io.Serializable;
026: import java.util.ArrayList;
027: import java.util.Collection;
028: import java.util.Collections;
029: import java.util.Comparator;
030: import java.util.HashMap;
031: import java.util.HashSet;
032: import java.util.Iterator;
033: import java.util.LinkedList;
034: import java.util.List;
035: import java.util.Map;
036: import java.util.Set;
037:
038: import biz.hammurapi.util.Visitable;
039: import biz.hammurapi.util.VisitableBase;
040: import biz.hammurapi.util.Visitor;
041:
042: /**
043: * @author Pavel Vlasov
044: * @version $Revision: 1.6 $
045: */
046: public class TableDescriptor extends VisitableBase implements
047: Serializable {
048: /**
049: * Comment for <code>serialVersionUID</code>
050: */
051: private static final long serialVersionUID = -8916715876656407677L;
052: private String catalog;
053: private String schema;
054: private String tableName;
055:
056: private String entityType;
057: private String factoryType;
058: private String pkType;
059: private String valueType;
060:
061: private String entityImplType;
062: private String factoryImplType;
063: private String pkImplType;
064: private String valueImplType;
065:
066: private Collection columnDescriptors = new ArrayList();
067: Map columnDescriptorsMap = new HashMap();
068:
069: private Map importedKeys = new HashMap();
070: private Map exportedKeys = new HashMap();
071:
072: private Collection primaryKey = new ArrayList();
073: private List normalizedPrimaryKey;
074:
075: private Set javaNames = new HashSet();
076: private Metadata metadata;
077:
078: TableDescriptor(Metadata metadata) {
079: this .metadata = metadata;
080: }
081:
082: Map indices = new HashMap();
083:
084: public Collection getIndices() {
085: return indices.values();
086: }
087:
088: /**
089: * @param columnDescriptor
090: */
091: public void add(ColumnDescriptor columnDescriptor) {
092: columnDescriptorsMap.put(columnDescriptor.getDbName(),
093: columnDescriptor);
094: columnDescriptors.add(columnDescriptor);
095: getJavaNames().add(columnDescriptor.getName());
096: }
097:
098: /**
099: * @param ikd
100: */
101: public void addImportedKey(KeyDescriptor ikd) {
102: getImportedKeys().put(ikd.getDbName(), ikd);
103: getJavaNames().add(ikd.getName());
104: }
105:
106: /**
107: * @param ikd
108: */
109: public void addExportedKey(KeyDescriptor ekd) {
110: getExportedKeys().put(ekd.getDbName(), ekd);
111: getJavaNames().add(ekd.getName());
112: }
113:
114: String fixJavaName(String name) {
115: if (name == null) {
116: return null;
117: }
118:
119: if (!Character.isJavaIdentifierStart(name.charAt(0))) {
120: name = "a" + name;
121: }
122: String ret = name;
123: int i = 0;
124: while (getJavaNames().contains(ret)) {
125: ret = name + "_"
126: + Integer.toString(i++, Character.MAX_RADIX);
127: }
128: return ret;
129: }
130:
131: public Collection getNormalizedPK() {
132: if (getNormalizedPrimaryKey() == null) {
133: normalizedPrimaryKey = new LinkedList(getPrimaryKey());
134: if (getNormalizedPrimaryKey().isEmpty()) {
135: Iterator acit = columnDescriptors.iterator();
136: for (int i = 0; acit.hasNext(); i++) {
137: KeyEntry ke = new KeyEntry(this );
138: ke.setColumnName(((ColumnDescriptor) acit.next())
139: .getDbName());
140: ke.setColumnSequence(i);
141: getNormalizedPrimaryKey().add(ke);
142: }
143: }
144:
145: if (!getNormalizedPrimaryKey().isEmpty()) {
146: List fkCandidates = new ArrayList();
147: Iterator iikit = getImportedKeys().values().iterator();
148: Y: while (iikit.hasNext()) {
149: KeyDescriptor ckd = (KeyDescriptor) iikit.next();
150: Iterator ckdit = ckd.getColumns().iterator();
151: Z: while (ckdit.hasNext()) {
152: KeyEntry fke = (KeyEntry) ckdit.next();
153: Iterator pkmit = getNormalizedPrimaryKey()
154: .iterator();
155: while (pkmit.hasNext()) {
156: KeyEntry pke = (KeyEntry) pkmit.next();
157: if (fke.getColumnName().equals(
158: pke.getColumnName())) {
159: continue Z;
160: }
161: }
162: continue Y;
163: }
164: fkCandidates.add(ckd);
165: }
166:
167: Collections.sort(fkCandidates, new Comparator() {
168: public int compare(Object o1, Object o2) {
169: return ((KeyDescriptor) o2).getColumns().size()
170: - ((KeyDescriptor) o1).getColumns()
171: .size();
172: }
173: });
174:
175: Iterator candidatesIterator = fkCandidates.iterator();
176: W: while (candidatesIterator.hasNext()) {
177: KeyDescriptor ckd = (KeyDescriptor) candidatesIterator
178: .next();
179: Iterator ckdit = ckd.getColumns().iterator();
180: Z: while (ckdit.hasNext()) {
181: KeyEntry fke = (KeyEntry) ckdit.next();
182: Iterator pkmit = getNormalizedPrimaryKey()
183: .iterator();
184: while (pkmit.hasNext()) {
185: Object next = pkmit.next();
186: if (next instanceof KeyEntry) {
187: KeyEntry pke = (KeyEntry) next;
188: if (fke.getColumnName().equals(
189: pke.getColumnName())) {
190: continue Z;
191: }
192: }
193: }
194: continue W;
195: }
196:
197: ckdit = ckd.getColumns().iterator();
198: while (ckdit.hasNext()) {
199: KeyEntry fke = (KeyEntry) ckdit.next();
200: Iterator pkmit = getNormalizedPrimaryKey()
201: .iterator();
202: while (pkmit.hasNext()) {
203: Object next = pkmit.next();
204: if (next instanceof KeyEntry) {
205: KeyEntry pke = (KeyEntry) next;
206: if (fke.getColumnName().equals(
207: pke.getColumnName())) {
208: pkmit.remove();
209: }
210: }
211: }
212: }
213: getNormalizedPrimaryKey().add(ckd);
214: }
215:
216: Collections.sort(getNormalizedPrimaryKey(),
217: new Comparator() {
218:
219: public int compare(Object o1, Object o2) {
220: return col(o1) - col(o2);
221: }
222:
223: private int col(Object o) {
224: if (o instanceof KeyEntry) {
225: return colPosition(o);
226: }
227:
228: int ret = Integer.MAX_VALUE;
229: KeyDescriptor kd = (KeyDescriptor) o;
230: Iterator it = kd.getColumns()
231: .iterator();
232: while (it.hasNext()) {
233: ret = Math.min(ret, colPosition(it
234: .next()));
235: }
236: return ret;
237: }
238:
239: /**
240: * @param td
241: * @param colName
242: * @return
243: */
244: private int colPosition(Object o) {
245: return ((ColumnDescriptor) columnDescriptorsMap
246: .get(((KeyEntry) o)
247: .getColumnName()))
248: .getPosition();
249: }
250:
251: });
252: }
253: }
254: return getNormalizedPrimaryKey();
255: }
256:
257: public String getPkType() {
258: if (getNormalizedPK().size() == 1) {
259: Object o = getNormalizedPK().iterator().next();
260: if (o instanceof KeyEntry) {
261: pkType = ((ColumnDescriptor) columnDescriptorsMap
262: .get(((KeyEntry) o).getColumnName())).getType();
263: } else {
264: pkType = ((KeyDescriptor) o).getType();
265: }
266: } else if (getPrimaryKey().size() == columnDescriptors.size()) {
267: pkType = null;
268: }
269: return pkType;
270: }
271:
272: public String getKeyType(Object o) {
273: if (o instanceof KeyEntry) {
274: return ((ColumnDescriptor) columnDescriptorsMap
275: .get(((KeyEntry) o).getColumnName())).getType();
276: }
277:
278: return ((KeyDescriptor) o).getType();
279: }
280:
281: public String getKeyName(Object o) {
282: if (o instanceof KeyEntry) {
283: return ((ColumnDescriptor) columnDescriptorsMap
284: .get(((KeyEntry) o).getColumnName())).getName();
285: }
286:
287: return ((KeyDescriptor) o).getName();
288: }
289:
290: /**
291: * @return
292: */
293: public String getName() {
294: StringBuffer ret = new StringBuffer();
295: if (getCatalog() != null) {
296: ret.append(getCatalog());
297: ret.append(".");
298: }
299: if (getSchema() != null) {
300: ret.append(getSchema());
301: ret.append(".");
302: }
303: return ret.append(getTableName()).toString();
304: }
305:
306: public Metadata getMetadata() {
307: return metadata;
308: }
309:
310: /**
311: * @param entityType The entityType to set.
312: */
313: public void setEntityType(String entityType) {
314: this .entityType = entityType;
315: }
316:
317: /**
318: * @return Returns the entityType.
319: */
320: public String getEntityType() {
321: return entityType;
322: }
323:
324: /**
325: * @param columnDescriptors The columnDescriptors to set.
326: */
327: public void setColumnDescriptors(Collection columnDescriptors) {
328: this .columnDescriptors = columnDescriptors;
329: }
330:
331: /**
332: * @return Returns the columnDescriptors.
333: */
334: public Collection getColumnDescriptors() {
335: return columnDescriptors;
336: }
337:
338: /**
339: * @param id
340: */
341: public void addIndex(IndexDescriptor id) {
342: indices.put(id.getName(), id);
343: }
344:
345: public void acceptChildren(Visitor visitor) {
346: Iterator it = columnDescriptors.iterator();
347: while (it.hasNext()) {
348: visitor.visit(it.next());
349: }
350:
351: it = indices.values().iterator();
352: while (it.hasNext()) {
353: ((Visitable) it.next()).accept(visitor);
354: }
355:
356: it = importedKeys.values().iterator();
357: while (it.hasNext()) {
358: ((Visitable) it.next()).accept(visitor);
359: }
360:
361: it = exportedKeys.values().iterator();
362: while (it.hasNext()) {
363: ((Visitable) it.next()).accept(visitor);
364: }
365: }
366:
367: /**
368: * @param catalog The catalog to set.
369: */
370: public void setCatalog(String catalog) {
371: this .catalog = catalog;
372: }
373:
374: /**
375: * @return Returns the catalog.
376: */
377: public String getCatalog() {
378: return catalog;
379: }
380:
381: /**
382: * @param schema The schema to set.
383: */
384: public void setSchema(String schema) {
385: this .schema = schema;
386: }
387:
388: /**
389: * @return Returns the schema.
390: */
391: public String getSchema() {
392: return schema;
393: }
394:
395: /**
396: * @param tableName The tableName to set.
397: */
398: public void setTableName(String tableName) {
399: this .tableName = tableName;
400: }
401:
402: /**
403: * @return Returns the tableName.
404: */
405: public String getTableName() {
406: return tableName;
407: }
408:
409: /**
410: * @param factoryType The factoryType to set.
411: */
412: public void setFactoryType(String factoryType) {
413: this .factoryType = factoryType;
414: }
415:
416: /**
417: * @return Returns the factoryType.
418: */
419: public String getFactoryType() {
420: return factoryType;
421: }
422:
423: public void setPkType(String pkType) {
424: this .pkType = pkType;
425:
426: }
427:
428: /**
429: * @param valueType The valueType to set.
430: */
431: public void setValueType(String valueType) {
432: this .valueType = valueType;
433: }
434:
435: /**
436: * @return Returns the valueType.
437: */
438: public String getValueType() {
439: return valueType;
440: }
441:
442: /**
443: * @param entityImplType The entityImplType to set.
444: */
445: public void setEntityImplType(String entityImplType) {
446: this .entityImplType = entityImplType;
447: }
448:
449: /**
450: * @return Returns the entityImplType.
451: */
452: public String getEntityImplType() {
453: return entityImplType;
454: }
455:
456: /**
457: * @param factoryImplType The factoryImplType to set.
458: */
459: public void setFactoryImplType(String factoryImplType) {
460: this .factoryImplType = factoryImplType;
461: }
462:
463: /**
464: * @return Returns the factoryImplType.
465: */
466: public String getFactoryImplType() {
467: return factoryImplType;
468: }
469:
470: /**
471: * @param pkImplType The pkImplType to set.
472: */
473: public void setPkImplType(String pkImplType) {
474: this .pkImplType = pkImplType;
475: }
476:
477: /**
478: * @return Returns the pkImplType.
479: */
480: public String getPkImplType() {
481: return pkImplType;
482: }
483:
484: /**
485: * @param valueImplType The valueImplType to set.
486: */
487: void setValueImplType(String valueImplType) {
488: this .valueImplType = valueImplType;
489: }
490:
491: /**
492: * @return Returns the valueImplType.
493: */
494: String getValueImplType() {
495: return valueImplType;
496: }
497:
498: /**
499: * @return Returns the importedKeys.
500: */
501: public Map getImportedKeys() {
502: return importedKeys;
503: }
504:
505: /**
506: * @return Returns the exportedKeys.
507: */
508: public Map getExportedKeys() {
509: return exportedKeys;
510: }
511:
512: /**
513: * @return Returns the primaryKey.
514: */
515: public Collection getPrimaryKey() {
516: return primaryKey;
517: }
518:
519: /**
520: * @return Returns the normalizedPrimaryKey.
521: */
522: List getNormalizedPrimaryKey() {
523: return normalizedPrimaryKey;
524: }
525:
526: /**
527: * @return Returns the javaNames.
528: */
529: Set getJavaNames() {
530: return javaNames;
531: }
532:
533: public String toString() {
534: return getCatalog() + "." + getSchema() + "." + getName();
535: }
536: }
|