Author: davsclaus
Date: Mon Oct 19 06:37:30 2009
New Revision: 826591
URL: http://svn.apache.org/viewvc?rev=826591&view=rev
Log:
CAMEL-2074, CAMEL-2075, CAMEL-2071: Bean component does not handle select
methods using the method name given (if any given). Also getter/setter is
skipped if Camel have to pick one itself.
Added:
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanChoseMethodWithMatchingTypeAndSkipSettersTest.java
(with props)
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java
(with props)
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MyDummyBean.java
(with props)
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/OrderServiceBean.java
(with props)
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java?rev=826591&r1=826590&r2=826591&view=diff
==============================================================================
---
camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
(original)
+++
camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
Mon Oct 19 06:37:30 2009
@@ -23,6 +23,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -42,6 +43,7 @@
import org.apache.camel.builder.ExpressionBuilder;
import org.apache.camel.language.LanguageAnnotation;
import org.apache.camel.spi.Registry;
+import org.apache.camel.util.IntrospectionSupport;
import org.apache.camel.util.ObjectHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -135,7 +137,16 @@
if (operations.containsKey(name)) {
List<MethodInfo> methods = operations.get(name);
if (methods != null && methods.size() == 1) {
+ // only one method then choose it
methodInfo = methods.get(0);
+ } else {
+ // there are more methods with that name so we cannot
decide which to use
+
+ // but first lets try to choose a method and see if that
comply with the name
+ methodInfo = chooseMethod(pojo, exchange, name);
+ if (!name.equals(methodInfo.getMethod().getName())) {
+ throw new AmbiguousMethodCallException(exchange,
methods);
+ }
}
} else {
// a specific method was given to invoke but not found
@@ -143,7 +154,7 @@
}
}
if (methodInfo == null) {
- methodInfo = chooseMethod(pojo, exchange);
+ methodInfo = chooseMethod(pojo, exchange, name);
}
if (methodInfo == null) {
methodInfo = defaultMethod;
@@ -327,15 +338,28 @@
*
* @param pojo the bean to invoke a method on
* @param exchange the message exchange
+ * @param name an optional name of the method that must match, use
<tt>null</tt> to indicate all methods
* @return the method to invoke or null if no definitive method could be
matched
* @throws AmbiguousMethodCallException is thrown if cannot chose method
due to ambiguous
*/
- protected MethodInfo chooseMethod(Object pojo, Exchange exchange) throws
AmbiguousMethodCallException {
+ protected MethodInfo chooseMethod(Object pojo, Exchange exchange, String
name) throws AmbiguousMethodCallException {
// @Handler should be select first
// then any single method that has a custom @annotation
// or any single method that has a match parameter type that matches
the Exchange payload
// and last then try to select the best among the rest
+ if (name != null) {
+ // filter all lists to only include methods with this name
+ removeNonMatchingMethods(operationsWithHandlerAnnotation, name);
+ removeNonMatchingMethods(operationsWithCustomAnnotation, name);
+ removeNonMatchingMethods(operationsWithBody, name);
+ } else {
+ // remove all getter/setter as we do not want to consider these
methods
+ removeAllSetterOrGetterMethods(operationsWithHandlerAnnotation);
+ removeAllSetterOrGetterMethods(operationsWithCustomAnnotation);
+ removeAllSetterOrGetterMethods(operationsWithBody);
+ }
+
if (operationsWithHandlerAnnotation.size() > 1) {
// if we have more than 1 @Handler then its ambiguous
throw new AmbiguousMethodCallException(exchange,
operationsWithHandlerAnnotation);
@@ -604,4 +628,29 @@
return null;
}
+ private static void removeAllSetterOrGetterMethods(List<MethodInfo>
methods) {
+ Iterator<MethodInfo> it = methods.iterator();
+ while (it.hasNext()) {
+ MethodInfo info = it.next();
+ if (IntrospectionSupport.isGetter(info.getMethod())) {
+ // skip getters
+ it.remove();
+ } else if (IntrospectionSupport.isSetter(info.getMethod())) {
+ // skip setters
+ it.remove();
+ }
+ }
+ }
+
+ private static void removeNonMatchingMethods(List<MethodInfo> methods,
String name) {
+ Iterator<MethodInfo> it = methods.iterator();
+ while (it.hasNext()) {
+ MethodInfo info = it.next();
+ if (!name.equals(info.getMethod().getName())) {
+ // name does not match so remove it
+ it.remove();
+ }
+ }
+ }
+
}
Added:
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanChoseMethodWithMatchingTypeAndSkipSettersTest.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanChoseMethodWithMatchingTypeAndSkipSettersTest.java?rev=826591&view=auto
==============================================================================
---
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanChoseMethodWithMatchingTypeAndSkipSettersTest.java
(added)
+++
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanChoseMethodWithMatchingTypeAndSkipSettersTest.java
Mon Oct 19 06:37:30 2009
@@ -0,0 +1,88 @@
+/**
+ * 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.component.bean;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.JndiRegistry;
+
+/**
+ * @version $Revision$
+ */
+public class BeanChoseMethodWithMatchingTypeAndSkipSettersTest extends
ContextTestSupport {
+
+ private OrderServiceBean service = new OrderServiceBean();
+
+ @Override
+ public void setUp() throws Exception {
+ deleteDirectory("target/file/order");
+ super.setUp();
+ }
+
+ @Override
+ protected JndiRegistry createRegistry() throws Exception {
+ JndiRegistry jndi = super.createRegistry();
+ jndi.bind("orderService", service);
+ return jndi;
+ }
+
+ @Override
+ protected CamelContext createCamelContext() throws Exception {
+ CamelContext context = super.createCamelContext();
+ service.setConverter(context.getTypeConverter());
+ return context;
+ }
+
+ public void testSendCSVFile() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:queue:order");
+ mock.expectedBodiesReceived("66554,123,456");
+
+ template.sendBodyAndHeader("file://target/file/order", "123,456",
Exchange.FILE_NAME, "66554.csv");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ public void testSendXMLData() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:queue:order");
+ mock.expectedBodiesReceived("77889,667,457");
+
+ String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+ "<order id=\"77889\">" +
+ "<customer id=\"667\"/>" +
+ "<confirm>457</confirm>" +
+ "</order>";
+ template.sendBody("seda:xml", xml);
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("file://target/file/order", "seda:xml")
+ .beanRef("orderService")
+ .to("mock:queue:order");
+ }
+ };
+ }
+
+}
Propchange:
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanChoseMethodWithMatchingTypeAndSkipSettersTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanChoseMethodWithMatchingTypeAndSkipSettersTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added:
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java?rev=826591&view=auto
==============================================================================
---
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java
(added)
+++
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java
Mon Oct 19 06:37:30 2009
@@ -0,0 +1,61 @@
+/**
+ * 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.component.bean;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.JndiRegistry;
+
+/**
+ * @version $Revision$
+ */
+public class BeanExplicitMethodAmbiguousTest extends ContextTestSupport {
+
+ @Override
+ protected JndiRegistry createRegistry() throws Exception {
+ JndiRegistry jndi = super.createRegistry();
+ jndi.bind("dummy", new MyDummyBean());
+ return jndi;
+ }
+
+ public void testBeanExplicitMethodAmbiguous() throws Exception {
+ try {
+ template.requestBody("direct:hello", "Camel");
+ fail("Should thrown an exception");
+ } catch (Exception e) {
+ AmbiguousMethodCallException cause =
assertIsInstanceOf(AmbiguousMethodCallException.class, e.getCause());
+ assertEquals(2, cause.getMethods().size());
+ }
+ }
+
+ public void testBeanExplicitMethodHandler() throws Exception {
+ String out = template.requestBody("direct:bye", "Camel", String.class);
+ assertEquals("Bye Camel", out);
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:hello").beanRef("dummy", "hello");
+
+ from("direct:bye").beanRef("dummy");
+ }
+ };
+ }
+}
Propchange:
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added:
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MyDummyBean.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MyDummyBean.java?rev=826591&view=auto
==============================================================================
---
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MyDummyBean.java
(added)
+++
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MyDummyBean.java
Mon Oct 19 06:37:30 2009
@@ -0,0 +1,38 @@
+/**
+ * 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.component.bean;
+
+import org.apache.camel.Handler;
+
+/**
+ * @version $Revision$
+ */
+public class MyDummyBean {
+
+ public String hello(String s) {
+ return "Hello " + s;
+ }
+
+ public String hello(String s, String t) {
+ return "Hello " + s + " and " + t;
+ }
+
+ @Handler
+ public String bye(String s) {
+ return "Bye " + s;
+ }
+}
Propchange:
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MyDummyBean.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MyDummyBean.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added:
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/OrderServiceBean.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/OrderServiceBean.java?rev=826591&view=auto
==============================================================================
---
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/OrderServiceBean.java
(added)
+++
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/OrderServiceBean.java
Mon Oct 19 06:37:30 2009
@@ -0,0 +1,64 @@
+/**
+ * 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.component.bean;
+
+import org.apache.camel.TypeConverter;
+import org.apache.camel.component.file.GenericFile;
+import org.apache.camel.util.FileUtil;
+import org.w3c.dom.Document;
+
+/**
+ * @version $Revision$
+ */
+public class OrderServiceBean {
+
+ private TypeConverter converter;
+
+ public void setConverter(TypeConverter converter) {
+ this.converter = converter;
+ }
+
+ public String handleCustom(GenericFile file) {
+ String content = converter.convertTo(String.class, file.getBody());
+ String orderId = FileUtil.stripExt(file.getFileNameOnly());
+
+ StringBuilder sb = new StringBuilder();
+ sb.append(orderId);
+ sb.append(",");
+ sb.append(content);
+
+ return sb.toString();
+ }
+
+ public String handleXML(Document doc) {
+ String xml = converter.convertTo(String.class, doc);
+
+ Integer orderId = 77889;
+ Integer customerId = 667;
+ Integer confirmId = 457;
+
+ StringBuilder sb = new StringBuilder();
+ sb.append(orderId);
+ sb.append(",");
+ sb.append(customerId);
+ sb.append(",");
+ sb.append(confirmId);
+
+ return sb.toString();
+ }
+
+}
Propchange:
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/OrderServiceBean.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/OrderServiceBean.java
------------------------------------------------------------------------------
svn:keywords = Rev Date