001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.sql.framework.model.visitors;
042:
043: import com.sun.sql.framework.exception.BaseException;
044: import com.sun.sql.framework.exception.DBSQLException;
045: import java.util.ArrayList;
046: import java.util.Iterator;
047: import java.util.List;
048: import org.netbeans.modules.sql.framework.model.SQLDBColumn;
049: import org.netbeans.modules.sql.framework.model.SQLDBModel;
050: import org.netbeans.modules.sql.framework.model.SQLDBTable;
051: import org.netbeans.modules.sql.framework.model.SQLDefinition;
052: import org.netbeans.modules.sql.framework.model.ValidationInfo;
053: import org.netbeans.modules.sql.framework.model.impl.ValidationInfoImpl;
054: import java.sql.Connection;
055:
056: import net.java.hulp.i18n.Logger;
057: import org.netbeans.modules.etl.logger.Localizer;
058: import org.netbeans.modules.etl.logger.LogUtil;
059: import org.netbeans.modules.sql.framework.model.DBMetaDataFactory;
060: import org.netbeans.modules.sql.framework.common.utils.DBExplorerUtil;
061: import org.netbeans.modules.sql.framework.model.DBConnectionDefinition;
062: import org.netbeans.modules.sql.framework.model.impl.AbstractDBTable;
063:
064: /**
065: * @author Girish Patil
066: * @author Ahimanikya Satapathy
067: * @version $Revision$
068: */
069: public class SQLDBSynchronizationValidationVisitor {
070:
071: private static transient final Logger mLogger = LogUtil
072: .getLogger(SQLDBSynchronizationValidationVisitor.class
073: .getName());
074: private static transient final Localizer mLoc = Localizer.get();
075:
076: private class Table extends AbstractDBTable {
077:
078: public Table(String tname, String tcatalog, String tschema) {
079: super (tname, tschema, tcatalog);
080: }
081: }
082:
083: private List<ValidationInfo> validationInfoList = new ArrayList<ValidationInfo>();
084:
085: public List<ValidationInfo> getValidationInfoList() {
086: return this .validationInfoList;
087: }
088:
089: public void visit(SQLDBModel etlDBModel) throws BaseException,
090: DBSQLException, Exception {
091: DBMetaDataFactory meta = new DBMetaDataFactory();
092: Connection conn = null;
093: DBConnectionDefinition connDef = null;
094: connDef = etlDBModel.getETLDBConnectionDefinition();
095:
096: if (connDef != null) {
097: try {
098: conn = DBExplorerUtil.createConnection(connDef
099: .getConnectionProperties());
100: if (conn == null) {
101: return;
102: }
103: meta.connectDB(conn);
104: List collabTables = etlDBModel.getTables();
105:
106: if ((collabTables != null) && (!collabTables.isEmpty())) {
107: Iterator itr = collabTables.iterator();
108: SQLDBTable collabTable = null;
109: while (itr.hasNext()) {
110: collabTable = (SQLDBTable) itr.next();
111: compareCollabTableWithDatabaseTable(
112: collabTable, meta);
113: }
114: }
115: } finally {
116: meta.disconnectDB();
117: meta = null;
118: }
119: }
120: }
121:
122: public void visit(SQLDefinition definition) {
123: List collabDatabases = definition.getAllDatabases();
124: if ((collabDatabases != null) && (collabDatabases.size() > 0)) {
125: SQLDBModel etlDBModel = null;
126: Iterator itr = collabDatabases.iterator();
127: while (itr.hasNext()) {
128: try {
129: etlDBModel = (SQLDBModel) itr.next();
130: visit(etlDBModel);
131: } catch (Exception ex) {
132: ValidationInfo vInfo = new ValidationInfoImpl(
133: etlDBModel, ex.getMessage(),
134: ValidationInfo.VALIDATION_ERROR);
135: this .validationInfoList.add(vInfo);
136: }
137: }
138: }
139: }
140:
141: private void checkForUpdates(SQLDBColumn collabColumn,
142: List newColumns, SQLDBTable table) {
143: Iterator itr = newColumns.iterator();
144: SQLDBColumn newColumn = null;
145: boolean columnMatched = true;
146:
147: while (itr.hasNext()) {
148: newColumn = (SQLDBColumn) itr.next();
149: columnMatched = (compareWith(collabColumn, newColumn) == 0);
150: if (columnMatched) {
151: break;
152: }
153: }
154:
155: if (!columnMatched) {
156: // Column not present or is modified in Database
157: String nbBundle1 = mLoc
158: .t(
159: "PRSR001: Column {0} is removed or updated for table {1} in Database",
160: collabColumn.getName(), table.getName());
161: String desc = Localizer.parse(nbBundle1);
162: ValidationInfo vInfo = new ValidationInfoImpl(table, desc,
163: ValidationInfo.VALIDATION_ERROR);
164: this .validationInfoList.add(vInfo);
165: }
166: }
167:
168: private void checkForNewColumns(SQLDBColumn newColumn,
169: List newColumns, SQLDBTable table) {
170: Iterator itr = newColumns.iterator();
171: SQLDBColumn collabColumn = null;
172: boolean columnMatched = true;
173:
174: while (itr.hasNext()) {
175: collabColumn = (SQLDBColumn) itr.next();
176: columnMatched = (compareWith(collabColumn, newColumn) == 0);
177: if (columnMatched) {
178: break;
179: }
180: }
181:
182: if (!columnMatched) {
183: // new column found
184: String nbBundle2 = mLoc
185: .t(
186: "PRSR001: Column {0} is removed or updated for table {1} in Database",
187: collabColumn.getName(), table.getName());
188: String desc = Localizer.parse(nbBundle2);
189: ValidationInfo vInfo = new ValidationInfoImpl(table, desc,
190: ValidationInfo.VALIDATION_ERROR);
191: this .validationInfoList.add(vInfo);
192: }
193: }
194:
195: private int compareWith(SQLDBColumn collabCol, SQLDBColumn newCol) {
196: // compare primary keys
197: if (collabCol.isPrimaryKey() && !newCol.isPrimaryKey()) {
198: return -1;
199: } else if (!collabCol.isPrimaryKey() && newCol.isPrimaryKey()) {
200: return 1;
201: }
202:
203: // compare foreign keys
204: if (collabCol.isForeignKey() && !newCol.isForeignKey()) {
205: return -1;
206: } else if (!collabCol.isForeignKey() && newCol.isForeignKey()) {
207: return 1;
208: }
209:
210: // compare type
211: if (collabCol.getJdbcType() != newCol.getJdbcType()) {
212: return -1;
213: }
214:
215: // compare scale
216: if (collabCol.getScale() != newCol.getScale()) {
217: return -1;
218: }
219:
220: // compare getPrecision
221: if (collabCol.getPrecision() != newCol.getPrecision()) {
222: return -1;
223: }
224:
225: // compare getOrdinalPosition
226: if (collabCol.getOrdinalPosition() != newCol
227: .getOrdinalPosition()) {
228: return -1;
229: }
230:
231: // compare isNullable
232: if (collabCol.isNullable() != newCol.isNullable()) {
233: return -1;
234: }
235:
236: return 0;
237: }
238:
239: private void compareCollabTableWithDatabaseTable(
240: SQLDBTable collabTable, DBMetaDataFactory meta)
241: throws Exception {
242: if (meta.isTableOrViewExist(collabTable.getCatalog(),
243: collabTable.getSchema(), collabTable.getName())) {
244: // Get the table from database
245: Table newTable = new Table(collabTable.getName(),
246: collabTable.getCatalog(), collabTable.getSchema());
247: meta.populateColumns(newTable);
248:
249: List collabColumns = collabTable.getColumnList();
250: List newColumns = newTable.getColumnList();
251:
252: //Check for update and delete
253: for (Iterator itr = collabColumns.iterator(); itr.hasNext();) {
254: checkForUpdates((SQLDBColumn) itr.next(), newColumns,
255: collabTable);
256: }
257:
258: // check for new columns
259: for (Iterator itr = newColumns.iterator(); itr.hasNext();) {
260: checkForNewColumns((SQLDBColumn) itr.next(),
261: collabColumns, collabTable);
262: }
263:
264: // TODO: XXXXX We also need to check PK, FK, Index modifications XXXXX
265: } else {
266: String nbBundle3 = mLoc
267: .t(
268: "PRSR001: Table {0} is removed or renamed in Database",
269: collabTable.getName());
270: String desc = Localizer.parse(nbBundle3) + " "
271: + meta.getDBName();
272: ValidationInfo vInfo = new ValidationInfoImpl(collabTable,
273: desc, ValidationInfo.VALIDATION_ERROR);
274: validationInfoList.add(vInfo);
275: return;
276: }
277: }
278: }
|