120 lines
5.4 KiB
Diff
120 lines
5.4 KiB
Diff
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/IADataForComplexProperty.java
|
|
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/IADataForComplexProperty.java
|
|
@@ -26,6 +26,7 @@ public class IADataForComplexProperty {
|
|
final AggregationType aggregationType;
|
|
final String complexPropertyName;
|
|
private Object nestedComplexProperty;
|
|
+ private Class<?> expectedPropertyType;
|
|
boolean inError;
|
|
|
|
public IADataForComplexProperty(PropertySetter parentBean, AggregationType aggregationType, String complexPropertyName) {
|
|
@@ -46,6 +47,14 @@ public class IADataForComplexProperty {
|
|
return complexPropertyName;
|
|
}
|
|
|
|
+ public Class<?> getExpectedPropertyType() {
|
|
+ return expectedPropertyType;
|
|
+ }
|
|
+
|
|
+ public void setExpectedPropertyType(Class<?> expectedPropertyType) {
|
|
+ this.expectedPropertyType = expectedPropertyType;
|
|
+ }
|
|
+
|
|
public void setNestedComplexProperty(Object nestedComplexProperty) {
|
|
this.nestedComplexProperty = nestedComplexProperty;
|
|
}
|
|
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.java
|
|
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.java
|
|
@@ -76,7 +76,9 @@ public class NestedComplexPropertyIA extends ImplicitAction {
|
|
// we only push action data if NestComponentIA is applicable
|
|
case AS_COMPLEX_PROPERTY_COLLECTION:
|
|
case AS_COMPLEX_PROPERTY:
|
|
+ Class<?> propertyType = parentBean.getTypeForComplexProperty(nestedElementTagName, aggregationType);
|
|
IADataForComplexProperty ad = new IADataForComplexProperty(parentBean, aggregationType, nestedElementTagName);
|
|
+ ad.setExpectedPropertyType(propertyType);
|
|
actionDataStack.push(ad);
|
|
|
|
return true;
|
|
@@ -118,7 +120,11 @@ public class NestedComplexPropertyIA extends ImplicitAction {
|
|
addInfo("Assuming default type [" + componentClass.getName() + "] for [" + localName + "] property");
|
|
}
|
|
|
|
- actionData.setNestedComplexProperty(componentClass.newInstance());
|
|
+ Class<?> expectedPropertyType = actionData.getExpectedPropertyType();
|
|
+
|
|
+ Object object = OptionHelper.instantiateClassWithSuperclassRestriction(componentClass, expectedPropertyType);
|
|
+
|
|
+ actionData.setNestedComplexProperty(object);
|
|
|
|
// pass along the repository
|
|
if (actionData.getNestedComplexProperty() instanceof ContextAware) {
|
|
--- a/logback-core/src/main/java/ch/qos/logback/core/joran/util/PropertySetter.java
|
|
+++ b/logback-core/src/main/java/ch/qos/logback/core/joran/util/PropertySetter.java
|
|
@@ -395,4 +395,36 @@ public class PropertySetter extends ContextAwareBase {
|
|
return getByConcreteType(name, relevantMethod);
|
|
}
|
|
|
|
+ public Class<?> getTypeForComplexProperty(String nestedElementTagName, AggregationType aggregationType) {
|
|
+
|
|
+ Method aMethod = null;
|
|
+ switch (aggregationType) {
|
|
+ case AS_COMPLEX_PROPERTY:
|
|
+ aMethod = findSetterMethod(nestedElementTagName);
|
|
+ break;
|
|
+ case AS_COMPLEX_PROPERTY_COLLECTION:
|
|
+ aMethod = findAdderMethod(nestedElementTagName);
|
|
+ }
|
|
+
|
|
+
|
|
+ checkParameterCount(aMethod, nestedElementTagName);
|
|
+
|
|
+ Class<?>[] paramTypes = aMethod.getParameterTypes();
|
|
+ return paramTypes[0];
|
|
+
|
|
+ }
|
|
+
|
|
+ private void checkParameterCount(Method aMethod, String nestedElementTagName) {
|
|
+ if(aMethod == null) {
|
|
+ String msg = "Could not find method for property [" + nestedElementTagName + "].";
|
|
+ addError(msg);
|
|
+ throw new IllegalStateException(msg);
|
|
+ }
|
|
+ int parameterCount = aMethod.getParameterCount();
|
|
+ if (parameterCount != 1) {
|
|
+ String msg = "Expected ["+aMethod.getName()+"] for property [" + nestedElementTagName + "] to have exactly one parameter.";
|
|
+ addError(msg);
|
|
+ throw new IllegalStateException(msg);
|
|
+ }
|
|
+ }
|
|
}
|
|
--- a/logback-core/src/main/java/ch/qos/logback/core/util/OptionHelper.java
|
|
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/OptionHelper.java
|
|
@@ -14,6 +14,7 @@
|
|
package ch.qos.logback.core.util;
|
|
|
|
import java.lang.reflect.Constructor;
|
|
+import java.lang.reflect.InvocationTargetException;
|
|
import java.util.Properties;
|
|
|
|
import ch.qos.logback.core.Context;
|
|
@@ -44,6 +45,19 @@ public class OptionHelper {
|
|
return instantiateByClassNameAndParameter(className, superClass, classLoader, null, null);
|
|
}
|
|
|
|
+ public static Object instantiateClassWithSuperclassRestriction(Class<?> classObj, Class<?> superClass)
|
|
+ throws IncompatibleClassException, DynamicClassLoadingException {
|
|
+ if (!superClass.isAssignableFrom(classObj)) {
|
|
+ throw new IncompatibleClassException(superClass, classObj);
|
|
+ }
|
|
+
|
|
+ try {
|
|
+ return classObj.getConstructor().newInstance();
|
|
+ } catch (NoSuchMethodException|InstantiationException|IllegalAccessException|InvocationTargetException e) {
|
|
+ throw new DynamicClassLoadingException("Failed to instantiate type " + classObj.getName(), e);
|
|
+ }
|
|
+ }
|
|
+
|
|
public static Object instantiateByClassNameAndParameter(String className, Class<?> superClass, ClassLoader classLoader, Class<?> type, Object parameter)
|
|
throws IncompatibleClassException, DynamicClassLoadingException {
|
|
|