KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > log4j > config > PropertySetter


1 /*
2  * Copyright 1999-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 // Contributors: Georg Lundesgaard
18

19 package org.apache.log4j.config;
20
21 import java.beans.Introspector JavaDoc;
22 import java.beans.PropertyDescriptor JavaDoc;
23 import java.beans.BeanInfo JavaDoc;
24 import java.beans.IntrospectionException JavaDoc;
25 import java.lang.reflect.*;
26 import java.util.*;
27 import org.apache.log4j.*;
28 import org.apache.log4j.helpers.LogLog;
29 import org.apache.log4j.helpers.OptionConverter;
30 import org.apache.log4j.spi.OptionHandler;
31
32 /**
33    General purpose Object property setter. Clients repeatedly invokes
34    {@link #setProperty setProperty(name,value)} in order to invoke setters
35    on the Object specified in the constructor. This class relies on the
36    JavaBeans {@link Introspector} to analyze the given Object Class using
37    reflection.
38    
39    <p>Usage:
40    <pre>
41      PropertySetter ps = new PropertySetter(anObject);
42      ps.set("name", "Joe");
43      ps.set("age", "32");
44      ps.set("isMale", "true");
45    </pre>
46    will cause the invocations anObject.setName("Joe"), anObject.setAge(32),
47    and setMale(true) if such methods exist with those signatures.
48    Otherwise an {@link IntrospectionException} are thrown.
49   
50    @author Anders Kristensen
51    @since 1.1
52  */

