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.impl;
018
019 import java.lang.reflect.Method;
020
021 import javax.xml.bind.annotation.XmlTransient;
022
023 import org.apache.camel.CamelContext;
024 import org.apache.camel.CamelContextAware;
025 import org.apache.camel.Consume;
026 import org.apache.camel.Consumer;
027 import org.apache.camel.ConsumerTemplate;
028 import org.apache.camel.Endpoint;
029 import org.apache.camel.PollingConsumer;
030 import org.apache.camel.Processor;
031 import org.apache.camel.Producer;
032 import org.apache.camel.ProducerTemplate;
033 import org.apache.camel.Service;
034 import org.apache.camel.component.bean.BeanProcessor;
035 import org.apache.camel.component.bean.ProxyHelper;
036 import org.apache.camel.util.CamelContextHelper;
037 import org.apache.camel.util.ObjectHelper;
038 import org.apache.commons.logging.Log;
039 import org.apache.commons.logging.LogFactory;
040
041 /**
042 * A helper class for Camel based injector or post processing hooks which can be reused by
043 * both the <a href="http://camel.apache.org/spring.html">Spring</a>
044 * and <a href="http://camel.apache.org/guice.html">Guice</a> support.
045 *
046 * @version $Revision: 835732 $
047 */
048 public class CamelPostProcessorHelper implements CamelContextAware {
049 private static final transient Log LOG = LogFactory.getLog(CamelPostProcessorHelper.class);
050
051 @XmlTransient
052 private CamelContext camelContext;
053
054 public CamelPostProcessorHelper() {
055 }
056
057 public CamelPostProcessorHelper(CamelContext camelContext) {
058 this.setCamelContext(camelContext);
059 }
060
061 public CamelContext getCamelContext() {
062 return camelContext;
063 }
064
065 public void setCamelContext(CamelContext camelContext) {
066 this.camelContext = camelContext;
067 }
068
069 /**
070 * Does the given context match this camel context
071 */
072 public boolean matchContext(String context) {
073 if (ObjectHelper.isNotEmpty(context)) {
074 if (!camelContext.getName().equals(context)) {
075 return false;
076 }
077 }
078 return true;
079 }
080
081 public void consumerInjection(Method method, Object bean) {
082 Consume consume = method.getAnnotation(Consume.class);
083 if (consume != null && matchContext(consume.context())) {
084 LOG.info("Creating a consumer for: " + consume);
085 subscribeMethod(method, bean, consume.uri(), consume.ref());
086 }
087 }
088
089 public void subscribeMethod(Method method, Object bean, String endpointUri, String endpointName) {
090 // lets bind this method to a listener
091 String injectionPointName = method.getName();
092 Endpoint endpoint = getEndpointInjection(endpointUri, endpointName, injectionPointName, true);
093 if (endpoint != null) {
094 try {
095 Processor processor = createConsumerProcessor(bean, method, endpoint);
096 Consumer consumer = endpoint.createConsumer(processor);
097 if (LOG.isDebugEnabled()) {
098 LOG.debug("Created processor: " + processor + " for consumer: " + consumer);
099 }
100 startService(consumer);
101 } catch (Exception e) {
102 throw ObjectHelper.wrapRuntimeCamelException(e);
103 }
104 }
105 }
106
107 /**
108 * Stats the given service
109 */
110 protected void startService(Service service) throws Exception {
111 getCamelContext().addService(service);
112 }
113
114 /**
115 * Create a processor which invokes the given method when an incoming
116 * message exchange is received
117 */
118 protected Processor createConsumerProcessor(final Object pojo, final Method method, final Endpoint endpoint) {
119 BeanProcessor answer = new BeanProcessor(pojo, getCamelContext());
120 answer.setMethodObject(method);
121 return answer;
122 }
123
124 protected Endpoint getEndpointInjection(String uri, String name, String injectionPointName, boolean mandatory) {
125 return CamelContextHelper.getEndpointInjection(getCamelContext(), uri, name, injectionPointName, mandatory);
126 }
127
128 /**
129 * Creates the object to be injected for an {@link org.apache.camel.EndpointInject} or {@link org.apache.camel.Produce} injection point
130 */
131 @SuppressWarnings("unchecked")
132 public Object getInjectionValue(Class<?> type, String endpointUri, String endpointRef, String injectionPointName) {
133 if (type.isAssignableFrom(ProducerTemplate.class)) {
134 return createInjectionProducerTemplate(endpointUri, endpointRef, injectionPointName);
135 } else if (type.isAssignableFrom(ConsumerTemplate.class)) {
136 return createInjectionConsumerTemplate(endpointUri, endpointRef, injectionPointName);
137 } else {
138 Endpoint endpoint = getEndpointInjection(endpointUri, endpointRef, injectionPointName, true);
139 if (endpoint != null) {
140 if (type.isInstance(endpoint)) {
141 return endpoint;
142 } else if (type.isAssignableFrom(Producer.class)) {
143 return createInjectionProducer(endpoint);
144 } else if (type.isAssignableFrom(PollingConsumer.class)) {
145 return createInjectionPollingConsumer(endpoint);
146 } else if (type.isInterface()) {
147 // lets create a proxy
148 try {
149 return ProxyHelper.createProxy(endpoint, type);
150 } catch (Exception e) {
151 throw createProxyInstantiationRuntimeException(type, endpoint, e);
152 }
153 } else {
154 throw new IllegalArgumentException("Invalid type: " + type.getName()
155 + " which cannot be injected via @EndpointInject/@Produce for: " + endpoint);
156 }
157 }
158 return null;
159 }
160 }
161
162 /**
163 * Factory method to create a {@link org.apache.camel.ProducerTemplate} to be injected into a POJO
164 */
165 protected ProducerTemplate createInjectionProducerTemplate(String endpointUri, String endpointRef, String injectionPointName) {
166 // endpoint is optional for this injection point
167 Endpoint endpoint = getEndpointInjection(endpointUri, endpointRef, injectionPointName, false);
168 return new DefaultProducerTemplate(getCamelContext(), endpoint);
169 }
170
171 /**
172 * Factory method to create a {@link org.apache.camel.ConsumerTemplate} to be injected into a POJO
173 */
174 protected ConsumerTemplate createInjectionConsumerTemplate(String endpointUri, String endpointRef, String injectionPointName) {
175 return new DefaultConsumerTemplate(getCamelContext());
176 }
177
178 /**
179 * Factory method to create a started {@link org.apache.camel.PollingConsumer} to be injected into a POJO
180 */
181 protected PollingConsumer createInjectionPollingConsumer(Endpoint endpoint) {
182 try {
183 PollingConsumer pollingConsumer = endpoint.createPollingConsumer();
184 startService(pollingConsumer);
185 return pollingConsumer;
186 } catch (Exception e) {
187 throw ObjectHelper.wrapRuntimeCamelException(e);
188 }
189 }
190
191 /**
192 * A Factory method to create a started {@link org.apache.camel.Producer} to be injected into a POJO
193 */
194 protected Producer createInjectionProducer(Endpoint endpoint) {
195 try {
196 Producer producer = endpoint.createProducer();
197 startService(producer);
198 return producer;
199 } catch (Exception e) {
200 throw ObjectHelper.wrapRuntimeCamelException(e);
201 }
202 }
203
204 protected RuntimeException createProxyInstantiationRuntimeException(Class<?> type, Endpoint endpoint, Exception e) {
205 return new ProxyInstantiationException(type, endpoint, e);
206 }
207 }