home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / main.bin / PropertyDescriptor.java < prev    next >
Text File  |  1997-05-20  |  10KB  |  274 lines

  1. /*
  2.  * @(#)PropertyDescriptor.java    1.36 97/02/11  
  3.  * 
  4.  * Copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  * CopyrightVersion bdk_beta
  20.  * 
  21.  */
  22.  
  23. package java.beans;
  24.  
  25. import java.lang.reflect.*;
  26.  
  27. /**
  28.  * A PropertyDescriptor describes one property that a Java Bean
  29.  * exports via a pair of accessor methods.
  30.  */
  31.  
  32. public class PropertyDescriptor extends FeatureDescriptor {
  33.  
  34.     /**
  35.      * Constructs a PropertyDescriptor for a property that follows
  36.      * the standard Java convention by having getFoo and setFoo 
  37.      * accessor methods.  Thus if the argument name is "fred", it will
  38.      * assume that the reader method is "getFred" and the writer method 
  39.      * is "setFred".  Note that the property name should start with a lower
  40.      * case character, which will be capitalized in the method names.
  41.      *
  42.      * @param propertyName The programmatic name of the property.
  43.      * @param beanClass The Class object for the target bean.  For
  44.      *        example sun.beans.OurButton.class.
  45.      * @exception IntrospectionException if an exception occurs during
  46.      *              introspection.
  47.      */
  48.     public PropertyDescriptor(String propertyName, Class beanClass)
  49.         throws IntrospectionException {
  50.     setName(propertyName);
  51.     String base = capitalize(propertyName);
  52.     writeMethod = Introspector.findMethod(beanClass, "set" + base, 1);
  53.     // If it's a boolean property check for an "isFoo" first.
  54.     if (writeMethod.getParameterTypes()[0] == Boolean.TYPE) {
  55.         try {
  56.         readMethod = Introspector.findMethod(beanClass, "is" + base, 0);
  57.         } catch (Exception ex) {
  58.         }
  59.     }
  60.     if (readMethod == null) {
  61.         readMethod = Introspector.findMethod(beanClass, "get" + base, 0);
  62.     }
  63.     findPropertyType();
  64.     }
  65.  
  66.     /**
  67.      * This constructor takes the name of a simple property, and method
  68.      * names for reading and writing the property.
  69.      *
  70.      * @param propertyName The programmatic name of the property.
  71.      * @param beanClass The Class object for the target bean.  For
  72.      *        example sun.beans.OurButton.class.
  73.      * @param getterName The name of the method used for reading the property
  74.      *         value.  May be null if the property is write-only.
  75.      * @param setterName The name of the method used for writing the property
  76.      *         value.  May be null if the property is read-only.
  77.      * @exception IntrospectionException if an exception occurs during
  78.      *              introspection.
  79.      */
  80.     public PropertyDescriptor(String propertyName, Class beanClass,
  81.         String getterName, String setterName)
  82.         throws IntrospectionException {
  83.     setName(propertyName);
  84.     readMethod = Introspector.findMethod(beanClass, getterName, 0);
  85.     writeMethod = Introspector.findMethod(beanClass, setterName, 1);
  86.     findPropertyType();
  87.     }
  88.  
  89.     /**
  90.      * This constructor takes the name of a simple property, and Method
  91.      * objects for reading and writing the property.
  92.      *
  93.      * @param propertyName The programmatic name of the property.
  94.      * @param getter The method used for reading the property value.
  95.      *        May be null if the property is write-only.
  96.      * @param setter The method used for writing the property value.  
  97.      *        May be null if the property is read-only.
  98.      * @exception IntrospectionException if an exception occurs during
  99.      *              introspection.
  100.      */
  101.     public PropertyDescriptor(String propertyName, Method getter, Method setter)
  102.         throws IntrospectionException {
  103.     setName(propertyName);
  104.     readMethod = getter;
  105.     writeMethod = setter;
  106.     findPropertyType(); 
  107.     }
  108.     
  109.     /**
  110.      * @return The Java type info for the property.  Note that
  111.      * the "Class" object may describe a built-in Java type such as "int".
  112.      * The result may be "null" if this is an indexed property that
  113.      * does not support non-indexed access.
  114.      * <p>
  115.      * This is the type that will be returned by the ReadMethod.
  116.      */
  117.     public Class getPropertyType() {
  118.     return propertyType;
  119.     }
  120.  
  121.     /**
  122.      * @return The method that should be used to read the property value.
  123.      * May return null if the property can't be read.
  124.      */
  125.     public Method getReadMethod() {
  126.     return readMethod;
  127.     }
  128.  
  129.     /**
  130.      * @return The method that should be used to write the property value.
  131.      * May return null if the property can't be written.
  132.      */
  133.     public Method getWriteMethod() {
  134.     return (writeMethod);
  135.     }
  136.  
  137.     /**
  138.      * Updates to "bound" properties will cause a "PropertyChange" event to
  139.      * get fired when the property is changed.
  140.      *
  141.      * @return True if this is a bound property.
  142.      */
  143.     public boolean isBound() {
  144.     return (bound);
  145.     }
  146.  
  147.     /**
  148.      * Updates to "bound" properties will cause a "PropertyChange" event to 
  149.      * get fired when the property is changed.
  150.      *
  151.      * @param bound True if this is a bound property.
  152.      */
  153.     public void setBound(boolean bound) {
  154.     this.bound = bound;
  155.     }
  156.  
  157.     /**
  158.      * Attempted updates to "Constrained" properties will cause a "VetoableChange"
  159.      * event to get fired when the property is changed.
  160.      *
  161.      * @return True if this is a constrained property.
  162.      */
  163.     public boolean isConstrained() {
  164.     return (constrained);
  165.     }
  166.  
  167.     /**
  168.      * Attempted updates to "Constrained" properties will cause a "VetoableChange"
  169.      * event to get fired when the property is changed.
  170.      *
  171.      * @param constrained True if this is a constrained property.
  172.      */
  173.     public void setConstrained(boolean constrained) {
  174.     this.constrained = constrained;
  175.     }
  176.  
  177.  
  178.     /**
  179.      * Normally PropertyEditors will be found using the PropertyEditorManager.
  180.      * However if for some reason you want to associate a particular
  181.      * PropertyEditor with a given property, then you can do it with
  182.      * this method.
  183.      * @param propertyEditorClass  The Class for the desired PropertyEditor.
  184.      */
  185.     public void setPropertyEditorClass(Class propertyEditorClass) {
  186.     this.propertyEditorClass = propertyEditorClass;
  187.     }
  188.  
  189.     /**
  190.      * @return Any explicit PropertyEditor Class that has been registered
  191.      *        for this property.  Normally this will return "null",
  192.      *        indicating that no special editor has been registered,
  193.      *        so the PropertyEditorManager should be used to locate
  194.      *        a suitable PropertyEditor.
  195.      */
  196.     public Class getPropertyEditorClass() {
  197.     return propertyEditorClass;
  198.     }
  199.  
  200.     /*
  201.      * Package-private constructor.
  202.      * Merge two property descriptors.  Where they conflict, give the
  203.      * second argument (y) priority over the first argumnnt (x).
  204.      * @param x  The first (lower priority) PropertyDescriptor
  205.      * @param y  The second (higher priority) PropertyDescriptor
  206.      */
  207.  
  208.     PropertyDescriptor(PropertyDescriptor x, PropertyDescriptor y) {
  209.     super(x,y);
  210.     readMethod = x.readMethod;
  211.     propertyType = x.propertyType;
  212.     if (y.readMethod != null) {
  213.         readMethod = y.readMethod;
  214.     }
  215.     writeMethod = x.writeMethod;
  216.     if (y.writeMethod != null) {
  217.         writeMethod = y.writeMethod;
  218.     }
  219.     propertyEditorClass = x.propertyEditorClass;
  220.     if (y.propertyEditorClass != null) {
  221.         propertyEditorClass = y.propertyEditorClass;
  222.     }
  223.     bound = x.bound | y.bound;
  224.     constrained = x.constrained | y.constrained;
  225.     try {
  226.         findPropertyType();
  227.     } catch (IntrospectionException ex) {
  228.         // Given we're merging two valid PDs, this "should never happen".
  229.         throw new Error("PropertyDescriptor: internal error while merging PDs");
  230.     }
  231.     }
  232.  
  233.     private void findPropertyType() throws IntrospectionException {
  234.     try {
  235.         propertyType = null;
  236.         if (readMethod != null) {
  237.         if (readMethod.getParameterTypes().length != 0) {
  238.             throw new IntrospectionException("bad read method arg count");
  239.         }
  240.         propertyType = readMethod.getReturnType();
  241.         if (propertyType == Void.TYPE) {
  242.             throw new IntrospectionException("read method " + 
  243.                     readMethod.getName() + " returns void");
  244.         }
  245.         }
  246.         if (writeMethod != null) {
  247.         Class params[] = writeMethod.getParameterTypes();
  248.         if (params.length != 1) {
  249.             throw new IntrospectionException("bad write method arg count");
  250.         }
  251.         if (propertyType != null && propertyType != params[0]) {
  252.             throw new IntrospectionException("type mismatch between read and write methods");
  253.         }
  254.         propertyType = params[0];
  255.         }
  256.     } catch (IntrospectionException ex) {
  257.         throw ex;
  258.     }
  259.     }
  260.  
  261.     private String capitalize(String s) {
  262.     char chars[] = s.toCharArray();
  263.     chars[0] = Character.toUpperCase(chars[0]);
  264.     return new String(chars);
  265.     }
  266.  
  267.     private Class propertyType;
  268.     private Method readMethod;
  269.     private Method writeMethod;
  270.     private boolean bound;
  271.     private boolean constrained;
  272.     private Class propertyEditorClass;
  273. }
  274.