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.DBSQLException;
044: import java.sql.Connection;
045: import java.util.Iterator;
046: import java.util.List;
047: import org.netbeans.modules.sql.framework.model.SQLDBColumn;
048: import org.netbeans.modules.sql.framework.model.SQLDBTable;
049: import org.netbeans.modules.sql.framework.model.SourceTable;
050: import org.netbeans.modules.sql.framework.model.TargetTable;
051: import org.netbeans.modules.sql.framework.model.ValidationInfo;
052: import org.netbeans.modules.sql.framework.model.impl.SourceColumnImpl;
053: import org.netbeans.modules.sql.framework.model.impl.TargetColumnImpl;
054: import org.netbeans.modules.sql.framework.model.impl.ValidationInfoImpl;
055: import org.netbeans.modules.sql.framework.ui.view.graph.MetaTableModel;
056: import java.util.ArrayList;
057: import net.java.hulp.i18n.Logger;
058: import org.netbeans.modules.etl.logger.Localizer;
059: import org.netbeans.modules.etl.logger.LogUtil;
060: import org.netbeans.modules.sql.framework.model.DBMetaDataFactory;
061: import org.netbeans.modules.sql.framework.common.utils.DBExplorerUtil;
062: import org.netbeans.modules.sql.framework.model.DBConnectionDefinition;
063: import org.netbeans.modules.sql.framework.model.SQLDBModel;
064: import org.netbeans.modules.sql.framework.model.impl.AbstractDBTable;
065:
066: /**
067: * @author Ahimanikya Satapathy
068: * @author Nithya Radhakrishnan
069: * @version $Revision$
070: */
071: public class SQLDBSynchronizationVisitor {
072:
073: private static transient final Logger mLogger = LogUtil
074: .getLogger(SQLDBSynchronizationVisitor.class.getName());
075: private static transient final Localizer mLoc = Localizer.get();
076:
077: private class Table extends AbstractDBTable {
078:
079: public Table(String tname, String tcatalog, String tschema) {
080: super (tname, tschema, tcatalog);
081: }
082: }
083:
084: public List<ValidationInfo> infoList = new ArrayList<ValidationInfo>();
085:
086: private void mergeUpdates(SQLDBColumn collabColumn,
087: List newColumns, SQLDBTable table, MetaTableModel tableModel) {
088: SQLDBColumn newColumn = null;
089: boolean columnMatched = true;
090:
091: for (Iterator itr = newColumns.iterator(); itr.hasNext();) {
092: newColumn = (SQLDBColumn) itr.next();
093: String newColName = newColumn.getName();
094: String collabColName = collabColumn.getName();
095:
096: // check whether column name match
097: columnMatched = (collabColName.compareTo(newColName) == 0);
098:
099: // If column name match
100: if (columnMatched) {
101: // Check whether the column metadata is not matching
102: if (compareWith(collabColumn, newColumn) != 0) {
103: // *** UPDATE ***
104: copyFrom(newColumn, collabColumn);
105: tableModel
106: .updateColumn(collabColName, collabColumn);
107: String desc = collabColumn.getQualifiedName()
108: + " was updated from Database "
109: + table.getParent().getModelName();
110: ValidationInfo vInfo = new ValidationInfoImpl(
111: collabColumn, desc,
112: ValidationInfo.VALIDATION_WARNING);
113: infoList.add(vInfo);
114: }
115: break;
116: }
117: }
118:
119: // column does not exist in the new table
120: if (!columnMatched) {
121: // *** DELETE *** the column
122: table.deleteColumn(collabColumn.getName());
123: tableModel.removeColumn(collabColumn);
124: String desc = collabColumn.getQualifiedName()
125: + " was deleted since it no longer exists in Database "
126: + table.getParent().getModelName();
127: ValidationInfo vInfo = new ValidationInfoImpl(collabColumn,
128: desc, ValidationInfo.VALIDATION_WARNING);
129: infoList.add(vInfo);
130: }
131: }
132:
133: public void copyFrom(SQLDBColumn source, SQLDBColumn target) {
134: target.setJdbcType(source.getJdbcType());
135: target.setScale(source.getScale());
136: target.setPrecision(source.getPrecision());
137: target.setOrdinalPosition(source.getOrdinalPosition());
138: target.setPrimaryKey(source.isPrimaryKey());
139: target.setForeignKey(source.isForeignKey());
140: target.setNullable(source.isNullable());
141: }
142:
143: private int compareWith(SQLDBColumn collabCol, SQLDBColumn newCol) {
144: // compare primary keys
145: if (collabCol.isPrimaryKey() && !newCol.isPrimaryKey()) {
146: return -1;
147: } else if (!collabCol.isPrimaryKey() && newCol.isPrimaryKey()) {
148: return 1;
149: }
150:
151: // compare foreign keys
152: if (collabCol.isForeignKey() && !newCol.isForeignKey()) {
153: return -1;
154: } else if (!collabCol.isForeignKey() && newCol.isForeignKey()) {
155: return 1;
156: }
157:
158: // compare type
159: if (collabCol.getJdbcType() != newCol.getJdbcType()) {
160: return -1;
161: }
162:
163: // compare scale
164: if (collabCol.getScale() != newCol.getScale()) {
165: return -1;
166: }
167:
168: // compare getPrecision
169: if (collabCol.getPrecision() != newCol.getPrecision()) {
170: return -1;
171: }
172:
173: // compare getOrdinalPosition
174: if (collabCol.getOrdinalPosition() != newCol
175: .getOrdinalPosition()) {
176: return -1;
177: }
178:
179: // compare isNullable
180: if (collabCol.isNullable() != newCol.isNullable()) {
181: return -1;
182: }
183:
184: return 0;
185: }
186:
187: private void mergeNewColumns(SQLDBColumn newColumn,
188: List collabColumns, SQLDBTable table,
189: MetaTableModel tableModel) {
190: SQLDBColumn collabColumn = null;
191: boolean columnMatched = true;
192:
193: for (Iterator itr = collabColumns.iterator(); itr.hasNext();) {
194: collabColumn = (SQLDBColumn) itr.next();
195: String newColName = newColumn.getName();
196: String collabColName = collabColumn.getName();
197:
198: // check whether column name match
199: columnMatched = (collabColName.compareTo(newColName) == 0);
200:
201: // If column name match
202: if (columnMatched) {
203: break;
204: }
205: }
206:
207: if (!columnMatched) {
208: SQLDBColumn col = null;
209: if (table instanceof SourceTable) {
210: col = new SourceColumnImpl(newColumn);
211: } else if (table instanceof TargetTable) {
212: col = new TargetColumnImpl(newColumn);
213: }
214: // *** ADD *** the column
215: table.addColumn(col);
216: tableModel.addColumn(col);
217: String desc1 = "Found new column in Database -> "
218: + table.getParent().getModelName()
219: + col.getQualifiedName() + " was added";
220: ValidationInfo vInfo1 = new ValidationInfoImpl(
221: collabColumn, desc1, ValidationInfo.VALIDATION_INFO);
222: infoList.add(vInfo1);
223: }
224: }
225:
226: public void mergeCollabTableWithDatabaseTable(
227: SQLDBTable collabTable, MetaTableModel tableModel)
228: throws DBSQLException, Exception {
229: DBMetaDataFactory meta = new DBMetaDataFactory();
230: DBConnectionDefinition connDef = ((SQLDBModel) collabTable
231: .getParentObject()).getETLDBConnectionDefinition();
232: Connection conn = DBExplorerUtil.createConnection(connDef
233: .getConnectionProperties());
234: if (conn == null) {
235: return;
236: }
237:
238: try {
239: meta.connectDB(conn);
240:
241: if (meta.isTableOrViewExist(collabTable.getCatalog(),
242: collabTable.getSchema(), collabTable.getName())) {
243: // Get the table from database
244: Table newTable = new Table(collabTable.getName(),
245: collabTable.getCatalog(), collabTable
246: .getSchema());
247: meta.populateColumns(newTable);
248:
249: List collabColumns = collabTable.getColumnList();
250: List newColumns = newTable.getColumnList();
251:
252: for (Iterator itr = collabColumns.iterator(); itr
253: .hasNext();) {
254: mergeUpdates((SQLDBColumn) itr.next(), newColumns,
255: collabTable, tableModel);
256: }
257: for (Iterator itr = newColumns.iterator(); itr
258: .hasNext();) {
259: mergeNewColumns((SQLDBColumn) itr.next(),
260: collabColumns, collabTable, tableModel);
261: }
262:
263: // TODO: XXXXX We also need to check PK, FK, Index modifications XXXXX
264: } else {
265: String nbBundle1 = mLoc
266: .t(
267: "PRSR001: Table {0} is removed or renamed in Database",
268: collabTable.getName());
269: String desc = Localizer.parse(nbBundle1) + " "
270: + connDef.getConnectionURL();
271: ValidationInfo vInfo = new ValidationInfoImpl(
272: collabTable, desc,
273: ValidationInfo.VALIDATION_ERROR);
274: infoList.add(vInfo);
275: return;
276: }
277: } finally {
278: meta.disconnectDB();
279: }
280: }
281: }
|