+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Contributors: Georg Lundesgaard
-
-package org.apache.log4j.config;
-
-import org.apache.log4j.Appender;
-import org.apache.log4j.Level;
-import org.apache.log4j.Priority;
-import org.apache.log4j.helpers.LogLog;
-import org.apache.log4j.helpers.OptionConverter;
-import org.apache.log4j.spi.OptionHandler;
-import org.apache.log4j.spi.ErrorHandler;
-
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.io.InterruptedIOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Enumeration;
-import java.util.Properties;
-
-/**
- General purpose Object property setter. Clients repeatedly invokes
- {@link #setProperty setProperty(name,value)} in order to invoke setters
- on the Object specified in the constructor. This class relies on the
- JavaBeans {@link Introspector} to analyze the given Object Class using
- reflection.
-
- <p>Usage:
- <pre>
- PropertySetter ps = new PropertySetter(anObject);
- ps.set("name", "Joe");
- ps.set("age", "32");
- ps.set("isMale", "true");
- </pre>
- will cause the invocations anObject.setName("Joe"), anObject.setAge(32),
- and setMale(true) if such methods exist with those signatures.
- Otherwise an {@link IntrospectionException} are thrown.
-
- @author Anders Kristensen
- @since 1.1
- */
-public class PropertySetter {
- protected Object obj;
- protected PropertyDescriptor[] props;
-
- /**
- 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) {
- this.obj = obj;
- }
-
- /**
- Uses JavaBeans {@link Introspector} to computer setters of object to be
- configured.
- */
- protected
- void introspect() {
- try {
- BeanInfo bi = Introspector.getBeanInfo(obj.getClass());
- props = bi.getPropertyDescriptors();
- } catch (IntrospectionException ex) {
- LogLog.error("Failed to introspect "+obj+": " + ex.getMessage());
- props = new PropertyDescriptor[0];
- }
- }
-
-
- /**
- Set the properties of an object passed as a parameter in one
- go. The <code>properties</code> are parsed relative to a
- <code>prefix</code>.
-
- @param obj The object to configure.
- @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) {
- new PropertySetter(obj).setProperties(properties, prefix);
- }
-
-
- /**
- Set the properites for the object that match the
- <code>prefix</code> passed as parameter.
-
-
- */
- public
- void setProperties(Properties properties, String prefix) {
- int len = prefix.length();
-
- for (Enumeration e = properties.propertyNames(); e.hasMoreElements(); ) {
- String key = (String) e.nextElement();
-
- // 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
- // +"], prefix=["+prefix+"].");
- continue;
- }
-
- String value = OptionConverter.findAndSubst(key, properties);
- key = key.substring(len);
- if (("layout".equals(key) || "errorhandler".equals(key)) && obj instanceof Appender) {
- continue;
- }
- //
- // if the property type is an OptionHandler
- // (for example, triggeringPolicy of org.apache.log4j.rolling.RollingFileAppender)
- PropertyDescriptor prop = getPropertyDescriptor(Introspector.decapitalize(key));
- if (prop != null
- && OptionHandler.class.isAssignableFrom(prop.getPropertyType())
- && prop.getWriteMethod() != null) {
- OptionHandler opt = (OptionHandler)
- OptionConverter.instantiateByKey(properties, prefix + key,
- prop.getPropertyType(),
- null);
- PropertySetter setter = new PropertySetter(opt);
- setter.setProperties(properties, prefix + key + ".");
- try {
- prop.getWriteMethod().invoke(this.obj, new Object[] { opt });
- } catch(IllegalAccessException ex) {
- LogLog.warn("Failed to set property [" + key +
- "] to value \"" + value + "\". ", ex);
- } catch(InvocationTargetException ex) {
- if (ex.getTargetException() instanceof InterruptedException
- || ex.getTargetException() instanceof InterruptedIOException) {
- Thread.currentThread().interrupt();
- }
- LogLog.warn("Failed to set property [" + key +
- "] to value \"" + value + "\". ", ex);
- } catch(RuntimeException ex) {
- LogLog.warn("Failed to set property [" + key +
- "] to value \"" + value + "\". ", ex);
- }
- continue;
- }
-
- setProperty(key, value);
- }
- }
- activate();
- }
-
- /**
- Set a property on this PropertySetter's Object. If successful, this
- method will invoke a setter method on the underlying Object. The
- setter is the one for the specified property name and the value is
- determined partly from the setter argument type and partly from the
- value specified in the call to this method.
-
- <p>If the setter expects a String no conversion is necessary.
- If it expects an int, then an attempt is made to convert 'value'
- to an int using new Integer(value). If the setter expects a boolean,
- the conversion is by new Boolean(value).
-
- @param name name of the property
- @param value String value of the property
- */
- public
- void setProperty(String name, String value) {
- if (value == null) {
- return;
- }
-
- name = Introspector.decapitalize(name);
- PropertyDescriptor prop = getPropertyDescriptor(name);
-
- //LogLog.debug("---------Key: "+name+", type="+prop.getPropertyType());
-
- if (prop == null) {
- LogLog.warn("No such property [" + name + "] in "+
- obj.getClass().getName()+"." );
- } else {
- try {
- setProperty(prop, name, value);
- } catch (PropertySetterException ex) {
- LogLog.warn("Failed to set property [" + name +
- "] to value \"" + value + "\". ", ex.rootCause);
- }
- }
- }
-
- /**
- Set the named property given a {@link PropertyDescriptor}.
-
- @param prop A PropertyDescriptor describing the characteristics
- of the property to set.
- @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)
- throws PropertySetterException {
- Method setter = prop.getWriteMethod();
- if (setter == null) {
- throw new PropertySetterException("No setter for property ["+name+"].");
- }
- Class[] paramTypes = setter.getParameterTypes();
- if (paramTypes.length != 1) {
- throw new PropertySetterException("#params for setter != 1");
- }
-
- Object arg;
- try {
- arg = convertArg(value, paramTypes[0]);
- } catch (Throwable t) {
- throw new PropertySetterException("Conversion to type ["+paramTypes[0]+
- "] failed. Reason: "+t);
- }
- if (arg == null) {
- throw new PropertySetterException(
- "Conversion to type ["+paramTypes[0]+"] failed.");
- }
- LogLog.debug("Setting property [" + name + "] to [" +arg+"].");
- try {
- setter.invoke(obj, new Object[] { arg });
- } catch (IllegalAccessException ex) {
- throw new PropertySetterException(ex);
- } catch (InvocationTargetException ex) {
- if (ex.getTargetException() instanceof InterruptedException
- || ex.getTargetException() instanceof InterruptedIOException) {
- Thread.currentThread().interrupt();
- }
- throw new PropertySetterException(ex);
- } catch (RuntimeException ex) {
- throw new PropertySetterException(ex);
- }
- }
-
-
- /**
- Convert <code>val</code> a String parameter to an object of a
- given type.
- */
- protected
- Object convertArg(String val, Class type) {
- if(val == null) {
- return null;
- }
-
- String v = val.trim();
- if (String.class.isAssignableFrom(type)) {
- return val;
- } else if (Integer.TYPE.isAssignableFrom(type)) {
- return new Integer(v);
- } else if (Long.TYPE.isAssignableFrom(type)) {
- return new Long(v);
- } else if (Boolean.TYPE.isAssignableFrom(type)) {
- if ("true".equalsIgnoreCase(v)) {
- return Boolean.TRUE;
- } else if ("false".equalsIgnoreCase(v)) {
- return Boolean.FALSE;
- }
- } else if (Priority.class.isAssignableFrom(type)) {
- return OptionConverter.toLevel(v, Level.DEBUG);
- } else if (ErrorHandler.class.isAssignableFrom(type)) {
- return OptionConverter.instantiateByClassName(v,
- ErrorHandler.class, null);
- }
- return null;
- }
-
-
- 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];
- }
- }
- return null;
- }
-
- public
- void activate() {
- if (obj instanceof OptionHandler) {
- ((OptionHandler) obj).activateOptions();
- }
- }
-}