X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=srcjar%2Forg%2Fapache%2Flog4j%2Fconfig%2FPropertySetter.java;fp=srcjar%2Forg%2Fapache%2Flog4j%2Fconfig%2FPropertySetter.java;h=dae3c00746eb654bb56fb773f9dc0da606fcbf0a;hb=2d6292c0377bc6b773c6844a45d3f2c5fac352c7;hp=0000000000000000000000000000000000000000;hpb=954af328a2a6a0055572cd1a09ee035301222574;p=jalview.git diff --git a/srcjar/org/apache/log4j/config/PropertySetter.java b/srcjar/org/apache/log4j/config/PropertySetter.java new file mode 100644 index 0000000..dae3c00 --- /dev/null +++ b/srcjar/org/apache/log4j/config/PropertySetter.java @@ -0,0 +1,315 @@ +/* + * 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. + +
Usage: +
+ PropertySetter ps = new PropertySetter(anObject); + ps.set("name", "Joe"); + ps.set("age", "32"); + ps.set("isMale", "true"); ++ 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
properties
are parsed relative to a
+ prefix
.
+
+ @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
+ prefix
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.
+
+ 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 val
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();
+ }
+ }
+}