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.visualweb.dataconnectivity.model;
042:
043: import org.netbeans.modules.visualweb.dataconnectivity.sql.DatabaseMetaDataHelper;
044: import org.netbeans.modules.visualweb.dataconnectivity.sql.DesignTimeDataSource;
045: import org.netbeans.modules.visualweb.dataconnectivity.sql.DesignTimeDataSourceAlias;
046: import javax.sql.DataSource;
047: import java.sql.SQLException;
048: import java.util.Arrays;
049: import java.util.Collection;
050: import java.util.HashSet;
051: import java.util.Iterator;
052: import java.util.Set;
053: import java.util.SortedSet;
054: import javax.naming.NamingException;
055: import javax.swing.SwingUtilities;
056: import org.openide.DialogDisplayer;
057: import org.openide.ErrorManager;
058: import org.openide.NotifyDescriptor;
059: import org.openide.util.NbBundle;
060:
061: /**
062: * Wrapper class, helps pass around info related to a database metadata
063: * and the name associated with the data source
064: * @author Octavian Tanase, Winston Prakash
065: */
066: // XXX - This class should just extend DesigntimeDatasource - WJP
067: public class DataSourceInfo {
068: /** Data Source name */
069: private String name;
070: /** */
071: private DesignTimeDataSource dataSource;
072: /** A handle to the database metadata */
073: private DatabaseMetaDataHelper dbmdh;
074:
075: String dataSourceId;
076:
077: Set listeners = new HashSet();
078:
079: boolean connected = false;
080: boolean connectionTested = false;
081:
082: String connectionMsg = null;
083:
084: long connectionTimeout = 30000;
085:
086: public DataSourceInfo(String name, DesignTimeDataSource dataSource) {
087: this .name = name;
088: setDataSource(dataSource);
089: dbmdh = null;
090: // setId(DataSourceInfoManager.getInstance().getUniqueDataSourceId());
091:
092: // Used as tooltip in the Datasource node
093: if (isAlias()) {
094: connectionMsg = "Alias to " + getAlias() + "("
095: + connectionMsg + ")";
096: connectionMsg = NbBundle.getMessage(DataSourceInfo.class,
097: "CONNECTION_MSG_FOR_ALIAS", getAlias(), getUrl());
098: } else {
099: connectionMsg = getUrl();
100: }
101: }
102:
103: public DataSourceInfo(String name, String driverClassName,
104: String url, String validationQuery, String username,
105: String password) {
106: this .name = name;
107: setDataSource(new DesignTimeDataSource(null, false,
108: driverClassName, url, validationQuery, username,
109: password));
110: dbmdh = null;
111: // setId(DataSourceInfoManager.getInstance().getUniqueDataSourceId());
112: }
113:
114: public DataSourceInfo(String name, String aliasName) {
115: this .name = name;
116: setDataSource(new DesignTimeDataSourceAlias(aliasName));
117: dbmdh = null;
118: // setId(DataSourceInfoManager.getInstance().getUniqueDataSourceId());
119: }
120:
121: private void setDataSource(DesignTimeDataSource dtds) {
122: this .dataSource = dtds;
123: if (isAlias()) {
124: alias = ((DesignTimeDataSourceAlias) dtds).getAlias();
125: }
126: }
127:
128: private String alias = null;
129: private String previousAlias = null;
130:
131: public String getAlias() {
132: if (isAlias())
133: return ((DesignTimeDataSourceAlias) dataSource).getAlias();
134: else
135: return null;
136: }
137:
138: public boolean isAlias() {
139: return this .dataSource instanceof DesignTimeDataSourceAlias;
140: }
141:
142: public void setAlias(String newAlias) {
143: previousAlias = ((DesignTimeDataSourceAlias) dataSource)
144: .getAlias();
145: ((DesignTimeDataSourceAlias) dataSource).setAlias(newAlias);
146: }
147:
148: public void swapAlias() {
149: ((DesignTimeDataSourceAlias) dataSource)
150: .setAlias(previousAlias);
151: }
152:
153: /***
154: * Compare two datasources for equal Info
155: * Names can be different.
156: * Useful for comparing an alias to a non-alias.
157: * return true if the values for name, username, etc. are the same.
158: */
159: public boolean isInfoEqual(DataSourceInfo dsi) {
160:
161: if (this .getUsername() == null) {
162: if (dsi.getUsername() != null)
163: return false;
164: } else {
165: if (!this .getUsername().equals(dsi.getUsername()))
166: return false;
167: }
168: if (this .getPassword() == null) {
169: if (dsi.getPassword() != null)
170: return false;
171: } else {
172: if (!this .getPassword().equals(dsi.getPassword()))
173: return false;
174: }
175: if (this .getUrl() == null) {
176: if (dsi.getUrl() != null)
177: return false;
178: } else {
179: if (!this .getUrl().equals(dsi.getUrl()))
180: return false;
181: }
182: if (this .getValidationTable() == null) {
183: if (dsi.getValidationTable() != null)
184: return false;
185: } else {
186: if (!this .getValidationTable().equals(
187: dsi.getValidationTable()))
188: return false;
189: }
190: if (this .getDriverClassName() == null) {
191: if (dsi.getDriverClassName() != null)
192: return false;
193: } else {
194: if (!this .getDriverClassName().equals(
195: dsi.getDriverClassName()))
196: return false;
197: }
198:
199: return true;
200: }
201:
202: public String toString() {
203: String retval = "Name: " + this .name + "\nUrl: "
204: + this .getUrl() + "\nUser: " + this .getUsername();
205: return retval;
206: }
207:
208: public void addConnectionListener(
209: DatasourceConnectionListener listener) {
210: listeners.add(listener);
211: }
212:
213: public void removeConnectionListener(
214: DatasourceConnectionListener listener) {
215: listeners.remove(listener);
216: }
217:
218: public boolean containsSchema(String schemaName) {
219: boolean found = false;
220: String[] schemas = getSchemas();
221: if (schemas != null) {
222: for (int i = 0; i < schemas.length; i++) {
223: if (schemas[i].equals(schemaName)) {
224: found = true;
225: }
226: }
227: }
228: return found;
229: }
230:
231: public void initSchemas() throws SQLException, NamingException {
232: dataSource.initSchemas();
233: }
234:
235: public String[] getSchemas() {
236: return dataSource.getSchemas();
237: }
238:
239: public void setSchemas(String[] schemas) {
240: dataSource.setSchemas(Arrays.asList(schemas));
241: }
242:
243: public void clearSchemas() {
244: dataSource.clearSchemas();
245: }
246:
247: public void setSchemasInitialized(boolean schemasInitialized) {
248: dataSource.setSchemasInitialized(schemasInitialized);
249: }
250:
251: public void addSchema(String schema) {
252: dataSource.addSchema(schema);
253: }
254:
255: public void removeSchema(String schema) {
256: dataSource.removeSchema(schema);
257: }
258:
259: public String getId() {
260: return dataSourceId;
261: }
262:
263: public void setId(String id) {
264: dataSourceId = id;
265: }
266:
267: public String getName() {
268: return name;
269: }
270:
271: public void setName(String name) {
272: this .name = name;
273: }
274:
275: public String getDriverClassName() {
276: return dataSource.getDriverClassName();
277: }
278:
279: public void setDriverClassName(String driverClassName) {
280: dataSource.setDriverClassName(driverClassName);
281: }
282:
283: public String getUrl() {
284: return dataSource.getUrl();
285: }
286:
287: public void setUrl(String url) {
288: dataSource.setUrl(url);
289: }
290:
291: public String getUsername() {
292: return dataSource.getUsername();
293: }
294:
295: public void setUsername(String username) {
296: dataSource.setUsername(username);
297: }
298:
299: public String getPassword() {
300: return dataSource.getPassword();
301: }
302:
303: public void setPassword(String password) {
304: dataSource.setPassword(password);
305: }
306:
307: public String getValidationQuery() {
308: return dataSource.getValidationQuery();
309: }
310:
311: public void setValidationQuery(String valQuery) {
312: dataSource.setValidationQuery(valQuery);
313: }
314:
315: public void setValidationTable(String valTable) {
316: dataSource.setValidationTable(valTable);
317: }
318:
319: public String getValidationTable() {
320: return dataSource.getValidationTable();
321: }
322:
323: public DatabaseMetaDataHelper getDatabaseMetaDataHelper() {
324: if (dbmdh == null) {
325: try {
326: dbmdh = new DatabaseMetaDataHelper(dataSource);
327: } catch (SQLException e) {
328: }
329: }
330: return dbmdh;
331: }
332:
333: public DesignTimeDataSource getDataSource() {
334: return dataSource;
335: }
336:
337: public boolean testConnection() {
338: return testConnection(connectionTimeout);
339: }
340:
341: public boolean testConnection(long timeOut) {
342: TestConnectionResults retVal = testConnectionAndValidation(timeOut);
343: return retVal.connected;
344: }
345:
346: private TestConnectionResults lastTestConnectionResults = null;
347:
348: public TestConnectionResults getLastTestResults() {
349: if (lastTestConnectionResults == null)
350: return null;
351: return lastTestConnectionResults.cloneResults();
352: }
353:
354: public TestConnectionResults testConnectionAndValidation() {
355: return testConnectionAndValidation(connectionTimeout);
356: }
357:
358: public TestConnectionResults testConnectionAndValidation(
359: long timeOut) {
360: lastTestConnectionResults = null;
361: connectionTested = true;
362: Thread connectionTestThread = new Thread(new Runnable() {
363: public void run() {
364: connected = dataSource.test();
365: }
366: });
367: connectionTestThread.start();
368:
369: TestConnectionResults retVal = new TestConnectionResults();
370:
371: try {
372: connectionTestThread.join(timeOut);
373: if (connectionTestThread.isAlive()) {
374: retVal.connected = false;
375: retVal.sqlException = NbBundle.getMessage(
376: DataSourceInfo.class,
377: "CONNECTION_TIMEDOUT_MSG", getUrl());
378: retVal.rows = DesignTimeDataSource.SQL_NOT_RUN;
379: return retVal;
380: }
381: } catch (InterruptedException exc) {
382: retVal.connected = false;
383: retVal.sqlException = NbBundle.getMessage(
384: DataSourceInfo.class, "CONNECTION_INTERRUPTED",
385: getUrl());
386: retVal.rows = DesignTimeDataSource.SQL_NOT_RUN;
387: return retVal;
388: }
389: retVal.connected = dataSource.getTestConnectionSucceeded();
390: retVal.sqlException = dataSource.getTestException() == null ? null
391: : dataSource.getTestException().getMessage();
392: retVal.rows = dataSource.getTestRowsReturned();
393:
394: Iterator iter = listeners.iterator();
395: while (iter.hasNext()) {
396: ((DatasourceConnectionListener) iter.next())
397: .dataSourceConnectionModified();
398: }
399: lastTestConnectionResults = retVal;
400: return retVal.cloneResults();
401: }
402:
403: public static class TestConnectionResults {
404: public boolean connected = false;
405: public String sqlException = null;
406: public SQLException sqlExceptionRootCause = null;
407: public int rows = DesignTimeDataSource.SQL_NOT_RUN;
408:
409: public TestConnectionResults cloneResults() {
410: TestConnectionResults x = new TestConnectionResults();
411: x.connected = this .connected;
412: x.rows = this .rows;
413: x.sqlException = this .sqlException;
414: x.sqlExceptionRootCause = this .sqlExceptionRootCause;
415: return x;
416: }
417: }
418:
419: public void reset() {
420: getDatabaseMetaDataHelper().refresh();
421: testConnectionAndValidation();
422: }
423:
424: public boolean isConnected() {
425: return connected;
426: }
427:
428: public boolean isConnectionTested() {
429: return connectionTested;
430: }
431:
432: public String getConnectionMsg() {
433: return connectionMsg;
434: }
435:
436: public void setDbmdh(DatabaseMetaDataHelper dbmdh) {
437: this.dbmdh = dbmdh;
438: }
439: }
|