53 public class PropertySetter {
54   protected Object JavaDoc obj;
55   protected PropertyDescriptor JavaDoc[] props;
56   
57   /**
58     Create a new PropertySetter for the specified Object. This is done
59     in prepartion for invoking {@link #setProperty} one or more times.
60     
61     @param obj the object for which to set properties
62    */

63   public
64   PropertySetter(Object JavaDoc obj) {
65     this.obj = obj;
66   }
67   
68   /**
69      Uses JavaBeans {@link Introspector} to computer setters of object to be
70      configured.
71    */

72   protected
73   void introspect() {
74     try {
75       BeanInfo JavaDoc bi = Introspector.getBeanInfo(obj.getClass());
76       props = bi.getPropertyDescriptors();
77     } catch (IntrospectionException JavaDoc ex) {
78       LogLog.error("Failed to introspect "+obj+": " + ex.getMessage());
79       props = new PropertyDescriptor JavaDoc[0];
80     }
81   }
82   
83
84   /**
85      Set the properties of an object passed as a parameter in one
86      go. The <code>properties</code> are parsed relative to a
87      <code>prefix</code>.
88
89      @param obj The object to configure.
90      @param properties A java.util.Properties containing keys and values.
91      @param prefix Only keys having the specified prefix will be set.
92   */

93   public
94   static
95   void setProperties(Object JavaDoc obj, Properties properties, String JavaDoc prefix) {
96     new PropertySetter(obj).setProperties(properties, prefix);
97   }
98   
99
100   /**
101      Set the properites for the object that match the
102      <code>prefix</code> passed as parameter.
103
104      
105    */

106   public
107   void setProperties(Properties properties, String JavaDoc prefix) {
108     int len = prefix.length();
109     
110     for (Enumeration e = properties.propertyNames(); e.hasMoreElements(); ) {
111       String JavaDoc key = (String JavaDoc) e.nextElement();
112       
113       // handle only properties that start with the desired frefix.
114
if (key.startsWith(prefix)) {
115
116     
117     // ignore key if it contains dots after the prefix
118
if (key.indexOf('.', len + 1) > 0) {
119       //System.err.println("----------Ignoring---["+key
120
// +"], prefix=["+prefix+"].");
121
continue;
122     }
123         
124     String JavaDoc value = OptionConverter.findAndSubst(key, properties);
125         key = key.substring(len);
126         if ("layout".equals(key) && obj instanceof Appender) {
127           continue;
128         }
129         setProperty(key, value);
130       }
131     }
132     activate();
133   }
134   
135   /**
136      Set a property on this PropertySetter's Object. If successful, this
137      method will invoke a setter method on the underlying Object. The
138      setter is the one for the specified property name and the value is
139      determined partly from the setter argument type and partly from the
140      value specified in the call to this method.
141      
142      <p>If the setter expects a String no conversion is necessary.
143      If it expects an int, then an attempt is made to convert 'value'
144      to an int using new Integer(value). If the setter expects a boolean,
145      the conversion is by new Boolean(value).
146      
147      @param name name of the property
148      @param value String value of the property
149    */

150   public
151   void setProperty(String JavaDoc name, String JavaDoc value) {
152     if (value == null) return;
153     
154     name = Introspector.decapitalize(name);
155     PropertyDescriptor JavaDoc prop = getPropertyDescriptor(name);
156     
157     //LogLog.debug("---------Key: "+name+", type="+prop.getPropertyType());
158

159     if (prop == null) {
160       LogLog.warn("No such property [" + name + "] in "+
161           obj.getClass().getName()+"." );
162     } else {
163       try {
164         setProperty(prop, name, value);
165       } catch (PropertySetterException ex) {
166         LogLog.warn("Failed to set property [" + name +
167                     "] to value \"" + value + "\". ", ex.rootCause);
168       }
169     }
170   }
171   
172   /**
173       Set the named property given a {@link PropertyDescriptor}.
174
175       @param prop A PropertyDescriptor describing the characteristics
176       of the property to set.
177       @param name The named of the property to set.
178       @param value The value of the property.
179    */

180   public
181   void setProperty(PropertyDescriptor JavaDoc prop, String JavaDoc name, String JavaDoc value)
182     throws PropertySetterException {
183     Method setter = prop.getWriteMethod();
184     if (setter == null) {
185       throw new PropertySetterException("No setter for property ["+name+"].");
186     }
187     Class JavaDoc[] paramTypes = setter.getParameterTypes();
188     if (paramTypes.length != 1) {
189       throw new PropertySetterException("#params for setter != 1");
190     }
191     
192     Object JavaDoc arg;
193     try {
194       arg = convertArg(value, paramTypes[0]);
195     } catch (Throwable JavaDoc t) {
196       throw new PropertySetterException("Conversion to type ["+paramTypes[0]+
197                     "] failed. Reason: "+t);
198     }
199     if (arg == null) {
200       throw new PropertySetterException(
201           "Conversion to type ["+paramTypes[0]+"] failed.");
202     }
203     LogLog.debug("Setting property [" + name + "] to [" +arg+"].");
204     try {
205       setter.invoke(obj, new Object JavaDoc[] { arg });
206     } catch (Exception JavaDoc ex) {
207       throw new PropertySetterException(ex);
208     }
209   }
210   
211
212   /**
213      Convert <code>val</code> a String parameter to an object of a
214      given type.
215   */

216   protected
217   Object JavaDoc convertArg(String JavaDoc val, Class JavaDoc type) {
218     if(val == null)
219       return null;
220
221     String JavaDoc v = val.trim();
222     if (String JavaDoc.class.isAssignableFrom(type)) {
223       return val;
224     } else if (Integer.TYPE.isAssignableFrom(type)) {
225       return new Integer JavaDoc(v);
226     } else if (Long.TYPE.isAssignableFrom(type)) {
227       return new Long JavaDoc(v);
228     } else if (Boolean.TYPE.isAssignableFrom(type)) {
229       if ("true".equalsIgnoreCase(v)) {
230         return Boolean.TRUE;
231       } else if ("false".equalsIgnoreCase(v)) {
232         return Boolean.FALSE;
233       }
234     } else if (Priority.class.isAssignableFrom(type)) {
235       return OptionConverter.toLevel(v, (Level) Level.DEBUG);
236     }
237     return null;
238   }
239   
240   
241   protected
242   PropertyDescriptor JavaDoc getPropertyDescriptor(String JavaDoc name) {
243     if (props == null) introspect();
244     
245     for (int i = 0; i < props.length; i++) {
246       if (name.equals(props[i].getName())) {
247     return props[i];
248       }
249     }
250     return null;
251   }
252   
253   public
254   void activate() {
255     if (obj instanceof OptionHandler) {
256       ((OptionHandler) obj).activateOptions();
257     }
258   }
259 }
260
Popular Tags