ceki        2002/10/16 06:44:09

  Modified:    src/java/org/apache/log4j/config PropertySetter.java
  Log:
  Added support for setting a property of any type not just primitives and Level.
  Added support for adding multiple child components to a parent object.
  
  Revision  Changes    Path
  1.16      +145 -32   
jakarta-log4j/src/java/org/apache/log4j/config/PropertySetter.java
  
  Index: PropertySetter.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-log4j/src/java/org/apache/log4j/config/PropertySetter.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- PropertySetter.java       9 Oct 2002 22:50:02 -0000       1.15
  +++ PropertySetter.java       16 Oct 2002 13:44:09 -0000      1.16
  @@ -10,6 +10,7 @@
   
   import java.beans.Introspector;
   import java.beans.PropertyDescriptor;
  +import java.beans.MethodDescriptor;
   import java.beans.BeanInfo;
   import java.beans.IntrospectionException;
   import java.lang.reflect.*;
  @@ -41,32 +42,43 @@
      @since 1.1
    */
   public class PropertySetter {
  +
  +  static Logger logger = Logger.getLogger("LOG4J."+PropertySetter.class.getName());
  +
     protected Object obj;
  -  protected PropertyDescriptor[] props;
  -  
  +  protected Class objClass;
  +  protected PropertyDescriptor[] propertyDescriptors;
  +  protected MethodDescriptor[] methodDescriptors;
  +  
  +  static public final int NOT_FOUND     = 0;
  +  static public final int AS_PROPERTY   = 1;
  +  static public final int AS_COLLECTION = 2;
  +
     /**
       Create a new PropertySetter for the specified Object. This is done
       in prepartion for invoking {@link #setProperty} one or more times.
       
       @param obj  the object for which to set properties
      */
  -  public
  -  PropertySetter(Object obj) {
  +  public PropertySetter(Object obj) {
       this.obj = obj;
  +    this.objClass = obj.getClass();
     }
     
     /**
        Uses JavaBeans {@link Introspector} to computer setters of object to be
        configured.
      */
  -  protected
  -  void introspect() {
  +  protected void introspect() {
       try {
         BeanInfo bi = Introspector.getBeanInfo(obj.getClass());
  -      props = bi.getPropertyDescriptors();
  +      propertyDescriptors = bi.getPropertyDescriptors();
  +      methodDescriptors = bi.getMethodDescriptors();
  +
       } catch (IntrospectionException ex) {
         LogLog.error("Failed to introspect "+obj+": " + ex.getMessage());
  -      props = new PropertyDescriptor[0];
  +      propertyDescriptors = new PropertyDescriptor[0];
  +      methodDescriptors = new MethodDescriptor[0];
       }
     }
     
  @@ -80,9 +92,7 @@
        @param properties A java.util.Properties containing keys and values.
        @param prefix Only keys having the specified prefix will be set.
     */
  -  public
  -  static
  -  void setProperties(Object obj, Properties properties, String prefix) {
  +  public static void setProperties(Object obj, Properties properties, String 
prefix) {
       new PropertySetter(obj).setProperties(properties, prefix);
     }
     
  @@ -93,8 +103,7 @@
   
        
      */
  -  public
  -  void setProperties(Properties properties, String prefix) {
  +  public void setProperties(Properties properties, String prefix) {
       int len = prefix.length();
       
       for (Enumeration e = properties.propertyNames(); e.hasMoreElements(); ) {
  @@ -102,8 +111,6 @@
         
         // handle only properties that start with the desired frefix.
         if (key.startsWith(prefix)) {
  -
  -     
        // ignore key if it contains dots after the prefix
           if (key.indexOf('.', len + 1) > 0) {
          //System.err.println("----------Ignoring---["+key
  @@ -137,8 +144,7 @@
        @param name    name of the property
        @param value   String value of the property
      */
  -  public
  -  void setProperty(String name, String value) {
  +  public void setProperty(String name, String value) {
       if (value == null) return;
       
       name = Introspector.decapitalize(name);
  @@ -147,8 +153,7 @@
       //LogLog.debug("---------Key: "+name+", type="+prop.getPropertyType());
   
       if (prop == null) {
  -      LogLog.warn("No such property [" + name + "] in "+
  -               obj.getClass().getName()+"." );
  +      LogLog.warn("No such property [" + name + "] in "+ objClass.getName()+"." );
       } else {
         try {
           setProperty(prop, name, value);
  @@ -167,8 +172,7 @@
         @param name The named of the property to set.
         @param value The value of the property.      
      */
  -  public
  -  void setProperty(PropertyDescriptor prop, String name, String value)
  +  public void setProperty(PropertyDescriptor prop, String name, String value)
       throws PropertySetterException {
       Method setter = prop.getWriteMethod();
       if (setter == null) {
  @@ -197,14 +201,114 @@
         throw new PropertySetterException(ex);
       }
     }
  +
  +  public int canContainComponent(String name) {
  +    String cName = capitalizeFirstLetter(name);
  +
  +
  +
  +    Method method = getMethod("add"+cName);
  +    if(method != null) {
  +      logger.debug("Found add"+cName+" method in class "+objClass.getName());
  +      return AS_COLLECTION;
  +    } 
  +
  +    PropertyDescriptor propertyDescriptor = getPropertyDescriptor(name);
  +    if(propertyDescriptor != null) {
  +      Method setter = propertyDescriptor.getWriteMethod();
  +      if (setter != null) {
  +     logger.debug("Found setter method for property ["+name+"] in class 
"+objClass.getName());
  +     return AS_PROPERTY;
  +      }
  +    }     
  +    // we have failed
  +    return NOT_FOUND;
  +  }
  +
  +  public Class getObjClass() {
  +    return objClass;
  +  }
  +
  +  public void addComponent(String name, Object childComponent) {
  +    Class ccc = childComponent.getClass();
  +    name = capitalizeFirstLetter(name);
  +    Method method = getMethod("add"+name);
  +    // first let us use the addXXX method
  +    if(method != null) {
  +      Class[] params = method.getParameterTypes();
  +      if(params.length == 1) {
  +     if(params[0].isAssignableFrom(childComponent.getClass())) {
  +       try {
  +         method.invoke(this.obj, new Object[] {childComponent});
  +       } catch(Exception e) {
  +         logger.error("Could not invoke method "+method.getName()
  +                      +" in class "+obj.getClass().getName()
  +                      +" with parameter of type "+ccc.getName(), e);
  +       }
  +     } else {
  +       logger.error("A \""+ccc.getName()+
  +                    "\" object is not assignable to a \""+
  +                    params[0].getName() + "\" variable.");
  +       logger.error("The class \""+ params[0].getName()+"\" was loaded by ");
  +       logger.error("["+params[0].getClassLoader()+"] whereas object of type ");
  +       logger.error("\"" +ccc.getName()+"\" was loaded by ["
  +                    +ccc.getClassLoader()+"].");
  +     }
  +      }
  +    } else {
  +      logger.error("Could not find method ["+"add"+name+"] in class ["+
  +                objClass.getName()+"].");
  +    }
  +  }
  +
  +
  +
  +  public void setComponent(String name, Object childComponent) {
  +    PropertyDescriptor propertyDescriptor = getPropertyDescriptor(name);
  +    
  +    if(propertyDescriptor == null) {
  +      logger.warn("Could not find PropertyDescriptor for ["+name+"] in "+
  +               objClass.getName());
  +      return;
  +    }
  +    
  +    Method setter = propertyDescriptor.getWriteMethod();
  +    if (setter == null) {
  +      logger.warn("Not setter method for property ["+name+"] in "+
  +               obj.getClass().getName());
  +      return;
  +    }
  +
  +    Class[] paramTypes = setter.getParameterTypes();
  +    if (paramTypes.length != 1) {
  +      logger.error("Wrong number of parameters in setter method for property 
["+name+"] in "+
  +               obj.getClass().getName());
  +       return;
  +    }
  +    
  +    try {
  +      setter.invoke(obj, new Object[] {childComponent});
  +      if(logger.isDebugEnabled()) {
  +     logger.debug("Set child component of type [" + 
childComponent.getClass().getName() 
  +                  + "] for [" +objClass.getName()+"].");
  +      }
  +    } catch (Exception e) {
  +      logger.error("Could not set component "+obj+" for parent component "+obj, e);
  +    }
  +  }
  +
  +
  +  String capitalizeFirstLetter(String name) {
  +    return name.substring(0,1).toUpperCase()+name.substring(1);
  +  }
  +    
     
   
     /**
        Convert <code>val</code> a String parameter to an object of a
        given type.
     */
  -  protected
  -  Object convertArg(String val, Class type) {
  +  protected Object convertArg(String val, Class type) {
       if(val == null)
         return null;
   
  @@ -228,20 +332,29 @@
     }
     
     
  -  protected
  -  PropertyDescriptor getPropertyDescriptor(String name) {
  -    if (props == null) introspect();
  -    
  -    for (int i = 0; i < props.length; i++) {
  -      if (name.equals(props[i].getName())) {
  -     return props[i];
  +  protected Method getMethod(String methodName) {
  +    if (methodDescriptors == null) introspect();
  +
  +    for (int i = 0; i < methodDescriptors.length; i++) {
  +      if (methodName.equals(methodDescriptors[i].getName())) {
  +     return methodDescriptors[i].getMethod();        
  +      }
  +    }
  +    return null; 
  +  }
  +
  +  protected PropertyDescriptor getPropertyDescriptor(String name) {
  +    if (propertyDescriptors == null) introspect();
  +    
  +    for (int i = 0;  i <  propertyDescriptors.length; i++) {
  +      if (name.equals(propertyDescriptors[i].getName())) {
  +     return propertyDescriptors[i];
         }
       }
       return null;
     }
     
  -  public
  -  void activate() {
  +  public void activate() {
       if (obj instanceof OptionHandler) {
         ((OptionHandler) obj).activateOptions();
       }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to