Author: davsclaus
Date: Thu Mar 7 18:59:10 2013
New Revision: 1454000
URL: http://svn.apache.org/r1454000
Log:
CAMEL-6130: Setting refernece parameters on endpoints improved to provide class
type when looking up in Registry. This fixes lookup with OSGi where the OSGi
Service Registry mandates registering the service with its class type. Thanks
to Aaron Whiteside for the patch and his hard work on this.
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/util/EndpointHelper.java
camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/util/EndpointHelper.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/EndpointHelper.java?rev=1454000&r1=1453999&r2=1454000&view=diff
==============================================================================
---
camel/trunk/camel-core/src/main/java/org/apache/camel/util/EndpointHelper.java
(original)
+++
camel/trunk/camel-core/src/main/java/org/apache/camel/util/EndpointHelper.java
Thu Mar 7 18:59:10 2013
@@ -16,7 +16,6 @@
*/
package org.apache.camel.util;
-import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -30,7 +29,6 @@ import org.apache.camel.CamelContext;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
-import org.apache.camel.NoTypeConversionAvailableException;
import org.apache.camel.PollingConsumer;
import org.apache.camel.Processor;
import org.apache.camel.ResolveEndpointFailedException;
@@ -271,40 +269,10 @@ public final class EndpointHelper {
Object v = entry.getValue();
String value = v != null ? v.toString() : null;
if (value != null && isReferenceParameter(value)) {
- List<Method> candidates =
IntrospectionSupport.findSetterMethodsOrderedByParameterType(bean.getClass(),
name, false);
-
- Exception typeConversionFailed = null;
- for (Method setter : candidates) {
- Class parameterType = setter.getParameterTypes()[0];
- // For backwards-compatibility reasons, no mandatory
lookup is done here
- Object ref = resolveReferenceParameter(context, value,
parameterType, false);
- if (ref != null) {
- try {
- boolean hit =
IntrospectionSupport.setProperty(context.getTypeConverter(), bean, setter, ref);
-
- if (hit) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Configured property: {} on
bean: {} with value: {}", new Object[]{name, bean, ref});
- }
- // must remove as its a valid option and we
could configure it
- it.remove();
- typeConversionFailed = null;
- break;
- }
- } catch (NoTypeConversionAvailableException e) {
- typeConversionFailed = e;
- } catch (IllegalArgumentException e) {
- typeConversionFailed = e;
- }
- }
- }
-
- if (typeConversionFailed != null) {
- // we did not find a setter method to use, and if we did
try to use a type converter then throw
- // this kind of exception as the caused by will hint this
error
- throw new IllegalArgumentException("Could not find a
suitable setter for property: " + name
- + " as there isn't a setter method with same type:
" + value.getClass().getCanonicalName()
- + " nor type conversion possible: " +
typeConversionFailed.getMessage());
+ boolean hit = IntrospectionSupport.setProperty(context,
context.getTypeConverter(), bean, name, null, value, true);
+ if (hit) {
+ // must remove as its a valid option and we could
configure it
+ it.remove();
}
}
}
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java?rev=1454000&r1=1453999&r2=1454000&view=diff
==============================================================================
---
camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java
(original)
+++
camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java
Thu Mar 7 18:59:10 2013
@@ -25,6 +25,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -36,6 +37,7 @@ import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
+import org.apache.camel.CamelContext;
import org.apache.camel.NoTypeConversionAvailableException;
import org.apache.camel.TypeConverter;
import org.slf4j.Logger;
@@ -438,10 +440,28 @@ public final class IntrospectionSupport
return setProperties(null, target, properties);
}
- public static boolean setProperty(TypeConverter typeConverter, Object
target, String name, Object value, boolean allowBuilderPattern) throws
Exception {
+ /**
+ * This method supports two modes to set a property:
+ *
+ * 1. Setting a property that has already been resolved, this is the case
when {@code context} and {@code refName} are
+ * NULL and {@code value} is non-NULL.
+ *
+ * 2. Setting a property that has not yet been resolved, the property will
be resolved based on the suitable methods
+ * found matching the property name on the {@code target} bean. For this
mode to be triggered the parameters
+ * {@code context} and {@code refName} must NOT be NULL, and {@code value}
MUST be NULL.
+ *
+ */
+ public static boolean setProperty(CamelContext context, TypeConverter
typeConverter, Object target, String name, Object value, String refName,
boolean allowBuilderPattern) throws Exception {
Class<?> clazz = target.getClass();
- // find candidates of setter methods as there can be overloaded setters
- Set<Method> setters = findSetterMethods(clazz, name, value,
allowBuilderPattern);
+ Collection<Method> setters;
+
+ // we need to lookup the value from the registry
+ if (context != null && refName != null && value == null) {
+ setters = findSetterMethodsOrderedByParameterType(clazz, name,
allowBuilderPattern);
+ } else {
+ // find candidates of setter methods as there can be overloaded
setters
+ setters = findSetterMethods(clazz, name, value,
allowBuilderPattern);
+ }
if (setters.isEmpty()) {
return false;
}
@@ -449,8 +469,45 @@ public final class IntrospectionSupport
// loop and execute the best setter method
Exception typeConversionFailed = null;
for (Method setter : setters) {
+ Class parameterType = setter.getParameterTypes()[0];
+ Object ref = value;
+ // try and lookup the reference based on the method
+ if (context != null && refName != null && ref == null) {
+ ref = CamelContextHelper.lookup(context,
refName.replaceAll("#", ""), parameterType);
+ if (ref == null) {
+ continue; // try the next method if nothing was found
+ }
+ }
+
try {
- return setProperty(typeConverter, target, setter, value);
+ try {
+ // If the type is null or it matches the needed type, just
use the value directly
+ if (value == null ||
parameterType.isAssignableFrom(ref.getClass())) {
+ setter.invoke(target, ref);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Configured property: {} on bean: {}
with value: {}", new Object[]{name, target, ref});
+ }
+ return true;
+ } else {
+ // We need to convert it
+ Object convertedValue = convert(typeConverter,
parameterType, ref);
+ setter.invoke(target, convertedValue);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Configured property: {} on bean: {}
with value: {}", new Object[]{name, target, ref});
+ }
+ return true;
+ }
+ } catch (InvocationTargetException e) {
+ // lets unwrap the exception
+ Throwable throwable = e.getCause();
+ if (throwable instanceof Exception) {
+ Exception exception = (Exception)throwable;
+ throw exception;
+ } else {
+ Error error = (Error)throwable;
+ throw error;
+ }
+ }
// ignore exceptions as there could be another setter method where
we could type convert successfully
} catch (NoTypeConversionAvailableException e) {
typeConversionFailed = e;
@@ -459,7 +516,7 @@ public final class IntrospectionSupport
}
if (LOG.isTraceEnabled()) {
LOG.trace("Setter \"{}\" with parameter type \"{}\" could not
be used for type conversions of {}",
- new Object[]{setter, setter.getParameterTypes()[0],
value});
+ new Object[]{setter, parameterType, ref});
}
}
@@ -474,38 +531,13 @@ public final class IntrospectionSupport
}
}
- public static boolean setProperty(TypeConverter typeConverter, Object
target, Method setter, Object value) throws Exception {
- try {
- // If the type is null or it matches the needed type, just use the
value directly
- if (value == null ||
setter.getParameterTypes()[0].isAssignableFrom(value.getClass())) {
- setter.invoke(target, value);
- return true;
- } else {
- // We need to convert it
- Object convertedValue = convert(typeConverter,
setter.getParameterTypes()[0], value);
- setter.invoke(target, convertedValue);
- return true;
- }
- } catch (InvocationTargetException e) {
- // lets unwrap the exception
- Throwable throwable = e.getCause();
- if (throwable instanceof Exception) {
- Exception exception = (Exception)throwable;
- throw exception;
- } else {
- Error error = (Error)throwable;
- throw error;
- }
- }
- }
-
public static boolean setProperty(TypeConverter typeConverter, Object
target, String name, Object value) throws Exception {
// allow build pattern as a setter as well
- return setProperty(typeConverter, target, name, value, true);
+ return setProperty(null, typeConverter, target, name, value, null,
true);
}
public static boolean setProperty(Object target, String name, Object
value, boolean allowBuilderPattern) throws Exception {
- return setProperty(null, target, name, value, allowBuilderPattern);
+ return setProperty(null, null, target, name, value, null,
allowBuilderPattern);
}
public static boolean setProperty(Object target, String name, Object
value) throws Exception {
@@ -588,7 +620,7 @@ public final class IntrospectionSupport
}
}
- public static List<Method>
findSetterMethodsOrderedByParameterType(Class<?> target, String propertyName,
boolean allowBuilderPattern) {
+ protected static List<Method>
findSetterMethodsOrderedByParameterType(Class<?> target, String propertyName,
boolean allowBuilderPattern) {
List<Method> answer = new LinkedList<Method>();
List<Method> primitives = new LinkedList<Method>();
Set<Method> setters = findSetterMethods(target, propertyName,
allowBuilderPattern);