001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.sql.framework.model.impl;
042:
043: import java.util.ArrayList;
044: import java.util.Collection;
045: import java.util.Collections;
046: import java.util.Comparator;
047: import java.util.Iterator;
048: import java.util.List;
049:
050: import org.netbeans.modules.sql.framework.model.DBColumn;
051: import org.netbeans.modules.sql.framework.common.utils.TagParserUtility;
052: import org.netbeans.modules.sql.framework.model.GUIInfo;
053: import org.netbeans.modules.sql.framework.model.SQLCondition;
054: import org.netbeans.modules.sql.framework.model.SQLConstants;
055: import org.netbeans.modules.sql.framework.model.SQLDBModel;
056: import org.netbeans.modules.sql.framework.model.SQLDefinition;
057: import org.netbeans.modules.sql.framework.model.SQLModelObjectFactory;
058: import org.netbeans.modules.sql.framework.model.SQLObject;
059: import org.netbeans.modules.sql.framework.model.SourceColumn;
060: import org.netbeans.modules.sql.framework.model.SourceTable;
061: import org.netbeans.modules.sql.framework.model.utils.ConditionUtil;
062: import org.netbeans.modules.sql.framework.model.utils.SQLObjectUtil;
063: import org.netbeans.modules.sql.framework.model.visitors.SQLVisitor;
064: import org.w3c.dom.Element;
065: import org.w3c.dom.Node;
066: import org.w3c.dom.NodeList;
067:
068: import com.sun.sql.framework.exception.BaseException;
069: import org.netbeans.modules.sql.framework.model.DBTable;
070: import org.netbeans.modules.sql.framework.model.SQLGroupBy;
071:
072: /**
073: * Concrete implementation of SourceTable and SQLConnectableObject classes / interfaces,
074: * representing table metadata and linking information for a target table.
075: *
076: * @author Jonathan Giron
077: * @version $Revision$
078: */
079: public class SourceTableImpl extends AbstractDBTable implements
080: SourceTable {
081:
082: /* Log4J category string */
083: static final String LOG_CATEGORY = AbstractDBTable.class.getName();
084:
085: private static final String ATTR_BATCHSIZE = "batchSize";
086:
087: private static final String ATTR_DROP_STAGING_TABLE = "deleteTemporaryTable";
088:
089: private static final String ATTR_FULLY_QUALIFIED_NAME = "fullyQualifiedName";
090: private static final String ATTR_TRUNCATE_STAGING_TABLE = "tuncateStagingTable";
091:
092: private static final String ATTR_DISTINCT = "distinct";
093:
094: private static final String ATTR_EXTRACTION_TYPE = "extractionType";
095:
096: private static final String ATTR_TEMPORARY_TABLE_NAME = "temporaryTableName";
097:
098: private static final String ATTR_USED_IN_JOIN = "usedInJoin";
099:
100: private SQLCondition dataValidationCondition;
101:
102: private SQLCondition extractionCondition;
103:
104: private SQLGroupBy groupBy;
105:
106: /** No-arg constructor; initializes Collections-related member variables. */
107: public SourceTableImpl() {
108: super ();
109: init();
110: }
111:
112: /**
113: * Creates a new instance of AbstractDBTable, cloning the contents of the given
114: * DBTable implementation instance.
115: *
116: * @param src DBTable instance to be cloned
117: */
118: public SourceTableImpl(DBTable src) {
119: this ();
120:
121: if (src == null) {
122: throw new IllegalArgumentException(
123: "Must supply non-null DBTable instance for src param.");
124: }
125: copyFrom(src);
126: }
127:
128: /**
129: * Creates a new instance of AbstractDBTable with the given name.
130: *
131: * @param aName name of new DBTable instance
132: * @param aSchema schema of new DBTable instance; may be null
133: * @param aCatalog catalog of new DBTable instance; may be null
134: */
135: public SourceTableImpl(String aName, String aSchema, String aCatalog) {
136: super (aName, aSchema, aCatalog);
137: init();
138: }
139:
140: /*
141: * Setters and non-API helper methods for this implementation.
142: */
143:
144: /**
145: * Adds an AbstractDBColumn instance to this table.
146: *
147: * @param theColumn column to be added.
148: * @return true if successful. false if failed.
149: */
150: public boolean addColumn(SourceColumn theColumn) {
151: if (theColumn != null) {
152: theColumn.setParent(this );
153: columns.put(theColumn.getName(), theColumn);
154: return true;
155: }
156:
157: return false;
158: }
159:
160: /**
161: * Clone a deep copy of SourceTableImpl
162: *
163: * @return a copy of SourceTableImpl
164: */
165: public Object clone() {
166: try {
167: SourceTableImpl aClone = new SourceTableImpl(this );
168: return aClone;
169: } catch (Exception e) {
170: throw new InternalError(e.toString());
171: }
172: }
173:
174: /**
175: * Sets the various member variables and collections using the given DBTable instance
176: * as a source object. Concrete implementations should override this method, call
177: * super.copyFrom(DBColumn) to pick up member variables defined in this class and then
178: * implement its own logic for copying member variables defined within itself.
179: *
180: * @param source DBTable from which to obtain values for member variables and
181: * collections
182: */
183: public void copyFrom(DBTable source) {
184: super .copyFrom(source);
185:
186: List sourceColumns = source.getColumnList();
187: if (sourceColumns != null) {
188: Iterator iter = sourceColumns.iterator();
189:
190: // Must do deep copy to ensure correct parent-child relationship.
191: while (iter.hasNext()) {
192: addColumn(new SourceColumnImpl((DBColumn) iter.next()));
193: }
194: }
195:
196: if (source instanceof SourceTableImpl) {
197: SourceTableImpl sTable = (SourceTableImpl) source;
198: extractionCondition = sTable.getExtractionCondition();
199: setExtractionConditionText(sTable
200: .getExtractionConditionText());
201: dataValidationCondition = sTable
202: .getDataValidationCondition();
203: }
204:
205: if (source instanceof SourceTable) {
206: SQLGroupBy grpBy = ((SourceTable) source).getSQLGroupBy();
207: if (grpBy != null) {
208: groupBy = new SQLGroupByImpl(grpBy);
209: }
210: }
211: }
212:
213: /**
214: * Convenience class to create SourceColumn instance (with the given column name, data
215: * source name, JDBC type, scale, precision, and nullable), and add it to this
216: * SourceTableImpl instance.
217: *
218: * @param columnName Column name
219: * @param jdbcType JDBC type defined in SQL.Types
220: * @param scale Scale
221: * @param precision Precision
222: * @param isPK true if part of primary key, false otherwise
223: * @param isFK true if part of foreign key, false otherwise
224: * @param isIndexed true if indexed, false otherwise
225: * @param nullable Nullable
226: * @return new DBColumnImpl instance
227: */
228: public SourceColumn createColumn(String columnName, int jdbcType,
229: int scale, int precision, boolean isPK, boolean isFK,
230: boolean isIndexed, boolean nullable) {
231: SourceColumn impl = new SourceColumnImpl(columnName, jdbcType,
232: scale, precision, isPK, isFK, isIndexed, nullable);
233: impl.setParent(this );
234: columns.put(columnName, impl);
235:
236: return impl;
237: }
238:
239: /**
240: * Overrides default implementation to return value based on memberwise comparison.
241: *
242: * @param obj Object against which we compare this instance
243: * @return true if obj is functionally identical to this SQLTable instance; false
244: * otherwise
245: */
246: public boolean equals(Object obj) {
247: // Check for reflexivity first.
248: if (this == obj) {
249: return true;
250: } else if (!(obj instanceof SourceTable)) {
251: return false;
252: }
253:
254: boolean result = super .equals(obj);
255: SourceTable src = (SourceTable) obj;
256:
257: result &= (extractionCondition != null) ? extractionCondition
258: .equals(src.getExtractionCondition()) : (src
259: .getExtractionCondition() == null);
260:
261: result &= (dataValidationCondition != null) ? dataValidationCondition
262: .equals(src.getDataValidationCondition())
263: : (src.getDataValidationCondition() == null);
264:
265: return result;
266: }
267:
268: /**
269: * set the data validation condition.
270: *
271: * @param condition data validation condition
272: */
273: public SQLCondition getDataValidationCondition() {
274: return dataValidationCondition;
275: }
276:
277: /**
278: * Gets the Validation conidition text.
279: *
280: * @return sql condition
281: */
282: public String getDataValidationConditionText() {
283: if (this .dataValidationCondition != null) {
284: return this .dataValidationCondition.getConditionText();
285: }
286: return "";
287: }
288:
289: /**
290: * Gets the extraction condition.
291: *
292: * @return filter to apply while doing extraction
293: */
294: public SQLCondition getExtractionCondition() {
295: // if there are no objects in graph then populate graph with the objects
296: // obtained from sql text
297: Collection objC = extractionCondition.getAllObjects();
298: if (objC == null || objC.size() == 0) {
299: SQLDefinition def = SQLObjectUtil
300: .getAncestralSQLDefinition(this );
301: try {
302: ConditionUtil.populateCondition(extractionCondition,
303: def, this .getExtractionConditionText());
304: } catch (Exception ex) {
305: // ignore this if condition typed by user is invalid
306: }
307: }
308:
309: return extractionCondition;
310: }
311:
312: /**
313: * Gets the extraction conidition text.
314: *
315: * @return sql condition
316: */
317: public String getExtractionConditionText() {
318: return this .extractionCondition.getConditionText();
319: }
320:
321: /**
322: * Gets extraction type.
323: *
324: * @return extraction type
325: */
326: public String getExtractionType() {
327: return (String) this .getAttributeObject(ATTR_EXTRACTION_TYPE);
328: }
329:
330: /**
331: * Overrides parent implementation to return SourceColumn, if any, that corresponds to
332: * the given argument name.
333: *
334: * @param argName argument name of linkable SQLObject
335: * @return linkable SQLObject corresponding to argName
336: * @throws BaseException if argName is null
337: * @see SQLObject#getOutput(java.lang.String)
338: */
339: public SQLObject getOutput(String argName) throws BaseException {
340: if (argName == null) {
341: throw new BaseException(
342: "Must supply non-empty String value for parameter 'argName'.");
343: }
344:
345: SQLObject column = (SQLObject) columns.get(argName);
346: return (column == null) ? this : column;
347: }
348:
349: /**
350: * Gets the SourceColumn, if any, associated with the given name
351: *
352: * @param columnName column name
353: * @return SourceColumn associated with columnName, or null if none exists
354: */
355: public SourceColumn getSourceColumn(String columnName) {
356: return (SourceColumn) columns.get(columnName);
357: }
358:
359: /**
360: * Gets temporary table name.
361: *
362: * @return temp table name
363: */
364: public String getTemporaryTableName() {
365: // If the Staging Table Name is set, return it.
366: if (getStagingTableName().length() != 0) {
367: return (String) getStagingTableName();
368: } else {
369: return (String) this
370: .getAttributeObject(ATTR_TEMPORARY_TABLE_NAME);
371: }
372: }
373:
374: /**
375: * @see org.netbeans.modules.sql.framework.model.SourceTable#getSQLGroupBy()
376: */
377: public SQLGroupBy getSQLGroupBy() {
378: return groupBy;
379: }
380:
381: /**
382: * Overrides default implementation to compute hashCode value for those members used
383: * in equals() for comparison.
384: *
385: * @return hash code for this object
386: * @see java.lang.Object#hashCode
387: */
388: public int hashCode() {
389: return super .hashCode()
390: + ((extractionCondition != null) ? extractionCondition
391: .hashCode() : 0)
392: + ((getExtractionConditionText() != null) ? getExtractionConditionText()
393: .hashCode()
394: : 0)
395: + ((getDataValidationCondition() != null) ? getDataValidationCondition()
396: .hashCode()
397: : 0);
398: }
399:
400: /**
401: * Indicates whether to delete temporary table before extraction.
402: *
403: * @return delete whether to delete temp table
404: */
405: public boolean isDropStagingTable() {
406: Boolean delete = (Boolean) this
407: .getAttributeObject(ATTR_DROP_STAGING_TABLE);
408: if (delete != null) {
409: return delete.booleanValue();
410: }
411:
412: return true;
413: }
414:
415: /**
416: * Indicates whether distinct rows of a column need to be selected.
417: *
418: * @return distinct
419: */
420: public boolean isSelectDistinct() {
421: Boolean distinct = (Boolean) this
422: .getAttributeObject(ATTR_DISTINCT);
423: if (distinct != null) {
424: return distinct.booleanValue();
425: }
426:
427: return false;
428: }
429:
430: /**
431: * Indicates whether this table is used in a join view.
432: *
433: * @return boolean
434: */
435: public boolean isUsedInJoin() {
436: Boolean used = (Boolean) this
437: .getAttributeObject(SourceTableImpl.ATTR_USED_IN_JOIN);
438: if (used != null) {
439: return used.booleanValue();
440: }
441:
442: return false;
443: }
444:
445: /**
446: * Parses elements which require a second pass to resolve their values.
447: *
448: * @param element DOM element containing XML marshalled version of this SQLObject
449: * instance
450: * @throws BaseException if element is null or error occurs during parsing
451: */
452: public void secondPassParse(Element element) throws BaseException {
453: }
454:
455: /**
456: * get the data validation condition.
457: *
458: * @return data validation condition.
459: */
460: public void setDataValidationCondition(SQLCondition condition) {
461: this .dataValidationCondition = condition;
462: if (this .dataValidationCondition != null) {
463: this .dataValidationCondition.setParent(this );
464: this .dataValidationCondition
465: .setDisplayName(SourceTable.DATA_VALIDATION_CONDITION);
466: }
467: }
468:
469: /**
470: * Sets the validation condition text.
471: *
472: * @param cond condition text
473: */
474: public void setDataValidationConditionText(String cond) {
475: if (this .extractionCondition != null) {
476: this .extractionCondition.setConditionText(cond);
477: }
478: }
479:
480: /**
481: * Set whether to delete temporary table before extraction.
482: *
483: * @param drop whether to delete temp table
484: */
485: public void setDropStagingTable(boolean drop) {
486: this .setAttribute(ATTR_DROP_STAGING_TABLE, new Boolean(drop));
487: }
488:
489: /**
490: * Set whether to delete temporary table before extraction.
491: *
492: * @param drop whether to delete temp table
493: */
494: public void setDropStagingTable(Boolean drop) {
495: this .setAttribute(ATTR_DROP_STAGING_TABLE, drop);
496: }
497:
498: /**
499: * Sets the extraction condition.
500: *
501: * @param condition condition
502: */
503: public void setExtractionCondition(SQLCondition condition) {
504: this .extractionCondition = condition;
505: if (this .extractionCondition != null) {
506: this .extractionCondition.setParent(this );
507: this .extractionCondition
508: .setDisplayName(SourceTable.EXTRACTION_CONDITION);
509: }
510: }
511:
512: /**
513: * Sets the extraction condition text.
514: *
515: * @param cond extraction condition text
516: */
517: public void setExtractionConditionText(String cond) {
518: this .extractionCondition.setConditionText(cond);
519: }
520:
521: /**
522: * Sets the extraction type.
523: *
524: * @param eType extraction type
525: */
526: public void setExtractionType(String eType) {
527: this .setAttribute(ATTR_EXTRACTION_TYPE, eType);
528: }
529:
530: /**
531: * Sets wehether to select distinct rows of a column.
532: *
533: * @param distinct distinct
534: */
535: public void setSelectDistinct(boolean distinct) {
536: this .setAttribute(ATTR_DISTINCT, new Boolean(distinct));
537: }
538:
539: /**
540: * Sets wehether to select distinct rows of a column.
541: *
542: * @param distinct distinct
543: */
544: public void setSelectDistinct(Boolean distinct) {
545: this .setAttribute(ATTR_DISTINCT, distinct);
546: }
547:
548: /**
549: * Sets the temporary table name.
550: *
551: * @param tName temp table name
552: */
553: public void setTemporaryTableName(String tName) {
554: this .setAttribute(SourceTableImpl.ATTR_TEMPORARY_TABLE_NAME,
555: tName);
556: }
557:
558: /**
559: * Sets whether this table is used in a join view.
560: *
561: * @param used boolean
562: */
563: public void setUsedInJoin(boolean used) {
564: this .setAttribute(ATTR_USED_IN_JOIN, new Boolean(used));
565: this .getGUIInfo().setVisible(!used);
566: }
567:
568: /**
569: * @see org.netbeans.modules.sql.framework.model.SourceTable#setSQLGroupBy(org.netbeans.modules.sql.framework.model.SQLGroupBy)
570: */
571: public void setSQLGroupBy(SQLGroupBy groupBy) {
572: this .groupBy = groupBy;
573: }
574:
575: /**
576: * Returns XML representation of table metadata.
577: *
578: * @param prefix prefix for the xml.
579: * @return XML representation of the table metadata.
580: * @exception BaseException - exception
581: */
582: public String toXMLString(String prefix) throws BaseException {
583: return toXMLString(prefix, false);
584: }
585:
586: /**
587: * Returns XML representation of table metadata.
588: *
589: * @param prefix prefix for the xml.
590: * @param tableOnly flag for generating table only metadata.
591: * @return XML representation of the table metadata.
592: * @exception BaseException - exception
593: */
594: public String toXMLString(String prefix, boolean tableOnly)
595: throws BaseException {
596: StringBuilder xml = new StringBuilder(INIT_XMLBUF_SIZE);
597:
598: xml.append(prefix).append("<").append(TABLE_TAG);
599: xml.append(" ").append(TABLE_NAME_ATTR).append("=\"").append(
600: name).append("\"");
601:
602: xml.append(" ").append(ID_ATTR).append("=\"").append(id)
603: .append("\"");
604:
605: if (displayName != null && displayName.trim().length() != 0) {
606: xml.append(" ").append(DISPLAY_NAME_ATTR).append("=\"")
607: .append(displayName).append("\"");
608: }
609:
610: if (schema != null && schema.trim().length() != 0) {
611: xml.append(" ").append(SCHEMA_NAME_ATTR).append("=\"")
612: .append(schema).append("\"");
613: }
614:
615: if (catalog != null && catalog.trim().length() != 0) {
616: xml.append(" ").append(CATALOG_NAME_ATTR).append("=\"")
617: .append(catalog).append("\"");
618: }
619:
620: xml.append(">\n");
621:
622: xml.append(toXMLAttributeTags(prefix));
623:
624: if (!tableOnly) {
625: writeColumns(prefix, xml);
626: writePrimaryKey(prefix, xml);
627: writeForeignKeys(prefix, xml);
628: writeIndices(prefix, xml);
629: }
630:
631: // write out extraction condition
632: if (extractionCondition != null) {
633: xml
634: .append(extractionCondition.toXMLString(prefix
635: + INDENT));
636: }
637:
638: // write out data validation condition
639: if (dataValidationCondition != null) {
640: xml.append(dataValidationCondition.toXMLString(prefix
641: + INDENT));
642: }
643:
644: // write out group by statement.
645: if (groupBy != null) {
646: xml.append(groupBy.toXMLString(prefix + INDENT));
647: }
648:
649: if (guiInfo != null) {
650: xml.append(guiInfo.toXMLString(prefix + INDENT));
651: }
652:
653: xml.append(prefix).append("</").append(TABLE_TAG).append(">\n");
654:
655: return xml.toString();
656: }
657:
658: public List validate() {
659: throw new UnsupportedOperationException(
660: "Use validation visitor framework to validate this object.");
661: }
662:
663: public void visit(SQLVisitor visitor) {
664: visitor.visit(this );
665: }
666:
667: /**
668: * @see org.netbeans.modules.sql.framework.model.impl.AbstractDBTable#getElementTagName
669: */
670: protected String getElementTagName() {
671: return TABLE_TAG;
672: }
673:
674: /**
675: * @see org.netbeans.modules.sql.framework.model.impl.AbstractDBTable#parseChildren
676: */
677: protected void parseChildren(NodeList childNodeList)
678: throws BaseException {
679: for (int i = 0; i < childNodeList.getLength(); i++) {
680: if (childNodeList.item(i).getNodeType() == Node.ELEMENT_NODE) {
681: Element childElement = (Element) childNodeList.item(i);
682: String tagName = childElement.getTagName();
683:
684: if (AbstractDBColumn.ELEMENT_TAG.equals(tagName)) {
685: SourceColumn columnInstance = new SourceColumnImpl();
686:
687: columnInstance.setParentObject(this );
688: columnInstance.parseXML(childElement);
689:
690: addColumn(columnInstance);
691: } else if (PrimaryKeyImpl.ELEMENT_TAG.equals(tagName)) {
692: PrimaryKeyImpl pkInstance = new PrimaryKeyImpl(
693: childElement);
694: pkInstance.parseXML();
695: setPrimaryKey(pkInstance);
696: } else if (ForeignKeyImpl.ELEMENT_TAG.equals(tagName)) {
697: ForeignKeyImpl fkInstance = new ForeignKeyImpl(
698: childElement);
699: fkInstance.parseXML();
700: addForeignKey(fkInstance);
701: } else if (IndexImpl.ELEMENT_TAG.equals(tagName)) {
702: IndexImpl indexInstance = new IndexImpl(
703: childElement);
704: indexInstance.parseXML();
705: addIndex(indexInstance);
706: } else if (TagParserUtility.TAG_OBJECTREF
707: .equals(tagName)) {
708: secondPassParse(childElement);
709: } else if (GUIInfo.TAG_GUIINFO.equals(tagName)) {
710: guiInfo = new GUIInfo(childElement);
711: } else if (SQLCondition.TAG_CONDITION.equals(tagName)) {
712: String conditionName = childElement
713: .getAttribute(SQLCondition.DISPLAY_NAME);
714:
715: if (conditionName != null
716: && conditionName
717: .equals(SourceTable.EXTRACTION_CONDITION)) {
718: SQLCondition exCondition = SQLModelObjectFactory
719: .getInstance().createSQLCondition(
720: EXTRACTION_CONDITION);
721: SQLDBModel parentDbModel = (SQLDBModel) this
722: .getParentObject();
723: if (parentDbModel != null) {
724: exCondition.setParent(this );
725: exCondition.parseXML(childElement);
726: this .setExtractionCondition(exCondition);
727: }
728: } else if (conditionName != null
729: && conditionName
730: .equals(SourceTable.DATA_VALIDATION_CONDITION)) {
731: SQLCondition dValidationCondition = SQLModelObjectFactory
732: .getInstance().createSQLCondition(
733: DATA_VALIDATION_CONDITION);
734: SQLDBModel parentDbModel = (SQLDBModel) this
735: .getParentObject();
736: if (parentDbModel != null) {
737: dValidationCondition.setParent(this );
738: dValidationCondition.parseXML(childElement);
739: this
740: .setDataValidationCondition(dValidationCondition);
741: }
742: }
743: } else if (SQLGroupByImpl.ELEMENT_TAG.equals(tagName)) {
744: groupBy = new SQLGroupByImpl();
745: groupBy.setParentObject(this );
746: groupBy.parseXML(childElement);
747: }
748: }
749: }
750: }
751:
752: /**
753: * Overrides parent implementation to also initialize locally-defined attributes.
754: */
755: protected void setDefaultAttributes() {
756: super .setDefaultAttributes();
757:
758: if (this
759: .getAttributeObject(SourceTableImpl.ATTR_EXTRACTION_TYPE) == null) {
760: setExtractionType(SQLConstants.EXTRACTION_CONDITIONAL);
761: }
762:
763: if (this .getAttributeObject(SourceTableImpl.ATTR_DISTINCT) == null) {
764: setSelectDistinct(false);
765: }
766:
767: if (this .getAttributeObject(ATTR_BATCHSIZE) == null) {
768: setBatchSize(5000);
769: }
770:
771: if (this .getAttributeObject(ATTR_DROP_STAGING_TABLE) == null) {
772: setDropStagingTable(true);
773: }
774:
775: }
776:
777: /**
778: * Write columns
779: *
780: * @param prefix - prefix
781: * @param xml - buffer
782: * @throws BaseException - exception
783: */
784: protected void writeColumns(String prefix, StringBuilder xml)
785: throws BaseException {
786: Comparator cmp = new AbstractDBTable.StringComparator();
787: // Ensure columns are written out in ascending name order.
788: List colList = new ArrayList(columns.keySet());
789: Collections.sort(colList, cmp);
790:
791: Iterator iter = colList.listIterator();
792: while (iter.hasNext()) {
793: String key = (String) iter.next();
794: SourceColumn column = (SourceColumn) columns.get(key);
795: xml.append(column.toXMLString(prefix + INDENT));
796: }
797: }
798:
799: /**
800: * Write foreign key
801: *
802: * @param prefix - prefix
803: * @param xml - buffer
804: */
805: protected void writeForeignKeys(String prefix, StringBuilder xml) {
806: Comparator cmp = new AbstractDBTable.StringComparator();
807: List fkNames = new ArrayList(foreignKeys.keySet());
808: Collections.sort(fkNames, cmp);
809: Iterator iter = fkNames.iterator();
810: while (iter.hasNext()) {
811: String key = (String) iter.next();
812: ForeignKeyImpl fk = (ForeignKeyImpl) foreignKeys.get(key);
813: xml.append(fk.toXMLString(prefix + INDENT));
814: }
815: }
816:
817: /**
818: * Write indices
819: *
820: * @param prefix - prefix
821: * @param xml - buffer
822: */
823: protected void writeIndices(String prefix, StringBuilder xml) {
824: Comparator cmp = new AbstractDBTable.StringComparator();
825: List indexNames = new ArrayList(indexes.keySet());
826: Collections.sort(indexNames, cmp);
827: Iterator iter = indexNames.iterator();
828: while (iter.hasNext()) {
829: String key = (String) iter.next();
830: IndexImpl index = (IndexImpl) indexes.get(key);
831: xml.append(index.toXMLString(prefix + INDENT));
832: }
833: }
834:
835: /**
836: * Write primary key
837: *
838: * @param prefix - prefix
839: * @param xml - buffer
840: */
841: protected void writePrimaryKey(String prefix, StringBuilder xml) {
842: if (primaryKey != null) {
843: xml.append(primaryKey.toXMLString(prefix + INDENT));
844: }
845: }
846:
847: /*
848: * Performs sql framework initialization functions for constructors which cannot first
849: * call this().
850: */
851: private void init() {
852: type = SQLConstants.SOURCE_TABLE;
853: setDefaultAttributes();
854: extractionCondition = SQLModelObjectFactory.getInstance()
855: .createSQLCondition(EXTRACTION_CONDITION);
856: setExtractionCondition(extractionCondition);
857:
858: dataValidationCondition = SQLModelObjectFactory.getInstance()
859: .createSQLCondition(DATA_VALIDATION_CONDITION);
860: setDataValidationCondition(dataValidationCondition);
861: }
862:
863: public boolean isTruncateStagingTable() {
864: Boolean truncate = (Boolean) this
865: .getAttributeObject(ATTR_TRUNCATE_STAGING_TABLE);
866: if (truncate != null) {
867: return truncate.booleanValue();
868: }
869:
870: return true;
871: }
872:
873: public boolean isUsingFullyQualifiedName() {
874: Boolean fullName = (Boolean) this
875: .getAttributeObject(ATTR_FULLY_QUALIFIED_NAME);
876: if (fullName != null) {
877: return fullName.booleanValue();
878: }
879: return true;
880: }
881:
882: public void setTruncateStagingTable(boolean truncate) {
883: this .setAttribute(ATTR_TRUNCATE_STAGING_TABLE, new Boolean(
884: truncate));
885: }
886:
887: public void setTruncateStagingTable(Boolean truncate) {
888: this .setAttribute(ATTR_TRUNCATE_STAGING_TABLE, truncate);
889: }
890:
891: public void setBatchSize(int newsize) {
892: this .setAttribute(ATTR_BATCHSIZE, new Integer(newsize));
893: }
894:
895: public void setBatchSize(Integer newsize) {
896: this .setAttribute(ATTR_BATCHSIZE, newsize);
897: }
898:
899: public void setUsingFullyQualifiedName(boolean usesFullName) {
900: this .setAttribute(ATTR_FULLY_QUALIFIED_NAME, new Boolean(
901: usesFullName));
902: }
903:
904: public void setUsingFullyQualifiedName(Boolean usesFullName) {
905: this.setAttribute(ATTR_FULLY_QUALIFIED_NAME, usesFullName);
906: }
907:
908: }
|