0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041: package org.netbeans.modules.sql.framework.model.impl;
0042:
0043: import com.sun.sql.framework.exception.DBSQLException;
0044: import java.sql.Connection;
0045: import java.sql.ResultSet;
0046: import java.sql.SQLException;
0047: import java.sql.Statement;
0048: import java.util.ArrayList;
0049: import java.util.Collection;
0050: import java.util.Collections;
0051: import java.util.Comparator;
0052: import java.util.HashMap;
0053: import java.util.Iterator;
0054: import java.util.List;
0055: import java.util.Map;
0056: import java.util.Set;
0057: import java.util.UUID;
0058:
0059: import org.netbeans.modules.etl.model.ETLObject;
0060: import org.netbeans.modules.mashup.db.common.Property;
0061: import org.netbeans.modules.sql.framework.common.jdbc.SQLDBConnectionDefinition;
0062: import org.netbeans.modules.sql.framework.model.SQLConstants;
0063: import org.netbeans.modules.sql.framework.model.SQLDBModel;
0064: import org.netbeans.modules.sql.framework.model.SQLDBTable;
0065: import org.netbeans.modules.sql.framework.model.SQLFrameworkParentObject;
0066: import org.netbeans.modules.sql.framework.model.SQLModelObjectFactory;
0067: import org.netbeans.modules.sql.framework.model.SQLObject;
0068: import org.netbeans.modules.sql.framework.model.SourceTable;
0069: import org.netbeans.modules.sql.framework.model.TargetTable;
0070: import org.openide.util.Exceptions;
0071: import org.w3c.dom.Element;
0072: import org.w3c.dom.Node;
0073: import org.w3c.dom.NodeList;
0074: import net.java.hulp.i18n.Logger;
0075: import com.sun.sql.framework.exception.BaseException;
0076: import com.sun.sql.framework.jdbc.DBConnectionParameters;
0077: import com.sun.sql.framework.utils.Attribute;
0078: import java.io.File;
0079: import java.util.StringTokenizer;
0080: import java.util.regex.Pattern;
0081: import org.netbeans.modules.etl.logger.Localizer;
0082: import org.netbeans.modules.etl.logger.LogUtil;
0083: import org.netbeans.modules.etl.ui.ETLEditorSupport;
0084: import org.netbeans.modules.sql.framework.common.utils.DBExplorerUtil;
0085: import org.netbeans.modules.sql.framework.model.DBConnectionDefinition;
0086: import org.netbeans.modules.sql.framework.model.DBTable;
0087: import org.netbeans.modules.sql.framework.model.DatabaseModel;
0088: import org.openide.awt.StatusDisplayer;
0089:
0090: /**
0091: * SQLBuilder-specific concrete implementation of DatabaseModel interface.
0092: *
0093: * @author Jonathan Giron
0094: * @version $Revision$
0095: */
0096: public class SQLDBModelImpl extends AbstractSQLObject implements
0097: Cloneable, SQLDBModel {
0098:
0099: private static transient final Logger mLogger = LogUtil
0100: .getLogger(SQLDBModelImpl.class.getName());
0101: private static transient final Localizer mLoc = Localizer.get();
0102: private static java.util.logging.Logger logger = java.util.logging.Logger
0103: .getLogger(SQLDBModelImpl.class.getName());
0104: /** Initial buffer size for StringBuilder used in marshaling Databases to XML */
0105: protected static final int INIT_XMLBUF_SIZE = 1000;
0106: /*
0107: * String used to separate name, schema, and/or catalog Strings in a
0108: * fully-qualified table name.
0109: */
0110: private static final String FQ_TBL_NAME_SEPARATOR = ".";
0111: /* String to use in prefixing each line of a generated XML document */
0112: private static final String INDENT = "\t";
0113: /* Initial buffer size for StringBuilder used in marshaling Databases to XML */
0114: private static final String LOG_CATEGORY = SQLDBModelImpl.class
0115: .getName();
0116: /** Connection definition used to retrieve metadata */
0117: protected DBConnectionDefinition connectionDefinition;
0118: /** User-supplied description */
0119: protected volatile String description;
0120: /** User-supplied name */
0121: protected volatile String name;
0122: /** Map of DBTable instances */
0123: protected Map tables;
0124: private transient SQLFrameworkParentObject mParent;
0125: /* Database that supplied metadata for this DatabaseModel instance. */
0126: protected transient ETLObject source;
0127:
0128: /** Constructs a new default instance of SQLDBModelImpl. */
0129: public SQLDBModelImpl() {
0130: tables = new HashMap();
0131: type = SQLConstants.SOURCE_DBMODEL;
0132: setRefKey("{" + UUID.randomUUID().toString() + "}");
0133: }
0134:
0135: /**
0136: * @type SQLConstants.SOURCE_DBMODEL or SQLConstants.TARGET_DBMODEL
0137: */
0138: public SQLDBModelImpl(int type) {
0139: this ();
0140: this .type = type;
0141: }
0142:
0143: /**
0144: * Creates a new instance of SQLDBModelImpl, cloning the contents of the
0145: * given DatabaseModel implementation instance.
0146: *
0147: * @param src
0148: * DatabaseModel instance to be cloned
0149: * @param modelType
0150: * model type, either SOURCE_DBMODEL or TARGET_DBMODEL
0151: * @see SQLConstants#SOURCE_DBMODEL
0152: * @see SQLConstants#TARGET_DBMODEL
0153: */
0154: public SQLDBModelImpl(DatabaseModel src, int modelType,
0155: SQLFrameworkParentObject sqlParent) {
0156: this ();
0157:
0158: if (src == null) {
0159: throw new IllegalArgumentException(
0160: "Must supply non-null DatabseModel instance for src param.");
0161: }
0162:
0163: mParent = sqlParent;
0164: copyFrom(src, modelType);
0165:
0166: if (src instanceof ETLObject) {
0167: setSource((ETLObject) src);
0168: }
0169: }
0170:
0171: /**
0172: * Adds table to this instance.
0173: *
0174: * @param table
0175: * new table to add
0176: * @throws IllegalStateException
0177: * if unable to add table
0178: */
0179: public void addTable(SQLDBTable table) throws IllegalStateException {
0180: if (table != null) {
0181:
0182: if (type == SQLConstants.TARGET_DBMODEL
0183: && table.getObjectType() != SQLConstants.TARGET_TABLE) {
0184: throw new IllegalStateException(
0185: "Cannot add TargetTable to a non-target DatabaseModel!");
0186: }
0187:
0188: if (type == SQLConstants.SOURCE_DBMODEL
0189: && table.getObjectType() != SQLConstants.SOURCE_TABLE) {
0190: throw new IllegalStateException(
0191: "Cannot add TargetTable to a non-target DatabaseModel!");
0192: }
0193:
0194: // if table already exists then we should throw exception
0195: String fqName = getFullyQualifiedTableName(table);
0196: if (this .getTable(fqName) != null) {
0197: //throw new IllegalStateException("Cannot add table " + fqName + ", it already exist!");
0198: }
0199:
0200: table.setParent(this );
0201: tables.put(fqName, table);
0202: }
0203: }
0204:
0205: public void clearOverride(boolean clearCatalogOverride,
0206: boolean clearSchemaOverride) {
0207: List tbls = getTables();
0208: Iterator itr = tbls.iterator();
0209: SQLDBTable table = null;
0210: while (itr.hasNext()) {
0211: table = (SQLDBTable) itr.next();
0212: table.clearOverride(clearCatalogOverride,
0213: clearSchemaOverride);
0214: }
0215: }
0216:
0217: /**
0218: * Clones this object.
0219: *
0220: * @return shallow copy of this SQLDataSource
0221: */
0222: @Override
0223: public Object clone() {
0224: try {
0225: SQLDBModelImpl myClone = (SQLDBModelImpl) super .clone();
0226:
0227: myClone.attributes = new HashMap(attributes);
0228: myClone.name = name;
0229: myClone.id = id;
0230: myClone.displayName = displayName;
0231: myClone.description = description;
0232:
0233: myClone.tables = new HashMap();
0234: tables.putAll(tables);
0235:
0236: myClone.connectionDefinition = new SQLDBConnectionDefinitionImpl(
0237: getConnectionDefinition());
0238:
0239: return myClone;
0240: } catch (CloneNotSupportedException e) {
0241: throw new InternalError(e.toString());
0242: }
0243: }
0244:
0245: /**
0246: * check if a table exists This will check if a table is in database model,
0247: */
0248: public boolean containsTable(SQLDBTable table) {
0249: if (this .getTable(this .getFullyQualifiedTableName(table)) != null) {
0250: return true;
0251: }
0252:
0253: return false;
0254: }
0255:
0256: /**
0257: * Copies member values to those contained in the given DatabaseModel
0258: * instance.
0259: *
0260: * @param src
0261: * DatabaseModel whose contents are to be copied into this
0262: * instance
0263: */
0264: public void copyFrom(DatabaseModel src) {
0265: if (src instanceof SQLDBModel) {
0266: copyFrom(src, ((SQLDBModel) src).getObjectType());
0267: } else {
0268: copyFrom(src, SQLConstants.SOURCE_DBMODEL);
0269: }
0270: }
0271:
0272: /**
0273: * Copies member values to those contained in the given DatabaseModel
0274: * instance, using the given value for object type.
0275: *
0276: * @param src
0277: * DatabaseModel whose contents are to be copied into this
0278: * instance
0279: * @param objType
0280: * type of object (SOURCE_DBMODEL or TARGET_DBMODEL)
0281: */
0282: public void copyFrom(DatabaseModel src, int objType) {
0283: if (src != null) {
0284: name = src.getModelName();
0285: description = src.getModelDescription();
0286: type = objType;
0287:
0288: // Defer creation of connection info - lazy load only when
0289: // getConnectionDefinition() is called.
0290: connectionDefinition = new SQLDBConnectionDefinitionImpl(
0291: src.getConnectionDefinition());
0292:
0293: tables.clear();
0294: List srcTables = src.getTables();
0295: if (srcTables != null) {
0296: Iterator iter = srcTables.iterator();
0297: while (iter.hasNext()) {
0298: DBTable tbl = (DBTable) iter.next();
0299: SQLDBTable localTable = null;
0300:
0301: switch (type) {
0302: case SQLConstants.SOURCE_DBMODEL:
0303: localTable = SQLModelObjectFactory
0304: .getInstance().createSourceTable(tbl);
0305: addTable(localTable);
0306: break;
0307:
0308: case SQLConstants.TARGET_DBMODEL:
0309: localTable = SQLModelObjectFactory
0310: .getInstance().createTargetTable(tbl);
0311: addTable(localTable);
0312: break;
0313: }
0314: }
0315: }
0316:
0317: if (src instanceof SQLDBModel) {
0318: SQLDBModel object = (SQLDBModel) src;
0319:
0320: id = object.getId();
0321: displayName = object.getDisplayName();
0322: parentObject = object.getParentObject();
0323: }
0324:
0325: // if (src instanceof JDBCConnectionProvider) {
0326: // try {
0327: // String dBPath = ProjectUtil.getProjectPath((ProjectElement) src,
0328: // true);
0329: // connectionDefinition.setDbPathName(dBPath);
0330: //
0331: // if (src instanceof ProjectElement){
0332: // displayName = ((ProjectElement) src).getName();
0333: // }
0334: // } catch (Exception ex) {
0335: // // Log the exception.
0336: // }
0337: // } else {
0338: // ETLObject repObj = src.getSource();
0339: // if (repObj instanceof JDBCConnectionProvider) {
0340: // try {
0341: // String dBPath = ProjectUtil.getProjectPath((ProjectElement)
0342: // repObj, true);
0343: // connectionDefinition.setDBPathName(dBPath);
0344: // } catch (Exception ex) {
0345: // // Log the exception.
0346: // }
0347: // }
0348: // }
0349:
0350: setSource(src.getSource());
0351: }
0352: }
0353:
0354: /**
0355: * Create DBTable instance with the given table, schema, and catalog names.
0356: *
0357: * @param tableName
0358: * table name of new table
0359: * @param schemaName
0360: * schema name of new table
0361: * @param catalogName
0362: * catalog name of new table
0363: * @return an instance of SQLTable if successful, null if failed.
0364: */
0365: public DBTable createTable(String tableName, String schemaName,
0366: String catalogName) {
0367: SQLDBTable table = null;
0368:
0369: if (tableName == null || tableName.length() == 0) {
0370: throw new IllegalArgumentException(
0371: "tableName cannot be null");
0372: }
0373:
0374: switch (type) {
0375: case SQLConstants.SOURCE_DBMODEL:
0376: table = SQLModelObjectFactory.getInstance()
0377: .createSourceTable(tableName, schemaName,
0378: catalogName);
0379: addTable(table);
0380: break;
0381:
0382: case SQLConstants.TARGET_DBMODEL:
0383: table = SQLModelObjectFactory.getInstance()
0384: .createTargetTable(tableName, schemaName,
0385: catalogName);
0386: addTable(table);
0387: break;
0388: }
0389:
0390: return table;
0391: }
0392:
0393: /**
0394: * Deletes all tables associated with this data source.
0395: *
0396: * @return true if all tables were deleted successfully, false otherwise.
0397: */
0398: public boolean deleteAllTables() {
0399: this .tables.clear();
0400: return true;
0401: }
0402:
0403: /**
0404: * Delete table from the SQLDataSource
0405: *
0406: * @param fqTableName
0407: * fully qualified name of table to be deleted.
0408: * @return true if successful. false if failed.
0409: */
0410: public boolean deleteTable(String fqTableName) {
0411: if (fqTableName != null && fqTableName.trim().length() != 0) {
0412: this .tables.remove(fqTableName);
0413: return true;
0414: }
0415: return false;
0416: }
0417:
0418: /**
0419: * @see java.lang.Object#equals
0420: */
0421: @Override
0422: public boolean equals(Object refObj) {
0423: // Check for reflexivity.
0424: if (this == refObj) {
0425: return true;
0426: }
0427:
0428: boolean result = false;
0429:
0430: // Ensure castability (also checks for null refObj)
0431: if (refObj instanceof SQLDBModelImpl) {
0432: SQLDBModelImpl aSrc = (SQLDBModelImpl) refObj;
0433:
0434: result = ((aSrc.name != null) ? aSrc.name.equals(name)
0435: : (name == null));
0436:
0437: DBConnectionDefinition myConnDef = this
0438: .getConnectionDefinition();
0439: DBConnectionDefinition srcConnDef = aSrc
0440: .getConnectionDefinition();
0441: boolean connCheck = ((srcConnDef != null) ? srcConnDef
0442: .equals(myConnDef) : (myConnDef == null));
0443: result &= connCheck;
0444:
0445: boolean typeCheck = (aSrc.type == type);
0446: result &= typeCheck;
0447:
0448: if (tables != null && aSrc.tables != null) {
0449: Set objTbls = aSrc.tables.keySet();
0450: Set myTbls = tables.keySet();
0451:
0452: // Must be identical (no subsetting), hence the pair of tests.
0453: boolean tblCheck = myTbls.containsAll(objTbls)
0454: && objTbls.containsAll(myTbls);
0455: result &= tblCheck;
0456: }
0457: }
0458:
0459: return result;
0460: }
0461:
0462: /**
0463: * Gets the allTables attribute of the SQLDataSource object
0464: *
0465: * @return The allTables value
0466: */
0467: public synchronized Map getAllSQLTables() {
0468: return tables;
0469: }
0470:
0471: /**
0472: * get a list of tables based on table name, schema name and catalog name
0473: * since we allow duplicate tables this will return a list of tables
0474: */
0475: public List getAllTables(String tableName, String schemaName,
0476: String catalogName) {
0477:
0478: ArrayList tbls = new ArrayList();
0479:
0480: Iterator it = this .tables.values().iterator();
0481: while (it.hasNext()) {
0482: SQLDBTable table = (SQLDBTable) it.next();
0483: String tName = table.getName();
0484: String tSchemaName = table.getSchema();
0485: String tCatalogName = table.getCatalog();
0486:
0487: boolean found = true;
0488: found = tName != null ? tName.equals(tableName)
0489: : tableName == null;
0490: found &= tSchemaName != null ? tSchemaName
0491: .equals(schemaName) : schemaName == null;
0492: found &= tCatalogName != null ? tCatalogName
0493: .equals(catalogName)
0494: : (catalogName == null || catalogName.trim()
0495: .equals(""));
0496:
0497: if (found) {
0498: tbls.add(table);
0499: }
0500: }
0501:
0502: return tbls;
0503: }
0504:
0505: /**
0506: * Gets List of child SQLObjects belonging to this instance.
0507: *
0508: * @return List of child SQLObjects
0509: */
0510: @Override
0511: public List getChildSQLObjects() {
0512: return this .getTables();
0513: }
0514:
0515: /**
0516: * Gets SQLDBConnectionDefinition of the SQLDataSource object
0517: *
0518: * @return ConnectionDefinition of the SQLDataSource object
0519: */
0520: public DBConnectionDefinition getConnectionDefinition() {
0521: try {
0522: return getETLDBConnectionDefinition();
0523: } catch (BaseException e) {
0524: throw new IllegalStateException(
0525: "Could not obtain reference to DBConnectionDefinition");
0526: }
0527: }
0528:
0529: /**
0530: * Gets SQLDBConnectionDefinition of the SQLDataSource object
0531: *
0532: * @return ConnectionDefinition of the SQLDataSource object
0533: */
0534: public DBConnectionDefinition getETLDBConnectionDefinition()
0535: throws BaseException {
0536: if (connectionDefinition == null) {
0537: mLogger
0538: .infoNoloc(mLoc
0539: .t(
0540: "PRSR114: Lazy loading connection definition for DB model{0}",
0541: getDisplayName()));
0542: connectionDefinition = createETLDBConnectionDefinition();
0543: }
0544: return connectionDefinition;
0545: }
0546:
0547: /**
0548: * @see org.netbeans.modules.sql.framework.model.impl.AbstractSQLObject#getFooter
0549: */
0550: @Override
0551: public String getFooter() {
0552: return "";
0553: }
0554:
0555: /**
0556: * @see org.netbeans.modules.model.database.DatabaseModel#getFullyQualifiedTableName(DBTable)
0557: */
0558: public String getFullyQualifiedTableName(DBTable tbl) {
0559:
0560: if (tbl != null) {
0561: String tblName = tbl.getName();
0562: String schName = tbl.getSchema();
0563: String catName = tbl.getCatalog();
0564:
0565: if (tblName == null) {
0566: throw new IllegalArgumentException(
0567: "Cannot construct fully qualified table name, table name is null.");
0568: }
0569:
0570: StringBuilder buf = new StringBuilder(50);
0571:
0572: // since now we allow duplicate tables we need to make sure map
0573: // entries are
0574: // unique so we will add id also to fully qualified map if it is
0575: // available.
0576: if (tbl instanceof SQLDBTable) {
0577: SQLDBTable table = (SQLDBTable) tbl;
0578:
0579: String id1 = table.getId();
0580: String alias = table.getAliasName();
0581: if (id1 != null && id1.trim().length() != 0) {
0582: buf.append(id1.trim());
0583: buf.append(FQ_TBL_NAME_SEPARATOR);
0584: } else if (alias != null && alias.trim().length() != 0) {
0585: buf.append(alias.trim());
0586: buf.append(FQ_TBL_NAME_SEPARATOR);
0587: }
0588: }
0589:
0590: if (catName != null && catName.trim().length() != 0) {
0591: buf.append(catName.trim());
0592: buf.append(FQ_TBL_NAME_SEPARATOR);
0593: }
0594:
0595: if (schName != null && schName.trim().length() != 0) {
0596: buf.append(schName.trim());
0597: buf.append(FQ_TBL_NAME_SEPARATOR);
0598: }
0599:
0600: buf.append(tblName.trim());
0601:
0602: return buf.toString();
0603: }
0604:
0605: return null;
0606: }
0607:
0608: /**
0609: * @see org.netbeans.modules.model.database.DatabaseModel#getFullyQualifiedTableName(
0610: * java.lang.String, java.lang.String, java.lang.String)
0611: */
0612: public String getFullyQualifiedTableName(String tblName,
0613: String schName, String catName) {
0614: throw new IllegalAccessError(
0615: "This method is not supported, use getFullyQualifiedTableName(DBTable) instead.");
0616: }
0617:
0618: /**
0619: * @see org.netbeans.modules.sql.framework.model.impl.AbstractSQLObject#getHeader
0620: */
0621: @Override
0622: public String getHeader() {
0623: return "";
0624: }
0625:
0626: /**
0627: * @see org.netbeans.modules.model.database.DatabaseModel#getModelDescription
0628: */
0629: public String getModelDescription() {
0630: return description;
0631: }
0632:
0633: /**
0634: * @see org.netbeans.modules.model.database.DatabaseModel#getModelName
0635: */
0636: public String getModelName() {
0637: return this .name;
0638: }
0639:
0640: /**
0641: * Gets SQLObject, if any, having the given object ID.
0642: *
0643: * @param objectId
0644: * ID of SQLObject being sought
0645: * @return SQLObject associated with objectID, or null if no such object
0646: * exists.
0647: */
0648: public SQLObject getObject(String objectId) {
0649: List list = this .getTables();
0650: Iterator it = list.iterator();
0651:
0652: while (it.hasNext()) {
0653: SQLDBTable dbTable = (SQLDBTable) it.next();
0654: // if looking for table then return table
0655: if (objectId.equals(dbTable.getId())) {
0656: return dbTable;
0657: }
0658:
0659: // check tables child list and see if a column is found
0660: SQLObject columnObj = dbTable.getObject(objectId);
0661: if (columnObj != null) {
0662: return columnObj;
0663: }
0664: }
0665:
0666: return null;
0667: }
0668:
0669: public String getRefKey() {
0670: return (String) getAttributeObject(REFKEY);
0671: }
0672:
0673: /**
0674: * Gets repository object, if any, providing underlying data for this
0675: * DatabaseModel implementation.
0676: *
0677: * @return ETLObject hosting this object's metadata, or null if data are not
0678: * held by a ETLObject.
0679: */
0680: public ETLObject getSource() {
0681: return this .source;
0682: }
0683:
0684: /**
0685: * @see org.netbeans.modules.model.database.DatabaseModel#getTable(java.lang.String)
0686: * fully qualified name should be catalog.schema.table.id
0687: */
0688: public DBTable getTable(String fqTableName) {
0689: return (DBTable) this .tables.get(fqTableName);
0690: }
0691:
0692: /**
0693: * NOTE: This method will return first matching table, since now we allow
0694: * duplicate tables, so if you want to get specific table use
0695: * getFullyQualifiedTableName(DBTable tbl) to generate a qualified name
0696: * which includes object id then call getTable(fqName)
0697: *
0698: * @see org.netbeans.modules.model.database.DatabaseModel#getTable(java.lang.String,
0699: * java.lang.String, java.lang.String)
0700: */
0701: public DBTable getTable(String tableName, String schemaName,
0702: String catalogName) {
0703: Iterator it = this .tables.values().iterator();
0704: while (it.hasNext()) {
0705: SQLDBTable table = (SQLDBTable) it.next();
0706: String tName = table.getName();
0707: String tSchemaName = table.getSchema();
0708: String tCatalogName = table.getCatalog();
0709:
0710: boolean found = true;
0711: found = tName != null ? tName.equals(tableName)
0712: : tableName == null;
0713: found &= tSchemaName != null ? tSchemaName
0714: .equals(schemaName) : schemaName == null;
0715: found &= tCatalogName != null ? tCatalogName
0716: .equals(catalogName)
0717: : (catalogName == null || catalogName.trim()
0718: .equals(""));
0719:
0720: if (found) {
0721: return table;
0722: }
0723: }
0724:
0725: return null;
0726: }
0727:
0728: /**
0729: * Gets a read-only Map of table names to available DBTable instances in
0730: * this model.
0731: *
0732: * @return readonly Map of table names to DBTable instances
0733: */
0734: public Map getTableMap() {
0735: return Collections.unmodifiableMap(tables);
0736: }
0737:
0738: /**
0739: * @see org.netbeans.modules.model.database.DatabaseModel#getTables
0740: */
0741: public List getTables() {
0742: List list = Collections.EMPTY_LIST;
0743: Collection tableColl = tables.values();
0744:
0745: if (tableColl.size() != 0) {
0746: list = new ArrayList(tableColl.size());
0747: list.addAll(tableColl);
0748: }
0749:
0750: return Collections.unmodifiableList(list);
0751: }
0752:
0753: /**
0754: * Overrides default implementation to compute hashCode value for those
0755: * members used in equals() for comparison.
0756: *
0757: * @return hash code for this object
0758: * @see java.lang.Object#hashCode
0759: */
0760: @Override
0761: public int hashCode() {
0762: int myHash = (name != null) ? name.hashCode() : 0;
0763: myHash += (connectionDefinition != null) ? connectionDefinition
0764: .hashCode() : 0;
0765: myHash += type;
0766:
0767: if (tables != null) {
0768: myHash += tables.keySet().hashCode();
0769: }
0770:
0771: return myHash;
0772: }
0773:
0774: public void overrideCatalogNames(Map catalogOverride) {
0775: List tbls = getTables();
0776: Iterator itr = tbls.iterator();
0777: SQLDBTable table = null;
0778: String origName = null;
0779: String newName = null;
0780:
0781: while (itr.hasNext()) {
0782: table = (SQLDBTable) itr.next();
0783: origName = table.getCatalog();
0784: if (origName != null) {
0785: newName = (String) catalogOverride.get(origName);
0786: if (newName != null) {
0787: table.overrideCatalogName(newName);
0788: }
0789: }
0790: }
0791: }
0792:
0793: public void overrideSchemaNames(Map schemaOverride) {
0794: List tbls = getTables();
0795: Iterator itr = tbls.iterator();
0796: SQLDBTable table = null;
0797: String origName = null;
0798: String newName = null;
0799:
0800: while (itr.hasNext()) {
0801: table = (SQLDBTable) itr.next();
0802: origName = table.getSchema();
0803: if (origName != null) {
0804: newName = (String) schemaOverride.get(origName);
0805: if (newName != null) {
0806: table.overrideSchemaName(newName);
0807: }
0808: }
0809: }
0810: }
0811:
0812: /**
0813: * Parses the XML content, if any, using the given Element as a source for
0814: * reconstituting the member variables and collections of this instance.
0815: *
0816: * @param dbElement
0817: * DOM element containing XML marshalled version of a
0818: * @exception BaseException
0819: * thrown while parsing XML, or if member variable element is
0820: * null
0821: */
0822: @Override
0823: public void parseXML(Element dbElement) throws BaseException {
0824: if (dbElement == null) {
0825: throw new BaseException(
0826: "Must supply non-null org.w3c.dom.Element ref for element. No <"
0827: + MODEL_TAG + "> element found.");
0828: }
0829:
0830: if (!MODEL_TAG.equals(dbElement.getNodeName())) {
0831: throw new BaseException("Invalid root element; expected "
0832: + MODEL_TAG + ", got " + dbElement.getNodeName());
0833: }
0834:
0835: super .parseXML(dbElement);
0836:
0837: name = dbElement.getAttribute(NAME);
0838:
0839: String typeStr = dbElement.getAttribute(TYPE);
0840:
0841: NodeList childNodeList = null;
0842:
0843: if (STRTYPE_TARGET.equals(typeStr)) {
0844: type = SQLConstants.TARGET_DBMODEL;
0845: childNodeList = dbElement
0846: .getElementsByTagName(SQLDBTable.TABLE_TAG);
0847: parseTargetTables(childNodeList);
0848: } else if (STRTYPE_SOURCE.equals(typeStr)) {
0849: type = SQLConstants.SOURCE_DBMODEL;
0850: childNodeList = dbElement
0851: .getElementsByTagName(SQLDBTable.TABLE_TAG);
0852: parseSourceTables(childNodeList);
0853: } else {
0854: throw new BaseException(
0855: "Missing or invalid modelType attribute: "
0856: + typeStr);
0857: }
0858:
0859: childNodeList = dbElement
0860: .getElementsByTagName(DBConnectionParameters.CONNECTION_DEFINITION_TAG);
0861: int length = childNodeList.getLength();
0862:
0863: for (int i = 0; i < length; i++) {
0864: if (childNodeList.item(i).getNodeType() == Node.ELEMENT_NODE) {
0865: Element tmpElement = (Element) (childNodeList.item(i));
0866:
0867: this .connectionDefinition = new SQLDBConnectionDefinitionImpl();
0868: ((DBConnectionParameters) this .connectionDefinition)
0869: .parseXML(tmpElement);
0870:
0871: }
0872: }
0873:
0874: }
0875:
0876: public void setConnectionDefinition(
0877: DBConnectionDefinition dbConnectionDef) {
0878: this .connectionDefinition = new SQLDBConnectionDefinitionImpl(
0879: dbConnectionDef);
0880: }
0881:
0882: /**
0883: * Sets the description string of this DatabaseModel
0884: *
0885: * @param newDesc
0886: * new description string
0887: */
0888: public void setDescription(String newDesc) {
0889: this .description = newDesc;
0890: }
0891:
0892: /**
0893: * @see org.netbeans.modules.model.database.DatabaseModel#getModelName
0894: */
0895: public void setModelName(String name) {
0896: if (name.startsWith(DBExplorerUtil.AXION_URL_PREFIX)
0897: && name.contains(ETLEditorSupport.PRJ_PATH)) {
0898: String[] urlParts = DBExplorerUtil.parseConnUrl(name);
0899: this .name = urlParts[0];
0900: } else {
0901: if (name.length() > 60) {
0902: this .name = name.substring(name.length() - 60);
0903: } else {
0904: this .name = name;
0905: }
0906: }
0907: }
0908:
0909: public void setRefKey(String aKey) {
0910: setAttribute(REFKEY, aKey);
0911: }
0912:
0913: /**
0914: * Sets repository object, if any, providing underlying data for this
0915: * DatabaseModel implementation.
0916: *
0917: * @param obj
0918: * Object hosting this object's metadata, or null if data are not
0919: * held by a ETLObject.
0920: */
0921: public void setSource(ETLObject obj) {
0922: source = obj;
0923: }
0924:
0925: @SuppressWarnings("unchecked")
0926: public void setSQLFrameworkParentObject(
0927: SQLFrameworkParentObject aParent) {
0928: if (mParent == null) {
0929: mParent = aParent;
0930: }
0931:
0932: if (getRefKey() == null) {
0933: this .setSource(source);
0934: }
0935: }
0936:
0937: private boolean validateConnDefinition(
0938: DBConnectionDefinition connDef) {
0939: String dbUrl = connDef.getConnectionURL();
0940: Pattern pattern = Pattern.compile("jdbc:axiondb:");
0941: java.util.regex.Matcher matcher = pattern.matcher(dbUrl);
0942: dbUrl = matcher.replaceAll("");
0943: StringTokenizer tokenizer = new StringTokenizer(dbUrl, ":");
0944: String conPath = null;
0945: ArrayList tmpList = new ArrayList();
0946: while (tokenizer.hasMoreTokens()) {
0947: tmpList.add(tokenizer.nextToken());
0948: }
0949: String[] recordSeps = (String[]) tmpList.toArray(new String[0]);
0950: //Check if conPath is a valid file/directory
0951: StringBuffer sb = new StringBuffer();
0952: if (recordSeps[1] != null && recordSeps[1].length() != 0) {
0953: sb.append(recordSeps[1]);
0954: }
0955: if (recordSeps[2] != null && recordSeps[2].length() != 0) {
0956: sb.append(":").append(recordSeps[2]);
0957: }
0958: File f = new File(sb.toString());
0959: if (!f.exists()) {
0960: StatusDisplayer.getDefault().setStatusText(
0961: "Check ConnectionDefinition." + conPath);
0962: return false;
0963: }
0964: return true;
0965: }
0966:
0967: /**
0968: * @param condef
0969: * @param element
0970: */
0971: @SuppressWarnings("unchecked")
0972: public HashMap<String, Property> getTableMetaData(
0973: DBConnectionDefinition conndef, SQLDBTable element) {
0974: HashMap<String, Property> map = new HashMap<String, Property>();
0975: final String prefix = "ORGPROP_";
0976: Collection<String> attrNames = (Collection<String>) element
0977: .getAttributeNames();
0978: for (String attrName : attrNames) {
0979: Object attrValue = element.getAttributeObject(attrName);
0980: if (attrName.startsWith(prefix)) {
0981: attrName = attrName.substring(attrName.indexOf(prefix)
0982: + prefix.length());
0983: Property prop = new Property();
0984: if (attrValue instanceof java.lang.Boolean) {
0985: prop = new Property(attrName, Boolean.class, true);
0986: prop.setValue((Boolean) attrValue);
0987: map.put(attrName, prop);
0988: } else if (attrValue instanceof java.lang.Integer) {
0989: prop = new Property(attrName, Integer.class, true);
0990: prop.setValue((Integer) attrValue);
0991: map.put(attrName, prop);
0992: } else {
0993: prop = new Property(attrName, String.class, true);
0994: prop.setValue((String) attrValue);
0995: map.put(attrName, prop);
0996: }
0997: }
0998: }
0999: return map;
1000: }
1001:
1002: /**
1003: * Overrides default implementation to return name of this DatabaseModel.
1004: *
1005: * @return model name.
1006: */
1007: @Override
1008: public String toString() {
1009: return this .getModelName();
1010: }
1011:
1012: /**
1013: * Gets xml representation of this DatabaseModel instance.
1014: *
1015: * @param prefix
1016: * for this xml.
1017: * @return Return the xml representation of data source metadata.
1018: * @exception BaseException -
1019: * exception
1020: */
1021: @Override
1022: public String toXMLString(String prefix) throws BaseException {
1023: StringBuilder xml = new StringBuilder(INIT_XMLBUF_SIZE);
1024: if (prefix == null) {
1025: prefix = "";
1026: }
1027:
1028: xml.append(prefix).append("<").append(MODEL_TAG).append(" ")
1029: .append(NAME).append("=\"").append(name.trim()).append(
1030: "\"");
1031:
1032: if (id != null && id.trim().length() != 0) {
1033: xml.append(" ").append(ID).append("=\"").append(id.trim())
1034: .append("\"");
1035: }
1036:
1037: if (displayName != null && displayName.trim().length() != 0) {
1038: xml.append(" ").append(DISPLAY_NAME).append("=\"").append(
1039: displayName.trim()).append("\"");
1040: }
1041:
1042: switch (type) {
1043: case SQLConstants.SOURCE_DBMODEL:
1044: xml.append(" " + TYPE + "=\"").append(STRTYPE_SOURCE)
1045: .append("\"");
1046: break;
1047:
1048: case SQLConstants.TARGET_DBMODEL:
1049: xml.append(" " + TYPE + "=\"").append(STRTYPE_TARGET)
1050: .append("\"");
1051: break;
1052:
1053: default:
1054: break;
1055: }
1056:
1057: xml.append(">\n");
1058:
1059: xml.append(super .toXMLAttributeTags(prefix));
1060:
1061: // write out tables
1062: writeTables(prefix, xml);
1063:
1064: // write connection defs
1065: xml.append(getXMLConnectionDefition());
1066:
1067: xml.append(prefix).append("</").append(MODEL_TAG).append(">\n");
1068: return xml.toString();
1069: }
1070:
1071: /**
1072: * Extracts SourceTable instances from the given NodeList.
1073: *
1074: * @param tableNodeList
1075: * Nodes to be unmarshaled
1076: * @throws BaseException
1077: * if error occurs while parsing
1078: */
1079: protected void parseSourceTables(NodeList tableNodeList)
1080: throws BaseException {
1081: for (int i = 0; i < tableNodeList.getLength(); i++) {
1082: if (tableNodeList.item(i).getNodeType() == Node.ELEMENT_NODE) {
1083: Element tableElement = (Element) tableNodeList.item(i);
1084:
1085: SourceTable table = new SourceTableImpl();
1086: table.setParentObject(this );
1087:
1088: table.parseXML(tableElement);
1089: addTable(table);
1090: }
1091: }
1092: }
1093:
1094: /**
1095: * Extracts TargetTable instances from the given NodeList.
1096: *
1097: * @param tableNodeList
1098: * Nodes to be unmarshaled
1099: * @throws BaseException
1100: * if error occurs while parsing
1101: */
1102: protected void parseTargetTables(NodeList tableNodeList)
1103: throws BaseException {
1104: for (int i = 0; i < tableNodeList.getLength(); i++) {
1105: if (tableNodeList.item(i).getNodeType() == Node.ELEMENT_NODE) {
1106: Element tableElement = (Element) tableNodeList.item(i);
1107:
1108: TargetTable table = new TargetTableImpl();
1109: table.setParentObject(this );
1110:
1111: table.parseXML(tableElement);
1112: this .addTable(table);
1113: }
1114: }
1115: }
1116:
1117: /**
1118: * Write table
1119: *
1120: * @param prefix -
1121: * prefix
1122: * @param xml -
1123: * StringBuilder
1124: * @throws BaseException -
1125: * exception
1126: */
1127: protected void writeTables(String prefix, StringBuilder xml)
1128: throws BaseException {
1129: // Ensure tables are written out in ascending name order.
1130: List tblList = new ArrayList(tables.keySet());
1131: Collections.sort(tblList, new Comparator() {
1132:
1133: public int compare(Object o1, Object o2) {
1134: if (o1 instanceof String && o2 instanceof String) {
1135: return ((String) o1).compareTo((String) o2);
1136: }
1137: throw new ClassCastException(
1138: "Cannot compare objects from different classes");
1139: }
1140: });
1141:
1142: Iterator iter = tblList.listIterator();
1143: while (iter.hasNext()) {
1144: String key = (String) iter.next();
1145: SQLDBTable table = (SQLDBTable) tables.get(key);
1146: xml.append(table.toXMLString(prefix + INDENT));
1147: }
1148: }
1149:
1150: private String getXMLConnectionDefition() {
1151: if (connectionDefinition != null
1152: && connectionDefinition instanceof SQLDBConnectionDefinition) {
1153: return ((SQLDBConnectionDefinition) connectionDefinition)
1154: .toXMLString();
1155: } else {
1156: return "";
1157: }
1158: }
1159:
1160: private SQLDBConnectionDefinition createETLDBConnectionDefinition() {
1161: DatabaseModel dbModel = (DatabaseModel) this .getSource();
1162: return createETLDBConnectionDefinition(dbModel);
1163: }
1164:
1165: private SQLDBConnectionDefinition createETLDBConnectionDefinition(
1166: DatabaseModel dbModel) {
1167: SQLDBConnectionDefinition etlConnDef = null;
1168: if (dbModel != null) {
1169: etlConnDef = new SQLDBConnectionDefinitionImpl(dbModel
1170: .getConnectionDefinition());
1171: try {
1172: etlConnDef.setName(this .getModelName());
1173: } catch (Exception ex) {
1174: mLogger.errorNoloc(mLoc.t("PRSR115: Exception{0}",
1175: LOG_CATEGORY), ex);
1176: }
1177: } else {
1178: etlConnDef = new SQLDBConnectionDefinitionImpl();
1179: }
1180:
1181: return etlConnDef;
1182: }
1183: }
|