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.data;
042:
043: import com.sun.rave.designtime.DesignBean;
044: import com.sun.rave.designtime.DesignContext;
045: import com.sun.rave.designtime.faces.FacesDesignProperty;
046: import java.lang.reflect.Constructor;
047: import java.util.ArrayList;
048: import java.awt.GridBagConstraints;
049: import java.awt.GridBagLayout;
050: import java.awt.Insets;
051: import javax.swing.JLabel;
052: import javax.swing.JTabbedPane;
053: import javax.swing.JTextField;
054:
055: import com.sun.rave.designtime.DesignProperty;
056: import com.sun.rave.designtime.faces.FacesDesignContext;
057: import org.netbeans.modules.visualweb.propertyeditors.binding.BindingTargetCallback;
058: import org.netbeans.modules.visualweb.propertyeditors.util.Bundle;
059:
060: import com.sun.data.provider.DataProvider;
061: import com.sun.rave.designtime.DesignProject;
062: import com.sun.rave.designtime.faces.FacesDesignProject;
063:
064: public class TabbedDataBindingPanel extends DataBindingPanel implements
065: BindingTargetCallback {
066:
067: private static final Bundle bundle = Bundle
068: .getBundle(TabbedDataBindingPanel.class);
069:
070: protected JTabbedPane tabs = new JTabbedPane();
071:
072: protected JTextField valueTextField = new JTextField(70); // resonable number of columns for value field to limit the preferred size
073: protected GridBagLayout gridBagLayout1 = new GridBagLayout();
074: protected JLabel valueLabel = new JLabel();
075:
076: public String getDataBindingTitle() {
077: return bundle.getMessage("bindToData"); // NOI18N
078: }
079:
080: public void refresh() {
081: this .validate();
082: this .doLayout();
083: this .repaint(100);
084: bindingCallback.refresh();
085: }
086:
087: public void setNewExpressionText(String newExpr) {
088: if (initializing) {
089: return;
090: }
091: valueTextField.setText(newExpr);
092: bindingCallback.setNewExpressionText(newExpr);
093: }
094:
095: public String getNewExpressionText() {
096: return valueTextField.getText();
097: }
098:
099: private static Class[] BINDING_PANEL_CONSTRUCTOR_SIG = new Class[] {
100: BindingTargetCallback.class, DesignProperty.class };
101:
102: public TabbedDataBindingPanel(BindingTargetCallback callback,
103: DesignProperty prop, Class[] bindingPanelClasses,
104: boolean showExpr) {
105: super (callback, prop);
106:
107: // find the current value
108: valueTextField.setText(prop.getValueSource());
109: valueLabel.setLabelFor(valueTextField);
110: valueLabel.setDisplayedMnemonic(bundle.getMessage(
111: "VALUE_EXP_DISPLAYED_MNEMONIC").charAt(0));
112: valueTextField.getAccessibleContext().setAccessibleName(
113: bundle.getMessage("VALUE_EXP_ACCESS_NAME"));
114: valueTextField.getAccessibleContext().setAccessibleDescription(
115: bundle.getMessage("VALUE_EXP_ACCESS_DESC"));
116:
117: ArrayList bindingPanels = new ArrayList();
118: if (bindingPanelClasses != null
119: && bindingPanelClasses.length > 0) {
120: for (int i = 0; i < bindingPanelClasses.length; i++) {
121: try {
122: Constructor con = bindingPanelClasses[i]
123: .getConstructor(BINDING_PANEL_CONSTRUCTOR_SIG);
124: DataBindingPanel bp = (DataBindingPanel) con
125: .newInstance(new Object[] { this , prop });
126: bindingPanels.add(bp);
127: } catch (Exception x) {
128: x.printStackTrace();
129: }
130: }
131: } else {
132: bindingPanels.add(new BindValueToObjectPanel(this , prop));
133: }
134:
135: this .setLayout(gridBagLayout1);
136: String lbl_current = bundle.getMessage("LBL_Current");
137: String lbl_setting = bundle.getMessage("LBL_Setting");
138: valueLabel.setText(lbl_current
139: + " "
140: + designProperty.getPropertyDescriptor()
141: .getDisplayName() + " " + lbl_setting); //NOI18N
142: if (showExpr && bindingPanels.size() > 0) {
143: this .add(valueLabel, new GridBagConstraints(0, 0, 1, 1,
144: 1.0, 0.0, GridBagConstraints.CENTER,
145: GridBagConstraints.HORIZONTAL, new Insets(8, 8, 2,
146: 8), 0, 0));
147: this .add(valueTextField, new GridBagConstraints(0, 1, 1, 1,
148: 1.0, 0.0, GridBagConstraints.WEST,
149: GridBagConstraints.HORIZONTAL, new Insets(0, 8, 4,
150: 8), 0, 0));
151: }
152:
153: if (bindingPanels.size() > 1) {
154: boolean shouldShowBindToObjectPanel = showBindToObjectPanel();
155: this .add(tabs, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0,
156: GridBagConstraints.CENTER, GridBagConstraints.BOTH,
157: new Insets(0, 8, 8, 8), 0, 0));
158: int selectedIndex = 0;
159: for (int i = 0; i < bindingPanels.size(); i++) {
160: DataBindingPanel bp = (DataBindingPanel) bindingPanels
161: .get(i);
162: tabs.add(bp, bp.getDataBindingTitle());
163: tabs.getAccessibleContext().setAccessibleDescription(
164: bp.getDataBindingTitle());
165: tabs.getAccessibleContext().setAccessibleName(
166: bp.getDataBindingTitle());
167: if (shouldShowBindToObjectPanel
168: && bp.getClass().isAssignableFrom(
169: BindValueToObjectPanel.class)) {
170: selectedIndex = i;
171: }
172: }
173: tabs.setSelectedIndex(selectedIndex);
174: } else if (bindingPanels.size() > 0) {
175: DataBindingPanel bp = (DataBindingPanel) bindingPanels
176: .get(0);
177: this .add(bp, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0,
178: GridBagConstraints.CENTER, GridBagConstraints.BOTH,
179: new Insets(0, 8, 8, 8), 0, 0));
180: }
181:
182: initializing = false;
183: }
184:
185: // For performance improvement. No need to get all the contexts in the project
186: private DesignContext[] getDesignContexts(DesignBean designBean) {
187: DesignProject designProject = designBean.getDesignContext()
188: .getProject();
189: DesignContext[] contexts;
190: if (designProject instanceof FacesDesignProject) {
191: contexts = ((FacesDesignProject) designProject)
192: .findDesignContexts(new String[] { "request",
193: "session", "application" });
194: } else {
195: contexts = new DesignContext[0];
196: }
197: DesignContext[] designContexts = new DesignContext[contexts.length + 1];
198: designContexts[0] = designBean.getDesignContext();
199: System.arraycopy(contexts, 0, designContexts, 1,
200: contexts.length);
201: return designContexts;
202: }
203:
204: private boolean showBindToObjectPanel() {
205: // Show the data provider panel by default
206: String valueExpression = null;
207: if (designProperty instanceof FacesDesignProperty) {
208: FacesDesignProperty fprop = (FacesDesignProperty) designProperty;
209: if (fprop.isBound() && fprop.getValueBinding() != null) {
210: valueExpression = fprop.getValueBinding()
211: .getExpressionString();
212: }
213: } else {
214: valueExpression = designProperty.getValueSource();
215: }
216: if (valueExpression != null) {
217: boolean dataProviderBound = false;
218: //DesignContext[] contexts = designProperty.getDesignBean().getDesignContext().getProject().getDesignContexts();
219: DesignContext[] contexts = getDesignContexts(designProperty
220: .getDesignBean());
221:
222: // Scan for all data providers
223: for (int i = 0; i < contexts.length; i++) {
224: DesignBean[] dpbs = contexts[i]
225: .getBeansOfType(DataProvider.class);
226: for (int j = 0; j < dpbs.length; j++) {
227: String modelBindingExpr = ((FacesDesignContext) contexts[i])
228: .getBindingExpr(dpbs[j]);
229: // Get only the qualified name
230: int startIndex = modelBindingExpr.indexOf('{');
231: int endIndex = modelBindingExpr.indexOf('}');
232: if ((startIndex != -1) && (endIndex != -1)) {
233: modelBindingExpr = modelBindingExpr.substring(
234: startIndex + 2, endIndex - 1);
235: }
236: if (valueExpression.indexOf(modelBindingExpr) != -1) {
237: dataProviderBound = true;
238: break;
239: }
240: }
241: }
242:
243: // Value bound but not to databound so assume bound to object
244: if (!dataProviderBound)
245: return true;
246: }
247: return false;
248: }
249:
250: protected boolean initializing = true;
251: }
|