001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.component.bean;
018
019 import java.lang.reflect.InvocationTargetException;
020 import java.lang.reflect.Method;
021
022 import org.apache.camel.CamelContext;
023 import org.apache.camel.Exchange;
024 import org.apache.camel.Message;
025 import org.apache.camel.Processor;
026 import org.apache.camel.impl.ServiceSupport;
027 import org.apache.camel.util.ObjectHelper;
028 import org.apache.camel.util.ServiceHelper;
029 import org.apache.commons.logging.Log;
030 import org.apache.commons.logging.LogFactory;
031
032 /**
033 * A {@link Processor} which converts the inbound exchange to a method
034 * invocation on a POJO
035 *
036 * @version $Revision: 790052 $
037 */
038 public class BeanProcessor extends ServiceSupport implements Processor {
039 private static final transient Log LOG = LogFactory.getLog(BeanProcessor.class);
040
041 private boolean multiParameterArray;
042 private Method methodObject;
043 private String method;
044 private BeanHolder beanHolder;
045
046 public BeanProcessor(Object pojo, BeanInfo beanInfo) {
047 this(new ConstantBeanHolder(pojo, beanInfo));
048 }
049
050 public BeanProcessor(Object pojo, CamelContext camelContext, ParameterMappingStrategy parameterMappingStrategy) {
051 this(pojo, new BeanInfo(camelContext, pojo.getClass(), parameterMappingStrategy));
052 }
053
054 public BeanProcessor(Object pojo, CamelContext camelContext) {
055 this(pojo, camelContext, BeanInfo.createParameterMappingStrategy(camelContext));
056 }
057
058 public BeanProcessor(BeanHolder beanHolder) {
059 this.beanHolder = beanHolder;
060 }
061
062 @Override
063 public String toString() {
064 String description = methodObject != null ? " " + methodObject : "";
065 return "BeanProcessor[" + beanHolder + description + "]";
066 }
067
068 public void process(Exchange exchange) throws Exception {
069 Object bean = beanHolder.getBean();
070 exchange.setProperty(Exchange.BEAN_HOLDER, beanHolder);
071
072 Processor processor = getProcessor();
073 BeanInfo beanInfo = beanHolder.getBeanInfo();
074
075 // do we have a custom adapter for this POJO to a Processor
076 if (processor != null) {
077 processor.process(exchange);
078 return;
079 }
080 Message in = exchange.getIn();
081
082 if (in.getHeader(Exchange.BEAN_MULTI_PARAMETER_ARRAY) == null) {
083 in.setHeader(Exchange.BEAN_MULTI_PARAMETER_ARRAY, isMultiParameterArray());
084 }
085
086 BeanInvocation beanInvoke = in.getBody(BeanInvocation.class);
087 if (beanInvoke != null) {
088 beanInvoke.invoke(bean, exchange);
089 return;
090 }
091
092 boolean isExplicitMethod = false;
093 String prevMethod = null;
094 MethodInvocation invocation;
095 if (methodObject != null) {
096 invocation = beanInfo.createInvocation(methodObject, bean, exchange);
097 } else {
098 // we just override the bean's invocation method name here
099 if (ObjectHelper.isNotEmpty(method)) {
100 prevMethod = in.getHeader(Exchange.BEAN_METHOD_NAME, String.class);
101 in.setHeader(Exchange.BEAN_METHOD_NAME, method);
102 isExplicitMethod = true;
103 }
104 invocation = beanInfo.createInvocation(bean, exchange);
105 }
106 if (invocation == null) {
107 throw new IllegalStateException(
108 "No method invocation could be created, no maching method could be found on: " + bean);
109 } else {
110 // set method name if not explicit given
111 if (method == null) {
112 method = invocation.getMethod().getName();
113 }
114 }
115
116 Object value = null;
117 try {
118 value = invocation.proceed();
119 } catch (InvocationTargetException e) {
120 // lets unwrap the exception
121 Throwable throwable = e.getCause();
122 if (throwable instanceof Exception) {
123 Exception exception = (Exception)throwable;
124 throw exception;
125 } else {
126 Error error = (Error)throwable;
127 throw error;
128 }
129 } finally {
130 if (isExplicitMethod) {
131 in.setHeader(Exchange.BEAN_METHOD_NAME, prevMethod);
132 }
133 }
134
135 if (value != null) {
136 if (exchange.getPattern().isOutCapable()) {
137 // force out creating if not already created (as its lazy)
138 if (LOG.isDebugEnabled()) {
139 LOG.debug("Setting bean invocation result on the OUT message: " + value);
140 }
141 exchange.getOut().setBody(value);
142 // propagate headers
143 exchange.getOut().getHeaders().putAll(exchange.getIn().getHeaders());
144 } else {
145 // if not out then set it on the in
146 if (LOG.isDebugEnabled()) {
147 LOG.debug("Setting bean invocation result on the IN message: " + value);
148 }
149 exchange.getIn().setBody(value);
150 }
151 }
152 }
153
154 protected Processor getProcessor() {
155 return beanHolder.getProcessor();
156 }
157
158 // Properties
159 // -----------------------------------------------------------------------
160
161 public Method getMethodObject() {
162 return methodObject;
163 }
164
165 public void setMethodObject(Method methodObject) {
166 this.methodObject = methodObject;
167 }
168
169 public String getMethod() {
170 return method;
171 }
172
173 public boolean isMultiParameterArray() {
174 return multiParameterArray;
175 }
176
177 public void setMultiParameterArray(boolean mpArray) {
178 multiParameterArray = mpArray;
179 }
180
181 /**
182 * Sets the method name to use
183 */
184 public void setMethod(String method) {
185 this.method = method;
186 }
187
188 // Implementation methods
189 //-------------------------------------------------------------------------
190 protected void doStart() throws Exception {
191 ServiceHelper.startService(getProcessor());
192 }
193
194 protected void doStop() throws Exception {
195 ServiceHelper.stopService(getProcessor());
196 }
197 }