1 /*
2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
105 * method implementation. One can use <code>createPropertyDescriptor</code>
106 * to set <code>FeatureDescriptor</code> attributes, as in "random attribute"
107 * "random object value".
108 * <p>
109 * All properties should provide a reasonable value for the
110 * <code>SHORTDESCRIPTION</code> keyword and should set <code>BOUND</code>
111 * to <code>Boolean.TRUE</code> if neccessary. The remaining keywords
112 * are optional. There's no need to provide values for keywords like
113 * READMETHOD if the correct value can be computed, i.e. if the properties
114 * get/is method follows the standard beans pattern.
115 * <p>
116 * The PREFERRED keyword is not supported by the JDK1.1 java.beans package.
117 * It's still worth setting it to true for properties that are most
118 * likely to be interested to the average developer, e.g. AbstractButton.title
119 * is a preferred property, AbstractButton.focusPainted is not.
120 *
121 * @see java.beans#BeanInfo
122 * @see java.beans#PropertyDescriptor
123 * @see java.beans#FeatureDescriptor
124 */
125 public static PropertyDescriptor createPropertyDescriptor(Class cls, String name, Object[] args)
126 {
127 PropertyDescriptor pd = null;
128 try {
129 pd = new PropertyDescriptor(name, cls);
130 } catch (IntrospectionException e) {
131 // Try creating a read-only property, in case setter isn't defined.
132 try {
133 pd = createReadOnlyPropertyDescriptor(name, cls);
134 } catch (IntrospectionException ie) {
135 throwError(ie, "Can't create PropertyDescriptor for " + name + " ");
136 }
137 }
138
139 for(int i = 0; i < args.length; i += 2) {
140 String key = (String)args[i];
141 Object value = args[i + 1];
142
143 if (BOUND.equals(key)) {
144 pd.setBound(((Boolean)value).booleanValue());
145 }
146
147 else if (CONSTRAINED.equals(key)) {
148 pd.setConstrained(((Boolean)value).booleanValue());
149 }
150
151 else if (PROPERTYEDITORCLASS.equals(key)) {
152 pd.setPropertyEditorClass((Class)value);
153 }
154
155 else if (READMETHOD.equals(key)) {
156 String methodName = (String)value;
157 Method method;
158 try {
159 method = cls.getMethod(methodName, new Class[0]);
160 pd.setReadMethod(method);
161 }
162 catch(Exception e) {
163 throwError(e, cls + " no such method as \"" + methodName + "\"");
164 }
165 }
166
167 else if (WRITEMETHOD.equals(key)) {
168 String methodName = (String)value;
169 Method method;
170 try {
171 Class type = pd.getPropertyType();
172 method = cls.getMethod(methodName, new Class[]{type});
173 pd.setWriteMethod(method);
174 }
175 catch(Exception e) {
176 throwError(e, cls + " no such method as \"" + methodName + "\"");
177 }
178 }
179
180 else {
181 initFeatureDescriptor(pd, key, value);
182 }
183 }
184
185 return pd;
186 }
187
188
189 /**
190 * Create a BeanDescriptor object given an of keyword/value
191 * arguments. The following sample call shows all of the supported
192 * keywords:
198 * HIDDEN, Boolean.FALSE,
199 * PREFERRED, Boolean.TRUE,
200 * SHORTDESCRIPTION, "A top level window with a window manager border",
201 * "random attribute","random object value"
202 * }
203 * );
204 * </pre>
205 * The keywords correspond to <code>java.beans.BeanDescriptor</code> and
206 * <code>java.beans.FeatureDescriptor</code> properties, e.g. providing a value
207 * for displayName is comparable to <code>FeatureDescriptor.setDisplayName()</code>.
208 * Using createBeanDescriptor instead of the BeanDescriptor
209 * constructor and set methods is preferrable in that it regularizes
210 * the code in a <code>java.beans.BeanInfo.getBeanDescriptor()</code>
211 * method implementation. One can use <code>createBeanDescriptor</code>
212 * to set <code>FeatureDescriptor</code> attributes, as in "random attribute"
213 * "random object value".
214 *
215 * @see java.beans#BeanInfo
216 * @see java.beans#PropertyDescriptor
217 */
218 public static BeanDescriptor createBeanDescriptor(Class cls, Object[] args)
219 {
220 Class customizerClass = null;
221
222 /* For reasons I don't understand, customizerClass is a
223 * readOnly property. So we have to find it and pass it
224 * to the constructor here.
225 */
226 for(int i = 0; i < args.length; i += 2) {
227 if (CUSTOMIZERCLASS.equals((String)args[i])) {
228 customizerClass = (Class)args[i + 1];
229 break;
230 }
231 }
232
233 BeanDescriptor bd = new BeanDescriptor(cls, customizerClass);
234
235 for(int i = 0; i < args.length; i += 2) {
236 String key = (String)args[i];
237 Object value = args[i + 1];
238 initFeatureDescriptor(bd, key, value);
239 }
240
241 return bd;
242 }
243
244 static private PropertyDescriptor createReadOnlyPropertyDescriptor(
245 String name, Class cls) throws IntrospectionException {
246
247 Method readMethod = null;
248 String base = capitalize(name);
249 Class[] parameters = new Class[0];
250
251 // Is it a boolean?
252 try {
253 readMethod = cls.getMethod("is" + base, parameters);
254 } catch (Exception ex) {}
255 if (readMethod == null) {
256 try {
257 // Try normal accessor pattern.
258 readMethod = cls.getMethod("get" + base, parameters);
259 } catch (Exception ex2) {}
260 }
261 if (readMethod != null) {
262 return new PropertyDescriptor(name, readMethod, null);
263 }
264
265 try {
266 // Try indexed accessor pattern.
267 parameters = new Class[1];
268 parameters[0] = int.class;
269 readMethod = cls.getMethod("get" + base, parameters);
270 } catch (NoSuchMethodException nsme) {
271 throw new IntrospectionException(
272 "cannot find accessor method for " + name + " property.");
273 }
274 return new IndexedPropertyDescriptor(name, null, null, readMethod, null);
275 }
276
277 // Modified methods from java.beans.Introspector
278 private static String capitalize(String s) {
279 if (s.length() == 0) {
280 return s;
281 }
282 char chars[] = s.toCharArray();
283 chars[0] = Character.toUpperCase(chars[0]);
284 return new String(chars);
285 }
286
287 /**
|
1 /*
2 * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
105 * method implementation. One can use <code>createPropertyDescriptor</code>
106 * to set <code>FeatureDescriptor</code> attributes, as in "random attribute"
107 * "random object value".
108 * <p>
109 * All properties should provide a reasonable value for the
110 * <code>SHORTDESCRIPTION</code> keyword and should set <code>BOUND</code>
111 * to <code>Boolean.TRUE</code> if neccessary. The remaining keywords
112 * are optional. There's no need to provide values for keywords like
113 * READMETHOD if the correct value can be computed, i.e. if the properties
114 * get/is method follows the standard beans pattern.
115 * <p>
116 * The PREFERRED keyword is not supported by the JDK1.1 java.beans package.
117 * It's still worth setting it to true for properties that are most
118 * likely to be interested to the average developer, e.g. AbstractButton.title
119 * is a preferred property, AbstractButton.focusPainted is not.
120 *
121 * @see java.beans#BeanInfo
122 * @see java.beans#PropertyDescriptor
123 * @see java.beans#FeatureDescriptor
124 */
125 public static PropertyDescriptor createPropertyDescriptor(Class<?> cls, String name, Object[] args)
126 {
127 PropertyDescriptor pd = null;
128 try {
129 pd = new PropertyDescriptor(name, cls);
130 } catch (IntrospectionException e) {
131 // Try creating a read-only property, in case setter isn't defined.
132 try {
133 pd = createReadOnlyPropertyDescriptor(name, cls);
134 } catch (IntrospectionException ie) {
135 throwError(ie, "Can't create PropertyDescriptor for " + name + " ");
136 }
137 }
138
139 for(int i = 0; i < args.length; i += 2) {
140 String key = (String)args[i];
141 Object value = args[i + 1];
142
143 if (BOUND.equals(key)) {
144 pd.setBound(((Boolean)value).booleanValue());
145 }
146
147 else if (CONSTRAINED.equals(key)) {
148 pd.setConstrained(((Boolean)value).booleanValue());
149 }
150
151 else if (PROPERTYEDITORCLASS.equals(key)) {
152 pd.setPropertyEditorClass((Class)value);
153 }
154
155 else if (READMETHOD.equals(key)) {
156 String methodName = (String)value;
157 Method method;
158 try {
159 method = cls.getMethod(methodName, new Class<?>[0]);
160 pd.setReadMethod(method);
161 }
162 catch(Exception e) {
163 throwError(e, cls + " no such method as \"" + methodName + "\"");
164 }
165 }
166
167 else if (WRITEMETHOD.equals(key)) {
168 String methodName = (String)value;
169 Method method;
170 try {
171 Class<?> type = pd.getPropertyType();
172 method = cls.getMethod(methodName, new Class<?>[]{type});
173 pd.setWriteMethod(method);
174 }
175 catch(Exception e) {
176 throwError(e, cls + " no such method as \"" + methodName + "\"");
177 }
178 }
179
180 else {
181 initFeatureDescriptor(pd, key, value);
182 }
183 }
184
185 return pd;
186 }
187
188
189 /**
190 * Create a BeanDescriptor object given an of keyword/value
191 * arguments. The following sample call shows all of the supported
192 * keywords:
198 * HIDDEN, Boolean.FALSE,
199 * PREFERRED, Boolean.TRUE,
200 * SHORTDESCRIPTION, "A top level window with a window manager border",
201 * "random attribute","random object value"
202 * }
203 * );
204 * </pre>
205 * The keywords correspond to <code>java.beans.BeanDescriptor</code> and
206 * <code>java.beans.FeatureDescriptor</code> properties, e.g. providing a value
207 * for displayName is comparable to <code>FeatureDescriptor.setDisplayName()</code>.
208 * Using createBeanDescriptor instead of the BeanDescriptor
209 * constructor and set methods is preferrable in that it regularizes
210 * the code in a <code>java.beans.BeanInfo.getBeanDescriptor()</code>
211 * method implementation. One can use <code>createBeanDescriptor</code>
212 * to set <code>FeatureDescriptor</code> attributes, as in "random attribute"
213 * "random object value".
214 *
215 * @see java.beans#BeanInfo
216 * @see java.beans#PropertyDescriptor
217 */
218 public static BeanDescriptor createBeanDescriptor(Class<?> cls, Object[] args)
219 {
220 Class<?> customizerClass = null;
221
222 /* For reasons I don't understand, customizerClass is a
223 * readOnly property. So we have to find it and pass it
224 * to the constructor here.
225 */
226 for(int i = 0; i < args.length; i += 2) {
227 if (CUSTOMIZERCLASS.equals((String)args[i])) {
228 customizerClass = (Class)args[i + 1];
229 break;
230 }
231 }
232
233 BeanDescriptor bd = new BeanDescriptor(cls, customizerClass);
234
235 for(int i = 0; i < args.length; i += 2) {
236 String key = (String)args[i];
237 Object value = args[i + 1];
238 initFeatureDescriptor(bd, key, value);
239 }
240
241 return bd;
242 }
243
244 static private PropertyDescriptor createReadOnlyPropertyDescriptor(
245 String name, Class<?> cls) throws IntrospectionException {
246
247 Method readMethod = null;
248 String base = capitalize(name);
249 Class<?>[] parameters = new Class<?>[0];
250
251 // Is it a boolean?
252 try {
253 readMethod = cls.getMethod("is" + base, parameters);
254 } catch (Exception ex) {}
255 if (readMethod == null) {
256 try {
257 // Try normal accessor pattern.
258 readMethod = cls.getMethod("get" + base, parameters);
259 } catch (Exception ex2) {}
260 }
261 if (readMethod != null) {
262 return new PropertyDescriptor(name, readMethod, null);
263 }
264
265 try {
266 // Try indexed accessor pattern.
267 parameters = new Class<?>[1];
268 parameters[0] = int.class;
269 readMethod = cls.getMethod("get" + base, parameters);
270 } catch (NoSuchMethodException nsme) {
271 throw new IntrospectionException(
272 "cannot find accessor method for " + name + " property.");
273 }
274 return new IndexedPropertyDescriptor(name, null, null, readMethod, null);
275 }
276
277 // Modified methods from java.beans.Introspector
278 private static String capitalize(String s) {
279 if (s.length() == 0) {
280 return s;
281 }
282 char chars[] = s.toCharArray();
283 chars[0] = Character.toUpperCase(chars[0]);
284 return new String(chars);
285 }
286
287 /**
|