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: /*
042: * DesignTimeDatasourceManager.java
043: *
044: * Created on June 2, 2006, 9:39 AM
045: *
046: * To change this template, choose Tools | Template Manager
047: * and open the template in the editor.
048: */
049:
050: package org.netbeans.modules.visualweb.dataconnectivity.model;
051:
052: import org.netbeans.modules.visualweb.api.designerapi.DesignTimeTransferDataCreator;
053: import org.netbeans.modules.visualweb.dataconnectivity.explorer.RowSetBeanCreateInfoSet;
054: import org.netbeans.modules.visualweb.dataconnectivity.DataconnectivitySettings;
055:
056: import com.sun.rave.designtime.DesignBean;
057: import com.sun.rave.designtime.DesignContext;
058: import com.sun.rave.designtime.DisplayItem;
059: import com.sun.rave.designtime.Result;
060:
061: import java.awt.datatransfer.DataFlavor;
062: import java.awt.datatransfer.Transferable;
063:
064: import java.sql.Connection;
065: import java.sql.DatabaseMetaData;
066: import java.sql.SQLException;
067:
068: import java.util.logging.Level;
069: import java.util.logging.Logger;
070: import org.netbeans.api.db.explorer.DatabaseConnection;
071: import org.netbeans.api.db.explorer.DatabaseMetaDataTransfer;
072: import org.netbeans.api.db.explorer.JDBCDriver;
073: import org.netbeans.api.project.Project;
074: import org.netbeans.modules.visualweb.dataconnectivity.datasource.CurrentProject;
075: import org.netbeans.modules.visualweb.dataconnectivity.datasource.DataSourceResolver;
076: import org.netbeans.modules.visualweb.dataconnectivity.ui.DataSourceNamePanel;
077: import org.openide.DialogDescriptor;
078: import org.openide.DialogDisplayer;
079: import org.openide.NotifyDescriptor;
080: import org.openide.util.HelpCtx;
081: import org.openide.util.NbBundle;
082: import org.openide.ErrorManager;
083: import org.openide.awt.StatusDisplayer;
084: import org.openide.util.Exceptions;
085:
086: /**
087: * Manages the Design Time Data sources transferables
088: * @author Winston Prakash, John Baker
089: */
090: public class DatasourceTransferManager implements
091: DesignTimeTransferDataCreator {
092:
093: protected static String dataProviderClassName = "com.sun.data.provider.impl.CachedRowSetDataProvider";
094: public static String rowSetClassName = "com.sun.sql.rowset.CachedRowSetXImpl";
095: private static final Logger LOGGER = Logger
096: .getLogger(DatasourceTransferManager.class.getName());
097:
098: public DisplayItem getDisplayItem(Transferable transferable) {
099: Object transferData = null;
100: try {
101: DataFlavor tableFlavor = DatabaseMetaDataTransfer.TABLE_FLAVOR;
102: DataFlavor viewFlavor = DatabaseMetaDataTransfer.VIEW_FLAVOR;
103:
104: if (transferable.isDataFlavorSupported(tableFlavor)) {
105: transferData = transferable
106: .getTransferData(tableFlavor);
107: if (transferData != null) {
108: if (transferData.getClass().isAssignableFrom(
109: DatabaseMetaDataTransfer.Table.class)) {
110: DatabaseMetaDataTransfer.Table tableInfo = (DatabaseMetaDataTransfer.Table) transferData;
111: DatabaseConnection dbConnection = tableInfo
112: .getDatabaseConnection();
113: String schemaName = dbConnection.getSchema();
114: Connection conn = dbConnection
115: .getJDBCConnection();
116: DatabaseMetaData metaData = (conn == null) ? null
117: : conn.getMetaData();
118: String tableName = ((schemaName == null) || (schemaName
119: .equals(""))) ? tableInfo
120: .getTableName() : schemaName + "."
121: + tableInfo.getTableName();
122: JDBCDriver jdbcDriver = tableInfo
123: .getJDBCDriver();
124:
125: // Create the Bean Create Infoset and return
126: return new DatasourceBeanCreateInfoSet(
127: dbConnection, jdbcDriver, tableName,
128: metaData);
129: }
130: }
131: } else if (transferable.isDataFlavorSupported(viewFlavor)) {
132: transferData = transferable.getTransferData(viewFlavor);
133: if (transferData != null) {
134: if (transferData.getClass().isAssignableFrom(
135: DatabaseMetaDataTransfer.View.class)) {
136: DatabaseMetaDataTransfer.View viewInfo = (DatabaseMetaDataTransfer.View) transferData;
137: DatabaseConnection dbConnection = viewInfo
138: .getDatabaseConnection();
139: String schemaName = dbConnection.getSchema();
140: Connection conn = dbConnection
141: .getJDBCConnection();
142: DatabaseMetaData metaData = (conn == null) ? null
143: : conn.getMetaData();
144: String viewName = ((schemaName == null) || (schemaName
145: .equals(""))) ? viewInfo.getViewName()
146: : schemaName + "."
147: + viewInfo.getViewName();
148: JDBCDriver jdbcDriver = viewInfo
149: .getJDBCDriver();
150:
151: // Create the Bean Create Infoset and return
152: return new DatasourceBeanCreateInfoSet(
153: dbConnection, jdbcDriver, viewName,
154: metaData);
155: }
156: }
157: }
158: } catch (Exception exc) {
159: ErrorManager.getDefault().notify(
160: ErrorManager.INFORMATIONAL, exc);
161: }
162: return null;
163: }
164:
165: private static final class DatasourceBeanCreateInfoSet extends
166: RowSetBeanCreateInfoSet {
167:
168: DatabaseConnection dbConnection = null;
169: JDBCDriver jdbcDriver = null;
170:
171: public DatasourceBeanCreateInfoSet(
172: DatabaseConnection connection, JDBCDriver driver,
173: String tableName, DatabaseMetaData metaData) {
174: super (tableName, metaData);
175: dbConnection = connection;
176: jdbcDriver = driver;
177: }
178:
179: public Result beansCreatedSetup(DesignBean[] designBeans) {
180: DesignBean designBean = designBeans[0];
181:
182: // Get the Database Connection information and add it to design time
183: // Naming Context
184: // Make sure duplicate datasources are not added
185: boolean cancel = false;
186: String databaseProductName = null;
187: try {
188: databaseProductName = dbConnection.getJDBCConnection()
189: .getMetaData().getDatabaseProductName()
190: .replaceAll("\\s{1}", "");
191: } catch (SQLException sqle) {
192: sqle.printStackTrace();
193: }
194:
195: String dsName = "dataSource";
196: String driverClassName = dbConnection.getDriverClass();
197: String url = dbConnection.getDatabaseURL();
198: String validationQuery = null;
199: String username = dbConnection.getUser();
200: String password = dbConnection.getPassword();
201: String schema = dbConnection.getSchema();
202:
203: if (schema.equals("")) {
204: if (databaseProductName.equals("MySQL")
205: && url.lastIndexOf("?") == -1)
206: dsName = url.substring(url.lastIndexOf("/") + 1,
207: url.length())
208: + "_" + databaseProductName;
209: else if (databaseProductName.contains("/")) {
210: int slashLoc = databaseProductName.indexOf("/");
211: String prefix = databaseProductName.substring(0,
212: slashLoc);
213: String suffix = databaseProductName
214: .substring(slashLoc + 1);
215: dsName = prefix + "_" + suffix;
216: } else if (databaseProductName.equals("MySQL")) {
217: dsName = url.substring(url.lastIndexOf("/") + 1,
218: url.lastIndexOf("?"))
219: + "_" + databaseProductName;
220: } else
221: dsName = getTableName() + "_" + databaseProductName;
222: } else if (databaseProductName.contains("/")) {
223: int slashLoc = databaseProductName.indexOf("/");
224: String prefix = databaseProductName.substring(0,
225: slashLoc);
226: String suffix = databaseProductName
227: .substring(slashLoc + 1);
228: dsName = prefix + "_" + suffix;
229: } else {
230: dsName = dbConnection.getSchema() + "_"
231: + databaseProductName;
232: }
233:
234: // Check if target server supports data source creation. If not then cancel drop
235: Project currentProj = CurrentProject.getInstance()
236: .getCurrentProject(designBeans);
237: if (!DataSourceResolver.getInstance()
238: .isDatasourceCreationSupported(currentProj)) {
239: cancel = true;
240: DataSourceResolver.getInstance()
241: .postUnsupportedDataSourceCreationDialog();
242: }
243:
244: // Disallow drop of Oracle table when version of driver is less than 10.2
245: if ("Oracle".equals(databaseProductName)) { // NOI18N
246: try {
247: if ((dbConnection.getJDBCConnection().getMetaData()
248: .getDriverMajorVersion() < 10)
249: && (dbConnection.getJDBCConnection()
250: .getMetaData()
251: .getDriverMinorVersion() < 2)) {
252: cancel = true;
253: LOGGER
254: .log(Level.WARNING,
255: "Oracle driver version 10 or later supported. Drop cancelled."); // NOI18N
256: StatusDisplayer
257: .getDefault()
258: .setStatusText(
259: NbBundle
260: .getMessage(
261: DatasourceBeanCreateInfoSet.class,
262: "ORACLE_DRIVER_WARNING")); // NOI18N
263: }
264: } catch (SQLException ex) {
265: Exceptions.printStackTrace(ex);
266: }
267: }
268:
269: // ensure data source name is unique
270: if (!DataSourceResolver.getInstance().isDataSourceUnique(
271: currentProj, dsName, url)) {
272: dsName = getUniqueName(dsName);
273: }
274:
275: if (DataconnectivitySettings.promptForName()) {
276: DataSourceNamePanel dataSourceNamePanel = new DataSourceNamePanel(
277: dsName);
278: final DialogDescriptor dialogDescriptor = new DialogDescriptor(
279: dataSourceNamePanel,
280: NbBundle.getMessage(DataSourceNamePanel.class,
281: "LBL_SpecifyDataSourceName"), //NOI18N
282: true, DialogDescriptor.DEFAULT_OPTION,
283: DialogDescriptor.OK_OPTION,
284: DialogDescriptor.DEFAULT_ALIGN,
285: HelpCtx.DEFAULT_HELP, null);
286:
287: // initial invalidation
288: dialogDescriptor.setValid(true);
289: // show and eventually save
290: Object option = DialogDisplayer.getDefault().notify(
291: dialogDescriptor);
292: if (option == NotifyDescriptor.OK_OPTION) {
293: dsName = dataSourceNamePanel.getDataSourceName();
294: } else if (option == NotifyDescriptor.CANCEL_OPTION) {
295: cancel = true;
296: }
297: }
298:
299: // if user has enabled Prompt for Data Source name and clicks cancel then don't create and bind the data source
300: if (!cancel) {
301: DataSourceInfo dataSourceInfo = new DataSourceInfo(
302: dsName, driverClassName, url, validationQuery,
303: username, password);
304:
305: // Logic to reuse the datasource exist in the project. No necessary to create new data source
306: ProjectDataSourceManager projectDataSourceManager = new ProjectDataSourceManager(
307: designBean);
308:
309: // Add the data sources to the project
310: projectDataSourceManager.addDataSource(dataSourceInfo);
311:
312: // create the rowset
313: setDataSourceInfo(dataSourceInfo);
314: return super .beansCreatedSetup(designBeans);
315: }
316:
317: // remove unused data provider that was created
318: final DesignBean deleteMeBean = designBeans[0];
319: DesignContext dc = deleteMeBean.getDesignContext();
320: dc.deleteBean(deleteMeBean);
321: return null;
322: }
323:
324: private int getIndex(String name) {
325: int index = -1;
326:
327: if (name.indexOf('_') != -1) {
328: try {
329: index = Integer.parseInt(name.substring(name
330: .lastIndexOf('_') + 1, name.length() - 1));
331: } catch (NumberFormatException nfe) {
332: // do nothing
333: }
334: }
335:
336: return index;
337: }
338:
339: private String getUniqueName(String name) {
340: int index = getIndex(name);
341: if (index != -1) {
342: index++;
343: String prefix = name.substring(0, name.indexOf('_'));
344: return prefix + "_" + Integer.toString(index); // NOI18N
345: } else {
346: return name + "_" + 1; // NOI18N
347: }
348: }
349: }
350: }
|