You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2008/08/21 14:51:23 UTC
svn commit: r687732 - in /activemq/camel/trunk/camel-core/src:
main/java/org/apache/camel/util/IntrospectionSupport.java
test/java/org/apache/camel/util/IntrospectionSupportTest.java
Author: davsclaus
Date: Thu Aug 21 05:51:21 2008
New Revision: 687732
URL: http://svn.apache.org/viewvc?rev=687732&view=rev
Log:
CAMEL-840: IntrospectionSupport to support overloaded setter methods for setting properties.
Added:
activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/util/IntrospectionSupportTest.java (with props)
Modified:
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java
Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java?rev=687732&r1=687731&r2=687732&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java Thu Aug 21 05:51:21 2008
@@ -28,6 +28,7 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
@@ -180,21 +181,42 @@
public static boolean setProperty(TypeConverter typeConverter, Object target, String name, Object value) throws Exception {
try {
Class clazz = target.getClass();
- Method setter = findSetterMethod(typeConverter, clazz, name, value);
- if (setter == null) {
+ // find candidates of setter methods as there can be overloaded setters
+ Set<Method> setters = findSetterMethods(typeConverter, clazz, name, value);
+ if (setters.isEmpty()) {
return false;
}
- // If the type is null or it matches the needed type, just use the
- // value directly
- if (value == null || value.getClass() == setter.getParameterTypes()[0]) {
- setter.invoke(target, value);
+ // loop and execute the best setter method
+ Exception typeConvertionFailed = null;
+ for (Method setter : setters) {
+ // If the type is null or it matches the needed type, just use the value directly
+ if (value == null || value.getClass() == setter.getParameterTypes()[0]) {
+ setter.invoke(target, value);
+ return true;
+ } else {
+ // We need to convert it
+ try {
+ Object convertedValue = convert(typeConverter, setter.getParameterTypes()[0], value);
+ setter.invoke(target, convertedValue);
+ return true;
+ } catch (IllegalArgumentException e) {
+ typeConvertionFailed = e;
+ // ignore as there could be another setter method where we could type convert with success
+ LOG.trace("Setter " + setter + " with parameter type " + setter.getParameterTypes()[0]
+ + " could not be used for type conertions of " + value);
+ }
+ }
+ }
+ // 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
+ if (typeConvertionFailed != null) {
+ 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 convertion possbile: " + typeConvertionFailed.getMessage());
} else {
- // We need to convert it
- Object convertedValue = convert(typeConverter, setter.getParameterTypes()[0], value);
- setter.invoke(target, convertedValue);
+ return false;
}
- return true;
} catch (InvocationTargetException e) {
Throwable throwable = e.getTargetException();
if (throwable instanceof Exception) {
@@ -242,7 +264,9 @@
return null;
}
- private static Method findSetterMethod(TypeConverter typeConverter, Class clazz, String name, Object value) {
+ private static Set<Method> findSetterMethods(TypeConverter typeConverter, Class clazz, String name, Object value) {
+ Set<Method> candidates = new LinkedHashSet<Method>();
+
// Build the method name.
name = "set" + ObjectHelper.capitalize(name);
while (clazz != Object.class) {
@@ -252,13 +276,38 @@
if (method.getName().equals(name) && params.length == 1) {
Class paramType = params[0];
if (typeConverter != null || isSettableType(paramType) || paramType.isInstance(value)) {
- return method;
+ candidates.add(method);
}
}
}
clazz = clazz.getSuperclass();
}
- return null;
+
+ if (candidates.isEmpty()) {
+ return candidates;
+ } else if (candidates.size() == 1 ){
+ // only one
+ return candidates;
+ } else {
+ // find the best match if possible
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Found " + candidates.size() + " suitable setter methods for setting " + name);
+ }
+ // perfer to use the one with the same instance if any exists
+ for (Method method : candidates) {
+ if (method.getParameterTypes()[0].isInstance(value)) {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Method " + method + " is the best candidate as it has parameter with same instance type");
+ }
+ // retain only this method in the answer
+ candidates.clear();
+ candidates.add(method);
+ return candidates;
+ }
+ }
+ // fallback to return what we have found as candidates so far
+ return candidates;
+ }
}
private static boolean isSettableType(Class clazz) {
Added: activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/util/IntrospectionSupportTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/util/IntrospectionSupportTest.java?rev=687732&view=auto
==============================================================================
--- activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/util/IntrospectionSupportTest.java (added)
+++ activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/util/IntrospectionSupportTest.java Thu Aug 21 05:51:21 2008
@@ -0,0 +1,59 @@
+/**
+ * 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.
+ */
+package org.apache.camel.util;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.util.jndi.ExampleBean;
+
+/**
+ * Unit test for IntrospectionSupport
+ */
+public class IntrospectionSupportTest extends ContextTestSupport {
+
+ public void testOverloadSetterChooseStringSetter() throws Exception {
+ MyOverloadedBean overloadedBean = new MyOverloadedBean();
+ IntrospectionSupport.setProperty(context.getTypeConverter(), overloadedBean, "bean", "James");
+ assertEquals("James", overloadedBean.getName());
+ }
+
+ public void testOverloadSetterChooseBeanSetter() throws Exception {
+ MyOverloadedBean overloadedBean = new MyOverloadedBean();
+ ExampleBean bean = new ExampleBean();
+ bean.setName("Claus");
+ IntrospectionSupport.setProperty(context.getTypeConverter(), overloadedBean, "bean", bean);
+ assertEquals("Claus", overloadedBean.getName());
+ }
+
+ public class MyOverloadedBean {
+ private ExampleBean bean;
+
+ public void setBean(ExampleBean bean) {
+ this.bean = bean;
+ }
+
+ public void setBean(String name) {
+ bean = new ExampleBean();
+ bean.setName(name);
+ }
+
+ public String getName() {
+ return bean.getName();
+ }
+ }
+
+}
+
Propchange: activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/util/IntrospectionSupportTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/util/IntrospectionSupportTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date