etl.editor/src/org/netbeans/modules/sql/framework/model/visitors/SQLDBSynchronizationValidationVisitor.java
author rnithya@netbeans.org
Wed, 23 Apr 2008 15:56:05 +0530
changeset 4205 2739cb16db12
parent 4204 8ccd56245a55
child 4207 774fa5120845
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.visitors;
    42 
    43 import com.sun.sql.framework.exception.BaseException;
    44 import com.sun.sql.framework.exception.DBSQLException;
    45 import java.util.ArrayList;
    46 import java.util.Iterator;
    47 import java.util.List;
    48 import org.netbeans.modules.sql.framework.model.SQLDBColumn;
    49 import org.netbeans.modules.sql.framework.model.SQLDBModel;
    50 import org.netbeans.modules.sql.framework.model.SQLDBTable;
    51 import org.netbeans.modules.sql.framework.model.SQLDefinition;
    52 import org.netbeans.modules.sql.framework.model.ValidationInfo;
    53 import org.netbeans.modules.sql.framework.model.impl.ValidationInfoImpl;
    54 import java.sql.Connection;
    55 
    56 import net.java.hulp.i18n.Logger;
    57 import org.netbeans.modules.etl.logger.Localizer;
    58 import org.netbeans.modules.sql.framework.model.DBMetaDataFactory;
    59 import org.netbeans.modules.sql.framework.common.utils.DBExplorerUtil;
    60 import org.netbeans.modules.sql.framework.model.DBConnectionDefinition;
    61 import org.netbeans.modules.sql.framework.model.impl.AbstractDBTable;
    62 
    63 /**
    64  * @author Girish Patil
    65  * @author Ahimanikya Satapathy
    66  * @version $Revision$
    67  */
    68 public class SQLDBSynchronizationValidationVisitor {
    69 
    70     private static transient final Logger mLogger = Logger.getLogger(SQLDBSynchronizationValidationVisitor.class.getName());
    71     private static transient final Localizer mLoc = Localizer.get();
    72 
    73     private class Table extends AbstractDBTable {
    74 
    75         public Table(String tname, String tcatalog, String tschema) {
    76             super(tname, tschema, tcatalog);
    77         }
    78     }
    79     private List<ValidationInfo> validationInfoList = new ArrayList<ValidationInfo>();
    80 
    81     public List<ValidationInfo> getValidationInfoList() {
    82         return this.validationInfoList;
    83     }
    84 
    85     public void visit(SQLDBModel etlDBModel) throws BaseException, DBSQLException, Exception {
    86         DBMetaDataFactory meta = new DBMetaDataFactory();
    87         Connection conn = null;
    88         DBConnectionDefinition connDef = null;
    89         connDef = etlDBModel.getETLDBConnectionDefinition();
    90 
    91         if (connDef != null) {
    92             try {
    93                 conn = DBExplorerUtil.createConnection(connDef.getConnectionProperties());
    94                 if (conn == null) {
    95                     return;
    96                 }
    97                 meta.connectDB(conn);
    98                 List collabTables = etlDBModel.getTables();
    99 
   100                 if ((collabTables != null) && (!collabTables.isEmpty())) {
   101                     Iterator itr = collabTables.iterator();
   102                     SQLDBTable collabTable = null;
   103                     while (itr.hasNext()) {
   104                         collabTable = (SQLDBTable) itr.next();
   105                         compareCollabTableWithDatabaseTable(collabTable, meta);
   106                     }
   107                 }
   108             } finally {
   109                 meta.disconnectDB();
   110                 meta = null;
   111             }
   112         }
   113     }
   114 
   115     public void visit(SQLDefinition definition) {
   116         List collabDatabases = definition.getAllDatabases();
   117         if ((collabDatabases != null) && (collabDatabases.size() > 0)) {
   118             SQLDBModel etlDBModel = null;
   119             Iterator itr = collabDatabases.iterator();
   120             while (itr.hasNext()) {
   121                 try {
   122                     etlDBModel = (SQLDBModel) itr.next();
   123                     visit(etlDBModel);
   124                 } catch (Exception ex) {
   125                     ValidationInfo vInfo = new ValidationInfoImpl(etlDBModel, ex.getMessage(), ValidationInfo.VALIDATION_ERROR);
   126                     this.validationInfoList.add(vInfo);
   127                 }
   128             }
   129         }
   130     }
   131 
   132     private void checkForUpdates(SQLDBColumn collabColumn, List newColumns, SQLDBTable table, boolean ignorePrecision) {
   133         Iterator itr = newColumns.iterator();
   134         SQLDBColumn newColumn = null;
   135         boolean columnMatched = true;
   136 
   137         while (itr.hasNext()) {
   138             newColumn = (SQLDBColumn) itr.next();
   139             columnMatched = (compareWith(collabColumn, newColumn, ignorePrecision) == 0);
   140             if (columnMatched) {
   141                 break;
   142             }
   143         }
   144 
   145         if (!columnMatched) {
   146             // Column not present or is modified in Database
   147             String nbBundle1 = mLoc.t("BUND298: Column {0} is removed or updated for table {1} in Database", collabColumn.getName(), table.getName());
   148             String desc = nbBundle1.substring(15);
   149             ValidationInfo vInfo = new ValidationInfoImpl(table, desc, ValidationInfo.VALIDATION_ERROR);
   150             this.validationInfoList.add(vInfo);
   151         }
   152     }
   153 
   154     private void checkForNewColumns(SQLDBColumn newColumn, List newColumns, SQLDBTable table, boolean ignorePrecision) {
   155         Iterator itr = newColumns.iterator();
   156         SQLDBColumn collabColumn = null;
   157         boolean columnMatched = true;
   158 
   159         while (itr.hasNext()) {
   160             collabColumn = (SQLDBColumn) itr.next();
   161             columnMatched = (compareWith(collabColumn, newColumn, ignorePrecision) == 0);
   162             if (columnMatched) {
   163                 break;
   164             }
   165         }
   166 
   167         if (!columnMatched) {
   168             // new column found
   169             String nbBundle2 = mLoc.t("BUND928: Found new column{0} in Database ->{1}" , collabColumn.getName(),table.getParent().getModelName());
   170             String desc = nbBundle2.substring(15);
   171             ValidationInfo vInfo = new ValidationInfoImpl(table, desc, ValidationInfo.VALIDATION_ERROR);
   172             this.validationInfoList.add(vInfo);
   173         }
   174     }
   175 
   176     private int compareWith(SQLDBColumn collabCol, SQLDBColumn newCol, boolean ignorePrecision) {
   177         // compare primary keys
   178         if (collabCol.isPrimaryKey() && !newCol.isPrimaryKey()) {
   179             return -1;
   180         } else if (!collabCol.isPrimaryKey() && newCol.isPrimaryKey()) {
   181             return 1;
   182         }
   183 
   184         // compare foreign keys
   185         if (collabCol.isForeignKey() && !newCol.isForeignKey()) {
   186             return -1;
   187         } else if (!collabCol.isForeignKey() && newCol.isForeignKey()) {
   188             return 1;
   189         }
   190 
   191         // compare type
   192         if (collabCol.getJdbcType() != newCol.getJdbcType()) {
   193             return -1;
   194         }
   195 
   196         if(!ignorePrecision) {
   197         // compare scale
   198         if (collabCol.getScale() != newCol.getScale()) {
   199             return -1;
   200         }
   201 
   202         // compare getPrecision
   203         if (collabCol.getPrecision() != newCol.getPrecision()) {
   204             return -1;
   205             }
   206         }
   207 
   208         // compare getOrdinalPosition
   209         if (collabCol.getOrdinalPosition() != newCol.getOrdinalPosition()) {
   210             return -1;
   211         }
   212 
   213         // compare isNullable
   214         if (collabCol.isNullable() != newCol.isNullable()) {
   215             return -1;
   216         }
   217 
   218         return 0;
   219     }
   220 
   221     private void compareCollabTableWithDatabaseTable(SQLDBTable collabTable, DBMetaDataFactory meta) throws Exception {
   222         AbstractDBTable ct = ((AbstractDBTable)collabTable);
   223         if (meta.isTableOrViewExist(ct.getResolvedCatalogName(), ct.getResolvedSchemaName(), ct.getResolvedTableName())) {
   224             // Get the table from database
   225             Table newTable = new Table(ct.getResolvedCatalogName(), ct.getResolvedSchemaName(), ct.getResolvedTableName());
   226             meta.populateColumns(newTable);
   227 
   228             List collabColumns = collabTable.getColumnList();
   229             List newColumns = newTable.getColumnList();
   230 
   231             //Check for update and delete
   232             for (Iterator itr = collabColumns.iterator(); itr.hasNext();) {
   233                 SQLDBColumn oldCol = (SQLDBColumn) itr.next();
   234                 int sqlTypeCode = oldCol.getJdbcType();
   235                 boolean ignorePrecision = false;
   236                 if ((sqlTypeCode == java.sql.Types.DATE || sqlTypeCode == java.sql.Types.TIME || sqlTypeCode == java.sql.Types.TIMESTAMP || sqlTypeCode == java.sql.Types.NUMERIC) && meta.getDBType().equals(DBMetaDataFactory.AXION)) {
   237                     ignorePrecision = true;
   238                 }
   239                 checkForUpdates(oldCol, newColumns, collabTable, ignorePrecision);
   240             }
   241 
   242             // check for new columns
   243             for (Iterator itr = newColumns.iterator(); itr.hasNext();) {
   244                 SQLDBColumn newCol = (SQLDBColumn) itr.next();
   245                 int sqlTypeCode = newCol.getJdbcType();
   246                 boolean ignorePrecision = false;
   247                 if ((sqlTypeCode == java.sql.Types.DATE || sqlTypeCode == java.sql.Types.TIME || sqlTypeCode == java.sql.Types.TIMESTAMP || sqlTypeCode == java.sql.Types.NUMERIC) && meta.getDBType().equals(DBMetaDataFactory.AXION)) {
   248                     ignorePrecision = true;
   249                 }
   250                 checkForNewColumns(newCol, collabColumns, collabTable,ignorePrecision);
   251             }
   252 
   253         // TODO: XXXXX We also need to check PK, FK, Index modifications XXXXX
   254         } else {
   255             String nbBundle3 = mLoc.t("BUND299: Table {0} is removed or renamed in Database", collabTable.getName());
   256             String desc = nbBundle3.substring(15) + " " + meta.getDBName();
   257             ValidationInfo vInfo = new ValidationInfoImpl(collabTable, desc, ValidationInfo.VALIDATION_ERROR);
   258             validationInfoList.add(vInfo);
   259             return;
   260         }
   261     }
   262 }