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.faces.dt.std;
042:
043: import java.awt.Component;
044: import java.awt.Dimension;
045: import java.awt.GridBagConstraints;
046: import java.awt.GridBagLayout;
047: import java.awt.Insets;
048: import java.awt.event.ItemEvent;
049: import java.awt.event.ItemListener;
050: import java.sql.ResultSetMetaData;
051: import java.util.ArrayList;
052: import java.util.HashMap;
053: import java.util.StringTokenizer;
054: import javax.sql.RowSet;
055: import javax.swing.DefaultListCellRenderer;
056: import javax.swing.DefaultListModel;
057: import javax.swing.JComboBox;
058: import javax.swing.JLabel;
059: import javax.swing.JList;
060: import javax.swing.JPanel;
061: import javax.swing.JScrollPane;
062: import javax.swing.JTextPane;
063: import javax.swing.ListModel;
064: import javax.swing.UIManager;
065: import javax.swing.event.ListSelectionEvent;
066: import javax.swing.event.ListSelectionListener;
067: import org.netbeans.modules.visualweb.faces.dt.util.ComponentBundle;
068: import com.sun.rave.designtime.Constants;
069: import com.sun.rave.designtime.DesignBean;
070: import com.sun.rave.designtime.DesignContext;
071: import com.sun.rave.designtime.DesignProject;
072: import com.sun.rave.designtime.DesignProperty;
073: import com.sun.rave.designtime.faces.FacesDesignContext;
074: import com.sun.rave.designtime.faces.FacesDesignProject;
075:
076: public class RowDataBindingPanel extends JPanel {
077:
078: private static final ComponentBundle bundle = ComponentBundle
079: .getBundle(RowDataBindingPanel.class);
080:
081: protected JTextPane noneText = new JTextPane();
082:
083: protected DesignProperty prop;
084: protected ValueBindingPanel vbp;
085:
086: protected JLabel rsLabel = new JLabel();
087: protected JComboBox rsCombo = new JComboBox();
088:
089: protected HashMap listModelHash = new HashMap();
090:
091: protected JLabel valueListLabel = new JLabel();
092: protected JList valueList = new JList();
093: protected JScrollPane valueListScroll = new JScrollPane(valueList);
094:
095: protected GridBagLayout gridbag = new GridBagLayout();
096: protected String parentName = null;
097:
098: protected int rsIndex = -1;
099: protected int valueIndex = 0;
100:
101: protected boolean initializing = true;
102:
103: protected class ListItem {
104: public String display;
105: public String table;
106: public String column;
107:
108: public String toString() {
109: return display;
110: }
111: }
112:
113: // // scans parent hierarchy for a specific bean type
114: // protected DesignBean scanForParent(Class beanClass, DesignBean child) {
115: // DesignBean parent = child.getBeanParent();
116: // if (parent != null && parent.getInstance() != null) {
117: // if (beanClass.isAssignableFrom(parent.getInstance().getClass())) {
118: // return parent;
119: // }
120: // return scanForParent(beanClass, parent);
121: // }
122: // return null;
123: // }
124:
125: protected RowDataBindingCustomizer customizer;
126:
127: public RowDataBindingPanel(ValueBindingPanel vbp,
128: RowDataBindingCustomizer customizer, DesignProperty prop) {
129: this .vbp = vbp;
130: this .customizer = customizer;
131: this .prop = prop;
132: try {
133: jbInit();
134: } catch (Exception e) {
135: e.printStackTrace();
136: }
137: if (prop != null) {
138: //DesignContext[] contexts = prop.getDesignBean().getDesignContext().getProject().getDesignContexts();
139: DesignContext[] contexts = getDesignContexts(prop
140: .getDesignBean());
141:
142: rsLabel.setText(bundle.getMessage("chooseRsToBind", prop
143: .getDesignBean().getInstanceName())); //NOI18N
144:
145: // // first check to see if the comp is in a UIData bound to a RowSet
146: // DesignBean tableBean = scanForParent(UIData.class, prop.getDesignBean());
147: // if (tableBean != null) {
148: // //!JOE do this later...
149: // }
150:
151: // find the current value
152: String currentRef = prop.getValueSource();
153: newRef = currentRef;
154: String contextName = null;
155: String rsName = null;
156: String valueField = null;
157: if (currentRef != null && currentRef.startsWith("#{") && //NOI18N
158: currentRef.endsWith("}")) { //NOI18N
159:
160: ArrayList parts = new ArrayList();
161: StringTokenizer st = new StringTokenizer(currentRef
162: .substring(2, currentRef.length() - 1), ".");
163: while (st.hasMoreElements()) {
164: parts.add(st.nextElement());
165: }
166:
167: if (parts.size() > 0) {
168: contextName = "" + parts.get(0);
169: }
170: if (parts.size() > 1) {
171: rsName = "" + parts.get(1);
172: }
173: if (parts.size() > 2) {
174: String val = String.valueOf(parts.get(2));
175: if (val.startsWith("currentRow['")
176: && val.endsWith("']")) { //NOI18N
177: valueField = val.substring("currentRow['"
178: .length(), val.length() - 2); //NOI18N
179: }
180: }
181: }
182:
183: // then scan for all rowsets
184: ArrayList rowsetBeans = new ArrayList();
185: for (int i = 0; i < contexts.length; i++) {
186: String scope = (String) contexts[i]
187: .getContextData(Constants.ContextData.SCOPE);
188: if ("request".equals(scope)
189: && contexts[i] != prop.getDesignBean()
190: .getDesignContext()) { //NOI18N
191: continue;
192: }
193: DesignBean[] rsbs = contexts[i]
194: .getBeansOfType(RowSet.class);
195: for (int j = 0; j < rsbs.length; j++) {
196: rowsetBeans.add(rsbs[j]);
197: }
198: }
199:
200: if (rowsetBeans.size() > 0) {
201: for (int i = 0; i < rowsetBeans.size(); i++) {
202: DesignBean rsBean = (DesignBean) rowsetBeans.get(i);
203: try {
204: RowSet rs = (RowSet) rsBean.getInstance();
205: if (rs != null) {
206: if (rsIndex < 0) {
207: DesignContext rsc = rsBean
208: .getDesignContext();
209: if (rsc instanceof FacesDesignContext) {
210: if (((FacesDesignContext) rsc)
211: .getReferenceName().equals(
212: contextName)
213: && rsBean.getInstanceName()
214: .equals(rsName)) {
215: rsIndex = i;
216: }
217: } else {
218: if (rsc.getDisplayName().equals(
219: contextName)
220: && rsBean.getInstanceName()
221: .equals(rsName)) {
222: rsIndex = i;
223: }
224: }
225: }
226:
227: ResultSetMetaData rsmd = rs.getMetaData();
228:
229: DefaultListModel dlm = new DefaultListModel();
230: ListItem none = new ListItem();
231: none.display = bundle
232: .getMessage("noneBrackets"); //NOI18N
233: dlm.addElement(none);
234:
235: rsCombo.addItem(rsBean);
236: listModelHash.put(rsBean, dlm);
237:
238: int cols = rsmd.getColumnCount();
239: for (int c = 1; c <= cols; c++) {
240: ListItem li = new ListItem();
241: li.table = rsmd.getTableName(c);
242: li.column = rsmd.getColumnName(c);
243: //li.display = li.table + "." + li.column; //NOI18N
244: li.display = (li.table == null || li.table
245: .length() == 0) ? li.column
246: : li.table + "." + li.column; //NOI18N
247: dlm.addElement(li);
248: if (rsIndex > -1) {
249: if (valueIndex <= 0
250: && li.column
251: .equals(valueField)) {
252: valueIndex = c;
253: }
254: }
255: }
256: }
257: } catch (Exception x) {
258: System.err.println(bundle
259: .getMessage("getMetaDataException")); //NOI18N
260: x.printStackTrace();
261: }
262: }
263: } else {
264: this .removeAll();
265: this .add(rsLabel, new GridBagConstraints(0, 0, 1, 1,
266: 0.0, 0.0, GridBagConstraints.WEST,
267: GridBagConstraints.NONE,
268: new Insets(8, 8, 2, 8), 0, 0));
269: this .add(noneText, new GridBagConstraints(0, 1, 1, 1,
270: 1.0, 1.0, GridBagConstraints.CENTER,
271: GridBagConstraints.BOTH,
272: new Insets(0, 8, 8, 8), 0, 0));
273: }
274: }
275: updateLists();
276: if (rsIndex > -1) {
277: rsCombo.setSelectedIndex(rsIndex);
278: }
279: if (valueIndex > -1) {
280: valueList.setSelectedIndex(valueIndex);
281: }
282: initializing = false;
283: repaint(100);
284: }
285:
286: // For performance improvement. No need to get all the contexts in the project
287: private DesignContext[] getDesignContexts(DesignBean designBean) {
288: DesignProject designProject = designBean.getDesignContext()
289: .getProject();
290: DesignContext[] contexts;
291: if (designProject instanceof FacesDesignProject) {
292: contexts = ((FacesDesignProject) designProject)
293: .findDesignContexts(new String[] { "request",
294: "session", "application" });
295: } else {
296: contexts = new DesignContext[0];
297: }
298: DesignContext[] designContexts = new DesignContext[contexts.length + 1];
299: designContexts[0] = designBean.getDesignContext();
300: System.arraycopy(contexts, 0, designContexts, 1,
301: contexts.length);
302: return designContexts;
303: }
304:
305: private void jbInit() throws Exception {
306: noneText.setEditable(false);
307: noneText.setFont(rsLabel.getFont());
308: noneText.setBorder(UIManager.getBorder("TextField.border")); //NOI18N
309: noneText.setText(bundle.getMessage("noRss")); //NOI18N
310:
311: rsLabel.setText(bundle.getMessage("chooseRsToBindSimple")); //NOI18N
312: valueListLabel.setText(bundle.getMessage("dataField")); //NOI18N
313: valueListScroll.setPreferredSize(new Dimension(200, 200));
314:
315: rsCombo.setRenderer(new RSComboRenderer());
316:
317: this .setPreferredSize(new Dimension(400, 200));
318: this .setLayout(gridbag);
319:
320: this .add(rsLabel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
321: GridBagConstraints.WEST, GridBagConstraints.NONE,
322: new Insets(8, 8, 2, 8), 0, 0));
323: this .add(rsCombo, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0,
324: GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
325: new Insets(0, 8, 8, 8), 0, 0));
326:
327: this .add(valueListLabel, new GridBagConstraints(0, 2, 1, 1,
328: 0.0, 0.0, GridBagConstraints.WEST,
329: GridBagConstraints.NONE, new Insets(0, 8, 2, 8), 0, 0));
330: this .add(valueListScroll, new GridBagConstraints(0, 3, 1, 1,
331: 1.0, 1.0, GridBagConstraints.CENTER,
332: GridBagConstraints.BOTH, new Insets(0, 8, 8, 8), 0, 0));
333:
334: rsCombo.addItemListener(new ItemListener() {
335: public void itemStateChanged(ItemEvent e) {
336: updateLists();
337: }
338: });
339: valueList.addListSelectionListener(new ListSelectionListener() {
340: public void valueChanged(ListSelectionEvent e) {
341: updateSelection();
342: }
343: });
344: }
345:
346: protected void updateLists() {
347: Object o = listModelHash.get(rsCombo.getSelectedItem());
348: if (o instanceof ListModel) {
349: ListModel lm = (ListModel) o;
350: valueList.setModel(lm);
351: }
352: updateSelection();
353: }
354:
355: protected void updateSelection() {
356: if (initializing) {
357: return;
358: }
359: DesignBean rsBean = null;
360: String valName = null;
361: Object o = rsCombo.getSelectedItem();
362: if (o instanceof DesignBean) {
363: rsBean = (DesignBean) o;
364: }
365: o = valueList.getSelectedValue();
366: if (o instanceof ListItem) {
367: valName = ((ListItem) o).column;
368: }
369: String ref = calcValueRef(rsBean, valName);
370: if (vbp != null) {
371: vbp.setValueBinding(ref);
372: } else if (customizer != null) {
373: newRef = ref;
374: customizer.firePropertyChange();
375: } else {
376: prop.setValue(ref);
377: }
378: }
379:
380: public boolean isModified() {
381: String curRef = prop.getValueSource();
382: return !((curRef == null && newRef == null) || (curRef != null && curRef
383: .equals(newRef)));
384: //return!(((curRef == null || curRef.length() == 0) && (newRef == null || newRef.length() == 0)) || (curRef != null && curRef.equals(newRef)));
385: }
386:
387: String newRef = null;
388:
389: public void customizerApply() {
390: prop.setValueSource(newRef);
391: //newRef = null;
392: }
393:
394: protected String calcValueRef(DesignBean rsBean, String valueColumn) {
395: if (rsBean == null || valueColumn == null
396: || valueColumn.length() == 0) {
397: //return ""; //NOI18N
398: return null;
399: }
400: DesignContext c = rsBean.getDesignContext();
401: if (c instanceof FacesDesignContext) {
402: return "#{" + ((FacesDesignContext) c).getReferenceName()
403: + "." + rsBean.getInstanceName() + ".currentRow['"
404: + valueColumn + "']}"; //NOI18N
405: }
406: return "#{" + c.getDisplayName() + "."
407: + rsBean.getInstanceName() + ".currentRow['"
408: + valueColumn + "']}"; //NOI18N
409: }
410:
411: class RSComboRenderer extends DefaultListCellRenderer {
412: public Component getListCellRendererComponent(JList list,
413: Object value, int index, boolean isSelected,
414: boolean cellHasFocus) {
415: super .getListCellRendererComponent(list, value, index,
416: isSelected, cellHasFocus);
417: DesignBean rsBean = (DesignBean) value;
418: this .setText(bundle.getMessage("rsDisplayTextPattern",
419: rsBean.getInstanceName(), rsBean.getDesignContext()
420: .getDisplayName())); //NOI18N
421: return this;
422: }
423: }
424: }
|