Save This Page
Home » slf4j-1.5.5 » org.apache » log4j » config » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    * 
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    * 
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   
   18   // Contributors:  Georg Lundesgaard
   19   
   20   package org.apache.log4j.config;
   21   
   22   import java.beans.Introspector;
   23   import java.beans.PropertyDescriptor;
   24   import java.beans.BeanInfo;
   25   import java.beans.IntrospectionException;
   26   import java.lang.reflect;
   27   import java.util;
   28   import org.apache.log4j;
   29   import org.apache.log4j.helpers.LogLog;
   30   import org.apache.log4j.helpers.OptionConverter;
   31   import org.apache.log4j.spi.OptionHandler;
   32   
   33   /**
   34      General purpose Object property setter. Clients repeatedly invokes
   35      {@link #setProperty setProperty(name,value)} in order to invoke setters
   36      on the Object specified in the constructor. This class relies on the
   37      JavaBeans {@link Introspector} to analyze the given Object Class using
   38      reflection.
   39      
   40      <p>Usage:
   41      <pre>
   42        PropertySetter ps = new PropertySetter(anObject);
   43        ps.set("name", "Joe");
   44        ps.set("age", "32");
   45        ps.set("isMale", "true");
   46      </pre>
   47      will cause the invocations anObject.setName("Joe"), anObject.setAge(32),
   48      and setMale(true) if such methods exist with those signatures.
   49      Otherwise an {@link IntrospectionException} are thrown.
   50     
   51      @author Anders Kristensen
   52      @since 1.1
   53    */
   54   public class PropertySetter {
   55     protected Object obj;
   56     protected PropertyDescriptor[] props;
   57     
   58     /**
   59       Create a new PropertySetter for the specified Object. This is done
   60       in prepartion for invoking {@link #setProperty} one or more times.
   61       
   62       @param obj  the object for which to set properties
   63      */
   64     public
   65     PropertySetter(Object obj) {
   66       this.obj = obj;
   67     }
   68     
   69     /**
   70        Uses JavaBeans {@link Introspector} to computer setters of object to be
   71        configured.
   72      */
   73     protected
   74     void introspect() {
   75       try {
   76         BeanInfo bi = Introspector.getBeanInfo(obj.getClass());
   77         props = bi.getPropertyDescriptors();
   78       } catch (IntrospectionException ex) {
   79         LogLog.error("Failed to introspect "+obj+": " + ex.getMessage());
   80         props = new PropertyDescriptor[0];
   81       }
   82     }
   83     
   84   
   85     /**
   86        Set the properties of an object passed as a parameter in one
   87        go. The <code>properties</code> are parsed relative to a
   88        <code>prefix</code>.
   89   
   90        @param obj The object to configure.
   91        @param properties A java.util.Properties containing keys and values.
   92        @param prefix Only keys having the specified prefix will be set.
   93     */
   94     public
   95     static
   96     void setProperties(Object obj, Properties properties, String prefix) {
   97       new PropertySetter(obj).setProperties(properties, prefix);
   98     }
   99     
  100   
  101     /**
  102        Set the properites for the object that match the
  103        <code>prefix</code> passed as parameter.
  104   
  105        
  106      */
  107     public
  108     void setProperties(Properties properties, String prefix) {
  109       int len = prefix.length();
  110       
  111       for (Enumeration e = properties.propertyNames(); e.hasMoreElements(); ) {
  112         String key = (String) e.nextElement();
  113         
  114         // handle only properties that start with the desired frefix.
  115         if (key.startsWith(prefix)) {
  116   
  117   	
  118   	// ignore key if it contains dots after the prefix
  119           if (key.indexOf('.', len + 1) > 0) {
  120   	  //System.err.println("----------Ignoring---["+key
  121   	  //	     +"], prefix=["+prefix+"].");
  122   	  continue;
  123   	}
  124           
  125   	String value = OptionConverter.findAndSubst(key, properties);
  126           key = key.substring(len);
  127           if ("layout".equals(key) && obj instanceof Appender) {
  128             continue;
  129           }        
  130           setProperty(key, value);
  131         }
  132       }
  133       activate();
  134     }
  135     
  136     /**
  137        Set a property on this PropertySetter's Object. If successful, this
  138        method will invoke a setter method on the underlying Object. The
  139        setter is the one for the specified property name and the value is
  140        determined partly from the setter argument type and partly from the
  141        value specified in the call to this method.
  142        
  143        <p>If the setter expects a String no conversion is necessary.
  144        If it expects an int, then an attempt is made to convert 'value'
  145        to an int using new Integer(value). If the setter expects a boolean,
  146        the conversion is by new Boolean(value).
  147        
  148        @param name    name of the property
  149        @param value   String value of the property
  150      */
  151     public
  152     void setProperty(String name, String value) {
  153       if (value == null) return;
  154       
  155       name = Introspector.decapitalize(name);
  156       PropertyDescriptor prop = getPropertyDescriptor(name);
  157       
  158       //LogLog.debug("---------Key: "+name+", type="+prop.getPropertyType());
  159   
  160       if (prop == null) {
  161         LogLog.warn("No such property [" + name + "] in "+
  162   		  obj.getClass().getName()+"." );
  163       } else {
  164         try {
  165           setProperty(prop, name, value);
  166         } catch (PropertySetterException ex) {
  167           LogLog.warn("Failed to set property [" + name +
  168                       "] to value \"" + value + "\". ", ex.rootCause);
  169         }
  170       }
  171     }
  172     
  173     /** 
  174         Set the named property given a {@link PropertyDescriptor}.
  175   
  176         @param prop A PropertyDescriptor describing the characteristics
  177         of the property to set.
  178         @param name The named of the property to set.
  179         @param value The value of the property.      
  180      */
  181     public
  182     void setProperty(PropertyDescriptor prop, String name, String value)
  183       throws PropertySetterException {
  184       Method setter = prop.getWriteMethod();
  185       if (setter == null) {
  186         throw new PropertySetterException("No setter for property ["+name+"].");
  187       }
  188       Class[] paramTypes = setter.getParameterTypes();
  189       if (paramTypes.length != 1) {
  190         throw new PropertySetterException("#params for setter != 1");
  191       }
  192       
  193       Object arg;
  194       try {
  195         arg = convertArg(value, paramTypes[0]);
  196       } catch (Throwable t) {
  197         throw new PropertySetterException("Conversion to type ["+paramTypes[0]+
  198   					"] failed. Reason: "+t);
  199       }
  200       if (arg == null) {
  201         throw new PropertySetterException(
  202             "Conversion to type ["+paramTypes[0]+"] failed.");
  203       }
  204       LogLog.debug("Setting property [" + name + "] to [" +arg+"].");
  205       try {
  206         setter.invoke(obj, new Object[]  { arg });
  207       } catch (Exception ex) {
  208         throw new PropertySetterException(ex);
  209       }
  210     }
  211     
  212   
  213     /**
  214        Convert <code>val</code> a String parameter to an object of a
  215        given type.
  216     */
  217     protected
  218     Object convertArg(String val, Class type) {
  219       if(val == null)
  220         return null;
  221   
  222       String v = val.trim();
  223       if (String.class.isAssignableFrom(type)) {
  224         return val;
  225       } else if (Integer.TYPE.isAssignableFrom(type)) {
  226         return new Integer(v);
  227       } else if (Long.TYPE.isAssignableFrom(type)) {
  228         return new Long(v);
  229       } else if (Boolean.TYPE.isAssignableFrom(type)) {
  230         if ("true".equalsIgnoreCase(v)) {
  231           return Boolean.TRUE;
  232         } else if ("false".equalsIgnoreCase(v)) {
  233           return Boolean.FALSE;
  234         }
  235       } else if (Priority.class.isAssignableFrom(type)) {
  236         return OptionConverter.toLevel(v, (Level) Level.DEBUG);
  237       }
  238       return null;
  239     }
  240     
  241     
  242     protected
  243     PropertyDescriptor getPropertyDescriptor(String name) {
  244       if (props == null) introspect();
  245       
  246       for (int i = 0; i < props.length; i++) {
  247         if (name.equals(props[i].getName())) {
  248   	return props[i];
  249         }
  250       }
  251       return null;
  252     }
  253     
  254     public
  255     void activate() {
  256       if (obj instanceof OptionHandler) {
  257         ((OptionHandler) obj).activateOptions();
  258       }
  259     }
  260   }

Save This Page
Home » slf4j-1.5.5 » org.apache » log4j » config » [javadoc | source]