etl.editor/src/org/netbeans/modules/sql/framework/model/impl/AbstractDBTable.java
author rnithya@netbeans.org
Wed, 23 Apr 2008 15:56:05 +0530
changeset 4205 2739cb16db12
parent 1439 873620e8e004
child 4208 2053b890487a
permissions -rw-r--r--
Fix for 6682455
     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
     5  *
     6  * The contents of this file are subject to the terms of either the GNU
     7  * General Public License Version 2 only ("GPL") or the Common
     8  * Development and Distribution License("CDDL") (collectively, the
     9  * "License"). You may not use this file except in compliance with the
    10  * License. You can obtain a copy of the License at
    11  * http://www.netbeans.org/cddl-gplv2.html
    12  * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    13  * specific language governing permissions and limitations under the
    14  * License.  When distributing the software, include this License Header
    15  * Notice in each file and include the License file at
    16  * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    17  * particular file as subject to the "Classpath" exception as provided
    18  * by Sun in the GPL Version 2 section of the License file that
    19  * accompanied this code. If applicable, add the following below the
    20  * License Header, with the fields enclosed by brackets [] replaced by
    21  * your own identifying information:
    22  * "Portions Copyrighted [year] [name of copyright owner]"
    23  *
    24  * Contributor(s):
    25  *
    26  * The Original Software is NetBeans. The Initial Developer of the Original
    27  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
    28  * Microsystems, Inc. All Rights Reserved.
    29  *
    30  * If you wish your version of this file to be governed by only the CDDL
    31  * or only the GPL Version 2, indicate your decision by adding
    32  * "[Contributor] elects to include this software in this distribution
    33  * under the [CDDL or GPL Version 2] license." If you do not indicate a
    34  * single choice of license, a recipient has the option to distribute
    35  * your version of this file under either the CDDL, the GPL Version 2 or
    36  * to extend the choice of license to its licensees as provided above.
    37  * However, if you add GPL Version 2 code and therefore, elected the GPL
    38  * Version 2 license, then the option applies only if the new code is
    39  * made subject to such option by the copyright holder.
    40  */
    41 package org.netbeans.modules.sql.framework.model.impl;
    42 
    43 import java.util.ArrayList;
    44 import java.util.Collection;
    45 import java.util.Collections;
    46 import java.util.Comparator;
    47 import java.util.HashMap;
    48 import java.util.HashSet;
    49 import java.util.Iterator;
    50 import java.util.List;
    51 import java.util.Map;
    52 import java.util.Set;
    53 
    54 import org.netbeans.modules.sql.framework.model.DBColumn;
    55 import org.netbeans.modules.sql.framework.common.utils.NativeColumnOrderComparator;
    56 import org.netbeans.modules.sql.framework.model.GUIInfo;
    57 import org.netbeans.modules.sql.framework.model.SQLDBColumn;
    58 import org.netbeans.modules.sql.framework.model.SQLDBModel;
    59 import org.netbeans.modules.sql.framework.model.SQLDBTable;
    60 import org.netbeans.modules.sql.framework.model.SQLObject;
    61 import org.w3c.dom.Element;
    62 import org.w3c.dom.NodeList;
    63 
    64 import com.sun.sql.framework.exception.BaseException;
    65 import com.sun.sql.framework.utils.StringUtil;
    66 import java.util.LinkedHashMap;
    67 import org.netbeans.modules.sql.framework.model.DBTable;
    68 import org.netbeans.modules.sql.framework.model.DatabaseModel;
    69 import org.netbeans.modules.sql.framework.model.ForeignKey;
    70 import org.netbeans.modules.sql.framework.model.Index;
    71 import org.netbeans.modules.sql.framework.model.PrimaryKey;
    72 
    73 /**
    74  * Abstract implementation for org.netbeans.modules.model.database.DBTable and SQLObject interfaces.
    75  * 
    76  * @author Sudhendra Seshachala, Jonathan Giron
    77  * @version $Revision$
    78  */
    79 public abstract class AbstractDBTable extends AbstractSQLObject implements SQLDBTable {
    80 
    81     static class StringComparator implements Comparator {
    82         public int compare(Object o1, Object o2) {
    83             if (o1 instanceof String && o2 instanceof String) {
    84                 return ((String) o1).compareTo((String) o2);
    85             }
    86             throw new ClassCastException("StringComparator cannot compare non-String objects.");
    87         }
    88     }
    89 
    90     /** Attribute name for commit batch size. */
    91     protected static final String ATTR_COMMIT_BATCH_SIZE = "commitBatchSize";
    92 
    93     /** String constant for table catalog name attribute. */
    94     protected static final String CATALOG_NAME_ATTR = "catalog"; // NOI18N
    95 
    96     /** String constants for dbTableRef tag. */
    97     protected static final String DB_TABLE_REF = "dbTableRef"; // NOI18N
    98 
    99     /** String constant for table name attribute. */
   100     protected static final String DISPLAY_NAME_ATTR = "displayName"; // NOI18N
   101 
   102     /** String constant for table ID attribute. */
   103     protected static final String ID_ATTR = "id"; // NOI18N
   104 
   105     /** String to use in prefixing each line of a generated XML document */
   106     protected static final String INDENT = "\t";
   107 
   108     /** Initial buffer size for StringBuilder used in marshalling SQLTable to XML */
   109     protected static final int INIT_XMLBUF_SIZE = 500;
   110 
   111     /** Constant for column model name tag. */
   112     protected static final String MODEL_NAME_TAG = "dbModelName"; // NOI18N
   113 
   114     /** String onstant for table schema attribute. */
   115     protected static final String SCHEMA_NAME_ATTR = "schema"; // NOI18N
   116 
   117     /** String constant for table name attribute. */
   118     protected static final String TABLE_NAME_ATTR = "name"; // NOI18N
   119 
   120     private static final String ATTR_ALIAS_NAME = "aliasName";
   121 
   122     private static final String ATTR_FLATFILE_LOCATION_RUNTIME_INPUT_NAME = "flatFileLocationRuntimeInputName";
   123 
   124     private static final String ATTR_TABLE_PREFIX = "tablePrefix";
   125 
   126     private static final String ATTR_USERDEFINED_CATALOG_NAME = "userDefinedCatalogName";
   127 
   128     private static final String ATTR_USERDEFINED_SCHEMA_NAME = "userDefinedSchemaName";
   129 
   130     private static final String ATTR_USERDEFINED_TABLE_NAME = "userDefinedTableName";
   131 
   132     private static final String ATTR_USING_FULLYQUALIFIED_NAME = "usingFullyQualifiedName";
   133 
   134     private static final int DEFAULT_COMMIT_BATCH_SIZE = 5000;
   135 
   136     private static final String FQ_TBL_NAME_SEPARATOR = ".";
   137 
   138     // RFE-102428
   139     private static final String ATTR_STAGING_TABLE_NAME = "stagingTableName";
   140     
   141     /** use alias is required : transient variable */
   142     protected boolean aliasUsed = false;
   143 
   144     /** catalog to which this table belongs. */
   145     protected String catalog;
   146 
   147     /** Map of column metadata. */
   148     protected Map<String, DBColumn> columns;
   149 
   150     /** User-defined description. */
   151     protected String description;
   152     /** editable */
   153     protected boolean editable = true;
   154 
   155     /** Map of names to ForeignKey instances for this table; may be empty. */
   156     protected Map<String, ForeignKey> foreignKeys;
   157 
   158     /** Contains UI state information */
   159     protected GUIInfo guiInfo;
   160 
   161     /** Map of names to Index instances for this table; may be empty. */
   162     protected Map<String, Index> indexes;
   163 
   164     /** Table name as supplied by data source. */
   165     protected String name;
   166 
   167     protected boolean overrideCatalogName = false;
   168 
   169     protected String overridenCatalogName = null;
   170 
   171     protected String overridenSchemaName = null;
   172     protected boolean overrideSchemaName = false;
   173 
   174     /** Model instance that "owns" this table */
   175     protected DatabaseModel parentDBModel;
   176     /** PrimaryKey for this table; may be null. */
   177     protected PrimaryKeyImpl primaryKey;
   178     /** schema to which this table belongs. */
   179     protected String schema;
   180     /** selected */
   181     protected boolean selected;
   182 
   183     /** No-arg constructor; initializes Collections-related member variables. */
   184     protected AbstractDBTable() {
   185         columns = new LinkedHashMap<String, DBColumn>();
   186         foreignKeys = new HashMap<String, ForeignKey>();
   187         indexes = new HashMap<String, Index>();
   188         guiInfo = new GUIInfo();
   189         setDefaultAttributes();
   190     }
   191 
   192     /**
   193      * Creates a new instance of AbstractDBTable, cloning the contents of the given
   194      * DBTable implementation instance.
   195      * 
   196      * @param src DBTable instance to be 43d
   197      */
   198     protected AbstractDBTable(DBTable src) {
   199         this();
   200 
   201         if (src == null) {
   202             throw new IllegalArgumentException("Must supply non-null DBTable instance for src param.");
   203         }
   204         copyFrom(src);
   205     }
   206 
   207     /**
   208      * Creates a new instance of AbstractDBTable with the given name.
   209      * 
   210      * @param aName name of new DBTable instance
   211      * @param aSchema schema of new DBTable instance; may be null
   212      * @param aCatalog catalog of new DBTable instance; may be null
   213      */
   214     protected AbstractDBTable(String aName, String aSchema, String aCatalog) {
   215         this();
   216 
   217         name = (aName != null) ? aName.trim() : null;
   218         schema = (aSchema != null) ? aSchema.trim() : null;
   219         catalog = (aCatalog != null) ? aCatalog.trim() : null;
   220     }
   221 
   222     /**
   223      * Adds an AbstractDBColumn instance to this table.
   224      * 
   225      * @param theColumn column to be added.
   226      * @return true if successful. false if failed.
   227      */
   228     public boolean addColumn(SQLDBColumn theColumn) {
   229         if (theColumn != null) {
   230             theColumn.setParent(this);
   231             columns.put(theColumn.getName(), theColumn);
   232             return true;
   233         }
   234 
   235         return false;
   236     }
   237 
   238     /**
   239      * Adds the given ForeignKeyImpl, associating it with this AbstractDBTable instance.
   240      * 
   241      * @param newFk new ForeignKeyImpl instance to be added
   242      * @return return true if addition succeeded, false otherwise
   243      */
   244     public boolean addForeignKey(ForeignKeyImpl newFk) {
   245         if (newFk != null) {
   246             newFk.setParent(this);
   247             foreignKeys.put(newFk.getName(), newFk);
   248             return true;
   249         }
   250         return false;
   251     }
   252 
   253     /**
   254      * Adds the given IndexImpl, associating it with this AbstractDBTable instance.
   255      * 
   256      * @param newIndex new IndexImpl instance to be added
   257      * @return return true if addition succeeded, false otherwise
   258      */
   259     public boolean addIndex(IndexImpl newIndex) {
   260         if (newIndex != null) {
   261             newIndex.setParent(this);
   262             indexes.put(newIndex.getName(), newIndex);
   263 
   264             return true;
   265         }
   266         return false;
   267     }
   268 
   269     /**
   270      * Clears list of foreign keys.
   271      */
   272     public void clearForeignKeys() {
   273         foreignKeys.clear();
   274     }
   275 
   276     /**
   277      * Clears list of indexes.
   278      */
   279     public void clearIndexes() {
   280         indexes.clear();
   281     }
   282 
   283     public void clearOverride(boolean clearCatalogOverride, boolean clearSchemaOverride) {
   284         if (clearCatalogOverride) {
   285             this.overrideCatalogName = false;
   286             this.overridenCatalogName = null;
   287         }
   288 
   289         if (clearSchemaOverride) {
   290             this.overrideSchemaName = false;
   291             this.overridenSchemaName = null;
   292         }
   293     }
   294 
   295     /**
   296      * Compares DBTable with another object for lexicographical ordering. Null objects and
   297      * those DBTables with null names are placed at the end of any ordered collection
   298      * using this method.
   299      * 
   300      * @param refObj Object to be compared.
   301      * @return -1 if the column name is less than obj to be compared. 0 if the column name
   302      *         is the same. 1 if the column name is greater than obj to be compared.
   303      */
   304     public int compareTo(Object refObj) {
   305         if (refObj == null) {
   306             return -1;
   307         }
   308 
   309         if (refObj == this) {
   310             return 0;
   311         }
   312 
   313         String refName = (parentDBModel != null) ? parentDBModel.getFullyQualifiedTableName((DBTable) refObj) : ((DBTable) refObj).getName();
   314 
   315         String myName = (parentDBModel != null) ? parentDBModel.getFullyQualifiedTableName(this) : name;
   316 
   317         return (myName != null) ? myName.compareTo(refName) : (refName != null) ? 1 : -1;
   318     }
   319 
   320     /**
   321      * Sets the various member variables and collections using the given DBTable instance
   322      * as a source object. Concrete implementations should override this method, call
   323      * super.copyFrom(DBColumn) to pick up member variables defined in this class and then
   324      * implement its own logic for copying member variables defined within itself.
   325      * 
   326      * @param source DBTable from which to obtain values for member variables and
   327      *        collections
   328      */
   329     public void copyFrom(DBTable source) {
   330         if (source == null) {
   331             throw new IllegalArgumentException("Must supply non-null ref for source");
   332         } else if (source == this) {
   333             return;
   334         }
   335 
   336         name = source.getName();
   337         description = source.getDescription();
   338         schema = source.getSchema();
   339         catalog = source.getCatalog();
   340 
   341         parentDBModel = source.getParent();
   342 
   343         if (source instanceof SQLDBTable) {
   344             SQLDBTable abstractTbl = (SQLDBTable) source;
   345             super.copyFromSource(abstractTbl);
   346             displayName = abstractTbl.getDisplayName();
   347             guiInfo = abstractTbl.getGUIInfo();
   348             aliasUsed = abstractTbl.isAliasUsed();
   349         }
   350 
   351         deepCopyReferences(source);
   352     }
   353 
   354     /**
   355      * Deletes all columns associated with this table.
   356      * 
   357      * @return true if all columns were deleted successfully, false otherwise.
   358      */
   359     public boolean deleteAllColumns() {
   360         columns.clear();
   361         return false;
   362     }
   363 
   364     /**
   365      * Deletes DBColumn, if any, associated with the given name from this table.
   366      * 
   367      * @param columnName column name to be removed.
   368      * @return true if successful. false if failed.
   369      */
   370     public boolean deleteColumn(String columnName) {
   371         if (columnName != null && columnName.trim().length() != 0) {
   372             return (columns.remove(columnName) != null);
   373         }
   374         return false;
   375     }
   376 
   377     /**
   378      * Overrides default implementation to return value based on memberwise comparison.
   379      * 
   380      * @param obj Object against which we compare this instance
   381      * @return true if obj is functionally identical to this SQLTable instance; false
   382      *         otherwise
   383      */
   384     @Override
   385     public boolean equals(Object obj) {
   386         boolean result = false;
   387 
   388         // Check for reflexivity first.
   389         if (this == obj) {
   390             return true;
   391         }
   392         if (!(obj instanceof SQLDBTable)) {
   393             return false;
   394         }
   395 
   396         result = super.equals(obj);
   397 
   398         if (!result) {
   399             return result;
   400         }
   401 
   402         SQLDBTable target = (SQLDBTable) obj;
   403 
   404         // since now we allow duplicate source tables we need to check the id and if id
   405         // is not equal then table is not equal
   406         result &= target.getId() != null ? target.getId().equals(this.getId()) : this.getId() == null;
   407 
   408         // Check for castability (also deals with null obj)
   409         if (obj instanceof DBTable) {
   410             DBTable aTable = (DBTable) obj;
   411             String aTableName = aTable.getName();
   412             DatabaseModel aTableParent = aTable.getParent();
   413             Map<String, DBColumn> aTableColumns = aTable.getColumns();
   414             PrimaryKey aTablePK = aTable.getPrimaryKey();
   415             List<ForeignKey> aTableFKs = aTable.getForeignKeys();
   416             List<Index> aTableIdxs = aTable.getIndexes();
   417 
   418             result &= (aTableName != null && name != null && name.equals(aTableName))
   419                 && (parentDBModel != null && aTableParent != null && parentDBModel.equals(aTableParent));
   420 
   421             if (columns != null && aTableColumns != null) {
   422                 Set<String> objCols = aTableColumns.keySet();
   423                 Set<String> myCols = columns.keySet();
   424 
   425                 // Must be identical (no subsetting), hence the pair of tests.
   426                 result &= myCols.containsAll(objCols) && objCols.containsAll(myCols);
   427             } else if (!(columns == null && aTableColumns == null)) {
   428                 result = false;
   429             }
   430 
   431             result &= (primaryKey != null) ? primaryKey.equals(aTablePK) : aTablePK == null;
   432 
   433             if (foreignKeys != null && aTableFKs != null) {
   434                 Collection<ForeignKey> myFKs = foreignKeys.values();
   435                 // Must be identical (no subsetting), hence the pair of tests.
   436                 result &= myFKs.containsAll(aTableFKs) && aTableFKs.containsAll(myFKs);
   437             } else if (!(foreignKeys == null && aTableFKs == null)) {
   438                 result = false;
   439             }
   440 
   441             if (indexes != null && aTableIdxs != null) {
   442                 Collection<Index> myIdxs = indexes.values();
   443                 // Must be identical (no subsetting), hence the pair of tests.
   444                 result &= myIdxs.containsAll(aTableIdxs) && aTableIdxs.containsAll(myIdxs);
   445             } else if (!(indexes == null && aTableIdxs == null)) {
   446                 result = false;
   447             }
   448         }
   449         return result;
   450     }
   451 
   452     /**
   453      * @see org.netbeans.modules.sql.framework.model.SQLDBTable#getAliasName()
   454      */
   455     public String getAliasName() {
   456         return (String) this.getAttributeObject(ATTR_ALIAS_NAME);
   457     }
   458 
   459     /**
   460      * @see org.netbeans.modules.sql.framework.model.SQLDBTable#getBatchSize()
   461      */
   462     public int getBatchSize() {
   463         Integer batchSize = (Integer) this.getAttributeObject(ATTR_COMMIT_BATCH_SIZE);
   464         return (batchSize != null) ? batchSize.intValue() : DEFAULT_COMMIT_BATCH_SIZE;
   465     }
   466 
   467     /**
   468      * @see org.netbeans.modules.model.database.DBTable#getCatalog
   469      */
   470     public String getCatalog() {
   471         return catalog;
   472     }
   473 
   474     /**
   475      * Gets List of child SQLObjects belonging to this instance.
   476      * 
   477      * @return List of child SQLObjects
   478      */
   479     @Override
   480     public List<DBColumn> getChildSQLObjects() {
   481         return this.getColumnList();
   482     }
   483 
   484     /**
   485      * Gets the DBColumn, if any, associated with the given name
   486      * 
   487      * @param columnName column name
   488      * @return DBColumn associated with columnName, or null if none exists
   489      */
   490     public DBColumn getColumn(String columnName) {
   491         return columns.get(columnName);
   492     }
   493 
   494     /**
   495      * @see org.netbeans.modules.model.database.DBTable#getColumnList
   496      */
   497     public List<DBColumn> getColumnList() {
   498         List<DBColumn> list = new ArrayList<DBColumn>();
   499         list.addAll(columns.values());
   500         Collections.sort(list, NativeColumnOrderComparator.getInstance());
   501 
   502         return list;
   503     }
   504 
   505     /**
   506      * @see org.netbeans.modules.model.database.DBTable#getColumns
   507      */
   508     public Map<String, DBColumn> getColumns() {
   509         return columns;
   510     }
   511 
   512     /**
   513      * @see org.netbeans.modules.model.database.DBTable#getDescription
   514      */
   515     public String getDescription() {
   516         return description;
   517     }
   518 
   519     /**
   520      * Get display name
   521      * 
   522      * @return display name
   523      */
   524     @Override
   525     public String getDisplayName() {
   526         return this.getQualifiedName();
   527     }
   528 
   529     /**
   530      * Gets the flat file location runtime input name which is generate when a flat file
   531      * table is added to collaboration. use this name at runtime for file location passed
   532      * by eInsight
   533      * 
   534      * @return String representing flatfile location runtime input name
   535      */
   536     public String getFlatFileLocationRuntimeInputName() {
   537         return (String) this.getAttributeObject(ATTR_FLATFILE_LOCATION_RUNTIME_INPUT_NAME);
   538     }
   539 
   540     /**
   541      * @see org.netbeans.modules.model.database.DBTable#getForeignKey(java.lang.String)
   542      */
   543     public ForeignKey getForeignKey(String fkName) {
   544         return foreignKeys.get(fkName);
   545     }
   546 
   547     /**
   548      * @see org.netbeans.modules.model.database.DBTable#getForeignKeys
   549      */
   550     public List<ForeignKey> getForeignKeys() {
   551         return new ArrayList<ForeignKey>(foreignKeys.values());
   552     }
   553 
   554     /**
   555      * get table fully qualified name including schema , catalog info
   556      * 
   557      * @return fully qualified table name prefixed with alias
   558      */
   559     public String getFullyQualifiedName() {
   560 
   561         String tblName = getName();
   562         String schName = getSchema();
   563         String catName = getCatalog();
   564 
   565         if (tblName == null) {
   566             throw new IllegalArgumentException("can not construct fully qualified table name, table name is null.");
   567         }
   568 
   569         StringBuilder buf = new StringBuilder(50);
   570 
   571         if (catName != null && catName.trim().length() != 0) {
   572             buf.append(catName.trim());
   573             buf.append(FQ_TBL_NAME_SEPARATOR);
   574         }
   575 
   576         if (schName != null && schName.trim().length() != 0) {
   577             buf.append(schName.trim());
   578             buf.append(FQ_TBL_NAME_SEPARATOR);
   579         }
   580 
   581         buf.append(tblName.trim());
   582 
   583         return buf.toString();
   584     }
   585 
   586     /**
   587      * @see SQLCanvasObject#getGUIInfo
   588      */
   589     public GUIInfo getGUIInfo() {
   590         return guiInfo;
   591     }
   592 
   593     /**
   594      * @see org.netbeans.modules.model.database.DBTable#getIndex
   595      */
   596     public Index getIndex(String indexName) {
   597         return indexes.get(indexName);
   598     }
   599 
   600     /**
   601      * @see org.netbeans.modules.model.database.DBTable#getIndexes
   602      */
   603     public List<Index> getIndexes() {
   604         return new ArrayList<Index>(indexes.values());
   605     }
   606 
   607     /**
   608      * @see org.netbeans.modules.model.database.DBTable#getName
   609      */
   610     public synchronized String getName() {
   611         return name;
   612     }
   613 
   614     /**
   615      * Get specified SQL object
   616      * 
   617      * @param objectId - object ID
   618      * @return SQLObject
   619      */
   620     public SQLObject getObject(String objectId) {
   621         List list = this.getColumnList();
   622         Iterator it = list.iterator();
   623 
   624         while (it.hasNext()) {
   625             SQLDBColumn dbColumn = (SQLDBColumn) it.next();
   626             // if looking for table then return table
   627             if (objectId.equals(dbColumn.getId())) {
   628                 return dbColumn;
   629             }
   630         }
   631         return null;
   632     }
   633 
   634     /**
   635      * @see org.netbeans.modules.model.database.DBTable#getParent
   636      */
   637     public DatabaseModel getParent() {
   638         return parentDBModel;
   639     }
   640 
   641     /**
   642      * @see org.netbeans.modules.model.database.DBTable#getPrimaryKey
   643      */
   644     public PrimaryKey getPrimaryKey() {
   645         return primaryKey;
   646     }
   647 
   648     /**
   649      * get table qualified name
   650      * 
   651      * @return qualified table name prefixed with alias
   652      */
   653     public String getQualifiedName() {
   654         StringBuilder buf = new StringBuilder(50);
   655         String aName = this.getAliasName();
   656         if (aName != null && !aName.trim().equals("")) {
   657             buf.append("(");
   658             buf.append(aName);
   659             buf.append(") ");
   660             buf.append(this.getName());
   661         } else {
   662             buf.append(this.getFullyQualifiedName());
   663         }
   664 
   665         return buf.toString();
   666     }
   667 
   668     /**
   669      * @see org.netbeans.modules.model.database.DBTable#getReferencedTables
   670      */
   671     public Set getReferencedTables() {
   672         List keys = getForeignKeys();
   673         Set<DBTable> tables = new HashSet<DBTable>(keys.size());
   674 
   675         if (keys.size() != 0) {
   676             Iterator iter = keys.iterator();
   677             while (iter.hasNext()) {
   678                 ForeignKeyImpl fk = (ForeignKeyImpl) iter.next();
   679                 DBTable pkTable = parentDBModel.getTable(fk.getPKTable(), fk.getPKSchema(), fk.getPKCatalog());
   680                 if (pkTable != null && fk.references(pkTable.getPrimaryKey())) {
   681                     tables.add(pkTable);
   682                 }
   683             }
   684 
   685             if (tables.size() == 0) {
   686                 tables.clear();
   687                 tables = Collections.emptySet();
   688             }
   689         }
   690 
   691         return tables;
   692     }
   693 
   694     /**
   695      * @see org.netbeans.modules.model.database.DBTable#getReferenceFor
   696      */
   697     public ForeignKey getReferenceFor(DBTable target) {
   698         if (target == null) {
   699             return null;
   700         }
   701 
   702         PrimaryKey targetPK = target.getPrimaryKey();
   703         if (targetPK == null) {
   704             return null;
   705         }
   706 
   707         Iterator iter = foreignKeys.values().iterator();
   708         while (iter.hasNext()) {
   709             ForeignKey myFK = (ForeignKey) iter.next();
   710             if (myFK.references(targetPK)) {
   711                 return myFK;
   712             }
   713         }
   714 
   715         return null;
   716     }
   717 
   718     public String getRuntimeArgumentName() {
   719         return this.getFlatFileLocationRuntimeInputName();
   720     }
   721 
   722     /**
   723      * @see org.netbeans.modules.model.database.DBTable#getSchema
   724      */
   725     public String getSchema() {
   726         return schema;
   727     }
   728 
   729     /**
   730      * @see org.netbeans.modules.sql.framework.model.SQLDBTable#getTablePrefix()
   731      */
   732     public String getTablePrefix() {
   733         return (String) this.getAttributeObject(ATTR_TABLE_PREFIX);
   734     }
   735     
   736     //RFE-102428
   737     /**
   738      * Gets the staging table name.
   739      * 
   740      * @return staging table name
   741      */
   742     public String getStagingTableName() {
   743     	return (String) this.getAttributeObject(ATTR_STAGING_TABLE_NAME);
   744     }
   745 
   746     /**
   747      * @see org.netbeans.modules.sql.framework.model.SQLDBTable#getUniqueTableName()
   748      */
   749     public String getUniqueTableName() {
   750         // Use alias name + given name to make this name consistent with the existing
   751         // name formats used in 5.0.x for flatfile runtime arguments.
   752         return this.getAliasName() + "_" + this.getName();
   753     }
   754 
   755     /**
   756      * @see org.netbeans.modules.sql.framework.model.SQLDBTable#getUserDefinedCatalogName()
   757      */
   758     public String getUserDefinedCatalogName() {
   759         if (overrideCatalogName) {
   760             return overridenCatalogName;
   761         } else {
   762             return (String) this.getAttributeObject(ATTR_USERDEFINED_CATALOG_NAME);
   763         }
   764     }
   765 
   766     /**
   767      * @see org.netbeans.modules.sql.framework.model.SQLDBTable#getUserDefinedSchemaName()
   768      */
   769     public String getUserDefinedSchemaName() {
   770         if (overrideSchemaName) {
   771             return overridenSchemaName;
   772         } else { 
   773             return (String) this.getAttributeObject(ATTR_USERDEFINED_SCHEMA_NAME);
   774         }
   775     }
   776 
   777     /**
   778      * @see org.netbeans.modules.sql.framework.model.SQLDBTable#getUserDefinedTableName()
   779      */
   780     public String getUserDefinedTableName() {
   781         return (String) this.getAttributeObject(ATTR_USERDEFINED_TABLE_NAME);
   782     }
   783 
   784     /**
   785      * Overrides default implementation to compute hashCode value for those members used
   786      * in equals() for comparison.
   787      * 
   788      * @return hash code for this object
   789      * @see java.lang.Object#hashCode
   790      */
   791     @Override
   792     public int hashCode() {
   793         int myHash = super.hashCode();
   794         myHash = (name != null) ? name.hashCode() : 0;
   795         myHash += (parentDBModel != null) ? parentDBModel.hashCode() : 0;
   796         myHash += (schema != null) ? schema.hashCode() : 0;
   797         myHash += (catalog != null) ? catalog.hashCode() : 0;
   798 
   799         // Include hashCodes of all column names.
   800         if (columns != null) {
   801             myHash += columns.keySet().hashCode();
   802         }
   803 
   804         if (primaryKey != null) {
   805             myHash += primaryKey.hashCode();
   806         }
   807 
   808         if (foreignKeys != null) {
   809             myHash += foreignKeys.keySet().hashCode();
   810         }
   811 
   812         if (indexes != null) {
   813             myHash += indexes.keySet().hashCode();
   814         }
   815 
   816         myHash += (displayName != null) ? displayName.hashCode() : 0;
   817 
   818         return myHash;
   819     }
   820 
   821     /**
   822      * @return Returns the aliasUsed.
   823      */
   824     public boolean isAliasUsed() {
   825         return aliasUsed;
   826     }
   827 
   828     /**
   829      * Get editable
   830      * 
   831      * @return true/false
   832      */
   833     public boolean isEditable() {
   834         return this.editable;
   835     }
   836 
   837     public boolean isInputStatic(String inputName) {
   838         return false;
   839     }
   840 
   841     /**
   842      * Get selected
   843      * 
   844      * @return selected
   845      */
   846     public boolean isSelected() {
   847         return this.selected;
   848     }
   849 
   850     /**
   851      * @see org.netbeans.modules.sql.framework.model.SQLDBTable#isUsingFullyQualifiedName()
   852      */
   853     public boolean isUsingFullyQualifiedName() {
   854         Boolean isUsing = (Boolean) getAttributeObject(ATTR_USING_FULLYQUALIFIED_NAME);
   855         return (isUsing != null) ? isUsing.booleanValue() : true;
   856     }
   857 
   858     public void overrideCatalogName(String nName) {
   859         this.overrideCatalogName = true;
   860         this.overridenCatalogName = nName;
   861     }
   862 
   863     public void overrideSchemaName(String nName) {
   864         this.overrideSchemaName = true;
   865         this.overridenSchemaName = nName;
   866     }
   867 
   868     /**
   869      * Parses the XML content, if any, using the given Element as a source for
   870      * reconstituting the member variables and collections of this instance.
   871      * 
   872      * @param tableElement DOM element containing XML marshalled version of a
   873      * @exception BaseException thrown while parsing XML, or if member variable element is
   874      *            null
   875      */
   876     @Override
   877     public void parseXML(Element tableElement) throws BaseException {
   878         if (tableElement == null) {
   879             throw new BaseException("Null ref for tableElement.");
   880         }
   881 
   882         if (!(tableElement.getNodeName().equals(getElementTagName()))) {
   883             throw new BaseException("No <" + getElementTagName() + "> element found.");
   884         }
   885 
   886         super.parseXML(tableElement);
   887 
   888         name = tableElement.getAttribute(TABLE_NAME_ATTR);
   889         schema = tableElement.getAttribute(SCHEMA_NAME_ATTR);
   890         catalog = tableElement.getAttribute(CATALOG_NAME_ATTR);
   891 
   892         NodeList childNodeList = tableElement.getChildNodes();
   893         parseChildren(childNodeList);
   894     }
   895 
   896     /**
   897      * @see org.netbeans.modules.model.database.DBTable#references
   898      */
   899     public boolean references(DBTable pkTarget) {
   900         return (getReferenceFor(pkTarget) != null);
   901     }
   902 
   903     /**
   904      * Dissociates the given ForeignKeyImpl from this AbstractDBTable instance, removing
   905      * it from its internal FK collection.
   906      * 
   907      * @param oldKey new ForeignKeyImpl instance to be removed
   908      * @return return true if removal succeeded, false otherwise
   909      */
   910     public boolean removeForeignKey(ForeignKeyImpl oldKey) {
   911         if (oldKey != null) {
   912             return (foreignKeys.remove(oldKey.getName()) != null);
   913         }
   914 
   915         return false;
   916     }
   917 
   918     /**
   919      * set the alias name for this table
   920      * 
   921      * @param aName alias name
   922      */
   923     public void setAliasName(String aName) {
   924         this.setAttribute(ATTR_ALIAS_NAME, aName);
   925     }
   926 
   927     /**
   928      * @param aliasUsed The aliasUsed to set.
   929      */
   930     public void setAliasUsed(boolean aliasUsed) {
   931         this.aliasUsed = aliasUsed;
   932     }
   933 
   934     /**
   935      * Clones contents of the given Map to this table's internal column map, overwriting
   936      * any previous mappings.
   937      * 
   938      * @param theColumns Map of columns to be substituted
   939      * @return true if successful. false if failed.
   940      */
   941     public boolean setAllColumns(Map<String, DBColumn> theColumns) {
   942         columns.clear();
   943         if (theColumns != null) {
   944             columns.putAll(theColumns);
   945         }
   946         return true;
   947     }
   948 
   949     public void setBatchSize(int newSize) {
   950         if (newSize < 0) {
   951             newSize = DEFAULT_COMMIT_BATCH_SIZE;
   952         }
   953 
   954         this.setAttribute(ATTR_COMMIT_BATCH_SIZE, new Integer(newSize));
   955     }
   956 
   957     /**
   958      * Sets catalog name to new value.
   959      * 
   960      * @param newCatalog new value for catalog name
   961      */
   962     public void setCatalog(String newCatalog) {
   963         catalog = newCatalog;
   964     }
   965 
   966     /**
   967      * Sets description text for this instance.
   968      * 
   969      * @param newDesc new descriptive text
   970      */
   971     public void setDescription(String newDesc) {
   972         description = newDesc;
   973     }
   974 
   975     /**
   976      * Set editable
   977      * 
   978      * @param edit - editable
   979      */
   980     public void setEditable(boolean edit) {
   981         this.editable = edit;
   982     }
   983 
   984     /**
   985      * set flat file location runtime input name which is generate when a flat file table
   986      * is added to collaboration
   987      * 
   988      * @param runtimeArgName name of runtime input argument for flat file location
   989      */
   990     public void setFlatFileLocationRuntimeInputName(String runtimeArgName) {
   991         this.setAttribute(ATTR_FLATFILE_LOCATION_RUNTIME_INPUT_NAME, runtimeArgName);
   992     }
   993 
   994     /**
   995      * Sets table name to new value.
   996      * 
   997      * @param newName new value for table name
   998      */
   999     public void setName(String newName) {
  1000         name = newName;
  1001     }
  1002 
  1003     /**
  1004      * Sets parentDBModel DatabaseModel to the given reference.
  1005      * 
  1006      * @param newParent new DatabaseModel parentDBModel
  1007      */
  1008     public void setParent(SQLDBModel newParent) {
  1009         parentDBModel = newParent;
  1010         try {
  1011             setParentObject(newParent);
  1012         } catch (BaseException ex) {
  1013             // do nothing
  1014         }
  1015     }
  1016 
  1017     /**
  1018      * Sets PrimaryKey instance for this DBTable to the given instance.
  1019      * 
  1020      * @param newPk new PrimaryKey instance to be associated
  1021      * @return true if association succeeded, false otherwise
  1022      */
  1023     public boolean setPrimaryKey(PrimaryKeyImpl newPk) {
  1024         if (newPk != null) {
  1025             newPk.setParent(this);
  1026         }
  1027 
  1028         primaryKey = newPk;
  1029         return true;
  1030     }
  1031     
  1032     public void setForeignKeyMap(Map<String, ForeignKey> fkMap){
  1033         foreignKeys = fkMap;
  1034     }
  1035 
  1036     /**
  1037      * Sets schema name to new value.
  1038      * 
  1039      * @param newSchema new value for schema name
  1040      */
  1041     public void setSchema(String newSchema) {
  1042         schema = newSchema;
  1043     }
  1044 
  1045     /**
  1046      * Set selected
  1047      * 
  1048      * @param sel - selected
  1049      */
  1050     public void setSelected(boolean sel) {
  1051         this.selected = sel;
  1052     }
  1053 
  1054     public void setTablePrefix(String tPrefix) {
  1055         this.setAttribute(ATTR_TABLE_PREFIX, tPrefix);
  1056     }
  1057 
  1058     //RFE-102428
  1059     /**
  1060      * Sets the staging table name.
  1061      * 
  1062      * @param stName staging table name
  1063      */
  1064     public void setStagingTableName(String stName) {
  1065     	this.setAttribute(ATTR_STAGING_TABLE_NAME, stName);
  1066     }
  1067     
  1068     /**
  1069      * @see org.netbeans.modules.sql.framework.model.SQLDBTable#setUserDefinedCatalogName(java.lang.String)
  1070      */
  1071     public void setUserDefinedCatalogName(String newName) {
  1072         this.setAttribute(ATTR_USERDEFINED_CATALOG_NAME, newName);
  1073     }
  1074 
  1075     /**
  1076      * @see org.netbeans.modules.sql.framework.model.SQLDBTable#setUserDefinedSchemaName(java.lang.String)
  1077      */
  1078     public void setUserDefinedSchemaName(String newName) {
  1079         this.setAttribute(ATTR_USERDEFINED_SCHEMA_NAME, newName);
  1080     }
  1081 
  1082     /**
  1083      * @see org.netbeans.modules.sql.framework.model.SQLDBTable#setUserDefinedTableName(java.lang.String)
  1084      */
  1085     public void setUserDefinedTableName(String newName) {
  1086         this.setAttribute(ATTR_USERDEFINED_TABLE_NAME, newName);
  1087     }
  1088 
  1089     /**
  1090      * @see org.netbeans.modules.sql.framework.model.SQLDBTable#setUsingFullyQualifiedName(boolean)
  1091      */
  1092     public void setUsingFullyQualifiedName(boolean usesFullName) {
  1093         this.setAttribute(ATTR_USING_FULLYQUALIFIED_NAME, (usesFullName ? Boolean.TRUE : Boolean.FALSE));
  1094     }
  1095 
  1096     /**
  1097      * Overrides default implementation to return appropriate display name of this DBTable
  1098      * 
  1099      * @return qualified table name.
  1100      */
  1101     @Override
  1102     public String toString() {
  1103         return getQualifiedName();
  1104     }
  1105 
  1106     /**
  1107      * @see SQLObject#toXMLString
  1108      */
  1109     @Override
  1110     public String toXMLString(String prefix) throws BaseException {
  1111         return toXMLString(prefix, false);
  1112     }
  1113 
  1114     /**
  1115      * Returns XML representation of table metadata.
  1116      * 
  1117      * @param prefix prefix for the xml.
  1118      * @param tableOnly flag for generating table only metadata.
  1119      * @return XML representation of the table metadata.
  1120      * @exception BaseException - exception
  1121      */
  1122      public String toXMLString(String prefix, boolean tableOnly) throws BaseException {
  1123             throw new UnsupportedOperationException("Not supported yet.");
  1124      }
  1125 
  1126     /**
  1127      * Perform deep copy of columns.
  1128      * 
  1129      * @param source SQLTable whose columns are to be copied.
  1130      */
  1131     protected void deepCopyReferences(DBTable source) {
  1132         if (source != null && source != this) {
  1133             primaryKey = null;
  1134             PrimaryKey srcPk = source.getPrimaryKey();
  1135             if (srcPk != null) {
  1136                 primaryKey = new PrimaryKeyImpl(source.getPrimaryKey());
  1137                 primaryKey.setParent(this);
  1138             }
  1139 
  1140             foreignKeys.clear();
  1141             Iterator iter = source.getForeignKeys().iterator();
  1142             while (iter.hasNext()) {
  1143                 ForeignKeyImpl impl = new ForeignKeyImpl((ForeignKey) iter.next());
  1144                 impl.setParent(this);
  1145                 foreignKeys.put(impl.getName(), impl);
  1146             }
  1147 
  1148             indexes.clear();
  1149             iter = source.getIndexes().iterator();
  1150 
  1151             while (iter.hasNext()) {
  1152                 IndexImpl impl = new IndexImpl((Index) iter.next());
  1153                 impl.setParent(this);
  1154                 indexes.put(impl.getName(), impl);
  1155             }
  1156 
  1157             columns.clear();
  1158             iter = source.getColumnList().iterator();
  1159             while (iter.hasNext()) {
  1160                 try {
  1161                     SQLDBColumn column = (SQLDBColumn) iter.next();
  1162                     SQLDBColumn clonedColumn = (SQLDBColumn) column.cloneSQLObject();
  1163                     columns.put(clonedColumn.getName(), clonedColumn);
  1164                 } catch (Exception ex) {
  1165                     // TODO Log this exception
  1166                 }
  1167             }
  1168         }
  1169     }
  1170 
  1171     /**
  1172      * Gets String representing tag name for this table class.
  1173      * 
  1174      * @return String representing element tag for this class
  1175      */
  1176      protected String getElementTagName() {
  1177         throw new UnsupportedOperationException("Not supported yet.");
  1178      }
  1179 
  1180     /**
  1181      * Parses node elements to extract child components to various collections (columns,
  1182      * PK, FK, indexes).
  1183      * 
  1184      * @param childNodeList Nodes to be unmarshalled
  1185      * @throws BaseException if error occurs while parsing
  1186      */
  1187      protected void parseChildren(NodeList childNodeList) throws BaseException {
  1188             throw new UnsupportedOperationException("Not supported yet.");
  1189      }
  1190 
  1191          /**
  1192      * Sets default values for attributes defined in this abstract class.
  1193      */
  1194     protected void setDefaultAttributes() {
  1195         setUserDefinedTableName("");
  1196         setUserDefinedSchemaName("");
  1197         setUserDefinedCatalogName("");
  1198         setTablePrefix("");
  1199         setAliasName("");
  1200         setUsingFullyQualifiedName(true);
  1201         setStagingTableName("");
  1202     }
  1203     
  1204     public String getResolvedCatalogName() {
  1205         // Ensure order of precedence for catalog name is followed.
  1206         String resolvedCatalogName = getUserDefinedCatalogName();
  1207         if (StringUtil.isNullString(resolvedCatalogName)) {
  1208             resolvedCatalogName = getCatalog();
  1209         }
  1210         return resolvedCatalogName;
  1211     }
  1212         
  1213     public String getResolvedSchemaName() {
  1214         // Ensure order of precedence for schema name is followed.
  1215         String resolvedSchemaName = getUserDefinedSchemaName();
  1216         if (StringUtil.isNullString(resolvedSchemaName)) {
  1217             resolvedSchemaName = getSchema();
  1218         }
  1219         return resolvedSchemaName;
  1220     }
  1221     
  1222     public String getResolvedTableName() {
  1223         // Ensure order of precedence for schema name is followed.
  1224         String resolvedTableName = getUserDefinedTableName();
  1225         if (StringUtil.isNullString(resolvedTableName)) {
  1226             resolvedTableName = getName();
  1227         }
  1228         return resolvedTableName;
  1229     }
  1230 }
  1231