/[classpath]/classpath/java/beans/PropertyDescriptor.java
ViewVC logotype

Diff of /classpath/java/beans/PropertyDescriptor.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.8 by mark, Fri Feb 7 16:13:54 2003 UTC revision 1.9 by mark, Fri Feb 7 16:33:48 2003 UTC
# Line 86  public class PropertyDescriptor extends Line 86  public class PropertyDescriptor extends
86     ** <CODE>&lt;beanClass&gt;</CODE>, where &lt;name&gt; has its     ** <CODE>&lt;beanClass&gt;</CODE>, where &lt;name&gt; has its
87     ** first letter capitalized by the constructor.<P>     ** first letter capitalized by the constructor.<P>
88     **     **
89     ** <B>Implementation note:</B> If there is a get method (or     ** <B>Implementation note:</B> If there is both are both isXXX and
90     ** boolean isXXX() method), then the return type of that method     ** getXXX methods, the former is used in preference to the latter.
91     ** is used to find the set method.  If there is no get method,     ** We do not check that an isXXX method returns a boolean. In both
92     ** then the set method is searched for exhaustively.<P>     ** cases, this matches the behaviour of JDK 1.4<P>
    **  
    ** <B>Spec note:</B>  
    ** If there is no get method and multiple set methods with  
    ** the same name and a single parameter (different type of course),  
    ** then an IntrospectionException is thrown.  While Sun's spec  
    ** does not state this, it can make Bean behavior different on  
    ** different systems (since method order is not guaranteed) and as  
    ** such, can be treated as a bug in the spec.  I am not aware of  
    ** whether Sun's implementation catches this.  
