make/data/swingbeaninfo/sun/swing/BeanInfoUtils.java

Print this page


   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     /**