activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jstrac...@apache.org
Subject svn commit: r535384 - in /activemq/camel/trunk: camel-core/src/main/java/org/apache/camel/ camel-core/src/main/java/org/apache/camel/builder/ camel-spring/src/main/java/org/apache/camel/spring/ camel-spring/src/main/java/org/apache/camel/spring/util/
Date Fri, 04 May 2007 21:26:17 GMT
Author: jstrachan
Date: Fri May  4 14:26:16 2007
New Revision: 535384

URL: http://svn.apache.org/viewvc?view=rev&rev=535384
Log:
added a rough implementation of a Spring BeanPostProcessor which provides dependency injection
of Camel types (Endpoints and Producers) together with a @MessageDriven injection point for
binding POJOs to consumers

Added:
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Body.java   (with props)
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Header.java   (with props)
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Property.java   (with props)
    activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java
  (with props)
    activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/
    activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/BeanInfo.java
  (with props)
    activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/DefaultMethodInvocationStrategy.java
  (with props)
    activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/MethodInfo.java
  (with props)
    activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/MethodInvocationStrategy.java
  (with props)
    activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/ReflectionUtils.java
  (with props)
Modified:
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Body.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Body.java?view=auto&rev=535384
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Body.java (added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Body.java Fri May  4 14:26:16
2007
@@ -0,0 +1,33 @@
+/**
+ *
+ * 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.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * Marks a parameter as being the body of an inbound {@link Message}
+ *
+ * @version $Revision: 523756 $
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface Body {
+}

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

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Header.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Header.java?view=auto&rev=535384
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Header.java (added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Header.java Fri May  4
14:26:16 2007
@@ -0,0 +1,34 @@
+/**
+ *
+ * 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.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * Marks a parameter as being a header on an inbound {@link Message}
+ *
+ * @version $Revision: 523756 $
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface Header {
+    String name();
+}

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

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Property.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Property.java?view=auto&rev=535384
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Property.java (added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Property.java Fri May 
4 14:26:16 2007
@@ -0,0 +1,34 @@
+/**
+ *
+ * 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.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * Marks a parameter as being a property on an {@link Exchange}
+ *
+ * @version $Revision: 523756 $
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface Property {
+    String name();
+}

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

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java?view=diff&rev=535384&r1=535383&r2=535384
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java
(original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java
Fri May  4 14:26:16 2007
@@ -56,6 +56,25 @@
     }
 
     /**
+     * Returns an expression for the property value with the given name
+     *
+     * @param propertyName the name of the property the expression will return
+     * @return an expression object which will return the property value
+     */
+    public static <E extends Exchange> Expression<E> propertyExpression(final
String propertyName) {
+        return new Expression<E>() {
+            public Object evaluate(E exchange) {
+                return exchange.getProperty(propertyName);
+            }
+
+            @Override
+            public String toString() {
+                return "property(" + propertyName + ")";
+            }
+        };
+    }
+
+    /**
      * Returns an expression for the contant value
      *
      * @param value the value the expression will return
@@ -119,6 +138,38 @@
             @Override
             public String toString() {
                 return "outBody";
+            }
+        };
+    }
+
+    /**
+     * Returns the expression for the exchange
+     */
+    public static <E extends Exchange> Expression<E> exchangeExpression() {
+        return new Expression<E>() {
+            public Object evaluate(E exchange) {
+                return exchange;
+            }
+
+            @Override
+            public String toString() {
+                return "exchange";
+            }
+        };
+    }
+
+    /**
+     * Returns the expression for the IN message
+     */
+    public static <E extends Exchange> Expression<E> inMessageExpression() {
+        return new Expression<E>() {
+            public Object evaluate(E exchange) {
+                return exchange.getIn();
+            }
+
+            @Override
+            public String toString() {
+                return "inMessage";
             }
         };
     }

Added: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java?view=auto&rev=535384
==============================================================================
--- activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java
(added)
+++ activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java
Fri May  4 14:26:16 2007
@@ -0,0 +1,212 @@
+/**
+ *
+ * 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;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Producer;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.MessageDriven;
+import org.apache.camel.Processor;
+import org.apache.camel.Consumer;
+import org.apache.camel.Exchange;
+import org.apache.camel.spring.util.ReflectionUtils;
+import org.apache.camel.spring.util.BeanInfo;
+import org.apache.camel.spring.util.MethodInvocationStrategy;
+import org.apache.camel.spring.util.DefaultMethodInvocationStrategy;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.aopalliance.intercept.MethodInvocation;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+/**
+ * A post processor to perform injection of {@link Endpoint} and {@link Producer} instances
together with binding
+ * methods annotated with {@link @MessageDriven} to a Camel consumer.
+ *
+ * @version $Revision: 1.1 $
+ */
+public class CamelBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware
{
+    private static final transient Log log = LogFactory.getLog(CamelBeanPostProcessor.class);
+
+    private CamelContext camelContext;
+    private ApplicationContext applicationContext;
+    private MethodInvocationStrategy invocationStrategy = new DefaultMethodInvocationStrategy();
+
+    public CamelBeanPostProcessor(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException
{
+        injectBean(bean);
+        return bean;
+    }
+
+    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException
{
+        return bean;
+    }
+
+    // Properties
+    //-------------------------------------------------------------------------
+
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
+        this.applicationContext = applicationContext;
+    }
+
+    public MethodInvocationStrategy getInvocationStrategy() {
+        return invocationStrategy;
+    }
+
+    public void setInvocationStrategy(MethodInvocationStrategy invocationStrategy) {
+        this.invocationStrategy = invocationStrategy;
+    }
+
+    // Implementation methods
+    //-------------------------------------------------------------------------
+
+    /**
+     * A strategy method to allow implementations to perform some custom JBI based injection
of the POJO
+     *
+     * @param bean the bean to be injected
+     */
+    protected void injectBean(final Object bean) {
+        ReflectionUtils.doWithFields(bean.getClass(), new ReflectionUtils.FieldCallback()
{
+            public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException
{
+                EndpointInject annotation = field.getAnnotation(EndpointInject.class);
+                if (annotation != null) {
+                    ReflectionUtils.setField(field, bean, getEndpointInjectionValue(field,
annotation));
+                }
+            }
+        });
+    }
+
+    protected void evaluateCallbacks(final Object bean) {
+        ReflectionUtils.doWithMethods(bean.getClass(), new ReflectionUtils.MethodCallback()
{
+            @SuppressWarnings("unchecked")
+            public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException
{
+                MessageDriven annotation = method.getAnnotation(MessageDriven.class);
+                if (annotation != null) {
+                    // lets bind this method to a listener
+                    Endpoint endpoint = getEndpointInjection(annotation.uri(), annotation.name());
+                    if (endpoint != null) {
+                        try {
+                            Processor processor = createConsumerProcessor(bean, method, endpoint);
+                            Consumer consumer = endpoint.createConsumer(processor);
+                            addConsumer(consumer);
+                        }
+                        catch (Exception e) {
+                            throw new RuntimeCamelException(e);
+                        }
+                    }
+                }
+                /*
+
+                TODO support callbacks?
+
+                if (method.getAnnotation(Callback.class) != null) {
+                    try {
+                        Expression e = ExpressionFactory.createExpression(
+                                method.getAnnotation(Callback.class).condition());
+                        JexlContext jc = JexlHelper.createContext();
+                        jc.getVars().put("this", obj);
+                        Object r = e.evaluate(jc);
+                        if (!(r instanceof Boolean)) {
+                            throw new RuntimeException("Expression did not returned a boolean
value but: " + r);
+                        }
+                        Boolean oldVal = req.getCallbacks().get(method);
+                        Boolean newVal = (Boolean) r;
+                        if ((oldVal == null || !oldVal) && newVal) {
+                            req.getCallbacks().put(method, newVal);
+                            method.invoke(obj, new Object[0]);
+                            // TODO: handle return value and sent it as the answer
+                        }
+                    } catch (Exception e) {
+                        throw new RuntimeException("Unable to invoke callback", e);
+                    }
+                }
+                */
+            }
+        });
+    }
+
+    /**
+     * Create a processor which invokes the given method when an incoming message exchange
is received
+     */
+    protected Processor createConsumerProcessor(final Object pojo, final Method method, final
Endpoint endpoint) {
+        final BeanInfo beanInfo = new BeanInfo(pojo.getClass(), invocationStrategy);
+
+        return new Processor() {
+            public void process(Exchange exchange) throws Exception {
+                MethodInvocation invocation = beanInfo.createInvocation(pojo, exchange);
+                try {
+                    invocation.proceed();
+                }
+                catch (Exception e) {
+                    throw e;
+                }
+                catch (Throwable throwable) {
+                    throw new Exception(throwable);
+                }
+            }
+        };
+    }
+
+    protected void addConsumer(Consumer consumer) {
+        log.debug("Adding consumer: " + consumer);
+    }
+
+    /**
+     * Creates the value for the injection point for the given annotation
+     */
+    protected Object getEndpointInjectionValue(Field field, EndpointInject annotation) {
+        Endpoint endpoint = getEndpointInjection(annotation.uri(), annotation.name());
+        if (endpoint != null) {
+            if (field.getType().isInstance(endpoint)) {
+                return endpoint;
+            }
+            else if (field.getType().isAssignableFrom(Producer.class)) {
+                try {
+                    return endpoint.createProducer();
+                }
+                catch (Exception e) {
+                    throw new RuntimeCamelException(e);
+                }
+            }
+        }
+        return null;
+    }
+
+    protected Endpoint getEndpointInjection(String uri, String name) {
+        Endpoint endpoint = null;
+        if (uri != null) {
+            endpoint = camelContext.getEndpoint(uri);
+        }
+        else {
+            if (name != null) {
+                endpoint = (Endpoint) applicationContext.getBean(name);
+            }
+        }
+        return endpoint;
+    }
+}

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

Added: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/BeanInfo.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/BeanInfo.java?view=auto&rev=535384
==============================================================================
--- activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/BeanInfo.java
(added)
+++ activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/BeanInfo.java
Fri May  4 14:26:16 2007
@@ -0,0 +1,193 @@
+/*
+ * 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.util;
+
+import org.aopalliance.intercept.MethodInvocation;
+import org.apache.camel.Body;
+import org.apache.camel.Exchange;
+import org.apache.camel.Expression;
+import org.apache.camel.Header;
+import org.apache.camel.Property;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.builder.ExpressionBuilder;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Represents the metadata about a bean type created via a combination of
+ * introspection and annotations together with some useful sensible defaults
+ *
+ * @version $Revision: $
+ */
+public class BeanInfo {
+    private static final transient Log log = LogFactory.getLog(BeanInfo.class);
+
+    private Class type;
+    private MethodInvocationStrategy strategy;
+    private Map<String, MethodInfo> operations = new ConcurrentHashMap<String, MethodInfo>();
+    private MethodInfo defaultExpression;
+
+    public BeanInfo(Class type, MethodInvocationStrategy strategy) {
+        this.type = type;
+        this.strategy = strategy;
+    }
+
+    public Class getType() {
+        return type;
+    }
+
+    public void introspect() {
+        introspect(getType());
+        if (operations.size() == 1) {
+            Collection<MethodInfo> methodInfos = operations.values();
+            for (MethodInfo methodInfo : methodInfos) {
+                defaultExpression = methodInfo;
+            }
+        }
+    }
+
+    public MethodInvocation createInvocation(Object pojo, Exchange messageExchange) throws
RuntimeCamelException {
+        MethodInfo methodInfo = null;
+
+        // TODO use some other mechanism?
+        String name = messageExchange.getIn().getHeader("org.apache.camel.MethodName", String.class);
+        if (name != null) {
+            methodInfo = operations.get(name);
+        }
+        if (methodInfo == null) {
+            methodInfo = defaultExpression;
+        }
+        if (methodInfo != null) {
+            return methodInfo.createMethodInvocation(pojo, messageExchange);
+        }
+        return null;
+    }
+
+    protected void introspect(Class clazz) {
+        Method[] methods = clazz.getDeclaredMethods();
+        for (Method method : methods) {
+            introspect(clazz, method);
+        }
+        Class superclass = clazz.getSuperclass();
+        if (superclass != null && !superclass.equals(Object.class)) {
+            introspect(superclass);
+        }
+    }
+
+    protected void introspect(Class clazz, Method method) {
+        Class[] parameterTypes = method.getParameterTypes();
+        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+        final Expression[] parameterExpressions = new Expression[parameterTypes.length];
+        for (int i = 0; i < parameterTypes.length; i++) {
+            Class parameterType = parameterTypes[i];
+            Expression expression = createParameterUnmarshalExpression(clazz, method,
+                    parameterType, parameterAnnotations[i]);
+            if (expression == null) {
+                if (log.isDebugEnabled()) {
+                    log.debug("No expression available for method: "
+                            + method.toString() + " parameter: " + i + " so ignoring method");
+                }
+                return;
+            }
+            parameterExpressions[i] = expression;
+        }
+
+        // now lets add the method to the repository
+        String opName = method.getName();
+
+        /*
+
+        TODO allow an annotation to expose the operation name to use
+
+        if (method.getAnnotation(Operation.class) != null) {
+            String name = method.getAnnotation(Operation.class).name();
+            if (name != null && name.length() > 0) {
+                opName = name;
+            }
+        }
+        */
+        Expression parametersExpression = createMethodParametersExpression(parameterExpressions);
+        operations.put(opName, new MethodInfo(clazz, method, parametersExpression));
+    }
+
+    protected Expression createMethodParametersExpression(final Expression[] parameterExpressions)
{
+        return new Expression<Exchange>() {
+            public Object evaluate(Exchange exchange) {
+                Object[] answer = new Object[parameterExpressions.length];
+                for (int i = 0; i < parameterExpressions.length; i++) {
+                    Expression parameterExpression = parameterExpressions[i];
+                    answer[i] = parameterExpression.evaluate(exchange);
+                }
+                return answer;
+            }
+
+            @Override
+            public String toString() {
+                return "parametersExpression" + Arrays.asList(parameterExpressions);
+            }
+        };
+    }
+
+    /**
+     * Creates an expression for the given parameter type if the parameter can be mapped
+     * automatically or null if the parameter cannot be mapped due to unsufficient
+     * annotations or not fitting with the default type conventions.
+     */
+    protected Expression createParameterUnmarshalExpression(Class clazz, Method method, Class
parameterType, Annotation[] parameterAnnotation) {
+
+        // TODO look for a parameter annotation that converts into an expression
+        for (Annotation annotation : parameterAnnotation) {
+            Expression answer = createParameterUnmarshalExpressionForAnnotation(
+                    clazz, method, parameterType, annotation);
+            if (answer != null) {
+                return answer;
+            }
+        }
+        return strategy.getDefaultParameterTypeExpression(parameterType);
+    }
+
+    protected Expression createParameterUnmarshalExpressionForAnnotation(Class clazz, Method
method, Class parameterType, Annotation annotation) {
+        if (annotation instanceof Property) {
+            Property propertyAnnotation = (Property) annotation;
+            return ExpressionBuilder.propertyExpression(propertyAnnotation.name());
+        }
+        else if (annotation instanceof Header) {
+            Header headerAnnotation = (Header) annotation;
+            return ExpressionBuilder.headerExpression(headerAnnotation.name());
+        }
+        else if (annotation instanceof Body) {
+            Body content = (Body) annotation;
+            return ExpressionBuilder.bodyExpression(parameterType);
+
+            // TODO allow annotations to be used to create expressions?
+/*
+        } else if (annotation instanceof XPath) {
+            XPath xpathAnnotation = (XPath) annotation;
+            return new JAXPStringXPathExpression(xpathAnnotation.xpath());
+        }
+*/
+        }
+        return null;
+    }
+}

Propchange: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/BeanInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/DefaultMethodInvocationStrategy.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/DefaultMethodInvocationStrategy.java?view=auto&rev=535384
==============================================================================
--- activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/DefaultMethodInvocationStrategy.java
(added)
+++ activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/DefaultMethodInvocationStrategy.java
Fri May  4 14:26:16 2007
@@ -0,0 +1,72 @@
+/*
+ * 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.util;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.aopalliance.intercept.MethodInvocation;
+import org.apache.camel.Expression;
+import org.apache.camel.Exchange;
+import org.apache.camel.Endpoint;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.Message;
+import org.apache.camel.builder.ExpressionBuilder;
+
+/**
+ * Represents the strategy used to figure out how to map a message exchange to a POJO method
invocation
+ *
+ * @version $Revision:$
+ */
+public class DefaultMethodInvocationStrategy implements MethodInvocationStrategy {
+
+    private Map<Class, Expression> parameterTypeToExpressionMap = new ConcurrentHashMap<Class,
Expression>();
+
+    public DefaultMethodInvocationStrategy() {
+    }
+
+    public synchronized Expression getDefaultParameterTypeExpression(Class parameterType)
{
+        return parameterTypeToExpressionMap.get(parameterType);
+    }
+
+    /**
+     * Adds a default parameter type mapping to an expression
+     */
+    public synchronized void addParameterMapping(Class parameterType, Expression expression)
{
+        parameterTypeToExpressionMap.put(parameterType, expression);
+    }
+
+
+    /**
+     * Creates an invocation on the given POJO using annotations to decide which method to
invoke
+     * and to figure out which parameters to use
+     */
+    public MethodInvocation createInvocation(Object pojo, 
+                                             BeanInfo beanInfo, 
+                                             Exchange messageExchange,
+                                             Endpoint pojoEndpoint) throws RuntimeCamelException
{
+        return beanInfo.createInvocation(pojo, messageExchange);
+    }
+
+
+    public void loadDefaultRegistry() {
+        addParameterMapping(Exchange.class, ExpressionBuilder.exchangeExpression());
+        addParameterMapping(Message.class, ExpressionBuilder.inMessageExpression());
+    }
+
+
+}

Propchange: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/DefaultMethodInvocationStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/MethodInfo.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/MethodInfo.java?view=auto&rev=535384
==============================================================================
--- activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/MethodInfo.java
(added)
+++ activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/MethodInfo.java
Fri May  4 14:26:16 2007
@@ -0,0 +1,81 @@
+/*
+ * 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.util;
+
+import org.aopalliance.intercept.MethodInvocation;
+import org.apache.camel.Exchange;
+import org.apache.camel.Expression;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * @version $Revision: $
+ */
+public class MethodInfo {
+    private Class type;
+    private Method method;
+    private Expression parametersExpression;
+
+    public MethodInfo(Class type, Method method, Expression parametersExpression) {
+        this.type = type;
+        this.method = method;
+        this.parametersExpression = parametersExpression;
+    }
+
+    public MethodInvocation createMethodInvocation(final Object pojo, final Exchange messageExchange)
{
+        final Object[] arguments = (Object[]) parametersExpression.evaluate(messageExchange);
+        return new MethodInvocation() {
+            public Method getMethod() {
+                return method;
+            }
+
+            public Object[] getArguments() {
+                return arguments;
+            }
+
+            public Object proceed() throws Throwable {
+                return invoke(method, pojo, arguments, messageExchange);
+            }
+
+            public Object getThis() {
+                return pojo;
+            }
+
+            public AccessibleObject getStaticPart() {
+                return method;
+            }
+        };
+    }
+
+    public Class getType() {
+        return type;
+    }
+
+    public Method getMethod() {
+        return method;
+    }
+
+    public Expression getParametersExpression() {
+        return parametersExpression;
+    }
+
+    protected Object invoke(Method mth, Object pojo, Object[] arguments, Exchange exchange)
throws IllegalAccessException, InvocationTargetException {
+        return mth.invoke(pojo, arguments);
+    }
+}

Propchange: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/MethodInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/MethodInvocationStrategy.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/MethodInvocationStrategy.java?view=auto&rev=535384
==============================================================================
--- activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/MethodInvocationStrategy.java
(added)
+++ activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/MethodInvocationStrategy.java
Fri May  4 14:26:16 2007
@@ -0,0 +1,41 @@
+/*
+ * 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.util;
+
+import org.aopalliance.intercept.MethodInvocation;
+import org.apache.camel.Exchange;
+import org.apache.camel.Expression;
+import org.apache.camel.Endpoint;
+import org.apache.camel.RuntimeCamelException;
+
+/**
+ * A strategy for invoking a method on a pojo from a message exchange
+ *
+ * @version $Revision: $
+ */
+public interface MethodInvocationStrategy {
+    /**
+     * Creates an invocation on the given POJO using annotations to decide which method to
invoke
+     * and to figure out which parameters to use
+     */
+    MethodInvocation createInvocation(Object pojo, 
+                                      BeanInfo beanInfo,
+                                      Exchange messageExchange,
+                                      Endpoint pojoEndpoint) throws RuntimeCamelException;
+
+    Expression getDefaultParameterTypeExpression(Class parameterType);
+}

Propchange: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/MethodInvocationStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/ReflectionUtils.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/ReflectionUtils.java?view=auto&rev=535384
==============================================================================
--- activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/ReflectionUtils.java
(added)
+++ activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/ReflectionUtils.java
Fri May  4 14:26:16 2007
@@ -0,0 +1,69 @@
+/*
+ * 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.util;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+public class ReflectionUtils extends org.springframework.util.ReflectionUtils {
+    public static <T extends Annotation> void callLifecycleMethod(final Object bean,
final Class<T> annotation) {
+        ReflectionUtils.doWithMethods(bean.getClass(), new ReflectionUtils.MethodCallback()
{
+            public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException
{
+                if (method.getAnnotation(annotation) != null) {
+                    try {
+                        method.invoke(bean, (Object[]) null);
+                    }
+                    catch (IllegalArgumentException ex) {
+                        throw new IllegalStateException("Failure to invoke " + method + "
on "
+                                + bean.getClass() + ": args=[]", ex);
+                    }
+                    catch (IllegalAccessException ex) {
+                        throw new UnsupportedOperationException(ex.toString());
+                    }
+                    catch (InvocationTargetException ex) {
+                        throw new UnsupportedOperationException("PostConstruct method on
bean threw exception",
+                                ex.getTargetException());
+                    }
+                }
+            }
+        });
+    }
+
+    public static void setField(Field f, Object instance, Object value) {
+        try {
+            boolean oldAccessible = f.isAccessible();
+            boolean shouldSetAccessible = !Modifier.isPublic(f.getModifiers()) &&
!oldAccessible;
+            if (shouldSetAccessible) {
+                f.setAccessible(true);
+            }
+            f.set(instance, value);
+            if (shouldSetAccessible) {
+                f.setAccessible(oldAccessible);
+            }
+        }
+        catch (IllegalArgumentException ex) {
+            throw new UnsupportedOperationException("Cannot inject value of class '"
+                    + value.getClass() + "' into " + f);
+        }
+        catch (IllegalAccessException ex) {
+            ReflectionUtils.handleReflectionException(ex);
+        }
+    }
+}

Propchange: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/util/ReflectionUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message