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 [EMAIL PROTECTED] Message}
+ *
+ * @version $Revision: 523756 $
+ */
[EMAIL PROTECTED](RetentionPolicy.RUNTIME)
[EMAIL PROTECTED]({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 [EMAIL PROTECTED] Message}
+ *
+ * @version $Revision: 523756 $
+ */
[EMAIL PROTECTED](RetentionPolicy.RUNTIME)
[EMAIL PROTECTED]({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 [EMAIL PROTECTED] Exchange}
+ *
+ * @version $Revision: 523756 $
+ */
[EMAIL PROTECTED](RetentionPolicy.RUNTIME)
[EMAIL PROTECTED]({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 [EMAIL PROTECTED] Endpoint} and
[EMAIL PROTECTED] Producer} instances together with binding
+ * methods annotated with [EMAIL PROTECTED] @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