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;
042:
043: import java.beans.BeanInfo;
044: import java.beans.Introspector;
045: import java.beans.PropertyDescriptor;
046: import java.lang.reflect.Method;
047: import java.util.ArrayList;
048: import java.util.HashMap;
049: import javax.faces.context.FacesContext;
050: import javax.faces.el.ValueBinding;
051: import com.sun.rave.designtime.CustomizerResult;
052: import com.sun.rave.designtime.DesignBean;
053: import com.sun.rave.designtime.DesignProperty;
054: import com.sun.rave.designtime.DisplayAction;
055: import com.sun.rave.designtime.Result;
056: import com.sun.rave.designtime.impl.BasicDisplayAction;
057: import org.netbeans.modules.visualweb.propertyeditors.util.Bundle;
058: import org.openide.ErrorManager;
059:
060: public class PropertyBindingHelper {
061:
062: public static final Bundle bundle = Bundle
063: .getBundle(PropertyBindingHelper.class);
064:
065: public static DisplayAction getContextItem(DesignBean bean) {
066: return new PropertyBindingsAction(bean);
067: }
068:
069: public static DisplayAction getContextItem(DesignProperty prop) {
070: return new PropertyBindingAction(prop);
071: }
072:
073: /**
074: * The PropertyBindingAction is the DisplayAction (context item) that appears on the right-click
075: * menu of the property sheet for a particular property. This displays the BindingsCustomizer
076: * with only the right-hand side (BindingTargetPanel) visible, with a single property to be bound.
077: */
078: private static class PropertyBindingAction extends
079: BasicDisplayAction {
080:
081: public PropertyBindingAction(DesignProperty prop) {
082: super (bundle.getMessage("propBindingEllipse")); //NOI18N
083: this .prop = prop;
084: }
085:
086: protected DesignProperty prop = null;
087:
088: public Result invoke() {
089: PropertyBindingsCustomizer bc = new PropertyBindingsCustomizer(
090: prop);
091: bc.panel.setShowSourcePanel(false);
092: return new CustomizerResult(prop.getDesignBean(), bc);
093: }
094: }
095:
096: /**
097: * The PropertyBindingsAction is the DisplayAction (context item) that appears on the right-click
098: * menu for every component. This displays the BindingsCustomizer dialog with both the left
099: * (BindingSourcePanel) and right-hand sides (BindingTargetPanel) visible, so the user can choose
100: * any properties to be bound.
101: */
102: private static class PropertyBindingsAction extends
103: BasicDisplayAction {
104:
105: public PropertyBindingsAction(DesignBean bean) {
106: super (bundle.getMessage("propBindingsEllipse")); //NOI18N
107: this .bean = bean;
108: }
109:
110: protected DesignBean bean;
111:
112: public Result invoke() {
113: PropertyBindingsCustomizer bc = new PropertyBindingsCustomizer(
114: bean);
115: return new CustomizerResult(bean, bc);
116: }
117: }
118:
119: //------------------------------------------------------------------------------- Helper methods
120:
121: public static Object getPropInstance(DesignBean bean,
122: PropertyDescriptor[] propPath) {
123: if (propPath != null && propPath.length > 0) {
124: try {
125: ArrayList propList = new ArrayList();
126: for (int i = 0; i < propPath.length; i++) {
127: propList.add(propPath[i]);
128: }
129: Object o = bean.getInstance();
130: outerloop: while (o != null && propList.size() > 0) {
131: PropertyDescriptor pdnext = (PropertyDescriptor) propList
132: .get(0);
133: BeanInfo bi = Introspector
134: .getBeanInfo(o.getClass());
135: PropertyDescriptor[] pdanext = bi
136: .getPropertyDescriptors();
137: for (int i = 0; i < pdanext.length; i++) {
138: if (pdanext[i].getName().equals(
139: pdnext.getName())) {
140: //System.out.println("found: " + pdnext.getName() + " : " + propList.size() + " left");
141: Method read = pdanext[i].getReadMethod();
142: if ((read != null)
143: && !read.getName().equals(
144: "getFieldKeys")) {
145: try {
146: o = read.invoke(o, new Object[] {});
147: if (o instanceof ValueBinding) {
148: o = ((ValueBinding) o)
149: .getValue(FacesContext
150: .getCurrentInstance());
151: }
152: } catch (Exception exc) {
153: ErrorManager.getDefault().notify(
154: ErrorManager.INFORMATIONAL,
155: exc);
156: return null;
157: }
158: if (o != null) {
159: propList.remove(0);
160: continue outerloop;
161: }
162: } else {
163: return null;
164: }
165: }
166: }
167: }
168: return o;
169: } catch (Exception exc) {
170: ErrorManager.getDefault().notify(exc);
171: }
172: } else {
173: return bean.getInstance();
174: }
175: return null;
176: }
177:
178: static HashMap arrayTypeKeyHash = new HashMap();
179: static {
180: arrayTypeKeyHash.put("B", "byte"); //NOI18N
181: arrayTypeKeyHash.put("C", "char"); //NOI18N
182: arrayTypeKeyHash.put("D", "double"); //NOI18N
183: arrayTypeKeyHash.put("F", "float"); //NOI18N
184: arrayTypeKeyHash.put("I", "int"); //NOI18N
185: arrayTypeKeyHash.put("J", "long"); //NOI18N
186: arrayTypeKeyHash.put("S", "short"); //NOI18N
187: arrayTypeKeyHash.put("Z", "boolean"); //NOI18N
188: arrayTypeKeyHash.put("V", "void"); //NOI18N
189: }
190:
191: public static String getPrettyTypeName(String tn) {
192: tn = getJavaTypeName(tn);
193: if (tn.indexOf(".") > -1) { //NOI18N
194: tn = tn.substring(tn.lastIndexOf(".") + 1);
195: }
196: return tn;
197: }
198:
199: public static String getJavaTypeName(String tn) {
200: if (tn.startsWith("[")) { //NOI18N
201: int depth = 0;
202: while (tn.startsWith("[")) { //NOI18N
203: tn = tn.substring(1);
204: depth++;
205: }
206: if (tn.startsWith("L")) { //NOI18N
207: tn = tn.substring(1);
208: tn = tn.substring(0, tn.length() - 1);
209: } else {
210: char typeKey = tn.charAt(0);
211: tn = (String) arrayTypeKeyHash.get("" + typeKey); //NOI18N
212: }
213: for (int i = 0; i < depth; i++) {
214: tn += "[]"; //NOI18N
215: }
216: }
217: return tn;
218: }
219: }
|