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.NoTypeConversionAvailableException;
026 import org.apache.camel.Processor;
027 import org.apache.camel.impl.ServiceSupport;
028 import org.apache.camel.util.ObjectHelper;
029 import org.apache.camel.util.ServiceHelper;
030 import org.apache.commons.logging.Log;
031 import org.apache.commons.logging.LogFactory;
032
033 /**
034 * A {@link Processor} which converts the inbound exchange to a method
035 * invocation on a POJO
036 *
037 * @version $Revision: 750349 $
038 */
039 public class BeanProcessor extends ServiceSupport implements Processor {
040 private static final transient Log LOG = LogFactory.getLog(BeanProcessor.class);
041
042 private boolean multiParameterArray;
043 private Method methodObject;
044 private String method;
045 private BeanHolder beanHolder;
046
047 public BeanProcessor(Object pojo, BeanInfo beanInfo) {
048 this(new ConstantBeanHolder(pojo, beanInfo));
049 }
050
051 public BeanProcessor(Object pojo, CamelContext camelContext, ParameterMappingStrategy parameterMappingStrategy) {
052 this(pojo, new BeanInfo(camelContext, pojo.getClass(), parameterMappingStrategy));
053 }
054
055 public BeanProcessor(Object pojo, CamelContext camelContext) {
056 this(pojo, camelContext, BeanInfo.createParameterMappingStrategy(camelContext));
057 }
058
059 public BeanProcessor(BeanHolder beanHolder) {
060 this.beanHolder = beanHolder;
061 }
062
063 @Override
064 public String toString() {
065 String description = methodObject != null ? " " + methodObject : "";
066 return "BeanProcessor[" + beanHolder + description + "]";
067 }
068
069 public void process(Exchange exchange) throws Exception {
070 Object bean = beanHolder.getBean();
071 exchange.setProperty(Exchange.BEAN_HOLDER, beanHolder);
072
073 Processor processor = getProcessor();
074 BeanInfo beanInfo = beanHolder.getBeanInfo();
075
076 // do we have a custom adapter for this POJO to a Processor
077 if (processor != null) {
078 processor.process(exchange);
079 return;
080 }
081 Message in = exchange.getIn();
082
083 if (in.getHeader(Exchange.BEAN_MULTI_PARAMETER_ARRAY) == null) {
084 in.setHeader(Exchange.BEAN_MULTI_PARAMETER_ARRAY, isMultiParameterArray());
085 }
086
087 try {
088 BeanInvocation beanInvoke = in.getBody(BeanInvocation.class);
089 if (beanInvoke != null) {
090 beanInvoke.invoke(bean, exchange);
091 return;
092 }
093 } catch (NoTypeConversionAvailableException ex) {
094 // ignore, body is not a BeanInvocation
095 }
096
097 boolean isExplicitMethod = false;
098 String prevMethod = null;
099 MethodInvocation invocation;
100 if (methodObject != null) {
101 invocation = beanInfo.createInvocation(methodObject, bean, exchange);
102 } else {
103 // we just override the bean's invocation method name here
104 if (ObjectHelper.isNotEmpty(method)) {
105 prevMethod = in.getHeader(Exchange.BEAN_METHOD_NAME, String.class);
106 in.setHeader(Exchange.BEAN_METHOD_NAME, method);
107 isExplicitMethod = true;
108 }
109 invocation = beanInfo.createInvocation(bean, exchange);
110 }
111 if (invocation == null) {
112 throw new IllegalStateException(
113 "No method invocation could be created, no maching method could be found on: " + bean);
114 }
115 try {
116 Object value = invocation.proceed();
117 if (value != null) {
118 if (exchange.getPattern().isOutCapable()) {
119 // force out creating if not already created (as its lazy)
120 if (LOG.isDebugEnabled()) {
121 LOG.debug("Setting bean invocation result on the OUT message: " + value);
122 }
123 exchange.getOut(true).setBody(value);
124 } else {
125 // if not out then set it on the in
126 if (LOG.isDebugEnabled()) {
127 LOG.debug("Setting bean invocation result on the IN message: " + value);
128 }
129 exchange.getIn().setBody(value);
130 }
131 }
132 } catch (InvocationTargetException e) {
133 // lets unwrap the exception
134 Throwable throwable = e.getCause();
135 if (throwable instanceof Exception) {
136 Exception exception = (Exception)throwable;
137 throw exception;
138 } else {
139 Error error = (Error)throwable;
140 throw error;
141 }
142 } finally {
143 if (isExplicitMethod) {
144 in.setHeader(Exchange.BEAN_METHOD_NAME, prevMethod);
145 }
146 }
147 }
148
149 protected Processor getProcessor() {
150 return beanHolder.getProcessor();
151 }
152
153 // Properties
154 // -----------------------------------------------------------------------
155
156 public Method getMethodObject() {
157 return methodObject;
158 }
159
160 public void setMethodObject(Method methodObject) {
161 this.methodObject = methodObject;
162 }
163
164 public String getMethod() {
165 return method;
166 }
167
168 public boolean isMultiParameterArray() {
169 return multiParameterArray;
170 }
171
172 public void setMultiParameterArray(boolean mpArray) {
173 multiParameterArray = mpArray;
174 }
175
176 /**
177 * Sets the method name to use
178 */
179 public void setMethod(String method) {
180 this.method = method;
181 }
182
183 // Implementation methods
184 //-------------------------------------------------------------------------
185 protected void doStart() throws Exception {
186 ServiceHelper.startService(getProcessor());
187 }
188
189 protected void doStop() throws Exception {
190 ServiceHelper.stopService(getProcessor());
191 }
192 }