[logback-dev] svn commit: r1711 - in logback/trunk/logback-core/src/main/java/ch/qos/logback/core: . joran/spi
noreply.ceki at qos.ch
noreply.ceki at qos.ch
Fri Jul 18 15:47:05 CEST 2008
Author: ceki
Date: Fri Jul 18 15:47:05 2008
New Revision: 1711
Modified:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/CoreGlobal.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/PropertySetter.java
Log:
- added support for "valueOf" convention.
Joran now assumes that any class which has a static
valueOf method taking a String as an argument can
be built from a string.
Level, Duration and FileSize classes follow this convention.
This patch is indirectly related to LBCLASSIC-53
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/CoreGlobal.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/CoreGlobal.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/CoreGlobal.java Fri Jul 18 15:47:05 2008
@@ -29,6 +29,15 @@
*/
static public final String EVALUATOR_MAP = "EVALUATOR_MAP";
+ /**
+ * By convention, we assume that the static method named "valueOf" taking
+ * a string argument can restore a given object from its string
+ * representation.
+ *
+ * <p>Classes participating in this convention must be declared
+ * as stringStorable in a (logback) context.
+ */
+ static public final String VALUE_OF = "valueOf";
/**
* An empty string.
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/PropertySetter.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/PropertySetter.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/spi/PropertySetter.java Fri Jul 18 15:47:05 2008
@@ -23,12 +23,12 @@
import java.beans.MethodDescriptor;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import ch.qos.logback.core.CoreGlobal;
import ch.qos.logback.core.joran.action.IADataForComplexProperty;
import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.util.AggregationType;
-import ch.qos.logback.core.util.Duration;
-import ch.qos.logback.core.util.FileSize;
import ch.qos.logback.core.util.PropertySetterException;
/**
@@ -207,7 +207,7 @@
Method adderMethod = getMethod("add" + name);
return adderMethod;
}
-
+
private Method findSetterMethod(String name) {
String dName = Introspector.decapitalize(name);
PropertyDescriptor propertyDescriptor = getPropertyDescriptor(dName);
@@ -219,7 +219,7 @@
}
Class<?> getParameterClassForMethod(Method method) {
- if(method == null) {
+ if (method == null) {
return null;
}
Class[] classArray = method.getParameterTypes();
@@ -229,21 +229,20 @@
return classArray[0];
}
}
+
private AggregationType computeRawAggregationType(Method method) {
- Class<?> clazz = getParameterClassForMethod(method);
- if (clazz == null) {
+ Class<?> parameterClass = getParameterClassForMethod(method);
+ if (parameterClass == null) {
return AggregationType.NOT_FOUND;
} else {
- Package p = clazz.getPackage();
- if (clazz.isPrimitive()) {
+ Package p = parameterClass.getPackage();
+ if (parameterClass.isPrimitive()) {
return AggregationType.AS_BASIC_PROPERTY;
} else if (p != null && "java.lang".equals(p.getName())) {
return AggregationType.AS_BASIC_PROPERTY;
- } else if (Duration.class.isAssignableFrom(clazz)) {
- return AggregationType.AS_BASIC_PROPERTY;
- } else if (FileSize.class.isAssignableFrom(clazz)) {
+ } else if (isBuildableFromString(parameterClass)) {
return AggregationType.AS_BASIC_PROPERTY;
- } else if (clazz.isEnum()) {
+ } else if (parameterClass.isEnum()) {
return AggregationType.AS_BASIC_PROPERTY;
} else {
return AggregationType.AS_COMPLEX_PROPERTY;
@@ -257,9 +256,10 @@
AggregationType at = actionData.getAggregationType();
switch (at) {
case AS_COMPLEX_PROPERTY:
- Method setterMethod = findSetterMethod(actionData.getComplexPropertyName());
- clazz = getParameterClassForMethod(setterMethod);
- if(clazz != null && isUnequivocallyInstantiable(clazz)) {
+ Method setterMethod = findSetterMethod(actionData
+ .getComplexPropertyName());
+ clazz = getParameterClassForMethod(setterMethod);
+ if (clazz != null && isUnequivocallyInstantiable(clazz)) {
return clazz;
} else {
return null;
@@ -267,7 +267,7 @@
case AS_COMPLEX_PROPERTY_COLLECTION:
Method adderMethod = findAdderMethod(actionData.getComplexPropertyName());
clazz = getParameterClassForMethod(adderMethod);
- if(clazz != null && isUnequivocallyInstantiable(clazz)) {
+ if (clazz != null && isUnequivocallyInstantiable(clazz)) {
return clazz;
} else {
return null;
@@ -282,18 +282,22 @@
if (clazz.isInterface()) {
return false;
}
+ // checking for constructors would be slightly more elegant, but in
+ // classes
+ // without any declared constructors, Class.getConstructor() returns null.
+ Object o;
try {
- // checking for constructors would be slightly more elegant, but in classes
- // without any declared constructors, Class.getConstructor() returns null.
- Object o = clazz.newInstance();
- if(o != null) {
+ o = clazz.newInstance();
+ if (o != null) {
return true;
} else {
return false;
}
- } catch (Exception e) {
+ } catch (InstantiationException e) {
+ return false;
+ } catch (IllegalAccessException e) {
return false;
- }
+ }
}
public Class getObjClass() {
@@ -426,9 +430,7 @@
if (val == null) {
return null;
}
-
String v = val.trim();
-
if (String.class.isAssignableFrom(type)) {
return val;
} else if (Integer.TYPE.isAssignableFrom(type)) {
@@ -445,20 +447,47 @@
} else if ("false".equalsIgnoreCase(v)) {
return Boolean.FALSE;
}
- } else if (Duration.class.isAssignableFrom(type)) {
- return Duration.valueOf(val);
- } else if (FileSize.class.isAssignableFrom(type)) {
- return FileSize.valueOf(val);
} else if (type.isEnum()) {
return convertEnum(val, type);
+ } else if (isBuildableFromString(type)) {
+ return buildFromString(type, val);
}
return null;
}
+ boolean isBuildableFromString(Class<?> parameterClass) {
+ try {
+ Method valueOfMethod = parameterClass.getMethod(CoreGlobal.VALUE_OF,
+ STING_CLASS_PARAMETER);
+ int mod = valueOfMethod.getModifiers();
+ if (Modifier.isStatic(mod)) {
+ return true;
+ }
+ } catch (SecurityException e) {
+ // nop
+ } catch (NoSuchMethodException e) {
+ // nop
+ }
+ return false;
+ }
+
+ Object buildFromString(Class type, String val) {
+ try {
+ Method valueOfMethod = type.getMethod(CoreGlobal.VALUE_OF,
+ STING_CLASS_PARAMETER);
+ return valueOfMethod.invoke(null, val);
+ } catch (Exception e) {
+ addError("Failed to invoke " + CoreGlobal.VALUE_OF
+ + "{} method in class [" + type.getName() + "] with value [" + val
+ + "]");
+ return null;
+ }
+ }
+
protected Object convertEnum(String val, Class type) {
try {
- Method m = type.getMethod("valueOf", STING_CLASS_PARAMETER);
+ Method m = type.getMethod(CoreGlobal.VALUE_OF, STING_CLASS_PARAMETER);
return m.invoke(null, val);
} catch (Exception e) {
addError("Failed to convert value [" + val + "] to enum ["
@@ -467,7 +496,6 @@
return null;
}
-
protected Method getMethod(String methodName) {
if (methodDescriptors == null) {
introspect();
More information about the logback-dev
mailing list