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.Collections;
045: import java.util.List;
046: import java.util.ListIterator;
047:
048: import org.netbeans.modules.sql.framework.model.DBColumn;
049: import org.w3c.dom.Element;
050:
051: import com.sun.sql.framework.exception.BaseException;
052: import com.sun.sql.framework.utils.StringUtil;
053: import java.sql.ResultSet;
054: import java.sql.SQLException;
055: import java.util.HashMap;
056: import java.util.Locale;
057: import java.util.Map;
058: import java.util.ResourceBundle;
059: import org.netbeans.modules.sql.framework.model.DBTable;
060: import org.netbeans.modules.sql.framework.model.ForeignKey;
061: import org.netbeans.modules.sql.framework.model.PrimaryKey;
062:
063: /**
064: * Implements ForeignKey interface.
065: *
066: * @author Jonathan Giron
067: * @version $Revision$
068: */
069: public class ForeignKeyImpl implements Cloneable, ForeignKey {
070:
071: /** Document element tag name for marshalling out this object to XML */
072: public static final String ELEMENT_TAG = "foreignKey"; // NOI18N
073: /** Name of attribute used for marshalling out FK column names to XML */
074: public static final String FK_COLUMNS_ATTR = "fkColumns"; // NOI18N
075: /** Name of attribute used for marshalling out FK name to XML */
076: public static final String FK_NAME_ATTR = "name"; // NOI18N
077: /** Name of attribute used for marshalling out catalog name of PK table to XML */
078: public static final String PK_CATALOG_ATTR = "pkCatalog"; // NOI18N
079: /** Name of attribute used for marshalling out PK column names to XML */
080: public static final String PK_COLUMNS_ATTR = "pkColumns"; // NOI18N
081: /** Name of attribute used for marshalling out deferrability rule to XML */
082: public static final String PK_DEFER_ATTR = "deferRule"; // NOI18N
083: /** Name of attribute used for marshalling out delete rule to XML */
084: public static final String PK_DELETE_ATTR = "deleteRule"; // NOI18N
085: /** Name of attribute used for marshalling out PK name to XML */
086: public static final String PK_NAME_ATTR = "pkName"; // NOI18N
087: /** Name of attribute used for marshalling out schema name of PK table to XML */
088: public static final String PK_SCHEMA_ATTR = "pkSchema"; // NOI18N
089: /** Name of attribute used for marshalling out PK table name to XML */
090: public static final String PK_TABLE_ATTR = "pkTable"; // NOI18N
091: /** Name of attribute used for marshalling out update rule to XML */
092: public static final String PK_UPDATE_ATTR = "updateRule"; // NOI18N
093: private static final String RS_PK_NAME = "PK_NAME"; // NOI18N
094: private static final String RS_PKCATALOG_NAME = "PKTABLE_CAT"; // NOI18N
095: private static final String RS_PKSCHEMA_NAME = "PKTABLE_SCHEM"; // NOI18N
096: private static final String RS_PKTABLE_NAME = "PKTABLE_NAME"; // NOI18N
097: private static final String RS_PKCOLUMN_NAME = "PKCOLUMN_NAME"; // NOI18N
098: private static final String RS_FK_NAME = "FK_NAME"; // NOI18N
099: private static final String RS_FKCOLUMN_NAME = "FKCOLUMN_NAME"; // NOI18N
100: private static final String RS_UPDATE_RULE = "UPDATE_RULE"; // NOI18N
101: private static final String RS_DELETE_RULE = "DELETE_RULE"; // NOI18N
102: private static final String RS_DEFERRABILITY = "DEFERRABILITY"; // NOI18N
103:
104: /*
105: * deferrability cascade rule; holds constant value as defined in
106: * java.sql.DatabaseMetaData
107: */
108: private int deferrability;
109:
110: /* delete cascade rule; holds constant value as defined in java.sql.DatabaseMetaData */
111: private int deleteRule;
112:
113: /* (optional) DOM element used to construct this instance of ForeignKey */
114: private transient Element element;
115:
116: /* List of column names for this foreign key in key sequence order. */
117: // TODO: Should it be a list ? -- Ahi
118: private List<String> fkColumnNames = new ArrayList<String>();
119:
120: /* Name of this key; may be null */
121: private String fkName;
122:
123: /* DBTable to which this PK belongs */
124: private DBTable parent;
125:
126: /* catalog name, if any, of PK table associated with this FK */
127: private String pkCatalog;
128:
129: /*
130: * List of column names of corresponding primary key columns, in key sequence order.
131: */
132: private List<String> pkColumnNames = new ArrayList<String>();
133:
134: /* Name of corresponding primary key; may be null */
135: private String pkName;
136:
137: /* schema name, if any, of PK table associated with this FK */
138: private String pkSchema;
139:
140: /* name of PK table associated with this FK */
141: private String pkTable;
142:
143: /* update cascade rule; holds constant value as defined in java.sql.DatabaseMetaData */
144: private int updateRule;
145:
146: /**
147: * Creates a List of ForeignKeyColumn instances from the given ResultSet.
148: *
149: * @param rs ResultSet containing foreign key metadata as obtained from
150: * DatabaseMetaData
151: * @return List of ForeignKeyColumn instances based from metadata in rs
152: *
153: * @throws SQLException if SQL error occurs while reading in data from
154: * given ResultSet
155: */
156: public static Map<String, ForeignKey> createForeignKeyColumnMap(
157: DBTable table, ResultSet rs) throws SQLException {
158: if (rs == null) {
159: Locale locale = Locale.getDefault();
160: ResourceBundle cMessages = ResourceBundle
161: .getBundle(
162: "org/netbeans/modules/sql/framework/model/impl/Bundle",
163: locale); // NO i18n
164: throw new IllegalArgumentException(cMessages
165: .getString("ERROR_NULL_RS")
166: + "(ERROR_NULL_RS)");
167: }
168:
169: Map<String, ForeignKey> fkColumns = new HashMap<String, ForeignKey>();
170: while (rs.next()) {
171: ForeignKeyImpl fk = (ForeignKeyImpl) fkColumns.get(rs
172: .getString(RS_FK_NAME));
173: if (fk != null) {
174: fk.addColumnNames(rs);
175: } else {
176: fk = new ForeignKeyImpl(rs);
177: fk.setParent(table);
178: fkColumns.put(fk.getName(), fk);
179: }
180: }
181: return fkColumns;
182: }
183:
184: private ForeignKeyImpl(ResultSet rs) throws SQLException {
185: if (rs == null) {
186: Locale locale = Locale.getDefault();
187: ResourceBundle cMessages = ResourceBundle
188: .getBundle(
189: "org/netbeans/modules/sql/framework/model/impl/Bundle",
190: locale); // NO i18n
191: throw new IllegalArgumentException(cMessages
192: .getString("ERROR_VALID_RS")
193: + "(ERROR_VALID_RS)");
194: }
195: //parent = fkTable;
196: fkName = rs.getString(RS_FK_NAME);
197: pkName = rs.getString(RS_PK_NAME);
198:
199: pkTable = rs.getString(RS_PKTABLE_NAME);
200: pkSchema = rs.getString(RS_PKSCHEMA_NAME);
201:
202: pkCatalog = rs.getString(RS_PKCATALOG_NAME);
203: addColumnNames(rs);
204:
205: //rs.getShort(RS_SEQUENCE_NUM)
206:
207: updateRule = rs.getShort(RS_UPDATE_RULE);
208: deleteRule = rs.getShort(RS_DELETE_RULE);
209: deferrability = rs.getShort(RS_DEFERRABILITY);
210: }
211:
212: /**
213: * Creates a new instance of ForeignKey with the given key name and referencing the
214: * column names in the given List.
215: *
216: * @param fkTable DBTable that owns this FK instance
217: * @param foreignKeyName name, if any, of this ForeignKeyImpl
218: * @param primaryKeyName name, if any, of PK associated with this ForeignKeyImpl
219: * @param primaryKeyTable table owning associated PK
220: * @param primaryKeySchema schema containing table which owns associated PK; may be
221: * null
222: * @param primaryKeyCatalog catalog containing table which owns associated PK; may be
223: * null
224: * @param updateFlag update cascade rule
225: * @param deleteFlag delete cascade rule
226: * @param deferFlag flag indicating deferrability of application of cascade rules
227: */
228: public ForeignKeyImpl(DBTable fkTable, String foreignKeyName,
229: String primaryKeyName, String primaryKeyTable,
230: String primaryKeySchema, String primaryKeyCatalog,
231: int updateFlag, int deleteFlag, int deferFlag) {
232: parent = fkTable;
233: fkName = foreignKeyName;
234: pkName = primaryKeyName;
235:
236: pkTable = primaryKeyTable;
237: pkSchema = primaryKeySchema;
238: pkCatalog = primaryKeyCatalog;
239:
240: updateRule = updateFlag;
241: deleteRule = deleteFlag;
242: deferrability = deferFlag;
243: }
244:
245: /**
246: * Creates a new instance of ForeignKeyImpl, using the keyElement as a source for
247: * reconstituting its contents. Caller must invoke parseXml() after this constructor
248: * returns in order to unmarshal and reconstitute the instance object.
249: *
250: * @param keyElement DOM element containing XML marshalled version of a ForeignKeyImpl
251: * instance
252: */
253: public ForeignKeyImpl(Element keyElement) {
254: if (keyElement == null) {
255: throw new IllegalArgumentException(
256: "Must supply non-null org.w3c.dom.Element ref for keyElement.");
257: }
258:
259: element = keyElement;
260: }
261:
262: /**
263: * Creates a new instance of ForeignKeyImpl, cloning the contents of the given
264: * ForeignKey implementation instance.
265: *
266: * @param src ForeignKey to be cloned
267: */
268: public ForeignKeyImpl(ForeignKey src) {
269: if (src == null) {
270: throw new IllegalArgumentException(
271: "Must supply non-null ForeignKey instance for src.");
272: }
273:
274: copyFrom(src);
275: }
276:
277: public void addColumnNames(ResultSet rs) throws SQLException {
278:
279: String pkColName = rs.getString(RS_PKCOLUMN_NAME);
280: if (!StringUtil.isNullString(pkColName)) {
281: pkColumnNames.add(pkColName);
282: }
283:
284: String fkColName = rs.getString(RS_FKCOLUMN_NAME);
285: if (!StringUtil.isNullString(pkColName)) {
286: fkColumnNames.add(fkColName);
287: }
288: }
289:
290: /**
291: * Create a clone of this PrimaryKeyImpl.
292: *
293: * @return cloned copy of DBColumn.
294: */
295: @Override
296: public Object clone() {
297: try {
298: ForeignKeyImpl impl = (ForeignKeyImpl) super .clone();
299: impl.pkColumnNames = new ArrayList<String>(
300: this .pkColumnNames);
301: impl.fkColumnNames = new ArrayList<String>(
302: this .fkColumnNames);
303:
304: return impl;
305: } catch (CloneNotSupportedException e) {
306: throw new InternalError(e.toString());
307: }
308: }
309:
310: /**
311: * @see org.netbeans.modules.model.database.ForeignKey#contains
312: */
313: public boolean contains(DBColumn fkCol) {
314: return contains(fkCol.getName());
315: }
316:
317: /**
318: * @see org.netbeans.modules.model.database.ForeignKey#contains(java.lang.String)
319: */
320: public boolean contains(String fkColumnName) {
321: return fkColumnNames.contains(fkColumnName);
322: }
323:
324: /**
325: * Overrides default implementation to return value based on memberwise comparison.
326: *
327: * @param refObj Object against which we compare this instance
328: * @return true if refObj is functionally identical to this instance; false otherwise
329: */
330: @Override
331: public boolean equals(Object refObj) {
332: if (this == refObj) {
333: return true;
334: }
335:
336: if (!(refObj instanceof ForeignKeyImpl)) {
337: return false;
338: }
339:
340: ForeignKeyImpl ref = (ForeignKeyImpl) refObj;
341:
342: boolean result = (fkName != null) ? fkName.equals(ref.fkName)
343: : (ref.fkName == null);
344: result &= (pkName != null) ? pkName.equals(ref.pkName)
345: : (ref.pkName == null);
346: result &= (pkTable != null) ? pkTable.equals(ref.pkTable)
347: : (ref.pkTable == null);
348: result &= (pkSchema != null) ? pkSchema.equals(ref.pkSchema)
349: : (ref.pkSchema == null);
350: result &= (pkCatalog != null) ? pkCatalog.equals(ref.pkCatalog)
351: : (ref.pkCatalog == null);
352: result &= (updateRule == ref.updateRule)
353: && (deleteRule == ref.deleteRule)
354: && (deferrability == ref.deferrability);
355: result &= (pkColumnNames != null) ? pkColumnNames
356: .equals(ref.pkColumnNames)
357: : (ref.pkColumnNames != null);
358: result &= (fkColumnNames != null) ? fkColumnNames
359: .equals(ref.fkColumnNames)
360: : (ref.fkColumnNames != null);
361:
362: return result;
363: }
364:
365: /**
366: * @see org.netbeans.modules.model.database.ForeignKey#getColumnCount
367: */
368: public int getColumnCount() {
369: return fkColumnNames.size();
370: }
371:
372: /**
373: * @see org.netbeans.modules.model.database.ForeignKey#getColumnName
374: */
375: public String getColumnName(int iColumn) {
376: return fkColumnNames.get(iColumn);
377: }
378:
379: /**
380: * @see org.netbeans.modules.model.database.ForeignKey#getColumnNames
381: */
382: public List<String> getColumnNames() {
383: return Collections.unmodifiableList(fkColumnNames);
384: }
385:
386: /**
387: * @see org.netbeans.modules.model.database.ForeignKey#getDeferrability
388: */
389: public int getDeferrability() {
390: return deferrability;
391: }
392:
393: /**
394: * @see org.netbeans.modules.model.database.ForeignKey#getDeleteRule
395: */
396: public int getDeleteRule() {
397: return deleteRule;
398: }
399:
400: /**
401: * @see org.netbeans.modules.model.database.ForeignKey#getMatchingPKColumn
402: */
403: public String getMatchingPKColumn(String fkColumnName) {
404: ListIterator it = fkColumnNames.listIterator();
405: while (it.hasNext()) {
406: String colName = (String) it.next();
407: if (colName.equals(fkColumnName.trim())) {
408: return pkColumnNames.get(it.previousIndex());
409: }
410: }
411:
412: return null;
413: }
414:
415: /**
416: * @see org.netbeans.modules.model.database.ForeignKey#getName
417: */
418: public String getName() {
419: return fkName;
420: }
421:
422: /**
423: * @see org.netbeans.modules.model.database.ForeignKey#getParent
424: */
425: public DBTable getParent() {
426: return parent;
427: }
428:
429: /**
430: * @see org.netbeans.modules.model.database.ForeignKey#getPKCatalog
431: */
432: public String getPKCatalog() {
433: return pkCatalog;
434: }
435:
436: /**
437: * @see org.netbeans.modules.model.database.ForeignKey#getPKColumnNames
438: */
439: public List<String> getPKColumnNames() {
440: return Collections.unmodifiableList(pkColumnNames);
441: }
442:
443: /**
444: * @see org.netbeans.modules.model.database.ForeignKey#getPKName
445: */
446: public String getPKName() {
447: return pkName;
448: }
449:
450: /**
451: * @see org.netbeans.modules.model.database.ForeignKey#getPKSchema
452: */
453: public String getPKSchema() {
454: return pkSchema;
455: }
456:
457: /**
458: * @see org.netbeans.modules.model.database.ForeignKey#getPKTable
459: */
460: public String getPKTable() {
461: return pkTable;
462: }
463:
464: /**
465: * @see org.netbeans.modules.model.database.ForeignKey#getSequence
466: */
467: public int getSequence(DBColumn col) {
468: if (col == null || col.getName() == null) {
469: return -1;
470: }
471:
472: return fkColumnNames.indexOf(col.getName().trim());
473: }
474:
475: /**
476: * @see org.netbeans.modules.model.database.ForeignKey#getUpdateRule
477: */
478: public int getUpdateRule() {
479: return updateRule;
480: }
481:
482: /**
483: * Overrides default implementation to compute hashCode value for those members used
484: * in equals() for comparison.
485: *
486: * @return hash code for this object
487: * @see java.lang.Object#hashCode
488: */
489: @Override
490: public int hashCode() {
491: int myHash = (fkName != null) ? fkName.hashCode() : 0;
492:
493: myHash += (pkName != null) ? pkName.hashCode() : 0;
494: myHash += (pkTable != null) ? pkTable.hashCode() : 0;
495: myHash += (pkSchema != null) ? pkSchema.hashCode() : 0;
496: myHash += (pkCatalog != null) ? pkCatalog.hashCode() : 0;
497: myHash += updateRule + deleteRule + deferrability;
498: myHash += (fkColumnNames != null) ? fkColumnNames.hashCode()
499: : 0;
500: myHash += (pkColumnNames != null) ? pkColumnNames.hashCode()
501: : 0;
502:
503: return myHash;
504: }
505:
506: /**
507: * Parses the XML content, if any, represented by the DOM element member varaible.
508: *
509: * @exception BaseException thrown while parsing XML, or if member variable element is
510: * null
511: */
512: @SuppressWarnings("unchecked")
513: public void parseXML() throws BaseException {
514: if (this .element == null) {
515: throw new BaseException("No <" + ELEMENT_TAG
516: + "> element found.");
517: }
518:
519: this .fkName = element.getAttribute(FK_NAME_ATTR);
520: this .pkName = element.getAttribute(PK_NAME_ATTR);
521: this .pkTable = element.getAttribute(PK_TABLE_ATTR);
522: this .pkSchema = element.getAttribute(PK_SCHEMA_ATTR);
523: this .pkCatalog = element.getAttribute(PK_CATALOG_ATTR);
524: String val = element.getAttribute(PK_UPDATE_ATTR);
525: try {
526: updateRule = Integer.parseInt(val);
527: } catch (Exception e) {
528: updateRule = 0;
529: }
530:
531: val = element.getAttribute(PK_DELETE_ATTR);
532: try {
533: deleteRule = Integer.parseInt(val);
534: } catch (Exception e) {
535: deleteRule = 0;
536: }
537:
538: val = element.getAttribute(PK_DEFER_ATTR);
539: try {
540: deferrability = Integer.parseInt(val);
541: } catch (Exception e) {
542: deferrability = 0;
543: }
544:
545: String pkColNames = element.getAttribute(PK_COLUMNS_ATTR);
546: pkColumnNames.addAll(StringUtil
547: .createStringListFrom(pkColNames));
548:
549: String fkColNames = element.getAttribute(FK_COLUMNS_ATTR);
550: fkColumnNames.addAll(StringUtil
551: .createStringListFrom(fkColNames));
552: }
553:
554: /**
555: * @see org.netbeans.modules.model.database.ForeignKey#references
556: */
557: public boolean references(DBTable aTable) {
558: return (aTable != null) ? references(aTable.getName(), aTable
559: .getSchema(), aTable.getCatalog()) : false;
560: }
561:
562: /**
563: * @see org.netbeans.modules.model.database.ForeignKey#references
564: */
565: public boolean references(PrimaryKey pk) {
566: if (pk == null) {
567: return false;
568: }
569:
570: List<String> targetColNames = pk.getColumnNames();
571: DBTable targetTable = pk.getParent();
572:
573: return references(targetTable)
574: && targetColNames.containsAll(pkColumnNames)
575: && pkColumnNames.containsAll(targetColNames);
576: }
577:
578: /**
579: * @see org.netbeans.modules.model.database.ForeignKey#references
580: */
581: public boolean references(String pkTableName, String pkSchemaName,
582: String pkCatalogName) {
583: if (pkCatalogName.equals("")) {
584: pkCatalogName = null;
585: }
586: if (pkSchemaName.equals("")) {
587: pkSchemaName = null;
588: }
589: if (pkTableName.equals("")) {
590: pkTableName = null;
591: }
592:
593: boolean tableMatches = (pkTableName != null) ? pkTableName
594: .equals(pkTable) : (pkTable == null);
595: boolean schemaMatches = (pkSchemaName != null) ? pkSchemaName
596: .equals(pkSchema) : (pkSchema == null);
597: boolean catalogMatches = (pkCatalogName != null) ? pkCatalogName
598: .equals(pkCatalog)
599: : (pkCatalog == null);
600: return tableMatches && schemaMatches && catalogMatches;
601: }
602:
603: /**
604: * Sets names of columns participating in this ForeignKeyImpl, using the given Lists
605: * of foreign key column names and corresponding names of primary key columns.
606: *
607: * @param fkColumns List of Strings representing the names of columns that are part of
608: * this ForeignKey, in sequential order.
609: * @param pkColumns List of Strings representing the names of corresponding primary
610: * key columns, in sequential order.
611: * @see org.netbeans.modules.sql.framework.model.impl.ForeignKeyImpl.Column
612: */
613: public void setColumnNames(List fkColumns, List pkColumns) {
614: fkColumnNames.clear();
615: pkColumnNames.clear();
616:
617: if (fkColumns == null || pkColumns == null) {
618: return;
619: }
620:
621: if (fkColumns.size() != pkColumns.size()) {
622: throw new IllegalArgumentException(
623: "Sizes of fkColumns and pkColumns lists must be identical!");
624: }
625:
626: for (ListIterator it = fkColumns.listIterator(); it.hasNext();) {
627: String myFkName = (String) it.next();
628: String myPkName = (String) pkColumns
629: .get(it.previousIndex());
630:
631: if (myFkName != null && myPkName != null) {
632: fkColumnNames.add(myFkName);
633: pkColumnNames.add(myPkName);
634: }
635: }
636: }
637:
638: /**
639: * Sets reference to DBTable that owns this foreign key.
640: *
641: * @param newParent new parent of this foreign key.
642: */
643: public void setParent(DBTable newParent) {
644: parent = newParent;
645: }
646:
647: /**
648: * Writes contents of this PrimaryKeyImpl instance out as an XML element, using the
649: * default prefix.
650: *
651: * @return String containing XML representation of this PrimaryKeyImpl instance
652: */
653: public synchronized String toXMLString() {
654: return toXMLString(null);
655: }
656:
657: /**
658: * Writes contents of this PrimaryKeyImpl instance out as an XML element, using the
659: * given prefix String.
660: *
661: * @param prefix String used to prefix each new line of the XML output
662: * @return String containing XML representation of this PrimaryKeyImpl instance
663: */
664: public synchronized String toXMLString(String prefix) {
665: if (prefix == null) {
666: prefix = "";
667: }
668:
669: StringBuilder buf = new StringBuilder(100);
670:
671: buf.append(prefix).append("<").append(ELEMENT_TAG).append(" ");
672: if (fkName != null && fkName.trim().length() != 0) {
673: buf.append(FK_NAME_ATTR).append("=\"")
674: .append(fkName.trim()).append("\" ");
675: }
676:
677: if (pkName != null && pkName.trim().length() != 0) {
678: buf.append(PK_NAME_ATTR).append("=\"")
679: .append(pkName.trim()).append("\" ");
680: }
681:
682: if (pkTable != null && pkTable.trim().length() != 0) {
683: buf.append(PK_TABLE_ATTR).append("=\"").append(
684: pkTable.trim()).append("\" ");
685: }
686:
687: if (pkSchema != null && pkSchema.trim().length() != 0) {
688: buf.append(PK_SCHEMA_ATTR).append("=\"").append(
689: pkSchema.trim()).append("\" ");
690: }
691:
692: if (pkCatalog != null && pkCatalog.trim().length() != 0) {
693: buf.append(PK_CATALOG_ATTR).append("=\"").append(
694: pkCatalog.trim()).append("\" ");
695: }
696:
697: buf.append(PK_UPDATE_ATTR).append("=\"").append(updateRule)
698: .append("\" ");
699:
700: buf.append(PK_DELETE_ATTR).append("=\"").append(deleteRule)
701: .append("\" ");
702:
703: buf.append(PK_DEFER_ATTR).append("=\"").append(deferrability)
704: .append("\" ");
705:
706: if (fkColumnNames.size() != 0) {
707: buf.append(FK_COLUMNS_ATTR).append("=\"");
708: buf.append(StringUtil
709: .createDelimitedStringFrom(fkColumnNames));
710: buf.append("\" ");
711: }
712:
713: if (pkColumnNames.size() != 0) {
714: buf.append(PK_COLUMNS_ATTR).append("=\"");
715: buf.append(StringUtil
716: .createDelimitedStringFrom(pkColumnNames));
717: buf.append("\" ");
718: }
719:
720: buf.append("/>\n");
721:
722: return buf.toString();
723: }
724:
725: /*
726: * Copies contents of given ForeignKey implementation. @param src ForeignKey whose
727: * contents are to be copied
728: */
729: private void copyFrom(ForeignKey src) {
730: parent = src.getParent();
731:
732: fkName = src.getName();
733: fkColumnNames.clear();
734: fkColumnNames.addAll(src.getColumnNames());
735:
736: pkName = src.getPKName();
737: pkCatalog = src.getPKCatalog();
738: pkSchema = src.getPKSchema();
739: pkTable = src.getPKTable();
740: pkColumnNames.clear();
741: pkColumnNames.addAll(src.getPKColumnNames());
742:
743: // Set cascade attributes
744: updateRule = src.getUpdateRule();
745: deleteRule = src.getDeleteRule();
746: deferrability = src.getDeferrability();
747: }
748: }
|