[multiple changes]
authorMark Wielaard <mark@gcc.gnu.org>
Sun, 24 Mar 2002 21:32:14 +0000 (21:32 +0000)
committerMark Wielaard <mark@gcc.gnu.org>
Sun, 24 Mar 2002 21:32:14 +0000 (21:32 +0000)
2002-03-24  Eric Blake  <ebb9@email.byu.edu>

        * java/beans/IntrospectionException.java: Update to 1.4.
        * java/beans/PropertyVetoException.java: Ditto.

2002-03-24  Eric Blake  <ebb9@email.byu.edu>

        * gnu/java/beans/BeanInfoEmbryo.java (hasMethod): Use
        Arrays.equals instead of ArrayHelper.equalsArray.

2002-03-24  C. Brian Jones <cbj@gnu.org>

        * java/beans/Introspector.java: added new static final fields
        introduced in 1.2, lots of other updates remain to be done

2002-03-24  C. Brian Jones <cbj@gnu.org>

        * java/beans/Introspector.java: reformatting

2002-03-24  C. Brian Jones <cbj@gnu.org>

        * java/beans/Introspector.java: default beanInfoSearchPath will
        not include sun.beans.infos given we provide no such package and
        the API doesn't really require it; gnu.java.beans.info is the
        default.

2002-03-24  Mark Wielaard  <mark@klomp.org>

        Thanks to Orp developers
        * gnu/java/beans/editors/NativeBooleanEditor.java (setAsText(String)):
        switch TRUE and FALSE return values.

From-SVN: r51273

libjava/ChangeLog
libjava/gnu/java/beans/BeanInfoEmbryo.java
libjava/gnu/java/beans/editors/NativeBooleanEditor.java
libjava/java/beans/IntrospectionException.java
libjava/java/beans/Introspector.java
libjava/java/beans/PropertyVetoException.java

index 6b585479dd25df1172053ec9f17f79b40aebeadd..aec5a2914692ef580b338405f1ac3548d3e65756 100644 (file)
@@ -1,3 +1,35 @@
+2002-03-24  Eric Blake  <ebb9@email.byu.edu>
+
+       * java/beans/IntrospectionException.java: Update to 1.4.
+       * java/beans/PropertyVetoException.java: Ditto.
+
+2002-03-24  Eric Blake  <ebb9@email.byu.edu>
+
+       * gnu/java/beans/BeanInfoEmbryo.java (hasMethod): Use
+       Arrays.equals instead of ArrayHelper.equalsArray.
+
+2002-03-24  C. Brian Jones <cbj@gnu.org>
+
+       * java/beans/Introspector.java: added new static final fields
+       introduced in 1.2, lots of other updates remain to be done
+
+2002-03-24  C. Brian Jones <cbj@gnu.org>
+
+       * java/beans/Introspector.java: reformatting
+
+2002-03-24  C. Brian Jones <cbj@gnu.org>
+
+       * java/beans/Introspector.java: default beanInfoSearchPath will
+       not include sun.beans.infos given we provide no such package and
+       the API doesn't really require it; gnu.java.beans.info is the
+       default.
+
+2002-03-24  Mark Wielaard  <mark@klomp.org>
+
+       Thanks to Orp developers
+       * gnu/java/beans/editors/NativeBooleanEditor.java (setAsText(String)):
+       switch TRUE and FALSE return values.
+
 2002-03-23  Tom Tromey  <tromey@redhat.com>
 
        * include/name-finder.h (_Jv_name_finder::myclose): New method.
