Author: jstrachan
Date: Tue Aug 12 10:20:09 2008
New Revision: 685233

URL: http://svn.apache.org/viewvc?rev=685233&view=rev
Log:
added an initial implementation of CAMEL-816 to support @Produce and @Consume

Added:
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Consume.java 
  (contents, props changed)
      - copied, changed from r685117, 
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/MessageDriven.java
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Produce.java 
  (with props)
    
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/
    
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListener.java
   (with props)
    
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListenerService.java
   (with props)
    
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/ProduceTest.java
   (with props)
    
activemq/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/produce/
    
activemq/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/produce/ProduceTest-context.xml
   (with props)
Modified:
    
activemq/camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java

Copied: 
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Consume.java 
(from r685117, 
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/MessageDriven.java)
URL: 
http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Consume.java?p2=activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Consume.java&p1=activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/MessageDriven.java&r1=685117&r2=685233&rev=685233&view=diff
==============================================================================
--- 
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/MessageDriven.java
 (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Consume.java 
Tue Aug 12 10:20:09 2008
@@ -22,19 +22,20 @@
 import java.lang.annotation.Target;
 
 /**
- * Used to indicate a method on a POJO which is used as a [EMAIL PROTECTED] 
Consumer} of
- * [EMAIL PROTECTED] Exchange} instances to process [EMAIL PROTECTED] Message} 
instances.
- * 
- * Either a <a href="http://activemq.apache.org/camel/uris.html";>URI</a> for an
- * endpoint should be configured, or a name of an endpoint which refers to a
- * Spring bean name in your Spring ApplicationContext.
+ * Subscribes a method to an [EMAIL PROTECTED] Endpoint} either via its
+ * <a href="http://activemq.apache.org/camel/uris.html";>URI</a> or via the 
name of the endpoint reference
+ * which is then resolved in a registry such as the Spring Application Context.
+ *
+ * When a message [EMAIL PROTECTED] Exchange} is received from the [EMAIL 
PROTECTED] Endpoint} then the
+ * <a href="http://activemq.apache.org/camel/bean-integration.html";>Bean 
Integration</a>
+ * mechanism is used to map the incoming [EMAIL PROTECTED] Message} to the 
method parameters.
  * 
  * @version $Revision$
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR })
-public @interface MessageDriven {
+public @interface Consume {
     String uri() default "";
 
-    String name() default "";
+    String ref() default "";
 }

Propchange: 
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Consume.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Consume.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Propchange: 
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Consume.java
------------------------------------------------------------------------------
    svn:mergeinfo = 

Added: 
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Produce.java
URL: 
http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Produce.java?rev=685233&view=auto
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Produce.java 
(added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Produce.java 
Tue Aug 12 10:20:09 2008
@@ -0,0 +1,43 @@
+/**
+ * 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;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a field or property as being a producer to an [EMAIL PROTECTED] 
org.apache.camel.Endpoint} either via its
+ * <a href="http://activemq.apache.org/camel/uris.html";>URI</a> or via the 
name of the endpoint reference
+ * which is then resolved in a registry such as the Spring Application Context.
+ *
+ * Methods invoked on the producer object are then converted to a message 
[EMAIL PROTECTED] org.apache.camel.Exchange} via the
+ * <a href="http://activemq.apache.org/camel/bean-integration.html";>Bean 
Integration</a>
+ * mechanism.
+ *
+ * @see InOnly
+ *
+ * @version $Revision: 630591 $
+ */
[EMAIL PROTECTED](RetentionPolicy.RUNTIME)
[EMAIL PROTECTED]({ElementType.FIELD, ElementType.METHOD, 
ElementType.CONSTRUCTOR })
+public @interface Produce {
+    public abstract String uri() default "";
+
+    public abstract String ref() default "";
+}
\ No newline at end of file

Propchange: 
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Produce.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
activemq/camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java
URL: 
http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java?rev=685233&r1=685232&r2=685233&view=diff
==============================================================================
--- 
activemq/camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java
 (original)
+++ 
activemq/camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java
 Tue Aug 12 10:20:09 2008
@@ -24,23 +24,16 @@
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlTransient;
 
-import org.apache.camel.CamelContextAware;
-import org.apache.camel.Consumer;
-import org.apache.camel.Endpoint;
-import org.apache.camel.EndpointInject;
-import org.apache.camel.MessageDriven;
-import org.apache.camel.PollingConsumer;
-import org.apache.camel.Processor;
-import org.apache.camel.Producer;
-import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.Service;
+import org.apache.camel.*;
 import org.apache.camel.component.bean.BeanProcessor;
+import org.apache.camel.component.bean.ProxyHelper;
 import org.apache.camel.impl.DefaultProducerTemplate;
 import org.apache.camel.spring.util.ReflectionUtils;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.springframework.beans.BeansException;
+import org.springframework.beans.BeanInstantiationException;
 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 import org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.context.ApplicationContext;
@@ -115,12 +108,20 @@
             public void doWith(Field field) throws IllegalArgumentException, 
IllegalAccessException {
                 EndpointInject annotation = 
field.getAnnotation(EndpointInject.class);
                 if (annotation != null) {
-                    ReflectionUtils.setField(field, bean, 
getEndpointInjectionValue(annotation, field.getType(), field.getName()));
+                    injectField(field, annotation.uri(), annotation.name(), 
bean);
+                }
+                Produce produce = field.getAnnotation(Produce.class);
+                if (produce != null) {
+                    injectField(field, produce.uri(), produce.ref(), bean);
                 }
             }
         });
     }
 