93     **     **
94     ** @param name the programmatic name of the property, usually     ** @param name the programmatic name of the property, usually
95     **             starting with a lowercase letter (e.g. fooManChu     **             starting with a lowercase letter (e.g. fooManChu
96     **             instead of FooManChu).     **             instead of FooManChu).
97     ** @param beanClass the class the get and set methods live in.     ** @param beanClass the class the get and set methods live in.
98     ** @exception IntrospectionException if the methods are not found or invalid.     ** @exception IntrospectionException if the methods are not found
99       **            or invalid.
100     **/     **/
101    public PropertyDescriptor(String name, Class beanClass)    public PropertyDescriptor(String name, Class beanClass)
102      throws IntrospectionException      throws IntrospectionException
103    {    {
104      setName(name);      setName(name);
105      String capitalized;      if (name.length() == 0) {
106      try {        throw new IntrospectionException("empty property name");
107        capitalized = Character.toUpperCase(name.charAt(0)) + name.substring(1);      }
108      }      String caps = Character.toUpperCase(name.charAt(0)) + name.substring(1);
109      catch (StringIndexOutOfBoundsException e) {      findMethods(beanClass, "is" + caps, "get" + caps, "set" + caps);
110        capitalized = "";      if (getMethod == null) {
111          throw new IntrospectionException("Cannot find an is" + caps +
112                                           " or get" + caps + " method");
113        }
114        if (setMethod == null) {
115          throw new IntrospectionException("Cannot find a " + caps + " method");
116      }      }
117      findMethods(beanClass, "is" + capitalized, "get" + capitalized,      checkMethods();
                 "set" + capitalized);  
118    }    }
119        
120    /** Create a new PropertyDescriptor by introspection.    /** Create a new PropertyDescriptor by introspection.
# Line 154  public class PropertyDescriptor extends Line 150  public class PropertyDescriptor extends
150    {    {
151      setName(name);      setName(name);
152      findMethods(beanClass, getMethodName, null, setMethodName);      findMethods(beanClass, getMethodName, null, setMethodName);
153        if (getMethod == null && getMethodName != null) {
154          throw new IntrospectionException("Cannot find a getter method called " +
155                                           getMethodName);
156        }
157        if (setMethod == null && setMethodName != null) {
158          throw new IntrospectionException("Cannot find a setter method called " +
159                                           setMethodName);
160        }
161        checkMethods();
162    }    }
163        
164    /** Create a new PropertyDescriptor using explicit Methods.    /** Create a new PropertyDescriptor using explicit Methods.
# Line 172  public class PropertyDescriptor extends Line 177  public class PropertyDescriptor extends
177      throws IntrospectionException      throws IntrospectionException
178    {    {
179      setName(name);      setName(name);
     if (getMethod != null && getMethod.getParameterTypes().length > 0) {  
       throw new IntrospectionException("get method has parameters");  
     }  
     if (setMethod != null && setMethod.getParameterTypes().length != 1) {  
       String msg = "set method does not have exactly one parameter";  
       throw new IntrospectionException(msg);  
     }  
     if (getMethod != null && setMethod != null) {  
       if (!getMethod.getReturnType().  
           equals(setMethod.getParameterTypes()[0])) {  
         String msg = "set and get methods do not share the same type";  
         throw new IntrospectionException(msg);  
       }  
       if ((!getMethod.getDeclaringClass().  
            isAssignableFrom(setMethod.getDeclaringClass())) &&  
           (!setMethod.getDeclaringClass().  
            isAssignableFrom(getMethod.getDeclaringClass()))) {  
         String msg = "set and get methods are not in the same class.";  
         throw new IntrospectionException(msg);  
       }  
     }  
180      this.getMethod = getMethod;      this.getMethod = getMethod;
181      this.setMethod = setMethod;      this.setMethod = setMethod;
182      if (getMethod != null) {      if (getMethod != null) {
183        this.propertyType = getMethod.getReturnType();        this.propertyType = getMethod.getReturnType();
184      }      }
185      else {      else if (setMethod != null) {
186        this.propertyType = setMethod.getParameterTypes()[0];        this.propertyType = setMethod.getParameterTypes()[0];
187      }      }
188        checkMethods();
189    }    }
190        
191    /** Get the property type.    /** Get the property type.
# Line 295  public class PropertyDescriptor extends Line 280  public class PropertyDescriptor extends
280      throws IntrospectionException      throws IntrospectionException
281    {    {
282      try {      try {
283          // Try the first get method name
284        if (getMethodName1 != null) {        if (getMethodName1 != null) {
285          try {          try {
286            getMethod = beanClass.getMethod(getMethodName1, new Class[0]);            getMethod = beanClass.getMethod(getMethodName1, new Class[0]);
287          }          }
288          catch (NoSuchMethodException E) {          catch (NoSuchMethodException e) {
289          }          }
290          if (getMethodName2 != null) {        }
291            if (getMethod != null &&  
292                !getMethod.getReturnType().equals(java.lang.Boolean.TYPE)) {        // Fall back to the second get method name
293              // If the is() method exists but isn't boolean, we'll just        if (getMethod == null && getMethodName2 != null) {
294              // go on and look for an ordinary get() method.          try {
295              getMethod = null;            getMethod = beanClass.getMethod(getMethodName2, new Class[0]);
296            }          }
297                      catch (NoSuchMethodException e) {
           Method getMethod2;  
           try {  
             getMethod2 = beanClass.getMethod(getMethodName2, new Class[0]);  
           }  
           catch (NoSuchMethodException E) {  
             getMethod2 = null;  
           }  
           if (getMethod2 != null) {  
             if (getMethod != null) {  
               if (!getMethod.getReturnType().  
                   equals(getMethod2.getReturnType())) {  
                 String msg = "Both " + getMethodName1 +  
                   " and " + getMethodName2 +  
                   " exist, and have contradictory return types.";  
                 throw new IntrospectionException(msg);  
               }  
             }  
             else {  
               getMethod = getMethod2;  
             }  
           }  
298          }          }
299        }        }
300          
301        if (getMethod != null) {        // Try the set method name
302          propertyType = getMethod.getReturnType();        if (setMethodName != null) {
303          if (setMethodName != null) {          if (getMethod != null) {
304            Class[] setArgs = new Class[1];            // If there is a get method, use its return type to help
305            setArgs[0] = propertyType;            // select the corresponding set method.
306              Class propertyType = getMethod.getReturnType();
307              if (propertyType == Void.TYPE) {
308                String msg = "The property's read method has return type 'void'";
309                throw new IntrospectionException(msg);
310              }
311              
312              Class[] setArgs = new Class[]{propertyType};
313            try {            try {
314              setMethod = beanClass.getMethod(setMethodName, setArgs);              setMethod = beanClass.getMethod(setMethodName, setArgs);
             if (!setMethod.getReturnType().equals(java.lang.Void.TYPE)) {  
               throw new IntrospectionException(setMethodName +  
                                                " has non-void return type");  
             }  
315            }            }
316            catch (NoSuchMethodException E) {            catch (NoSuchMethodException e) {
317            }            }
318          }          }
319        }          else if (getMethodName1 == null && getMethodName2 == null) {
320        else if (setMethodName != null) {            // If this is a write-only property, choose the first set method
321          Method[] m = beanClass.getMethods();            // with the required name, one parameter and return type 'void'
322          for(int i = 0; i < m.length; i++) {            Method[] methods = beanClass.getMethods();
323            Method current = m[i];            for (int i = 0; i < methods.length; i++) {
324            if (current.getName().equals(setMethodName) &&              if (methods[i].getName().equals(setMethodName) &&
325                current.getParameterTypes().length == 1 &&                  methods[i].getParameterTypes().length == 1 &&
326                current.getReturnType().equals(java.lang.Void.TYPE)) {                  methods[i].getReturnType() == Void.TYPE) {
327              if (setMethod != null) {                setMethod = methods[i];
328                String msg =                break;
                 "Multiple, different set methods found that fit the bill!";  
               throw new IntrospectionException(msg);  
             }  
             else {  
               setMethod = current;  
               propertyType = current.getParameterTypes()[0];  
329              }              }
330            }            }
331          }          }
         if (setMethod == null) {  
           throw new IntrospectionException("Cannot find get or set methods.");  
         }  
       }  
       else {  
         throw new IntrospectionException("Cannot find get or set methods.");  
332        }        }
333      }      }
334      catch (SecurityException E) {      catch (SecurityException e) {
335          // FIXME -- shouldn't we just allow SecurityException to propagate?
336        String msg = "SecurityException thrown on attempt to access methods.";        String msg = "SecurityException thrown on attempt to access methods.";
337        throw new IntrospectionException(msg);        throw new IntrospectionException(msg);
338      }      }
339    }    }
340    
341      private void checkMethods()
342        throws IntrospectionException
343      {
344        if (getMethod != null) {
345          if (getMethod.getParameterTypes().length > 0) {
346            throw new IntrospectionException("get method has parameters");
347          }
348          this.propertyType = getMethod.getReturnType();
349          if (propertyType == Void.TYPE) {
350            throw new IntrospectionException("get method has void return type");
351          }
352        }
353        if (setMethod != null) {
354          if (setMethod.getParameterTypes().length != 1) {
355            String msg = "set method does not have exactly one parameter";
356            throw new IntrospectionException(msg);
357          }
358          if (getMethod == null) {
359            propertyType = setMethod.getParameterTypes()[0];
360          }
361          else {
362            if (!propertyType.equals(setMethod.getParameterTypes()[0])) {
363              String msg = "set and get methods do not share the same type";
364              throw new IntrospectionException(msg);
365            }
366            if ((!getMethod.getDeclaringClass().
367                 isAssignableFrom(setMethod.getDeclaringClass())) &&
368                (!setMethod.getDeclaringClass().
369                 isAssignableFrom(getMethod.getDeclaringClass()))) {
370              String msg = "set and get methods are not in the same class.";
371              throw new IntrospectionException(msg);
372            }
373          }
374        }
375      }
376  }  }

Legend:
Removed from v.1.8  
changed lines
  Added in v.1.9

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26