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.propertyeditors.binding.nodes;
042:
043: import org.netbeans.modules.visualweb.propertyeditors.binding.PropertyBindingPanel;
044: import java.beans.PropertyDescriptor;
045: import java.sql.ResultSet;
046: import java.sql.ResultSetMetaData;
047: import java.sql.Timestamp;
048: import java.sql.Types;
049: import javax.faces.model.SelectItem;
050: import java.awt.Component;
051: import java.awt.GridBagConstraints;
052: import java.awt.GridBagLayout;
053: import java.awt.Insets;
054: import java.awt.event.ActionEvent;
055: import java.awt.event.ActionListener;
056: import javax.swing.DefaultListCellRenderer;
057: import javax.swing.JComboBox;
058: import javax.swing.JComponent;
059: import javax.swing.JLabel;
060: import javax.swing.JList;
061: import javax.swing.JPanel;
062: import com.sun.rave.designtime.DesignBean;
063: import org.netbeans.modules.visualweb.propertyeditors.binding.BindingTargetNode;
064: import org.netbeans.modules.visualweb.propertyeditors.binding.BindingTargetNodeFactory;
065: import org.netbeans.modules.visualweb.propertyeditors.binding.PropertyBindingHelper;
066: import org.netbeans.modules.visualweb.propertyeditors.util.Bundle;
067: import javax.swing.SwingUtilities;
068: import org.openide.ErrorManager;
069:
070: public class ResultSetTargetNodeFactory implements
071: BindingTargetNodeFactory {
072:
073: private static final Bundle bundle = Bundle
074: .getBundle(ResultSetTargetNodeFactory.class);
075:
076: public boolean supportsTargetClass(Class targetClass) {
077: return ResultSet.class.isAssignableFrom(targetClass);
078: }
079:
080: public BindingTargetNode createTargetNode(BindingTargetNode parent,
081: DesignBean bean, PropertyDescriptor[] propPath,
082: Object propInstance) {
083: return new ResultSetTargetNode(parent, bean, propPath,
084: propInstance);
085: }
086:
087: public class ResultSetTargetNode extends PropertyTargetNode {
088: protected ResultSet resultSet;
089:
090: public ResultSetTargetNode(BindingTargetNode parent,
091: DesignBean bean, PropertyDescriptor[] propPath,
092: Object propInstance) {
093: super (parent, bean, propPath, propInstance);
094: if (propInstance == null) {
095: propInstance = PropertyBindingHelper.getPropInstance(
096: bean, propPath);
097: }
098: if (propInstance instanceof ResultSet) {
099: resultSet = (ResultSet) propInstance;
100: }
101: }
102:
103: public void lazyLoadCustomTargetNodes() {
104: if (resultSet != null) {
105: Thread resuleSetNodeThread = new Thread(new Runnable() {
106: public void run() {
107: try {
108: final ResultSetMetaData rsmd = resultSet
109: .getMetaData();
110:
111: SwingUtilities.invokeLater(new Runnable() {
112: public void run() {
113: try {
114: final int cols = rsmd
115: .getColumnCount();
116: if (cols > 0) {
117: for (int i = 0; i < cols; i++) {
118: //System.out.println("*** Adding column : " + rsmd.getColumnName(i + 1)); //NOI18N
119: ResultSetTargetNode.super
120: .add(new ColumnNode(
121: ResultSetTargetNode.this ,
122: rsmd
123: .getColumnName(i + 1),
124: rsmd
125: .getColumnType(i + 1)));
126: }
127: }
128: ResultSetTargetNode.super
129: .add(new SelectItemsNode(
130: ResultSetTargetNode.this ,
131: rsmd));
132: } catch (Exception exc) {
133: ErrorManager.getDefault()
134: .notify(exc);
135: }
136: }
137: });
138: } catch (Exception exc) {
139: ErrorManager.getDefault().notify(exc);
140: }
141: }
142: });
143: resuleSetNodeThread.setPriority(Thread.MIN_PRIORITY);
144: resuleSetNodeThread.start();
145: }
146: }
147:
148: public class ColumnNode extends BindingTargetNode {
149: protected String columnName;
150: protected int columnType;
151:
152: public ColumnNode(BindingTargetNode parent,
153: String columnName, int columnType) {
154: super (parent);
155: this .columnName = columnName;
156: this .columnType = columnType;
157: }
158:
159: public int getChildCount() {
160: return 0;
161: }
162:
163: public boolean lazyLoad() {
164: return true;
165: }
166:
167: public boolean isValidBindingTarget() {
168: return true;
169: }
170:
171: public String getBindingExpressionPart() {
172: return "currentRow['" + columnName + "']"; //NOI81N
173: }
174:
175: public Class getTargetTypeClass() {
176: return getJavaType(columnType);
177: }
178:
179: public String getDisplayText(boolean enableNode) {
180: String tn = getTypeName(columnType);
181: StringBuffer sb = new StringBuffer();
182: sb.append("<html>"); //NOI18N
183: if (!enableNode) {
184: sb.append("<font color=\"gray\">"); //NOI18N
185: }
186: sb.append(bundle.getMessage("column")); //NOI18N
187: sb.append(" "); //NOI18N
188: if (enableNode) {
189: sb.append("<b>"); //NOI18N
190: }
191: sb.append(columnName);
192: if (enableNode) {
193: sb.append("</b>"); //NOI18N
194: }
195: sb.append(" <font size=\"-1\"><i>"); //NOI18N
196: sb.append(tn);
197: sb.append("</i></font>"); //NOI18N
198: if (!enableNode) {
199: sb.append("</font>"); //NOI18N
200: }
201: sb.append("</html>"); //NOI18N
202: return sb.toString();
203: }
204: }
205:
206: public class SelectItemsNode extends BindingTargetNode {
207: protected ResultSetMetaData metaData;
208:
209: public SelectItemsNode(BindingTargetNode parent,
210: ResultSetMetaData metaData) {
211: super (parent);
212: this .metaData = metaData;
213: initCustomPanel();
214: displayTextEnabled = getDisplayText(true);
215: displayTextDisabled = getDisplayText(false);
216: }
217:
218: protected String displayTextEnabled = null;
219: protected String displayTextDisabled = null;
220:
221: public String getDisplayText(boolean enableNode) {
222: if (enableNode && displayTextEnabled != null) {
223: return displayTextEnabled;
224: } else if (!enableNode && displayTextDisabled != null) {
225: return displayTextDisabled;
226: }
227: StringBuffer sb = new StringBuffer();
228: sb.append("<html>"); //NOI18N
229: if (!enableNode) {
230: sb.append("<font color=\"gray\">"); //NOI18N
231: }
232: if (enableNode) {
233: sb.append("<b>"); //NOI18N
234: }
235: sb.append(bundle.getMessage("selectItems")); //NOI81N
236: if (enableNode) {
237: sb.append("</b>"); //NOI18N
238: }
239: sb.append(" <font size=\"-1\"><i>"); //NOI18N
240: sb.append(bundle.getMessage("parenItemsForListBoxOr")); //NOI18N
241: sb.append("</i></font>"); //NOI18N
242: if (!enableNode) {
243: sb.append("</font>"); //NOI18N
244: }
245: sb.append("</html>"); //NOI18N
246: return sb.toString();
247: }
248:
249: public int getChildCount() {
250: return 0;
251: }
252:
253: public boolean lazyLoad() {
254: return true;
255: }
256:
257: public Class getTargetTypeClass() {
258: return SelectItem[].class;
259: }
260:
261: public boolean isValidBindingTarget() {
262: return true;
263: }
264:
265: public String getBindingExpressionPart() {
266: return "selectItems['" + getColumnPicks() + "']"; //NOI18N
267: }
268:
269: String getColumnPicks() {
270: StringBuffer sb = new StringBuffer();
271: Object o = valueCombo.getSelectedItem();
272: if (o instanceof ComboDisplayColumn) {
273: sb.append(((ComboDisplayColumn) o).columnName);
274: }
275: o = labelCombo.getSelectedItem();
276: if (o instanceof ComboDisplayColumn) {
277: sb.append(","); //NOI18N
278: sb.append(((ComboDisplayColumn) o).columnName);
279: }
280: o = descrCombo.getSelectedItem();
281: if (o instanceof ComboDisplayColumn) {
282: sb.append(","); //NOI18N
283: sb.append(((ComboDisplayColumn) o).columnName);
284: }
285: return sb.toString();
286: }
287:
288: JPanel pickerPanel = new JPanel();
289: JLabel valueLabel = new JLabel(bundle
290: .getMessage("valueField")); //NOI18N
291: JLabel labelLabel = new JLabel(bundle
292: .getMessage("displayField")); //NOI18N
293: JLabel descrLabel = new JLabel(bundle
294: .getMessage("tooltipField")); //NOI18N
295: JComboBox valueCombo = new JComboBox();
296: JComboBox labelCombo = new JComboBox();
297: JComboBox descrCombo = new JComboBox();
298:
299: void initCustomPanel() {
300: ComboDisplayColumnRenderer cdcr = new ComboDisplayColumnRenderer();
301: valueCombo.setRenderer(cdcr);
302: labelCombo.setRenderer(cdcr);
303: descrCombo.setRenderer(cdcr);
304: labelCombo.addItem(bundle.getMessage("noneBrackets")); //NOI18N
305: descrCombo.addItem(bundle.getMessage("noneBrackets")); //NOI18N
306: try {
307: int cols = metaData.getColumnCount();
308: if (cols > 0) {
309: for (int i = 0; i < cols; i++) {
310: ComboDisplayColumn col = new ComboDisplayColumn(
311: metaData.getColumnName(i + 1),
312: metaData.getColumnType(i + 1));
313: valueCombo.addItem(col);
314: labelCombo.addItem(col);
315: descrCombo.addItem(col);
316: }
317: }
318: } catch (Exception x) {
319: x.printStackTrace();
320: }
321: pickerPanel.setLayout(new GridBagLayout());
322: pickerPanel.add(valueLabel, new GridBagConstraints(0,
323: 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST,
324: GridBagConstraints.HORIZONTAL, new Insets(0, 0,
325: 2, 4), 0, 0));
326: pickerPanel.add(labelLabel, new GridBagConstraints(1,
327: 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST,
328: GridBagConstraints.HORIZONTAL, new Insets(0, 0,
329: 2, 4), 0, 0));
330: pickerPanel.add(descrLabel, new GridBagConstraints(2,
331: 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST,
332: GridBagConstraints.HORIZONTAL, new Insets(0, 0,
333: 2, 0), 0, 0));
334: pickerPanel.add(valueCombo, new GridBagConstraints(0,
335: 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST,
336: GridBagConstraints.HORIZONTAL, new Insets(0, 0,
337: 0, 4), 0, 0));
338: pickerPanel.add(labelCombo, new GridBagConstraints(1,
339: 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST,
340: GridBagConstraints.HORIZONTAL, new Insets(0, 0,
341: 0, 4), 0, 0));
342: pickerPanel.add(descrCombo, new GridBagConstraints(2,
343: 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST,
344: GridBagConstraints.HORIZONTAL, new Insets(0, 0,
345: 0, 0), 0, 0));
346: valueCombo.addActionListener(updateAdapter);
347: labelCombo.addActionListener(updateAdapter);
348: descrCombo.addActionListener(updateAdapter);
349: }
350:
351: public JComponent getCustomDisplayPanel(
352: ActionListener updateCallback) {
353: this .updateCallback = updateCallback;
354: return pickerPanel;
355: }
356:
357: ActionListener updateCallback = null;
358: ActionListener updateAdapter = new ActionListener() {
359: public void actionPerformed(ActionEvent e) {
360: if (updateCallback != null) {
361: updateCallback.actionPerformed(e);
362: }
363: }
364: };
365: }
366: }
367:
368: public class ComboDisplayColumn {
369: public String columnName;
370: public int columnType;
371:
372: public ComboDisplayColumn(String columnName, int columnType) {
373: this .columnName = columnName;
374: this .columnType = columnType;
375: }
376: }
377:
378: public class ComboDisplayColumnRenderer extends
379: DefaultListCellRenderer {
380: public Component getListCellRendererComponent(JList list,
381: Object value, int index, boolean isSelected,
382: boolean cellHasFocus) {
383: super .getListCellRendererComponent(list, value, index,
384: isSelected, cellHasFocus);
385: if (value instanceof ComboDisplayColumn) {
386: ComboDisplayColumn cdc = (ComboDisplayColumn) value;
387: String tn = getTypeName(cdc.columnType);
388: StringBuffer sb = new StringBuffer();
389: sb.append("<html><b>"); //NOI18N
390: sb.append(cdc.columnName);
391: sb.append("</b> <font size=\"-1\"><i>"); //NOI18N
392: sb.append(tn);
393: sb.append("</i></font></html>"); //NOI18N
394: this .setText(sb.toString());
395: } else {
396: this .setText(bundle.getMessage("noneBrackets")); //NOI18N
397: }
398: return this ;
399: }
400: }
401:
402: public static String getTypeName(int sqlType) {
403: switch (sqlType) {
404: case Types.SMALLINT:
405: return "SMALLINT"; //NOI18N
406: case Types.INTEGER:
407: return "INTEGER"; //NOI18N
408: case Types.TINYINT:
409: return "TINYINT"; //NOI18N
410: case Types.BIGINT:
411: return "BIGINT"; //NOI18N
412: case Types.BIT:
413: return "BIT"; //NOI18N
414: case Types.BOOLEAN:
415: return "BOOLEAN"; //NOI18N
416: case Types.DATE:
417: return "DATE"; //NOI18N
418: case Types.TIME:
419: return "TIME"; //NOI18N
420: case Types.DECIMAL:
421: return "DECIMAL"; //NOI18N
422: case Types.NUMERIC:
423: return "NUMERIC"; //NOI18N
424: case Types.DOUBLE:
425: return "DOUBLE"; //NOI18N
426: case Types.REAL:
427: return "REAL"; //NOI18N
428: case Types.FLOAT:
429: return "FLOAT"; //NOI18N
430: case Types.BINARY:
431: return "BINARY"; //NOI18N
432: case Types.CHAR:
433: return "CHAR"; //NOI18N
434: case Types.LONGVARCHAR:
435: return "LONGVARCHAR"; //NOI18N
436: case Types.VARCHAR:
437: return "VARCHAR"; //NOI18N
438: case Types.BLOB:
439: return "BLOB"; //NOI18N
440: case Types.CLOB:
441: return "CLOB"; //NOI18N
442: case Types.DATALINK:
443: return "DATALINK"; //NOI18N
444: case Types.DISTINCT:
445: return "DISTINCT"; //NOI18N
446: case Types.JAVA_OBJECT:
447: return "JAVA_OBJECT"; //NOI18N
448: case Types.LONGVARBINARY:
449: return "LONGVARBINARY"; //NOI18N
450: case Types.NULL:
451: return "NULL"; //NOI18N
452: case Types.OTHER:
453: return "OTHER"; //NOI18N
454: case Types.REF:
455: return "REF"; //NOI18N
456: case Types.STRUCT:
457: return "STRUCT"; //NOI18N
458: case Types.TIMESTAMP:
459: return "TIMESTAMP"; //NOI18N
460: case Types.VARBINARY:
461: return "VARBINARY"; //NOI18N
462: }
463: return null;
464: }
465:
466: public static Class getJavaType(int sqlType) {
467: switch (sqlType) {
468: case Types.SMALLINT:
469: return Short.class;
470: case Types.INTEGER:
471: return Integer.class;
472: case Types.TINYINT:
473: return Byte.class;
474: case Types.BIGINT:
475: return Long.class;
476: case Types.BIT:
477: case Types.BOOLEAN:
478: return Boolean.class;
479: case Types.DATE:
480: case Types.TIME:
481: return Timestamp.class;
482: case Types.DECIMAL:
483: case Types.NUMERIC:
484: return Number.class;
485: case Types.DOUBLE:
486: case Types.REAL:
487: return Double.class;
488: case Types.FLOAT:
489: return Float.class;
490: case Types.BINARY:
491: case Types.CHAR:
492: case Types.LONGVARCHAR:
493: case Types.VARCHAR:
494: case Types.BLOB:
495: case Types.CLOB:
496: case Types.DATALINK:
497: case Types.DISTINCT:
498: case Types.JAVA_OBJECT:
499: case Types.LONGVARBINARY:
500: case Types.NULL:
501: case Types.OTHER:
502: case Types.REF:
503: case Types.STRUCT:
504: case Types.TIMESTAMP:
505: case Types.VARBINARY:
506: return null;
507: }
508: return null;
509: }
510: }
|