+    protected void injectField(Field field, String endpointUri, String 
endpointRef, Object bean) {
+        ReflectionUtils.setField(field, bean, 
getInjectionValue(field.getType(), endpointUri, endpointRef, field.getName()));
+    }
+
     protected void injectMethods(final Object bean) {
         ReflectionUtils.doWithMethods(bean.getClass(), new 
ReflectionUtils.MethodCallback() {
             @SuppressWarnings("unchecked")
@@ -134,15 +135,23 @@
     protected void setterInjection(Method method, Object bean) {
         EndpointInject annoation = method.getAnnotation(EndpointInject.class);
         if (annoation != null) {
-            Class<?>[] parameterTypes = method.getParameterTypes();
-            if (parameterTypes != null) {
-                if (parameterTypes.length != 1) {
-                    LOG.warn("Ignoring badly annotated method for injection 
due to incorrect number of parameters: " + method);
-                } else {
-                    String propertyName = ObjectHelper.getPropertyName(method);
-                    Object value = getEndpointInjectionValue(annoation, 
parameterTypes[0], propertyName);
-                    ObjectHelper.invokeMethod(method, bean, value);
-                }
+            setterInjection(method, bean, annoation.uri(), annoation.name());
+        }
+        Produce produce = method.getAnnotation(Produce.class);
+        if (produce != null) {
+            setterInjection(method, bean, produce.uri(), produce.ref());
+        }
+    }
+
+    protected void setterInjection(Method method, Object bean, String 
endpointUri, String endpointRef) {
+        Class<?>[] parameterTypes = method.getParameterTypes();
+        if (parameterTypes != null) {
+            if (parameterTypes.length != 1) {
+                LOG.warn("Ignoring badly annotated method for injection due to 
incorrect number of parameters: " + method);
+            } else {
+                String propertyName = ObjectHelper.getPropertyName(method);
+                Object value = getInjectionValue(parameterTypes[0], 
endpointUri, endpointRef, propertyName);
+                ObjectHelper.invokeMethod(method, bean, value);
             }
         }
     }
@@ -176,20 +185,29 @@
         MessageDriven annotation = method.getAnnotation(MessageDriven.class);
         if (annotation != null) {
             LOG.info("Creating a consumer for: " + annotation);
+            subscribeMethod(method, bean, annotation.uri(), annotation.name());
+        }
 
-            // lets bind this method to a listener
-            String injectionPointName = method.getName();
-            Endpoint endpoint = getEndpointInjection(annotation.uri(), 
annotation.name(), injectionPointName);
-            if (endpoint != null) {
-                try {
-                    Processor processor = createConsumerProcessor(bean, 
method, endpoint);
-                    LOG.info("Created processor: " + processor);
-                    Consumer consumer = endpoint.createConsumer(processor);
-                    startService(consumer);
-                } catch (Exception e) {
-                    LOG.warn(e);
-                    throw new RuntimeCamelException(e);
-                }
+        Consume consume = method.getAnnotation(Consume.class);
+        if (consume != null) {
+            LOG.info("Creating a consumer for: " + consume);
+            subscribeMethod(method, bean, consume.uri(), consume.ref());
+        }
+    }
+
+    protected void subscribeMethod(Method method, Object bean, String 
endpointUri, String endpointName) {
+        // lets bind this method to a listener
+        String injectionPointName = method.getName();
+        Endpoint endpoint = getEndpointInjection(endpointUri, endpointName, 
injectionPointName);
+        if (endpoint != null) {
+            try {
+                Processor processor = createConsumerProcessor(bean, method, 
endpoint);
+                LOG.info("Created processor: " + processor);
+                Consumer consumer = endpoint.createConsumer(processor);
+                startService(consumer);
+            } catch (Exception e) {
+                LOG.warn(e);
+                throw new RuntimeCamelException(e);
             }
         }
     }
@@ -210,10 +228,10 @@
 
 
     /**
-     * Creates the value for the injection point for the given annotation
+     * Creates the object to be injected for an [EMAIL PROTECTED] 
org.apache.camel.EndpointInject} or [EMAIL PROTECTED] Produce} injection point
      */
-    protected Object getEndpointInjectionValue(EndpointInject annotation, 
Class<?> type, String injectionPointName) {
-        Endpoint endpoint = getEndpointInjection(annotation.uri(), 
annotation.name(), injectionPointName);
+    protected Object getInjectionValue(Class<?> type, String endpointUri, 
String endpointRef, String injectionPointName) {
+        Endpoint endpoint = getEndpointInjection(endpointUri, endpointRef, 
injectionPointName);
         if (endpoint != null) {
             if (type.isInstance(endpoint)) {
                 return endpoint;
@@ -223,6 +241,13 @@
                 return new DefaultProducerTemplate(getCamelContext(), 
endpoint);
             } else if (type.isAssignableFrom(PollingConsumer.class)) {
                 return createInjectionPollingConsumer(endpoint);
+            } else if (type.isInterface()) {
+                // lets create a proxy
+                try {
+                    return ProxyHelper.createProxy(endpoint, type);
+                } catch (Exception e) {
+                    throw new BeanInstantiationException(type, "Could not 
instantiate proxy of type " + type.getName() + " on endpoint " + endpoint, e);
+                }
             } else {
                 throw new IllegalArgumentException("Invalid type: " + 
type.getName() + " which cannot be injected via @EndpointInject for " + 
endpoint);
             }

Added: 
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListener.java
URL: 
http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListener.java?rev=685233&view=auto
==============================================================================
--- 
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListener.java
 (added)
+++ 
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListener.java
 Tue Aug 12 10:20:09 2008
@@ -0,0 +1,25 @@
+/**
+ *
+ * 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.spring.produce;
+
+/**
+ * @version $Revision: 1.1 $
+ */
+public interface MyListener {
+    String sayHello(String name);
+}

Propchange: 
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListenerService.java
URL: 
http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListenerService.java?rev=685233&view=auto
==============================================================================
--- 
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListenerService.java
 (added)
+++ 
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListenerService.java
 Tue Aug 12 10:20:09 2008
@@ -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.spring.produce;
+
+import org.apache.camel.Consume;
+import org.springframework.stereotype.Service;
+
+/**
+ * @version $Revision: 1.1 $
+ */
[EMAIL PROTECTED]
+public class MyListenerService implements MyListener {
+
+    public MyListenerService() {
+        System.out.println("Instantiated service: " + this);
+    }
+
+    @Consume(uri = "direct:myService")
+    public String sayHello(String name) {
+        System.out.println("Invoked sayHello with: " + name);
+        return "Hello " + name;
+    }
+}

Propchange: 
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListenerService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/ProduceTest.java
URL: 
http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/ProduceTest.java?rev=685233&view=auto
==============================================================================
--- 
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/ProduceTest.java
 (added)
+++ 
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/ProduceTest.java
 Tue Aug 12 10:20:09 2008
@@ -0,0 +1,50 @@
+/**
+ * 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.spring.produce;
+
+import java.util.List;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.ExchangePattern;
+import org.apache.camel.Produce;
+import org.apache.camel.spring.remoting.IAsyncService;
+import org.apache.camel.spring.remoting.SpringRemotingWithOneWayTest;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import 
org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests;
+
+/**
+ * @version $Revision: 685051 $
+ */
[EMAIL PROTECTED]
+public class ProduceTest extends AbstractJUnit38SpringContextTests {
+    private static final Log LOG = LogFactory.getLog(ProduceTest.class);
+
+    @Produce(uri = "direct:myService")
+    protected MyListener producer;
+
+    public void testInvokeService() throws Exception {
+        // lets send a message
+        String actual = producer.sayHello("James");
+        assertEquals("response", "Hello James", actual);
+
+    }
+}
\ No newline at end of file

Propchange: 
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/ProduceTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
activemq/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/produce/ProduceTest-context.xml
URL: 
http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/produce/ProduceTest-context.xml?rev=685233&view=auto
==============================================================================
--- 
activemq/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/produce/ProduceTest-context.xml
 (added)
+++ 
activemq/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/produce/ProduceTest-context.xml
 Tue Aug 12 10:20:09 2008
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<!-- START SNIPPET: example -->
+<beans xmlns="http://www.springframework.org/schema/beans";
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xmlns:context="http://www.springframework.org/schema/context";
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+       http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context-2.5.xsd
+       http://activemq.apache.org/camel/schema/spring 
http://activemq.apache.org/camel/schema/spring/camel-spring.xsd
+    ">
+
+
+  <context:component-scan base-package="org.apache.camel.spring.produce"/>
+
+  <camelContext xmlns="http://activemq.apache.org/camel/schema/spring";>
+  </camelContext>
+
+</beans>
+        <!-- END SNIPPET: example -->

Propchange: 
activemq/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/produce/ProduceTest-context.xml
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to