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.blueprint;
018
019 import java.text.Collator;
020 import java.util.ArrayList;
021 import java.util.Collection;
022 import java.util.HashMap;
023 import java.util.LinkedHashMap;
024 import java.util.List;
025 import java.util.Map;
026
027 import javax.xml.bind.annotation.XmlAccessType;
028 import javax.xml.bind.annotation.XmlAccessorType;
029 import javax.xml.bind.annotation.XmlAttribute;
030 import javax.xml.bind.annotation.XmlElement;
031 import javax.xml.bind.annotation.XmlElements;
032 import javax.xml.bind.annotation.XmlRootElement;
033 import javax.xml.bind.annotation.XmlTransient;
034
035 import org.apache.aries.blueprint.ExtendedBlueprintContainer;
036 import org.apache.camel.RoutesBuilder;
037 import org.apache.camel.ShutdownRoute;
038 import org.apache.camel.ShutdownRunningTask;
039 import org.apache.camel.builder.RouteBuilder;
040 import org.apache.camel.core.osgi.OsgiCamelContextPublisher;
041 import org.apache.camel.core.osgi.OsgiEventAdminNotifier;
042 import org.apache.camel.core.osgi.utils.BundleDelegatingClassLoader;
043 import org.apache.camel.core.xml.AbstractCamelContextFactoryBean;
044 import org.apache.camel.core.xml.CamelJMXAgentDefinition;
045 import org.apache.camel.core.xml.CamelPropertyPlaceholderDefinition;
046 import org.apache.camel.core.xml.CamelProxyFactoryDefinition;
047 import org.apache.camel.core.xml.CamelServiceExporterDefinition;
048 import org.apache.camel.model.ContextScanDefinition;
049 import org.apache.camel.model.InterceptDefinition;
050 import org.apache.camel.model.InterceptFromDefinition;
051 import org.apache.camel.model.InterceptSendToEndpointDefinition;
052 import org.apache.camel.model.OnCompletionDefinition;
053 import org.apache.camel.model.OnExceptionDefinition;
054 import org.apache.camel.model.PackageScanDefinition;
055 import org.apache.camel.model.RouteBuilderDefinition;
056 import org.apache.camel.model.RouteContextRefDefinition;
057 import org.apache.camel.model.RouteDefinition;
058 import org.apache.camel.model.ThreadPoolProfileDefinition;
059 import org.apache.camel.model.config.PropertiesDefinition;
060 import org.apache.camel.model.dataformat.DataFormatsDefinition;
061 import org.apache.camel.spi.PackageScanFilter;
062 import org.apache.camel.spi.Registry;
063 import org.apache.commons.logging.Log;
064 import org.apache.commons.logging.LogFactory;
065 import org.osgi.framework.BundleContext;
066 import org.osgi.service.blueprint.container.BlueprintContainer;
067 import org.osgi.service.blueprint.reflect.BeanMetadata;
068 import org.osgi.service.blueprint.reflect.ComponentMetadata;
069 import org.osgi.service.blueprint.reflect.ReferenceMetadata;
070
071 /**
072 * A bean to create and initialize a {@link BlueprintCamelContext}
073 * and install routes either explicitly configured in
074 * Blueprint XML or found by searching the classpath for Java classes which extend
075 * {@link RouteBuilder} using the nested {@link #setPackages(String[])}.
076 *
077 * @version $Revision: 1051031 $
078 */
079 @XmlRootElement(name = "camelContext")
080 @XmlAccessorType(XmlAccessType.FIELD)
081 public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<BlueprintCamelContext> {
082 private static final Log LOG = LogFactory.getLog(CamelContextFactoryBean.class);
083
084 @XmlAttribute(name = "depends-on", required = false)
085 private String dependsOn;
086 @XmlAttribute(required = false)
087 private String trace;
088 @XmlAttribute(required = false)
089 private String streamCache = "false";
090 @XmlAttribute(required = false)
091 private String delayer;
092 @XmlAttribute(required = false)
093 private String handleFault;
094 @XmlAttribute(required = false)
095 private String errorHandlerRef;
096 @XmlAttribute(required = false)
097 private String autoStartup = "true";
098 @XmlAttribute(required = false)
099 private ShutdownRoute shutdownRoute;
100 @XmlAttribute(required = false)
101 private ShutdownRunningTask shutdownRunningTask;
102 @XmlAttribute(required = false)
103 private Boolean lazyLoadTypeConverters = Boolean.FALSE;
104 @XmlElement(name = "properties", required = false)
105 private PropertiesDefinition properties;
106 @XmlElement(name = "propertyPlaceholder", type = CamelPropertyPlaceholderDefinition.class, required = false)
107 private CamelPropertyPlaceholderDefinition camelPropertyPlaceholder;
108 @XmlElement(name = "package", required = false)
109 private String[] packages = {};
110 @XmlElement(name = "packageScan", type = PackageScanDefinition.class, required = false)
111 private PackageScanDefinition packageScan;
112 @XmlElement(name = "contextScan", type = ContextScanDefinition.class, required = false)
113 private ContextScanDefinition contextScan;
114 @XmlElement(name = "jmxAgent", type = CamelJMXAgentDefinition.class, required = false)
115 private CamelJMXAgentDefinition camelJMXAgent;
116 @XmlElements({
117 @XmlElement(name = "template", type = CamelProducerTemplateFactoryBean.class, required = false),
118 @XmlElement(name = "consumerTemplate", type = CamelConsumerTemplateFactoryBean.class, required = false),
119 @XmlElement(name = "proxy", type = CamelProxyFactoryBean.class, required = false),
120 @XmlElement(name = "export", type = CamelServiceExporterDefinition.class, required = false),
121 @XmlElement(name = "errorHandler", type = CamelErrorHandlerFactoryBean.class, required = false)
122 })
123 private List beans;
124 @XmlElement(name = "routeBuilder", required = false)
125 private List<RouteBuilderDefinition> builderRefs = new ArrayList<RouteBuilderDefinition>();
126 @XmlElement(name = "routeContextRef", required = false)
127 private List<RouteContextRefDefinition> routeRefs = new ArrayList<RouteContextRefDefinition>();
128 @XmlElement(name = "threadPoolProfile", required = false)
129 private List<ThreadPoolProfileDefinition> threadPoolProfiles;
130 @XmlElement(name = "threadPool", required = false)
131 private List<CamelThreadPoolFactoryBean> threadPools;
132 @XmlElement(name = "endpoint", required = false)
133 private List<CamelEndpointFactoryBean> endpoints;
134 @XmlElement(name = "dataFormats", required = false)
135 private DataFormatsDefinition dataFormats;
136 @XmlElement(name = "onException", required = false)
137 private List<OnExceptionDefinition> onExceptions = new ArrayList<OnExceptionDefinition>();
138 @XmlElement(name = "onCompletion", required = false)
139 private List<OnCompletionDefinition> onCompletions = new ArrayList<OnCompletionDefinition>();
140 @XmlElement(name = "intercept", required = false)
141 private List<InterceptDefinition> intercepts = new ArrayList<InterceptDefinition>();
142 @XmlElement(name = "interceptFrom", required = false)
143 private List<InterceptFromDefinition> interceptFroms = new ArrayList<InterceptFromDefinition>();
144 @XmlElement(name = "interceptSendToEndpoint", required = false)
145 private List<InterceptSendToEndpointDefinition> interceptSendToEndpoints = new ArrayList<InterceptSendToEndpointDefinition>();
146 @XmlElement(name = "route", required = false)
147 private List<RouteDefinition> routes = new ArrayList<RouteDefinition>();
148 @XmlTransient
149 private BlueprintCamelContext context;
150 @XmlTransient
151 private BlueprintContainer blueprintContainer;
152 @XmlTransient
153 private BundleContext bundleContext;
154 @XmlTransient
155 private boolean implicitId;
156
157
158 public Class getObjectType() {
159 return BlueprintCamelContext.class;
160 }
161
162 @Override
163 public BlueprintCamelContext getContext(boolean create) {
164 if (context == null && create) {
165 context = createContext();
166 if (!isImplicitId()) {
167 context.setName(getId());
168 }
169 }
170 return context;
171 }
172
173 public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
174 this.blueprintContainer = blueprintContainer;
175 }
176
177 public void setBundleContext(BundleContext bundleContext) {
178 this.bundleContext = bundleContext;
179 }
180
181 protected BlueprintCamelContext createContext() {
182 return new BlueprintCamelContext(bundleContext, blueprintContainer);
183 }
184
185 @Override
186 protected void initCustomRegistry(BlueprintCamelContext context) {
187 Registry registry = getBeanForType(Registry.class);
188 if (registry != null) {
189 LOG.info("Using custom Registry: " + registry);
190 context.setRegistry(registry);
191 }
192 }
193
194 @Override
195 protected <S> S getBeanForType(Class<S> clazz) {
196 Collection<S> objects = BlueprintContainerRegistry.lookupByType(blueprintContainer, clazz).values();
197 if (objects.size() == 1) {
198 return objects.iterator().next();
199 }
200 return null;
201 }
202
203 @Override
204 protected void initBeanPostProcessor(BlueprintCamelContext context) {
205 }
206
207 @Override
208 protected void postProcessBeforeInit(RouteBuilder builder) {
209 }
210
211 @Override
212 protected void findRouteBuildersByPackageScan(String[] packages, PackageScanFilter filter, List<RoutesBuilder> builders) throws Exception {
213 // add filter to class resolver which then will filter
214 getContext().getPackageScanClassResolver().addFilter(filter);
215 ClassLoader classLoader = new BundleDelegatingClassLoader(((ExtendedBlueprintContainer) blueprintContainer).getBundleContext().getBundle());
216 PackageScanRouteBuilderFinder finder = new PackageScanRouteBuilderFinder(getContext(), packages, classLoader,
217 /*getBeanPostProcessor(),*/ getContext().getPackageScanClassResolver());
218 finder.appendBuilders(builders);
219
220 // and remove the filter
221 getContext().getPackageScanClassResolver().removeFilter(filter);
222 }
223
224 @Override
225 protected void findRouteBuildersByContextScan(PackageScanFilter filter, List<RoutesBuilder> builders) throws Exception {
226 ContextScanRouteBuilderFinder finder = new ContextScanRouteBuilderFinder(getContext(), filter);
227 finder.appendBuilders(builders);
228 }
229
230 @Override
231 public void afterPropertiesSet() throws Exception {
232 super.afterPropertiesSet();
233 getContext().getManagementStrategy().addEventNotifier(new OsgiCamelContextPublisher(bundleContext));
234 try {
235 getClass().getClassLoader().loadClass("org.osgi.service.event.EventAdmin");
236 getContext().getManagementStrategy().addEventNotifier(new OsgiEventAdminNotifier(bundleContext));
237 } catch (Throwable t) {
238 // Ignore, if the EventAdmin package is not available, just don't use it
239 LOG.debug("EventAdmin package is not available, just don't use it");
240 }
241 }
242
243 public String getDependsOn() {
244 return dependsOn;
245 }
246
247 public void setDependsOn(String dependsOn) {
248 this.dependsOn = dependsOn;
249 }
250
251 public String getAutoStartup() {
252 return autoStartup;
253 }
254
255 public void setAutoStartup(String autoStartup) {
256 this.autoStartup = autoStartup;
257 }
258
259 public Boolean getLazyLoadTypeConverters() {
260 return lazyLoadTypeConverters;
261 }
262
263 public void setLazyLoadTypeConverters(Boolean lazyLoadTypeConverters) {
264 this.lazyLoadTypeConverters = lazyLoadTypeConverters;
265 }
266
267 public ShutdownRoute getShutdownRoute() {
268 return shutdownRoute;
269 }
270
271 public void setShutdownRoute(ShutdownRoute shutdownRoute) {
272 this.shutdownRoute = shutdownRoute;
273 }
274
275 public ShutdownRunningTask getShutdownRunningTask() {
276 return shutdownRunningTask;
277 }
278
279 public void setShutdownRunningTask(ShutdownRunningTask shutdownRunningTask) {
280 this.shutdownRunningTask = shutdownRunningTask;
281 }
282
283 public CamelPropertyPlaceholderDefinition getCamelPropertyPlaceholder() {
284 return camelPropertyPlaceholder;
285 }
286
287 public void setCamelPropertyPlaceholder(CamelPropertyPlaceholderDefinition camelPropertyPlaceholder) {
288 this.camelPropertyPlaceholder = camelPropertyPlaceholder;
289 }
290
291 public List<RouteContextRefDefinition> getRouteRefs() {
292 return routeRefs;
293 }
294
295 public void setRouteRefs(List<RouteContextRefDefinition> routeRefs) {
296 this.routeRefs = routeRefs;
297 }
298
299 public List<ThreadPoolProfileDefinition> getThreadPoolProfiles() {
300 return threadPoolProfiles;
301 }
302
303 public void setThreadPoolProfiles(List<ThreadPoolProfileDefinition> threadPoolProfiles) {
304 this.threadPoolProfiles = threadPoolProfiles;
305 }
306
307 public List<CamelThreadPoolFactoryBean> getThreadPools() {
308 return threadPools;
309 }
310
311 public void setThreadPools(List<CamelThreadPoolFactoryBean> threadPools) {
312 this.threadPools = threadPools;
313 }
314
315 public String getTrace() {
316 return trace;
317 }
318
319 public void setTrace(String trace) {
320 this.trace = trace;
321 }
322
323 public String getStreamCache() {
324 return streamCache;
325 }
326
327 public void setStreamCache(String streamCache) {
328 this.streamCache = streamCache;
329 }
330
331 public String getDelayer() {
332 return delayer;
333 }
334
335 public void setDelayer(String delayer) {
336 this.delayer = delayer;
337 }
338
339 public String getHandleFault() {
340 return handleFault;
341 }
342
343 public void setHandleFault(String handleFault) {
344 this.handleFault = handleFault;
345 }
346
347 public String getErrorHandlerRef() {
348 return errorHandlerRef;
349 }
350
351 public void setErrorHandlerRef(String errorHandlerRef) {
352 this.errorHandlerRef = errorHandlerRef;
353 }
354
355 public PropertiesDefinition getProperties() {
356 return properties;
357 }
358
359 public void setProperties(PropertiesDefinition properties) {
360 this.properties = properties;
361 }
362
363 public String[] getPackages() {
364 return packages;
365 }
366
367 public void setPackages(String[] packages) {
368 this.packages = packages;
369 }
370
371 public PackageScanDefinition getPackageScan() {
372 return packageScan;
373 }
374
375 public void setPackageScan(PackageScanDefinition packageScan) {
376 this.packageScan = packageScan;
377 }
378
379 public ContextScanDefinition getContextScan() {
380 return contextScan;
381 }
382
383 public void setContextScan(ContextScanDefinition contextScan) {
384 this.contextScan = contextScan;
385 }
386
387 public CamelJMXAgentDefinition getCamelJMXAgent() {
388 return camelJMXAgent;
389 }
390
391 public void setCamelJMXAgent(CamelJMXAgentDefinition camelJMXAgent) {
392 this.camelJMXAgent = camelJMXAgent;
393 }
394
395 public List getBeans() {
396 return beans;
397 }
398
399 public void setBeans(List beans) {
400 this.beans = beans;
401 }
402
403 public List<RouteBuilderDefinition> getBuilderRefs() {
404 return builderRefs;
405 }
406
407 public void setBuilderRefs(List<RouteBuilderDefinition> builderRefs) {
408 this.builderRefs = builderRefs;
409 }
410
411 public List<CamelEndpointFactoryBean> getEndpoints() {
412 return endpoints;
413 }
414
415 public void setEndpoints(List<CamelEndpointFactoryBean> endpoints) {
416 this.endpoints = endpoints;
417 }
418
419 public DataFormatsDefinition getDataFormats() {
420 return dataFormats;
421 }
422
423 public void setDataFormats(DataFormatsDefinition dataFormats) {
424 this.dataFormats = dataFormats;
425 }
426
427 public List<OnExceptionDefinition> getOnExceptions() {
428 return onExceptions;
429 }
430
431 public void setOnExceptions(List<OnExceptionDefinition> onExceptions) {
432 this.onExceptions = onExceptions;
433 }
434
435 public List<OnCompletionDefinition> getOnCompletions() {
436 return onCompletions;
437 }
438
439 public void setOnCompletions(List<OnCompletionDefinition> onCompletions) {
440 this.onCompletions = onCompletions;
441 }
442
443 public List<InterceptDefinition> getIntercepts() {
444 return intercepts;
445 }
446
447 public void setIntercepts(List<InterceptDefinition> intercepts) {
448 this.intercepts = intercepts;
449 }
450
451 public List<InterceptFromDefinition> getInterceptFroms() {
452 return interceptFroms;
453 }
454
455 public void setInterceptFroms(List<InterceptFromDefinition> interceptFroms) {
456 this.interceptFroms = interceptFroms;
457 }
458
459 public List<InterceptSendToEndpointDefinition> getInterceptSendToEndpoints() {
460 return interceptSendToEndpoints;
461 }
462
463 public void setInterceptSendToEndpoints(List<InterceptSendToEndpointDefinition> interceptSendToEndpoints) {
464 this.interceptSendToEndpoints = interceptSendToEndpoints;
465 }
466
467 public List<RouteDefinition> getRoutes() {
468 return routes;
469 }
470
471 public void setRoutes(List<RouteDefinition> routes) {
472 this.routes = routes;
473 }
474
475 public boolean isImplicitId() {
476 return implicitId;
477 }
478
479 public void setImplicitId(boolean flag) {
480 implicitId = flag;
481 }
482
483 }