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.explorer;
042:
043: import java.awt.Image;
044: import java.sql.SQLException;
045: import java.sql.DatabaseMetaData;
046: import javax.swing.SwingUtilities;
047:
048: import org.netbeans.modules.visualweb.dataconnectivity.DataconnectivitySettings;
049: import org.netbeans.modules.visualweb.dataconnectivity.Log;
050: import org.netbeans.modules.visualweb.dataconnectivity.customizers.RowSetSelection;
051:
052: import org.openide.ErrorManager;
053: import org.netbeans.modules.visualweb.dataconnectivity.sql.DesignTimeDataSource;
054: import org.netbeans.modules.visualweb.dataconnectivity.model.DataSourceInfo;
055:
056: import com.sun.rave.designtime.BeanCreateInfoSet;
057: import com.sun.rave.designtime.Constants;
058: import com.sun.rave.designtime.DesignBean;
059: import com.sun.rave.designtime.DesignContext;
060: import com.sun.rave.designtime.DesignInfo;
061: import com.sun.rave.designtime.Result;
062:
063: // XXX Originally RowSetPaletteItem, but extracted the uneeded palette stuff.
064: /**
065: * Pallette iteam representation for Table (or View) - used for dragging from
066: * Server Nav to pages or app outline.
067: *
068: * This creates a data provider (unless canceled). It will like this
069: * dataprovider to a rowset. The rowset may be an existing one or it
070: * might be created (depends on options and user feedback).
071: *
072: * jfbrown - 25-may-2005 separted from SingleTableNode and revised to create
073: * the rowset in the appropriate bean.
074: */
075:
076: public class RowSetBeanCreateInfoSet implements BeanCreateInfoSet {
077:
078: DataSourceInfo dsInfo;
079: String tableName;
080: String bareTableName;
081: String rowSetInstanceName;
082: DatabaseMetaData metaData;
083:
084: protected static String rowSetNameSuffix = DataconnectivitySettings
085: .getRsSuffix();
086: public static Class rowSetClass = com.sun.sql.rowset.CachedRowSetXImpl.class;
087: protected static String dataProviderProperty = "cachedRowSet"; // NOI18N ,
088: protected static String dataProviderClassName = "com.sun.data.provider.impl.CachedRowSetDataProvider"; // NOI18N
089:
090: /*
091: * Lazily set the datasource info
092: */
093: public RowSetBeanCreateInfoSet(String tableName,
094: DatabaseMetaData metaData) {
095: this .tableName = tableName;
096: int bt = tableName.lastIndexOf('.');
097: if (bt >= 0) {
098: this .bareTableName = tableName.substring(bt + 1);
099: } else {
100: this .bareTableName = tableName;
101: }
102: this .metaData = metaData;
103: Log
104: .log("RowSetPaletteItem =" + tableName + ","
105: + bareTableName);
106: }
107:
108: public String getDisplayName() {
109: return null;
110: }
111:
112: public String getDescription() {
113: return null;
114: }
115:
116: public Image getLargeIcon() {
117: return null;
118: }
119:
120: public Image getSmallIcon() {
121: return null;
122: }
123:
124: public String getHelpKey() {
125: return null;
126: }
127:
128: public String getTableName() {
129: return tableName;
130: }
131:
132: public void setDataSourceInfo(DataSourceInfo dsi) {
133: dsInfo = dsi;
134: try {
135: rowSetInstanceName = dsInfo.getDatabaseMetaDataHelper()
136: .getNoSchemaName(tableName).toLowerCase()
137: + rowSetNameSuffix; // NOI18N
138: } catch (SQLException e) {
139: rowSetInstanceName = bareTableName.toLowerCase()
140: + rowSetNameSuffix; // NOI18N
141: }
142: // remove blanks
143: rowSetInstanceName = rowSetInstanceName.replaceAll(" ", ""); // NOI18N
144: }
145:
146: public DataSourceInfo getDataSourceInfo(DataSourceInfo dsi) {
147: return dsInfo;
148: }
149:
150: String dsName = null;
151:
152: private String getDataSourceName() {
153: if (dsName == null) {
154: dsName = "java:comp/env/jdbc/" + dsInfo.getName(); // NOI18N
155: }
156: return dsName;
157: }
158:
159: String command = null;
160:
161: private String getCommand() {
162: if (command == null) {
163: command = DesignTimeDataSource.composeSelect(tableName,
164: metaData);
165: }
166: return command;
167: }
168:
169: public String[] getBeanClassNames() {
170: return new String[] {
171: /* rowSetClass.getName(), */
172: dataProviderClassName };
173: }
174:
175: DesignBean rsBean = null;
176:
177: public Result beansCreatedSetup(DesignBean[] designBeans) {
178:
179: // DesignBean rsBean = null;
180: rsBean = null;
181: DesignBean dpBean = null;
182:
183: // only one bean expected - see getBeanClassNames().
184: if (designBeans.length > 0) {
185: dpBean = designBeans[0];
186: }
187: if (dpBean == null
188: || !dataProviderClassName.equals(dpBean.getInstance()
189: .getClass().getName())) {
190: // should never be here.
191: String cname = (dpBean == null ? "none provided" : dpBean
192: .getInstance().getClass().getName()); // NOI18N
193: String msg = "Unknown dataProvider bean given to SingleTableNode: "
194: + cname; // NOI18N
195: RuntimeException ree = new RuntimeException(msg);
196: Log.err.notify(ErrorManager.ERROR, ree);
197: throw ree;
198: }
199:
200: DesignContext ctx = dpBean.getDesignContext();
201: String dpBeanScope = (String) ctx
202: .getContextData(Constants.ContextData.SCOPE);
203: if (Log.isLoggable()) {
204: Log.log("RSPI: dpBeanScope='" + dpBeanScope + "' for "
205: + ctx.getDisplayName()); // NOI18N
206: Log.log("RSPI: canDropAnywhere="
207: + DataconnectivitySettings.canDropAnywhere());
208: }
209:
210: // locate or create the correct CachedRowSet bean.
211: // -------------------------
212:
213: final RowSetSelection rss = new RowSetSelection(ctx,
214: this .tableName, getDataSourceName(), "", "",
215: getCommand());
216:
217: DesignContext rsContext = null;
218: if (!rss.hasMatchingRowSets()) {
219:
220: // no existing rowset - so find the context where we should create it.
221: String rsScope = getScopeForNewRowSet(dpBeanScope, ctx);
222: if (!rsScope.equals(dpBeanScope)) {
223: // rsContext = findPreferredBean( ctx, rsScope ) ;
224: for (; rsScope != null; rsScope = getNextScope(rsScope)) {
225: Object[] contexts = rss.getCreateBeans(rsScope);
226: if (contexts.length < 1) {
227: continue;
228: }
229: String beanName = rsScope.substring(0, 1)
230: .toUpperCase()
231: + rsScope.substring(1) + "Bean1";
232: for (int i = 0; i < contexts.length; i++) {
233: if (((DesignContext) contexts[i])
234: .getDisplayName().equals(beanName)) {
235: rsContext = (DesignContext) contexts[i];
236: break;
237: }
238: }
239: if (rsContext == null) {
240: // just use the first on.
241: rsContext = (DesignContext) contexts[0];
242: }
243: break;
244: }
245: }
246: if (rsContext == null) {
247: rsContext = ctx; // create the thing in the same context.
248: }
249:
250: } else {
251: // have rowset matches, so prompt for the rowset. User always has to pick one.
252: boolean makeStuff = rss.showDialog();
253: final DesignBean dp = dpBean;
254: if (!makeStuff) {
255: // delete the already-created
256: final DesignBean deleteMeBean = dpBean;
257: SwingUtilities.invokeLater(new Runnable() {
258: public void run() {
259: DesignContext dc = deleteMeBean
260: .getDesignContext();
261: dc.deleteBean(deleteMeBean);
262: }
263: });
264: return Result.FAILURE;
265: }
266:
267: rsContext = rss.getSelectedDesignContext();
268: rsBean = rss.getSelectedRowSetBean();
269: if (rsBean == null) {
270: // if here, we're going to create one later.
271: rowSetInstanceName = rss.getSelectedRowSetName();
272: }
273: }
274: if (rsBean == null) {
275: // create the rowset design bean here.
276: rsBean = rsContext.createBean(rowSetClass.getName(), null,
277: null);
278: setRowSetProperties(rsBean, rowSetInstanceName);
279: DesignInfo rsBeanDesignInfo = rsBean.getDesignInfo();
280: if (rsBeanDesignInfo != null) {
281: rsBeanDesignInfo.beanCreatedSetup(rsBean);
282: }
283: if (Log.isLoggable()) {
284: Log.log("RSPI: created rowset " + rowSetInstanceName
285: + " in " + rsContext.getDisplayName());
286: }
287: }
288:
289: String dpInstanceName = rowSetInstanceName.replaceAll(
290: rowSetNameSuffix, DataconnectivitySettings
291: .getDpSuffix()); // NOI18N
292: if (dpInstanceName.indexOf(DataconnectivitySettings
293: .getDpSuffix()) < 0) { // NOI18N
294: // if existing rowset was renamed, the replaceall might not have changed anything.
295: dpInstanceName = dpInstanceName
296: + DataconnectivitySettings.getDpSuffix(); // NOI18N
297: }
298: dpBean.setInstanceName(dpInstanceName, true);
299: Log.log("RSPI: setting prop " + dataProviderProperty);
300: dpBean.getProperty(dataProviderProperty).setValue(
301: rsBean.getInstance());
302:
303: return Result.SUCCESS;
304: }
305:
306: /****
307: * for a rowset bean, set it's properties.
308: */
309: private DesignBean setRowSetProperties(DesignBean rsBean,
310: String nameForInstance) {
311:
312: if (nameForInstance != null && nameForInstance.length() > 0) {
313: rsBean.setInstanceName(nameForInstance, true); // NOI18N
314: }
315: String curValue;
316: curValue = (String) rsBean.getProperty("dataSourceName")
317: .getValue();
318: if (curValue == null || curValue.length() < 1) {
319: rsBean.getProperty("dataSourceName").setValue(
320: getDataSourceName());
321: }
322:
323: curValue = (String) rsBean.getProperty("command").getValue();
324: if (curValue == null || curValue.length() < 1) {
325: rsBean.getProperty("command").setValue(getCommand()); // NOI18N
326: }
327:
328: if (rowSetClass == com.sun.sql.rowset.CachedRowSetXImpl.class) {
329: curValue = (String) rsBean.getProperty("tableName")
330: .getValue();
331: if (curValue == null || curValue.length() < 1) {
332: rsBean.getProperty("tableName").setValue(bareTableName); // NOI18N
333: }
334: }
335: return rsBean;
336: }
337:
338: /***
339: * Determine if it's a request bean.
340: * TODO EA HACK: just look for "RequestBean" in the name
341: */
342: private static boolean isRequestBean(DesignContext context) {
343: if (SCOPE_REQUEST.equals(context
344: .getContextData(Constants.ContextData.SCOPE))) {
345: if (context.getDisplayName().indexOf("RequestBean") >= 0) {
346: return true;
347: }
348: }
349: return false;
350: }
351:
352: private static final String SCOPE_PAGE = "page"; // ??unused??
353: private static final String SCOPE_REQUEST = "request";
354: private static final String SCOPE_SESSION = "session";
355: private static final String SCOPE_APPLICATION = "application";
356:
357: // navigate up the scope hierarchy
358: private static String getNextScope(String curScope) {
359: if (curScope.equals(SCOPE_PAGE))
360: return SCOPE_REQUEST;
361: if (curScope.equals(SCOPE_REQUEST))
362: return SCOPE_SESSION;
363: if (curScope.equals(SCOPE_SESSION))
364: return SCOPE_APPLICATION;
365: return null;
366: }
367:
368: /**
369: * for a new rowset bean, determine the scope where it should be created.
370: * goal: if dragging to a page, return session. (a page has request scope).
371: * if dragging to a "RequestBean" in the app outline, return request.
372: */
373: private String getScopeForNewRowSet(String curScope,
374: DesignContext context) {
375: // if page or request, return session
376: // if session or application, return the same.
377: if (DataconnectivitySettings.canDropAnywhere()) {
378: return curScope;
379: }
380: if (curScope.equals(SCOPE_PAGE))
381: return SCOPE_SESSION;
382: if (curScope.equals(SCOPE_REQUEST)) {
383: if (isRequestBean(context)) {
384: return SCOPE_REQUEST;
385: }
386: return SCOPE_SESSION;
387: }
388: if (curScope.equals(SCOPE_SESSION))
389: return SCOPE_SESSION;
390: if (curScope.equals(SCOPE_APPLICATION))
391: return SCOPE_APPLICATION;
392: return SCOPE_SESSION; // should never be here.
393: }
394: }
|