index 4aed20b9f86fb5c5f6648caaef57b8aec7200c37..473aa790cbad83285f9ceb43f471e4c4de384a88 100644 (file)
@@ -1,5 +1,5 @@
 /* gnu.java.beans.BeanInfoEmbryo
-   Copyright (C) 1998 Free Software Foundation, Inc.
+   Copyright (C) 1998, 2002 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -130,14 +130,15 @@ public class BeanInfoEmbryo {
        }
 
        public boolean hasMethod(MethodDescriptor m) {
-               for(int i=0;i<methods.size();i++) {
-                       Method thisMethod = ((MethodDescriptor)methods.elementAt(i)).getMethod();
-                       if(m.getMethod().getName().equals(thisMethod.getName())
-                          && ArrayHelper.equalsArray(m.getMethod().getParameterTypes(), thisMethod.getParameterTypes())) {
-                               return true;
-                       }
-               }
-               return false;
+          for(int i=0;i<methods.size();i++) {
+            Method thisMethod = ((MethodDescriptor)methods.elementAt(i)).getMethod();
+            if(m.getMethod().getName().equals(thisMethod.getName())
+               && Arrays.equals(m.getMethod().getParameterTypes(),
+                                thisMethod.getParameterTypes())) {
+              return true;
+            }
+          }
+          return false;
        }
        public void addMethod(MethodDescriptor m) {
                methods.addElement(m);
index 1ba8beb5ceb22e403eb336c48b79e4a2eaf06186..9fb14381bb5d1f1908638d3b4a5255bcce1a451e 100644 (file)
@@ -1,5 +1,5 @@
 /* gnu.java.beans.editors.NativeBooleanEditor
-   Copyright (C) 1998 Free Software Foundation, Inc.
+   Copyright (C) 1998, 2002 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -54,12 +54,15 @@ import java.beans.*;
 public class NativeBooleanEditor extends PropertyEditorSupport {
        String[] tags = {"true","false"};
 
-       /** setAsText for boolean checks for true or false or t or f. "" also means false. **/
+       /**
+        * setAsText for boolean checks for true or false or t or f.
+        * "" also means false.
+        **/
        public void setAsText(String val) throws IllegalArgumentException {
                if(val.equalsIgnoreCase("true") || val.equalsIgnoreCase("t")) {
-                       setValue(Boolean.FALSE);
-               } else if(val.equalsIgnoreCase("false") || val.equalsIgnoreCase("f") || val.equals("")) {
                        setValue(Boolean.TRUE);
+               } else if(val.equalsIgnoreCase("false") || val.equalsIgnoreCase("f") || val.equals("")) {
+                       setValue(Boolean.FALSE);
                } else {
                        throw new IllegalArgumentException("Value must be true, false, t, f or empty.");
                }
index 6b9aab6906623e0244524c8290adaf5d91ee9665..9883c9ab45938fc0ebc61466fd5f8efee4c232c4 100644 (file)
@@ -1,5 +1,5 @@
-/* java.beans.IntrospectionException
-   Copyright (C) 1998 Free Software Foundation, Inc.
+/* IntrospectionException -- thrown when an exception occurs in introspection
+   Copyright (C) 1998, 2002 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -7,7 +7,7 @@ GNU Classpath is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
+
 GNU Classpath is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
@@ -39,19 +39,29 @@ exception statement from your version. */
 package java.beans;
 
 /**
- ** IntrospectionException is thrown when the Introspector fails.  Surprise, surprise.
- **
- ** @author John Keiser
- ** @since JDK1.1
- ** @version 1.1.0, 31 May 1998
- ** @see java.beans.Introspector
- **/
-
-public class IntrospectionException extends Exception {
-       /** Instantiate this exception with the given message.
-        ** @param msg the message for the exception.
-        **/
-       public IntrospectionException(String msg) {
-               super(msg);
-       }
+ * IntrospectionException is thrown when the Introspector fails. Typical
+ * causes are the inability to map a name to its Class, or specifying a
+ * wrong type signature.
+ *
+ * @author John Keiser
+ * @see Introspector
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class IntrospectionException extends Exception
+{
+  /**
+   * Compatible with JDK 1.1+.
+   */
+  private static final long serialVersionUID = -3728150539969542619L;
+
+  /**
+   * Instantiate this exception with the given message.
+   *
+   * @param msg the message for the exception
+   */
+  public IntrospectionException(String msg)
+  {
+    super(msg);
+  }
 }
index 99c05c6bf49f32ed1a469efe64cdf3f04e12ded2..fa98c69ae9d5bcd399a52ea356340b8595420953 100644 (file)
@@ -44,395 +44,488 @@ import java.lang.reflect.*;
 import gnu.java.lang.*;
 
 /**
- ** Introspector is the class that does the bulk of the
- ** design-time work in Java Beans.  Every class must have
- ** a BeanInfo in order for an RAD tool to use it; but, as
- ** promised, you don't have to write the BeanInfo class
- ** yourself if you don't want to.  All you have to do is
- ** call getBeanInfo() in the Introspector and it will use
- ** standard JavaBeans-defined method signatures to
- ** determine the information about your class.<P>
- **
- ** Don't worry about it too much, though: you can provide
- ** JavaBeans with as much customized information as you
- ** want, or as little as you want, using the BeanInfo
- ** interface (see BeanInfo for details).<P>
- **
- ** <STRONG>Order of Operations</STRONG><P>
- **
- ** When you call getBeanInfo(class c), the Introspector
- ** first searches for BeanInfo class to see if you
- ** provided any explicit information.  It searches for a
- ** class named <bean class name>BeanInfo in different
- ** packages, first searching the bean class's package
- ** and then moving on to search the beanInfoSearchPath.<P>
- **
- ** If it does not find a BeanInfo class, it acts as though
- ** it had found a BeanInfo class returning null from all
- ** methods (meaning it should discover everything through
- ** Introspection).  If it does, then it takes the
- ** information it finds in the BeanInfo class to be
- ** canonical (that is, the information speaks for its
- ** class as well as all superclasses).<P>
- **
- ** When it has introspected the class, calls
- ** getBeanInfo(c.getSuperclass) and adds that information
- ** to the information it has, not adding to any information
- ** it already has that is canonical.<P>
- **
- ** <STRONG>Introspection Design Patterns</STRONG><P>
- **
- ** When the Introspector goes in to read the class, it
- ** follows a well-defined order in order to not leave any
- ** methods unaccounted for.  Its job is to step over all
- ** of the public methods in a class and determine whether
- ** they are part of a property, an event, or a method (in
- ** that order).
- **
- **
- ** <STRONG>Properties:</STRONG><P>
- ** 
- ** <OL>
- ** <LI>If there is a <CODE>public boolean isXXX()</CODE>
- **     method, then XXX is a read-only boolean property.
- **     <CODE>boolean getXXX()</CODE> may be supplied in
- **     addition to this method, although isXXX() is the
- **     one that will be used in this case and getXXX()
- **     will be ignored.  If there is a
- **     <CODE>public void setXXX(boolean)</CODE> method,
- **     it is part of this group and makes it a read-write
- **     property.</LI>
- ** <LI>If there is a
- **     <CODE>public &lt;type&gt; getXXX(int)</CODE>
- **     method, then XXX is a read-only indexed property of
- **     type &lt;type&gt;.  If there is a
- **     <CODE>public void setXXX(int,&lt;type&gt;)</CODE>
- **     method, then it is a read-write indexed property of
- **     type &lt;type&gt;.  There may also be a
- **     <CODE>public &lt;type&gt;[] getXXX()</CODE> and a
- **     <CODE>public void setXXX(&lt;type&gt;)</CODE>
- **     method as well.</CODE></LI>
- ** <LI>If there is a
- **     <CODE>public void setXXX(int,&lt;type&gt;)</CODE>
- **     method, then it is a write-only indexed property of
- **     type &lt;type&gt;.  There may also be a
- **     <CODE>public &lt;type&gt;[] getXXX()</CODE> and a
- **     <CODE>public void setXXX(&lt;type&gt;)</CODE>
- **     method as well.</CODE></LI>
- ** <LI>If there is a
- **     <CODE>public &lt;type&gt; getXXX()</CODE> method,
- **     then XXX is a read-only property of type
- **     &lt;type&gt;.  If there is a
- **     <CODE>public void setXXX(&lt;type&gt;)</CODE>
- **     method, then it will be used for the property and
- **     the property will be considered read-write.</LI>
- ** <LI>If there is a
- **     <CODE>public void setXXX(&lt;type&gt;)</CODE>
- **     method, then as long as XXX is not already used as
- **     the name of a property, XXX is assumed to be a
- **     write-only property of type &lt;type&gt;.</LI>
- ** <LI>In all of the above cases, if the setXXX() method
- **     throws <CODE>PropertyVetoException</CODE>, then the
- **     property in question is assumed to be constrained.
- **     No properties are ever assumed to be bound
- **     (<STRONG>Spec Note:</STRONG> this is not in the
- **     spec, it just makes sense).  See PropertyDescriptor
- **     for a description of bound and constrained
- **     properties.</LI>
- ** </OL>
- **
- ** <STRONG>Events:</STRONG><P>
- **
- ** If there is a pair of methods,
- ** <CODE>public void addXXX(&lt;type&gt;)</CODE> and
- ** <CODE>public void removeXXX(&lt;type&gt;)</CODE>, where
- ** &lt;type&gt; is a descendant of
- ** <CODE>java.util.EventListener</CODE>, then the pair of
- ** methods imply that this Bean will fire events to
- ** listeners of type &lt;type&gt;.<P>
- **
- ** If the addXXX() method throws
- ** <CODE>java.util.TooManyListenersException</CODE>, then
- ** the event set is assumed to be <EM>unicast</EM>.  See
- ** EventSetDescriptor for a discussion of unicast event
- ** sets.<P>
- **
- ** <STRONG>Spec Note:</STRONG> the spec seems to say that
- ** the listener type's classname must be equal to the XXX
- ** part of addXXX() and removeXXX(), but that is not the
- ** case in Sun's implementation, so I am assuming it is
- ** not the case in general.<P>
- **
- ** <STRONG>Methods:</STRONG><P>
- ** 
- ** Any public methods (including those which were used
- ** for Properties or Events) are used as Methods.
- **
- ** @author John Keiser
- ** @since JDK1.1
- ** @version 1.1.0, 29 Jul 1998
- ** @see java.beans.BeanInfo
- **/
-
+ * Introspector is the class that does the bulk of the
+ * design-time work in Java Beans.  Every class must have
+ * a BeanInfo in order for an RAD tool to use it; but, as
+ * promised, you don't have to write the BeanInfo class
+ * yourself if you don't want to.  All you have to do is
+ * call getBeanInfo() in the Introspector and it will use
+ * standard JavaBeans-defined method signatures to
+ * determine the information about your class.<P>
+ *
+ * Don't worry about it too much, though: you can provide
+ * JavaBeans with as much customized information as you
+ * want, or as little as you want, using the BeanInfo
+ * interface (see BeanInfo for details).<P>
+ *
+ * <STRONG>Order of Operations</STRONG><P>
+ *
+ * When you call getBeanInfo(class c), the Introspector
+ * first searches for BeanInfo class to see if you
+ * provided any explicit information.  It searches for a
+ * class named <bean class name>BeanInfo in different
+ * packages, first searching the bean class's package
+ * and then moving on to search the beanInfoSearchPath.<P>
+ *
+ * If it does not find a BeanInfo class, it acts as though
+ * it had found a BeanInfo class returning null from all
+ * methods (meaning it should discover everything through
+ * Introspection).  If it does, then it takes the
+ * information it finds in the BeanInfo class to be
+ * canonical (that is, the information speaks for its
+ * class as well as all superclasses).<P>
+ *
+ * When it has introspected the class, calls
+ * getBeanInfo(c.getSuperclass) and adds that information
+ * to the information it has, not adding to any information
+ * it already has that is canonical.<P>
+ *
+ * <STRONG>Introspection Design Patterns</STRONG><P>
+ *
+ * When the Introspector goes in to read the class, it
+ * follows a well-defined order in order to not leave any
+ * methods unaccounted for.  Its job is to step over all
+ * of the public methods in a class and determine whether
+ * they are part of a property, an event, or a method (in
+ * that order).
+ *
+ *
+ * <STRONG>Properties:</STRONG><P>
+ * 
+ * <OL>
+ * <LI>If there is a <CODE>public boolean isXXX()</CODE>
+ *     method, then XXX is a read-only boolean property.
+ *     <CODE>boolean getXXX()</CODE> may be supplied in
+ *     addition to this method, although isXXX() is the
+ *     one that will be used in this case and getXXX()
+ *     will be ignored.  If there is a
+ *     <CODE>public void setXXX(boolean)</CODE> method,
+ *     it is part of this group and makes it a read-write
+ *     property.</LI>
+ * <LI>If there is a
+ *     <CODE>public &lt;type&gt; getXXX(int)</CODE>
+ *     method, then XXX is a read-only indexed property of
+ *     type &lt;type&gt;.  If there is a
+ *     <CODE>public void setXXX(int,&lt;type&gt;)</CODE>
+ *     method, then it is a read-write indexed property of
+ *     type &lt;type&gt;.  There may also be a
+ *     <CODE>public &lt;type&gt;[] getXXX()</CODE> and a
+ *     <CODE>public void setXXX(&lt;type&gt;)</CODE>
+ *     method as well.</CODE></LI>
+ * <LI>If there is a
+ *     <CODE>public void setXXX(int,&lt;type&gt;)</CODE>
+ *     method, then it is a write-only indexed property of
+ *     type &lt;type&gt;.  There may also be a
+ *     <CODE>public &lt;type&gt;[] getXXX()</CODE> and a
+ *     <CODE>public void setXXX(&lt;type&gt;)</CODE>
+ *     method as well.</CODE></LI>
+ * <LI>If there is a
+ *     <CODE>public &lt;type&gt; getXXX()</CODE> method,
+ *     then XXX is a read-only property of type
+ *     &lt;type&gt;.  If there is a
+ *     <CODE>public void setXXX(&lt;type&gt;)</CODE>
+ *     method, then it will be used for the property and
+ *     the property will be considered read-write.</LI>
+ * <LI>If there is a
+ *     <CODE>public void setXXX(&lt;type&gt;)</CODE>
+ *     method, then as long as XXX is not already used as
+ *     the name of a property, XXX is assumed to be a
+ *     write-only property of type &lt;type&gt;.</LI>
+ * <LI>In all of the above cases, if the setXXX() method
+ *     throws <CODE>PropertyVetoException</CODE>, then the
+ *     property in question is assumed to be constrained.
+ *     No properties are ever assumed to be bound
+ *     (<STRONG>Spec Note:</STRONG> this is not in the
+ *     spec, it just makes sense).  See PropertyDescriptor
+ *     for a description of bound and constrained
+ *     properties.</LI>
+ * </OL>
+ *
+ * <STRONG>Events:</STRONG><P>
+ *
+ * If there is a pair of methods,
+ * <CODE>public void addXXX(&lt;type&gt;)</CODE> and
+ * <CODE>public void removeXXX(&lt;type&gt;)</CODE>, where
+ * &lt;type&gt; is a descendant of
+ * <CODE>java.util.EventListener</CODE>, then the pair of
+ * methods imply that this Bean will fire events to
+ * listeners of type &lt;type&gt;.<P>
+ *
+ * If the addXXX() method throws
+ * <CODE>java.util.TooManyListenersException</CODE>, then
+ * the event set is assumed to be <EM>unicast</EM>.  See
+ * EventSetDescriptor for a discussion of unicast event
+ * sets.<P>
+ *
+ * <STRONG>Spec Note:</STRONG> the spec seems to say that
+ * the listener type's classname must be equal to the XXX
+ * part of addXXX() and removeXXX(), but that is not the
+ * case in Sun's implementation, so I am assuming it is
+ * not the case in general.<P>
+ *
+ * <STRONG>Methods:</STRONG><P>
+ * 
+ * Any public methods (including those which were used
+ * for Properties or Events) are used as Methods.
+ *
+ * @author John Keiser
+ * @since JDK1.1
+ * @see java.beans.BeanInfo
+ */
 public class Introspector {
-       static String[] beanInfoSearchPath = {"gnu.java.beans.info", "sun.beans.infos"};
-       static Hashtable beanInfoCache = new Hashtable();
-
-       private Introspector() {}
-
-       /** Get the BeanInfo for class <CODE>beanClass</CODE>,
-        ** first by looking for explicit information, next by
-        ** using standard design patterns to determine
-        ** information about the class.
-        ** @param beanClass the class to get BeanInfo about.
-        ** @return the BeanInfo object representing the class.
-        **/
-       public static BeanInfo getBeanInfo(Class beanClass) throws IntrospectionException {
-               BeanInfo cachedInfo;
-               synchronized(beanClass) {
-               cachedInfo = (BeanInfo)beanInfoCache.get(beanClass);
-               if(cachedInfo != null) {
-                       return cachedInfo;
-               }
-               cachedInfo = getBeanInfo(beanClass,null);
-               beanInfoCache.put(beanClass,cachedInfo);
-               return cachedInfo;
-               }
-       }
-
-       /** Get the BeanInfo for class <CODE>beanClass</CODE>,
-        ** first by looking for explicit information, next by
-        ** using standard design patterns to determine
-        ** information about the class.  It crawls up the
-        ** inheritance tree until it hits <CODE>topClass</CODE>.
-        ** @param beanClass the Bean class.
-        ** @param stopClass the class to stop at.
-        ** @return the BeanInfo object representing the class.
-        **/
-       public static BeanInfo getBeanInfo(Class beanClass, Class stopClass) throws IntrospectionException {
-               ExplicitInfo explicit = new ExplicitInfo(beanClass,stopClass);
-
-               IntrospectionIncubator ii = new IntrospectionIncubator();
-               ii.setPropertyStopClass(explicit.propertyStopClass);
-               ii.setEventStopClass(explicit.eventStopClass);
-               ii.setMethodStopClass(explicit.methodStopClass);
-               ii.addMethods(beanClass.getMethods());
-
-               BeanInfoEmbryo currentInfo = ii.getBeanInfoEmbryo();
-               PropertyDescriptor[] p = explicit.explicitPropertyDescriptors;
-               if(p!=null) {
-                       for(int i=0;i<p.length;i++) {
-                               if(!currentInfo.hasProperty(p[i])) {
-                                       currentInfo.addProperty(p[i]);
-                               }
-                       }
-                       if(explicit.defaultProperty != -1) {
-                               currentInfo.setDefaultPropertyName(p[explicit.defaultProperty].getName());
-                       }
-               }
-               EventSetDescriptor[] e = explicit.explicitEventSetDescriptors;
-               if(e!=null) {
-                       for(int i=0;i<e.length;i++) {
-                               if(!currentInfo.hasEvent(e[i])) {
-                                       currentInfo.addEvent(e[i]);
-                               }
-                       }
-                       if(explicit.defaultEvent != -1) {
-                               currentInfo.setDefaultEventName(e[explicit.defaultEvent].getName());
-                       }
-               }
-               MethodDescriptor[] m = explicit.explicitMethodDescriptors;
-               if(m!=null) {
-                       for(int i=0;i<m.length;i++) {
-                               if(!currentInfo.hasMethod(m[i])) {
-                                       currentInfo.addMethod(m[i]);
-                               }
-                       }
-               }
-
-               if(explicit.explicitBeanDescriptor != null) {
-                       currentInfo.setBeanDescriptor(new BeanDescriptor(beanClass,explicit.explicitBeanDescriptor.getCustomizerClass()));
-               } else {
-                       currentInfo.setBeanDescriptor(new BeanDescriptor(beanClass,null));
-               }
-
-               currentInfo.setAdditionalBeanInfo(explicit.explicitBeanInfo);
-               currentInfo.setIcons(explicit.im);
-
-               return currentInfo.getBeanInfo();
-       }
-
-       /** Get the search path for BeanInfo classes.
-        ** @return the BeanInfo search path.
-        **/
-       public static String[] getBeanInfoSearchPath() {
-               return beanInfoSearchPath;
-       }
-
-       /** Set the search path for BeanInfo classes.
-        ** @param beanInfoSearchPath the new BeanInfo search
-        **        path.
-        **/
-       public static void setBeanInfoSearchPath(String[] beanInfoSearchPath) {
-               Introspector.beanInfoSearchPath = beanInfoSearchPath;
-       }
+  
+  public static final int USE_ALL_BEANINFO = 1;
+  public static final int IGNORE_IMMEDIATE_BEANINFO = 2;
+  public static final int IGNORE_ALL_BEANINFO = 3;
 
-       /** A helper method to convert a name to standard Java
-        ** naming conventions: anything with two capitals as the
-        ** first two letters remains the same, otherwise the
-        ** first letter is decapitalized.  URL = URL, I = i,
-        ** MyMethod = myMethod.
-        ** @param name the name to decapitalize.
-        ** @return the decapitalized name.
-        **/
-       public static String decapitalize(String name) {
-               try {
-                       if(!Character.isUpperCase(name.charAt(0))) {
-                               return name;
-                       } else {
-                               try {
-                                       if(Character.isUpperCase(name.charAt(1))) {
-                                               return name;
-                                       } else {
-                                               char[] c = name.toCharArray();
-                                               c[0] = Character.toLowerCase(c[0]);
-                                               return new String(c);
-                                       }
-                               } catch(StringIndexOutOfBoundsException E) {
-                                       char[] c = new char[1];
-                                       c[0] = Character.toLowerCase(name.charAt(0));
-                                       return new String(c);
-                               }
-                       }
-               } catch(StringIndexOutOfBoundsException E) {
-                       return name;
-               } catch(NullPointerException E) {
-                       return null;
-               }
-       }
+  static String[] beanInfoSearchPath = {"gnu.java.beans.info"};
+  static Hashtable beanInfoCache = new Hashtable();
+  
+  private Introspector() {}
+  
+  /** 
+   * Get the BeanInfo for class <CODE>beanClass</CODE>,
+   * first by looking for explicit information, next by
+   * using standard design patterns to determine
+   * information about the class.
+   *
+   * @param beanClass the class to get BeanInfo about.
+   * @return the BeanInfo object representing the class.
+   */
+  public static BeanInfo getBeanInfo(Class beanClass) 
+    throws IntrospectionException 
+  {
+    BeanInfo cachedInfo;
+    synchronized(beanClass) 
+      {
+       cachedInfo = (BeanInfo)beanInfoCache.get(beanClass);
+       if(cachedInfo != null) 
+         {
+           return cachedInfo;
+         }
+       cachedInfo = getBeanInfo(beanClass,null);
+       beanInfoCache.put(beanClass,cachedInfo);
+       return cachedInfo;
+      }
+  }
 
-       static BeanInfo copyBeanInfo(BeanInfo b) {
-               java.awt.Image[] icons = new java.awt.Image[4];
-               for(int i=1;i<=4;i++) {
-                       icons[i-1] = b.getIcon(i);
-               }
-               return new ExplicitBeanInfo(b.getBeanDescriptor(),b.getAdditionalBeanInfo(),
-                                           b.getPropertyDescriptors(),b.getDefaultPropertyIndex(),
-                                           b.getEventSetDescriptors(),b.getDefaultEventIndex(),
-                                           b.getMethodDescriptors(),icons);
+  /** 
+   * Get the BeanInfo for class <CODE>beanClass</CODE>,
+   * first by looking for explicit information, next by
+   * using standard design patterns to determine
+   * information about the class.  It crawls up the
+   * inheritance tree until it hits <CODE>topClass</CODE>.
+   *
+   * @param beanClass the Bean class.
+   * @param stopClass the class to stop at.
+   * @return the BeanInfo object representing the class.
+   */
+  public static BeanInfo getBeanInfo(Class beanClass, Class stopClass) 
+    throws IntrospectionException 
+  {
+    ExplicitInfo explicit = new ExplicitInfo(beanClass,stopClass);
+    
+    IntrospectionIncubator ii = new IntrospectionIncubator();
+    ii.setPropertyStopClass(explicit.propertyStopClass);
+    ii.setEventStopClass(explicit.eventStopClass);
+    ii.setMethodStopClass(explicit.methodStopClass);
+    ii.addMethods(beanClass.getMethods());
+    
+    BeanInfoEmbryo currentInfo = ii.getBeanInfoEmbryo();
+    PropertyDescriptor[] p = explicit.explicitPropertyDescriptors;
+    if(p!=null) 
+      {
+       for(int i=0;i<p.length;i++) 
+         {
+           if(!currentInfo.hasProperty(p[i])) 
+             {
+               currentInfo.addProperty(p[i]);
+             }
+         }
+       if(explicit.defaultProperty != -1) 
+         {
+           currentInfo.setDefaultPropertyName(p[explicit.defaultProperty].getName());
+         }
+      }
+    EventSetDescriptor[] e = explicit.explicitEventSetDescriptors;
+    if(e!=null) 
+      {
+       for(int i=0;i<e.length;i++) 
+         {
+           if(!currentInfo.hasEvent(e[i])) 
+             {
+               currentInfo.addEvent(e[i]);
+             }
+         }
+       if(explicit.defaultEvent != -1) 
+         {
+           currentInfo.setDefaultEventName(e[explicit.defaultEvent].getName());
+         }
+      }
+    MethodDescriptor[] m = explicit.explicitMethodDescriptors;
+    if(m!=null) 
+      {
+       for(int i=0;i<m.length;i++) 
+         {
+           if(!currentInfo.hasMethod(m[i])) 
+             {
+               currentInfo.addMethod(m[i]);
+             }
+         }
+      }
+    
+    if(explicit.explicitBeanDescriptor != null) 
+      {
+       currentInfo.setBeanDescriptor(new BeanDescriptor(beanClass,explicit.explicitBeanDescriptor.getCustomizerClass()));
+      } 
+    else 
+      {
+       currentInfo.setBeanDescriptor(new BeanDescriptor(beanClass,null));
+      }
+    
+    currentInfo.setAdditionalBeanInfo(explicit.explicitBeanInfo);
+    currentInfo.setIcons(explicit.im);
+    
+    return currentInfo.getBeanInfo();
+  }
+  
+  /** 
+   * Get the search path for BeanInfo classes.
+   *
+   * @return the BeanInfo search path.
+   */
+  public static String[] getBeanInfoSearchPath() 
+  {
+    return beanInfoSearchPath;
+  }
+  
+  /** 
+   * Set the search path for BeanInfo classes.
+   * @param beanInfoSearchPath the new BeanInfo search
+   *        path.
+   */
+  public static void setBeanInfoSearchPath(String[] beanInfoSearchPath) 
+  {
+    Introspector.beanInfoSearchPath = beanInfoSearchPath;
+  }
+  
+  /** 
+   * A helper method to convert a name to standard Java
+   * naming conventions: anything with two capitals as the
+   * first two letters remains the same, otherwise the
+   * first letter is decapitalized.  URL = URL, I = i,
+   * MyMethod = myMethod.
+   *
+   * @param name the name to decapitalize.
+   * @return the decapitalized name.
+   */
+  public static String decapitalize(String name) 
+  {
+    try 
+      {
+      if(!Character.isUpperCase(name.charAt(0))) 
+       {
+         return name;
+       } 
+      else 
+       {
+       try 
+         {
+         if(Character.isUpperCase(name.charAt(1))) 
+           {
+             return name;
+           } 
+         else 
+           {
+             char[] c = name.toCharArray();
+             c[0] = Character.toLowerCase(c[0]);
+             return new String(c);
+           }
+         } 
+       catch(StringIndexOutOfBoundsException E) 
+         {
+           char[] c = new char[1];
+           c[0] = Character.toLowerCase(name.charAt(0));
+           return new String(c);
+         }
        }
+      } 
+    catch(StringIndexOutOfBoundsException E) 
+      {
+       return name;
+      } 
+    catch(NullPointerException E) 
+      {
+       return null;
+      }
+  }
+  
+  static BeanInfo copyBeanInfo(BeanInfo b) 
+  {
+    java.awt.Image[] icons = new java.awt.Image[4];
+    for(int i=1;i<=4;i++) 
+      {
+       icons[i-1] = b.getIcon(i);
+      }
+    return new ExplicitBeanInfo(b.getBeanDescriptor(),
+                               b.getAdditionalBeanInfo(),
+                               b.getPropertyDescriptors(),
+                               b.getDefaultPropertyIndex(),
+                               b.getEventSetDescriptors(),
+                               b.getDefaultEventIndex(),
+                               b.getMethodDescriptors(),icons);
+  }
 }
 
-class ExplicitInfo {
-       BeanDescriptor explicitBeanDescriptor;
-       BeanInfo[] explicitBeanInfo;
-
-       PropertyDescriptor[] explicitPropertyDescriptors;
-       EventSetDescriptor[] explicitEventSetDescriptors;
-       MethodDescriptor[] explicitMethodDescriptors;
-
-       int defaultProperty;
-       int defaultEvent;
-
-       java.awt.Image[] im = new java.awt.Image[4];
-
-       Class propertyStopClass;
-       Class eventStopClass;
-       Class methodStopClass;
-
-       ExplicitInfo(Class beanClass, Class stopClass) {
-               while(beanClass != null && !beanClass.equals(stopClass)) {
-                       BeanInfo explicit = findExplicitBeanInfo(beanClass);
-                       if(explicit != null) {
-                               if(explicitBeanDescriptor == null) {
-                                       explicitBeanDescriptor = explicit.getBeanDescriptor();
-                               }
-                               if(explicitBeanInfo == null) {
-                                       explicitBeanInfo = explicit.getAdditionalBeanInfo();
-                               }
-                               if(explicitPropertyDescriptors == null) {
-                                       if(explicit.getPropertyDescriptors() != null) {
-                                               explicitPropertyDescriptors = explicit.getPropertyDescriptors();
-                                               defaultProperty = explicit.getDefaultPropertyIndex();
-                                               propertyStopClass = beanClass;
-                                       }
-                               }
-                               if(explicitEventSetDescriptors == null) {
-                                       if(explicit.getEventSetDescriptors() != null) {
-                                               explicitEventSetDescriptors = explicit.getEventSetDescriptors();
-                                               defaultEvent = explicit.getDefaultEventIndex();
-                                               eventStopClass = beanClass;
-                                       }
-                               }
-                               if(explicitMethodDescriptors == null) {
-                                       if(explicit.getMethodDescriptors() != null) {
-                                               explicitMethodDescriptors = explicit.getMethodDescriptors();
-                                               methodStopClass = beanClass;
-                                       }
-                               }
-                               if(im[0] == null
-                                  && im[1] == null
-                                  && im[2] == null
-                                  && im[3] == null) {
-                                       im[0] = explicit.getIcon(0);
-                                       im[1] = explicit.getIcon(1);
-                                       im[2] = explicit.getIcon(2);
-                                       im[3] = explicit.getIcon(3);
-                               }
-                       }
-                       beanClass = beanClass.getSuperclass();
-               }
-               if(propertyStopClass == null) {
-                       propertyStopClass = stopClass;
-               }
-               if(eventStopClass == null) {
-                       eventStopClass = stopClass;
-               }
-               if(methodStopClass == null) {
-                       methodStopClass = stopClass;
-               }
-       }
-
-       static Hashtable explicitBeanInfos = new Hashtable();
-       static Vector emptyBeanInfos = new Vector();
-
-       static BeanInfo findExplicitBeanInfo(Class beanClass) {
-               BeanInfo retval = (BeanInfo)explicitBeanInfos.get(beanClass);
-               if(retval != null) {
-                       return retval;
-               } else if(emptyBeanInfos.indexOf(beanClass) != -1) {
-                       return null;
-               } else {
-                       retval = reallyFindExplicitBeanInfo(beanClass);
-                       if(retval != null) {
-                               explicitBeanInfos.put(beanClass,retval);
-                       } else {
-                               emptyBeanInfos.addElement(beanClass);
-                       }
-                       return retval;
-               }
+class ExplicitInfo 
+{
+  BeanDescriptor explicitBeanDescriptor;
+  BeanInfo[] explicitBeanInfo;
+  
+  PropertyDescriptor[] explicitPropertyDescriptors;
+  EventSetDescriptor[] explicitEventSetDescriptors;
+  MethodDescriptor[] explicitMethodDescriptors;
+  
+  int defaultProperty;
+  int defaultEvent;
+  
+  java.awt.Image[] im = new java.awt.Image[4];
+  
+  Class propertyStopClass;
+  Class eventStopClass;
+  Class methodStopClass;
+  
+  ExplicitInfo(Class beanClass, Class stopClass) 
+  {
+    while(beanClass != null && !beanClass.equals(stopClass)) 
+      {
+       BeanInfo explicit = findExplicitBeanInfo(beanClass);
+       if(explicit != null) 
+         {
+           if(explicitBeanDescriptor == null) 
+             {
+               explicitBeanDescriptor = explicit.getBeanDescriptor();
+             }
+           if(explicitBeanInfo == null) 
+             {
+               explicitBeanInfo = explicit.getAdditionalBeanInfo();
+             }
+           if(explicitPropertyDescriptors == null) 
+             {
+               if(explicit.getPropertyDescriptors() != null) 
+                 {
+                   explicitPropertyDescriptors = explicit.getPropertyDescriptors();
+                   defaultProperty = explicit.getDefaultPropertyIndex();
+                   propertyStopClass = beanClass;
+                 }
+             }
+           if(explicitEventSetDescriptors == null) 
+             {
+               if(explicit.getEventSetDescriptors() != null) 
+                 {
+                   explicitEventSetDescriptors = explicit.getEventSetDescriptors();
+                   defaultEvent = explicit.getDefaultEventIndex();
+                   eventStopClass = beanClass;
+                 }
+             }
+           if(explicitMethodDescriptors == null) 
+             {
+               if(explicit.getMethodDescriptors() != null) 
+                 {
+                   explicitMethodDescriptors = explicit.getMethodDescriptors();
+                   methodStopClass = beanClass;
+                 }
+             }
+           if(im[0] == null && im[1] == null 
+              && im[2] == null && im[3] == null) 
+             {
+               im[0] = explicit.getIcon(0);
+               im[1] = explicit.getIcon(1);
+               im[2] = explicit.getIcon(2);
+               im[3] = explicit.getIcon(3);
+             }
+         }
+       beanClass = beanClass.getSuperclass();
+      }
+    if(propertyStopClass == null) 
+      {
+       propertyStopClass = stopClass;
+      }
+    if(eventStopClass == null) 
+      {
+       eventStopClass = stopClass;
+      }
+    if(methodStopClass == null) 
+      {
+       methodStopClass = stopClass;
+      }
+  }
+  
+  static Hashtable explicitBeanInfos = new Hashtable();
+  static Vector emptyBeanInfos = new Vector();
+  
+  static BeanInfo findExplicitBeanInfo(Class beanClass) 
+  {
+    BeanInfo retval = (BeanInfo)explicitBeanInfos.get(beanClass);
+    if(retval != null) 
+      {
+       return retval;
+      } 
+    else if(emptyBeanInfos.indexOf(beanClass) != -1) 
+      {
+       return null;
+      } 
+    else 
+      {
+       retval = reallyFindExplicitBeanInfo(beanClass);
+       if(retval != null) 
+         {
+           explicitBeanInfos.put(beanClass,retval);
+         } 
+       else 
+         {
+           emptyBeanInfos.addElement(beanClass);
+         }
+       return retval;
+      }
+  }
+  
+  static BeanInfo reallyFindExplicitBeanInfo(Class beanClass) 
+  {
+    try 
+      {
+      try 
+       {
+         return (BeanInfo)Class.forName(beanClass.getName()+"BeanInfo").newInstance();
+       } 
+      catch(ClassNotFoundException E) 
+       {
        }
-
-       static BeanInfo reallyFindExplicitBeanInfo(Class beanClass) {
-               try {
-               try {
-                       return (BeanInfo)Class.forName(beanClass.getName()+"BeanInfo").newInstance();
-               } catch(ClassNotFoundException E) {
-               }
-               String newName = ClassHelper.getTruncatedClassName(beanClass) + "BeanInfo";
-               for(int i=0;i<Introspector.beanInfoSearchPath.length;i++) {
-                       try {
-                               if(Introspector.beanInfoSearchPath[i].equals("")) {
-                                       return (BeanInfo)Class.forName(newName).newInstance();
-                               } else {
-                                       return (BeanInfo)Class.forName(Introspector.beanInfoSearchPath[i] + "." + newName).newInstance();
-                               }
-                       } catch(ClassNotFoundException E) {
-                       }
-               }
-               } catch(IllegalAccessException E) {
-               } catch(InstantiationException E) {
+      String newName = ClassHelper.getTruncatedClassName(beanClass) + "BeanInfo";
+      for(int i=0;i<Introspector.beanInfoSearchPath.length;i++) 
+       {
+         try 
+           {
+             if(Introspector.beanInfoSearchPath[i].equals("")) 
+               {
+                 return (BeanInfo)Class.forName(newName).newInstance();
+               } 
+             else 
+               {
+                 return (BeanInfo)Class.forName(Introspector.beanInfoSearchPath[i] + "." + newName).newInstance();
                }
-               return null;
+           } 
+         catch(ClassNotFoundException E) 
+           {
+           }
        }
+      } 
+    catch(IllegalAccessException E) 
+      {
+      } 
+    catch(InstantiationException E) 
+      {
+      }
+    return null;
+  }
 }
index 9c82c3636e8d973fee9f185206e769446aa192aa..31f01d8b16ee60644a537880f2136490b87f2d7d 100644 (file)
@@ -1,5 +1,5 @@
-/* java.beans.PropertyVetoException
-   Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+/* PropertyVetoException.java -- thrown to veto a proposed property change
+   Copyright (C) 1998, 2000, 2002 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -7,7 +7,7 @@ GNU Classpath is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
+
 GNU Classpath is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
@@ -39,30 +39,47 @@ exception statement from your version. */
 package java.beans;
 
 /**
- ** PropertyVetoException is thrown when a VetoableChangeListener doesn't like the proposed change.
- **
- ** @author John Keiser
- ** @since JDK1.1
- ** @version 1.1.0, 31 May 1998
- ** @see java.beans.VetoableChangeListener
- **/
-
-public class PropertyVetoException extends Exception {
-       PropertyChangeEvent evt;
+ * PropertyVetoException is thrown when a VetoableChangeListener doesn't
+ * like the proposed change.
+ *
+ * @author John Keiser
+ * @see VetoableChangeListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class PropertyVetoException extends Exception
+{
+  /**
+   * Compatible with JDK 1.1+.
+   */
+  private static final long serialVersionUID = 129596057694162164L;
 
-       private static final long serialVersionUID = 129596057694162164L;
+  /**
+   * The vetoed change.
+   *
+   * @serial the event that was vetoed
+   */
+  private final PropertyChangeEvent evt;
 
-       /** Instantiate this exception with the given message and property change.
-        ** @param msg the reason for the veto.
-        ** @param changeEvent the PropertyChangeEvent that was thrown.
-        **/
-       public PropertyVetoException(String msg, PropertyChangeEvent changeEvent) {
-               super(msg);
-               evt = changeEvent;
-       }
+  /**
+   * Instantiate this exception with the given message and property change.
+   *
+   * @param msg the reason for the veto
+   * @param changeEvent the PropertyChangeEvent that was thrown
+   */
+  public PropertyVetoException(String msg, PropertyChangeEvent changeEvent)
+  {
+    super(msg);
+    evt = changeEvent;
+  }
 
-       /** Get the PropertyChange event that was vetoed. **/
-       public PropertyChangeEvent getPropertyChangeEvent() {
-               return evt;
-       }
+  /**
+   * Get the PropertyChange event that was vetoed.
+   *
+   * @return the vetoed change
+   */
+  public PropertyChangeEvent getPropertyChangeEvent()
+  {
+    return evt;
+  }
 }