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 */ 017package org.apache.camel.blueprint.handler; 018 019import java.lang.reflect.Field; 020import java.lang.reflect.Method; 021import java.lang.reflect.Modifier; 022import java.net.URI; 023import java.net.URISyntaxException; 024import java.net.URL; 025import java.util.Arrays; 026import java.util.HashSet; 027import java.util.List; 028import java.util.Map; 029import java.util.Set; 030import java.util.concurrent.Callable; 031import javax.xml.bind.Binder; 032import javax.xml.bind.JAXBContext; 033import javax.xml.bind.JAXBException; 034 035import org.w3c.dom.Document; 036import org.w3c.dom.Element; 037import org.w3c.dom.NamedNodeMap; 038import org.w3c.dom.Node; 039import org.w3c.dom.NodeList; 040 041import org.apache.aries.blueprint.BeanProcessor; 042import org.apache.aries.blueprint.ComponentDefinitionRegistry; 043import org.apache.aries.blueprint.ComponentDefinitionRegistryProcessor; 044import org.apache.aries.blueprint.NamespaceHandler; 045import org.apache.aries.blueprint.ParserContext; 046import org.apache.aries.blueprint.PassThroughMetadata; 047import org.apache.aries.blueprint.mutable.MutableBeanMetadata; 048import org.apache.aries.blueprint.mutable.MutablePassThroughMetadata; 049import org.apache.aries.blueprint.mutable.MutableRefMetadata; 050import org.apache.aries.blueprint.mutable.MutableReferenceMetadata; 051import org.apache.camel.BeanInject; 052import org.apache.camel.CamelContext; 053import org.apache.camel.Endpoint; 054import org.apache.camel.EndpointInject; 055import org.apache.camel.Produce; 056import org.apache.camel.PropertyInject; 057import org.apache.camel.blueprint.BlueprintCamelContext; 058import org.apache.camel.blueprint.BlueprintModelJAXBContextFactory; 059import org.apache.camel.blueprint.CamelContextFactoryBean; 060import org.apache.camel.blueprint.CamelEndpointFactoryBean; 061import org.apache.camel.blueprint.CamelRestContextFactoryBean; 062import org.apache.camel.blueprint.CamelRouteContextFactoryBean; 063import org.apache.camel.builder.xml.Namespaces; 064import org.apache.camel.component.properties.PropertiesComponent; 065import org.apache.camel.core.xml.AbstractCamelFactoryBean; 066import org.apache.camel.impl.CamelPostProcessorHelper; 067import org.apache.camel.impl.DefaultCamelContextNameStrategy; 068import org.apache.camel.model.AggregateDefinition; 069import org.apache.camel.model.CatchDefinition; 070import org.apache.camel.model.DataFormatDefinition; 071import org.apache.camel.model.ExpressionNode; 072import org.apache.camel.model.ExpressionSubElementDefinition; 073import org.apache.camel.model.FromDefinition; 074import org.apache.camel.model.MarshalDefinition; 075import org.apache.camel.model.OnExceptionDefinition; 076import org.apache.camel.model.ProcessorDefinition; 077import org.apache.camel.model.ResequenceDefinition; 078import org.apache.camel.model.RouteDefinition; 079import org.apache.camel.model.SendDefinition; 080import org.apache.camel.model.SortDefinition; 081import org.apache.camel.model.ToDefinition; 082import org.apache.camel.model.UnmarshalDefinition; 083import org.apache.camel.model.WireTapDefinition; 084import org.apache.camel.model.language.ExpressionDefinition; 085import org.apache.camel.model.rest.RestDefinition; 086import org.apache.camel.model.rest.VerbDefinition; 087import org.apache.camel.spi.CamelContextNameStrategy; 088import org.apache.camel.spi.ComponentResolver; 089import org.apache.camel.spi.DataFormatResolver; 090import org.apache.camel.spi.LanguageResolver; 091import org.apache.camel.spi.NamespaceAware; 092import org.apache.camel.util.ObjectHelper; 093import org.apache.camel.util.URISupport; 094import org.apache.camel.util.blueprint.KeyStoreParametersFactoryBean; 095import org.apache.camel.util.blueprint.SSLContextParametersFactoryBean; 096import org.apache.camel.util.blueprint.SecureRandomParametersFactoryBean; 097import org.apache.camel.util.jsse.KeyStoreParameters; 098import org.apache.camel.util.jsse.SSLContextParameters; 099import org.apache.camel.util.jsse.SecureRandomParameters; 100import org.osgi.framework.Bundle; 101import org.osgi.service.blueprint.container.BlueprintContainer; 102import org.osgi.service.blueprint.container.ComponentDefinitionException; 103import org.osgi.service.blueprint.reflect.BeanMetadata; 104import org.osgi.service.blueprint.reflect.ComponentMetadata; 105import org.osgi.service.blueprint.reflect.Metadata; 106import org.osgi.service.blueprint.reflect.RefMetadata; 107import org.slf4j.Logger; 108import org.slf4j.LoggerFactory; 109 110 111import static org.osgi.service.blueprint.reflect.ComponentMetadata.ACTIVATION_LAZY; 112import static org.osgi.service.blueprint.reflect.ServiceReferenceMetadata.AVAILABILITY_MANDATORY; 113import static org.osgi.service.blueprint.reflect.ServiceReferenceMetadata.AVAILABILITY_OPTIONAL; 114 115 116/** 117 * Camel {@link NamespaceHandler} to parse the Camel related namespaces. 118 */ 119public class CamelNamespaceHandler implements NamespaceHandler { 120 121 public static final String BLUEPRINT_NS = "http://camel.apache.org/schema/blueprint"; 122 public static final String SPRING_NS = "http://camel.apache.org/schema/spring"; 123 124 private static final String CAMEL_CONTEXT = "camelContext"; 125 private static final String ROUTE_CONTEXT = "routeContext"; 126 private static final String REST_CONTEXT = "restContext"; 127 private static final String ENDPOINT = "endpoint"; 128 private static final String KEY_STORE_PARAMETERS = "keyStoreParameters"; 129 private static final String SECURE_RANDOM_PARAMETERS = "secureRandomParameters"; 130 private static final String SSL_CONTEXT_PARAMETERS = "sslContextParameters"; 131 132 private static final Logger LOG = LoggerFactory.getLogger(CamelNamespaceHandler.class); 133 134 private JAXBContext jaxbContext; 135 136 /** 137 * Prepares the nodes before parsing. 138 */ 139 public static void doBeforeParse(Node node, String fromNamespace, String toNamespace) { 140 if (node.getNodeType() == Node.ELEMENT_NODE) { 141 Document doc = node.getOwnerDocument(); 142 if (node.getNamespaceURI().equals(fromNamespace)) { 143 doc.renameNode(node, toNamespace, node.getLocalName()); 144 } 145 146 // remove whitespace noise from uri, xxxUri attributes, eg new lines, and tabs etc, which allows end users to format 147 // their Camel routes in more human readable format, but at runtime those attributes must be trimmed 148 // the parser removes most of the noise, but keeps double spaces in the attribute values 149 NamedNodeMap map = node.getAttributes(); 150 for (int i = 0; i < map.getLength(); i++) { 151 Node att = map.item(i); 152 if (att.getNodeName().equals("uri") || att.getNodeName().endsWith("Uri")) { 153 String value = att.getNodeValue(); 154 // remove all double spaces 155 String changed = value.replaceAll("\\s{2,}", ""); 156 157 if (!value.equals(changed)) { 158 LOG.debug("Removed whitespace noise from attribute {} -> {}", value, changed); 159 att.setNodeValue(changed); 160 } 161 } 162 } 163 } 164 NodeList list = node.getChildNodes(); 165 for (int i = 0; i < list.getLength(); ++i) { 166 doBeforeParse(list.item(i), fromNamespace, toNamespace); 167 } 168 } 169 170 public URL getSchemaLocation(String namespace) { 171 return getClass().getClassLoader().getResource("camel-blueprint.xsd"); 172 } 173 174 @SuppressWarnings({"unchecked", "rawtypes"}) 175 public Set<Class> getManagedClasses() { 176 return new HashSet<Class>(Arrays.asList(BlueprintCamelContext.class)); 177 } 178 179 public Metadata parse(Element element, ParserContext context) { 180 LOG.trace("Parsing element {}", element); 181 182 try { 183 // as the camel-core model namespace is Spring we need to rename from blueprint to spring 184 doBeforeParse(element, BLUEPRINT_NS, SPRING_NS); 185 186 if (element.getLocalName().equals(CAMEL_CONTEXT)) { 187 return parseCamelContextNode(element, context); 188 } 189 if (element.getLocalName().equals(ROUTE_CONTEXT)) { 190 return parseRouteContextNode(element, context); 191 } 192 if (element.getLocalName().equals(REST_CONTEXT)) { 193 return parseRestContextNode(element, context); 194 } 195 if (element.getLocalName().equals(ENDPOINT)) { 196 return parseEndpointNode(element, context); 197 } 198 if (element.getLocalName().equals(KEY_STORE_PARAMETERS)) { 199 return parseKeyStoreParametersNode(element, context); 200 } 201 if (element.getLocalName().equals(SECURE_RANDOM_PARAMETERS)) { 202 return parseSecureRandomParametersNode(element, context); 203 } 204 if (element.getLocalName().equals(SSL_CONTEXT_PARAMETERS)) { 205 return parseSSLContextParametersNode(element, context); 206 } 207 } finally { 208 // make sure to rename back so we leave the DOM as-is 209 doBeforeParse(element, SPRING_NS, BLUEPRINT_NS); 210 } 211 212 return null; 213 } 214 215 private Metadata parseCamelContextNode(Element element, ParserContext context) { 216 LOG.trace("Parsing CamelContext {}", element); 217 // Find the id, generate one if needed 218 String contextId = element.getAttribute("id"); 219 boolean implicitId = false; 220 221 // let's avoid folks having to explicitly give an ID to a camel context 222 if (ObjectHelper.isEmpty(contextId)) { 223 // if no explicit id was set then use a default auto generated name 224 CamelContextNameStrategy strategy = new DefaultCamelContextNameStrategy(); 225 contextId = strategy.getName(); 226 element.setAttributeNS(null, "id", contextId); 227 implicitId = true; 228 } 229 230 // now let's parse the routes with JAXB 231 Binder<Node> binder; 232 try { 233 binder = getJaxbContext().createBinder(); 234 } catch (JAXBException e) { 235 throw new ComponentDefinitionException("Failed to create the JAXB binder : " + e, e); 236 } 237 Object value = parseUsingJaxb(element, context, binder); 238 if (!(value instanceof CamelContextFactoryBean)) { 239 throw new ComponentDefinitionException("Expected an instance of " + CamelContextFactoryBean.class); 240 } 241 242 CamelContextFactoryBean ccfb = (CamelContextFactoryBean) value; 243 ccfb.setImplicitId(implicitId); 244 245 // The properties component is always used / created by the CamelContextFactoryBean 246 // so we need to ensure that the resolver is ready to use 247 ComponentMetadata propertiesComponentResolver = getComponentResolverReference(context, "properties"); 248 249 MutablePassThroughMetadata factory = context.createMetadata(MutablePassThroughMetadata.class); 250 factory.setId(".camelBlueprint.passThrough." + contextId); 251 factory.setObject(new PassThroughCallable<Object>(value)); 252 253 MutableBeanMetadata factory2 = context.createMetadata(MutableBeanMetadata.class); 254 factory2.setId(".camelBlueprint.factory." + contextId); 255 factory2.setFactoryComponent(factory); 256 factory2.setFactoryMethod("call"); 257 factory2.setInitMethod("afterPropertiesSet"); 258 factory2.setDestroyMethod("destroy"); 259 factory2.addProperty("blueprintContainer", createRef(context, "blueprintContainer")); 260 factory2.addProperty("bundleContext", createRef(context, "blueprintBundleContext")); 261 factory2.addDependsOn(propertiesComponentResolver.getId()); 262 context.getComponentDefinitionRegistry().registerComponentDefinition(factory2); 263 264 MutableBeanMetadata ctx = context.createMetadata(MutableBeanMetadata.class); 265 ctx.setId(contextId); 266 ctx.setRuntimeClass(BlueprintCamelContext.class); 267 ctx.setFactoryComponent(factory2); 268 ctx.setFactoryMethod("getContext"); 269 ctx.setInitMethod("init"); 270 ctx.setDestroyMethod("destroy"); 271 272 // Register factory beans 273 registerBeans(context, contextId, ccfb.getThreadPools()); 274 registerBeans(context, contextId, ccfb.getEndpoints()); 275 registerBeans(context, contextId, ccfb.getRedeliveryPolicies()); 276 registerBeans(context, contextId, ccfb.getBeans()); 277 278 // Register processors 279 MutablePassThroughMetadata beanProcessorFactory = context.createMetadata(MutablePassThroughMetadata.class); 280 beanProcessorFactory.setId(".camelBlueprint.processor.bean.passThrough." + contextId); 281 beanProcessorFactory.setObject(new PassThroughCallable<Object>(new CamelInjector(contextId))); 282 283 MutableBeanMetadata beanProcessor = context.createMetadata(MutableBeanMetadata.class); 284 beanProcessor.setId(".camelBlueprint.processor.bean." + contextId); 285 beanProcessor.setRuntimeClass(CamelInjector.class); 286 beanProcessor.setFactoryComponent(beanProcessorFactory); 287 beanProcessor.setFactoryMethod("call"); 288 beanProcessor.setProcessor(true); 289 beanProcessor.addProperty("blueprintContainer", createRef(context, "blueprintContainer")); 290 context.getComponentDefinitionRegistry().registerComponentDefinition(beanProcessor); 291 292 MutablePassThroughMetadata regProcessorFactory = context.createMetadata(MutablePassThroughMetadata.class); 293 regProcessorFactory.setId(".camelBlueprint.processor.registry.passThrough." + contextId); 294 regProcessorFactory.setObject(new PassThroughCallable<Object>(new CamelDependenciesFinder(contextId, context))); 295 296 MutableBeanMetadata regProcessor = context.createMetadata(MutableBeanMetadata.class); 297 regProcessor.setId(".camelBlueprint.processor.registry." + contextId); 298 regProcessor.setRuntimeClass(CamelDependenciesFinder.class); 299 regProcessor.setFactoryComponent(regProcessorFactory); 300 regProcessor.setFactoryMethod("call"); 301 regProcessor.setProcessor(true); 302 regProcessor.addDependsOn(".camelBlueprint.processor.bean." + contextId); 303 regProcessor.addProperty("blueprintContainer", createRef(context, "blueprintContainer")); 304 context.getComponentDefinitionRegistry().registerComponentDefinition(regProcessor); 305 306 // lets inject the namespaces into any namespace aware POJOs 307 injectNamespaces(element, binder); 308 309 LOG.trace("Parsing CamelContext done, returning {}", ctx); 310 return ctx; 311 } 312 313 protected void injectNamespaces(Element element, Binder<Node> binder) { 314 NodeList list = element.getChildNodes(); 315 Namespaces namespaces = null; 316 int size = list.getLength(); 317 for (int i = 0; i < size; i++) { 318 Node child = list.item(i); 319 if (child instanceof Element) { 320 Element childElement = (Element) child; 321 Object object = binder.getJAXBNode(child); 322 if (object instanceof NamespaceAware) { 323 NamespaceAware namespaceAware = (NamespaceAware) object; 324 if (namespaces == null) { 325 namespaces = new Namespaces(element); 326 } 327 namespaces.configure(namespaceAware); 328 } 329 injectNamespaces(childElement, binder); 330 } 331 } 332 } 333 334 private Metadata parseRouteContextNode(Element element, ParserContext context) { 335 LOG.trace("Parsing RouteContext {}", element); 336 // now parse the routes with JAXB 337 Binder<Node> binder; 338 try { 339 binder = getJaxbContext().createBinder(); 340 } catch (JAXBException e) { 341 throw new ComponentDefinitionException("Failed to create the JAXB binder : " + e, e); 342 } 343 Object value = parseUsingJaxb(element, context, binder); 344 if (!(value instanceof CamelRouteContextFactoryBean)) { 345 throw new ComponentDefinitionException("Expected an instance of " + CamelRouteContextFactoryBean.class); 346 } 347 348 CamelRouteContextFactoryBean rcfb = (CamelRouteContextFactoryBean) value; 349 String id = rcfb.getId(); 350 351 MutablePassThroughMetadata factory = context.createMetadata(MutablePassThroughMetadata.class); 352 factory.setId(".camelBlueprint.passThrough." + id); 353 factory.setObject(new PassThroughCallable<Object>(rcfb)); 354 355 MutableBeanMetadata factory2 = context.createMetadata(MutableBeanMetadata.class); 356 factory2.setId(".camelBlueprint.factory." + id); 357 factory2.setFactoryComponent(factory); 358 factory2.setFactoryMethod("call"); 359 360 MutableBeanMetadata ctx = context.createMetadata(MutableBeanMetadata.class); 361 ctx.setId(id); 362 ctx.setRuntimeClass(List.class); 363 ctx.setFactoryComponent(factory2); 364 ctx.setFactoryMethod("getRoutes"); 365 // must be lazy as we want CamelContext to be activated first 366 ctx.setActivation(ACTIVATION_LAZY); 367 368 // lets inject the namespaces into any namespace aware POJOs 369 injectNamespaces(element, binder); 370 371 LOG.trace("Parsing RouteContext done, returning {}", element, ctx); 372 return ctx; 373 } 374 375 private Metadata parseRestContextNode(Element element, ParserContext context) { 376 LOG.trace("Parsing RestContext {}", element); 377 // now parse the rests with JAXB 378 Binder<Node> binder; 379 try { 380 binder = getJaxbContext().createBinder(); 381 } catch (JAXBException e) { 382 throw new ComponentDefinitionException("Failed to create the JAXB binder : " + e, e); 383 } 384 Object value = parseUsingJaxb(element, context, binder); 385 if (!(value instanceof CamelRestContextFactoryBean)) { 386 throw new ComponentDefinitionException("Expected an instance of " + CamelRestContextFactoryBean.class); 387 } 388 389 CamelRestContextFactoryBean rcfb = (CamelRestContextFactoryBean) value; 390 String id = rcfb.getId(); 391 392 MutablePassThroughMetadata factory = context.createMetadata(MutablePassThroughMetadata.class); 393 factory.setId(".camelBlueprint.passThrough." + id); 394 factory.setObject(new PassThroughCallable<Object>(rcfb)); 395 396 MutableBeanMetadata factory2 = context.createMetadata(MutableBeanMetadata.class); 397 factory2.setId(".camelBlueprint.factory." + id); 398 factory2.setFactoryComponent(factory); 399 factory2.setFactoryMethod("call"); 400 401 MutableBeanMetadata ctx = context.createMetadata(MutableBeanMetadata.class); 402 ctx.setId(id); 403 ctx.setRuntimeClass(List.class); 404 ctx.setFactoryComponent(factory2); 405 ctx.setFactoryMethod("getRests"); 406 // must be lazy as we want CamelContext to be activated first 407 ctx.setActivation(ACTIVATION_LAZY); 408 409 // lets inject the namespaces into any namespace aware POJOs 410 injectNamespaces(element, binder); 411 412 LOG.trace("Parsing RestContext done, returning {}", element, ctx); 413 return ctx; 414 } 415 416 private Metadata parseEndpointNode(Element element, ParserContext context) { 417 LOG.trace("Parsing Endpoint {}", element); 418 // now parse the rests with JAXB 419 Binder<Node> binder; 420 try { 421 binder = getJaxbContext().createBinder(); 422 } catch (JAXBException e) { 423 throw new ComponentDefinitionException("Failed to create the JAXB binder : " + e, e); 424 } 425 Object value = parseUsingJaxb(element, context, binder); 426 if (!(value instanceof CamelEndpointFactoryBean)) { 427 throw new ComponentDefinitionException("Expected an instance of " + CamelEndpointFactoryBean.class); 428 } 429 430 CamelEndpointFactoryBean rcfb = (CamelEndpointFactoryBean) value; 431 String id = rcfb.getId(); 432 433 MutablePassThroughMetadata factory = context.createMetadata(MutablePassThroughMetadata.class); 434 factory.setId(".camelBlueprint.passThrough." + id); 435 factory.setObject(new PassThroughCallable<Object>(rcfb)); 436 437 MutableBeanMetadata factory2 = context.createMetadata(MutableBeanMetadata.class); 438 factory2.setId(".camelBlueprint.factory." + id); 439 factory2.setFactoryComponent(factory); 440 factory2.setFactoryMethod("call"); 441 factory2.setInitMethod("afterPropertiesSet"); 442 factory2.setDestroyMethod("destroy"); 443 factory2.addProperty("blueprintContainer", createRef(context, "blueprintContainer")); 444 445 MutableBeanMetadata ctx = context.createMetadata(MutableBeanMetadata.class); 446 ctx.setId(id); 447 ctx.setRuntimeClass(Endpoint.class); 448 ctx.setFactoryComponent(factory2); 449 ctx.setFactoryMethod("getObject"); 450 // must be lazy as we want CamelContext to be activated first 451 ctx.setActivation(ACTIVATION_LAZY); 452 453 LOG.trace("Parsing endpoint done, returning {}", element, ctx); 454 return ctx; 455 } 456 457 private Metadata parseKeyStoreParametersNode(Element element, ParserContext context) { 458 LOG.trace("Parsing KeyStoreParameters {}", element); 459 // now parse the key store parameters with JAXB 460 Binder<Node> binder; 461 try { 462 binder = getJaxbContext().createBinder(); 463 } catch (JAXBException e) { 464 throw new ComponentDefinitionException("Failed to create the JAXB binder : " + e, e); 465 } 466 Object value = parseUsingJaxb(element, context, binder); 467 if (!(value instanceof KeyStoreParametersFactoryBean)) { 468 throw new ComponentDefinitionException("Expected an instance of " + KeyStoreParametersFactoryBean.class); 469 } 470 471 KeyStoreParametersFactoryBean kspfb = (KeyStoreParametersFactoryBean) value; 472 String id = kspfb.getId(); 473 474 MutablePassThroughMetadata factory = context.createMetadata(MutablePassThroughMetadata.class); 475 factory.setId(".camelBlueprint.passThrough." + id); 476 factory.setObject(new PassThroughCallable<Object>(kspfb)); 477 478 MutableBeanMetadata factory2 = context.createMetadata(MutableBeanMetadata.class); 479 factory2.setId(".camelBlueprint.factory." + id); 480 factory2.setFactoryComponent(factory); 481 factory2.setFactoryMethod("call"); 482 factory2.setInitMethod("afterPropertiesSet"); 483 factory2.setDestroyMethod("destroy"); 484 factory2.addProperty("blueprintContainer", createRef(context, "blueprintContainer")); 485 486 MutableBeanMetadata ctx = context.createMetadata(MutableBeanMetadata.class); 487 ctx.setId(id); 488 ctx.setRuntimeClass(KeyStoreParameters.class); 489 ctx.setFactoryComponent(factory2); 490 ctx.setFactoryMethod("getObject"); 491 // must be lazy as we want CamelContext to be activated first 492 ctx.setActivation(ACTIVATION_LAZY); 493 494 LOG.trace("Parsing KeyStoreParameters done, returning {}", ctx); 495 return ctx; 496 } 497 498 private Metadata parseSecureRandomParametersNode(Element element, ParserContext context) { 499 LOG.trace("Parsing SecureRandomParameters {}", element); 500 // now parse the key store parameters with JAXB 501 Binder<Node> binder; 502 try { 503 binder = getJaxbContext().createBinder(); 504 } catch (JAXBException e) { 505 throw new ComponentDefinitionException("Failed to create the JAXB binder : " + e, e); 506 } 507 Object value = parseUsingJaxb(element, context, binder); 508 if (!(value instanceof SecureRandomParametersFactoryBean)) { 509 throw new ComponentDefinitionException("Expected an instance of " + SecureRandomParametersFactoryBean.class); 510 } 511 512 SecureRandomParametersFactoryBean srfb = (SecureRandomParametersFactoryBean) value; 513 String id = srfb.getId(); 514 515 MutablePassThroughMetadata factory = context.createMetadata(MutablePassThroughMetadata.class); 516 factory.setId(".camelBlueprint.passThrough." + id); 517 factory.setObject(new PassThroughCallable<Object>(srfb)); 518 519 MutableBeanMetadata factory2 = context.createMetadata(MutableBeanMetadata.class); 520 factory2.setId(".camelBlueprint.factory." + id); 521 factory2.setFactoryComponent(factory); 522 factory2.setFactoryMethod("call"); 523 factory2.setInitMethod("afterPropertiesSet"); 524 factory2.setDestroyMethod("destroy"); 525 factory2.addProperty("blueprintContainer", createRef(context, "blueprintContainer")); 526 527 MutableBeanMetadata ctx = context.createMetadata(MutableBeanMetadata.class); 528 ctx.setId(id); 529 ctx.setRuntimeClass(SecureRandomParameters.class); 530 ctx.setFactoryComponent(factory2); 531 ctx.setFactoryMethod("getObject"); 532 // must be lazy as we want CamelContext to be activated first 533 ctx.setActivation(ACTIVATION_LAZY); 534 535 LOG.trace("Parsing SecureRandomParameters done, returning {}", ctx); 536 return ctx; 537 } 538 539 private Metadata parseSSLContextParametersNode(Element element, ParserContext context) { 540 LOG.trace("Parsing SSLContextParameters {}", element); 541 // now parse the key store parameters with JAXB 542 Binder<Node> binder; 543 try { 544 binder = getJaxbContext().createBinder(); 545 } catch (JAXBException e) { 546 throw new ComponentDefinitionException("Failed to create the JAXB binder : " + e, e); 547 } 548 Object value = parseUsingJaxb(element, context, binder); 549 if (!(value instanceof SSLContextParametersFactoryBean)) { 550 throw new ComponentDefinitionException("Expected an instance of " + SSLContextParametersFactoryBean.class); 551 } 552 553 SSLContextParametersFactoryBean scpfb = (SSLContextParametersFactoryBean) value; 554 String id = scpfb.getId(); 555 556 MutablePassThroughMetadata factory = context.createMetadata(MutablePassThroughMetadata.class); 557 factory.setId(".camelBlueprint.passThrough." + id); 558 factory.setObject(new PassThroughCallable<Object>(scpfb)); 559 560 MutableBeanMetadata factory2 = context.createMetadata(MutableBeanMetadata.class); 561 factory2.setId(".camelBlueprint.factory." + id); 562 factory2.setFactoryComponent(factory); 563 factory2.setFactoryMethod("call"); 564 factory2.setInitMethod("afterPropertiesSet"); 565 factory2.setDestroyMethod("destroy"); 566 factory2.addProperty("blueprintContainer", createRef(context, "blueprintContainer")); 567 568 MutableBeanMetadata ctx = context.createMetadata(MutableBeanMetadata.class); 569 ctx.setId(id); 570 ctx.setRuntimeClass(SSLContextParameters.class); 571 ctx.setFactoryComponent(factory2); 572 ctx.setFactoryMethod("getObject"); 573 // must be lazy as we want CamelContext to be activated first 574 ctx.setActivation(ACTIVATION_LAZY); 575 576 LOG.trace("Parsing SSLContextParameters done, returning {}", ctx); 577 return ctx; 578 } 579 580 private void registerBeans(ParserContext context, String contextId, List<?> beans) { 581 if (beans != null) { 582 for (Object bean : beans) { 583 if (bean instanceof AbstractCamelFactoryBean) { 584 registerBean(context, contextId, (AbstractCamelFactoryBean<?>) bean); 585 } 586 } 587 } 588 } 589 590 protected void registerBean(ParserContext context, String contextId, AbstractCamelFactoryBean<?> fact) { 591 String id = fact.getId(); 592 593 fact.setCamelContextId(contextId); 594 595 MutablePassThroughMetadata eff = context.createMetadata(MutablePassThroughMetadata.class); 596 eff.setId(".camelBlueprint.bean.passthrough." + id); 597 eff.setObject(new PassThroughCallable<Object>(fact)); 598 599 MutableBeanMetadata ef = context.createMetadata(MutableBeanMetadata.class); 600 ef.setId(".camelBlueprint.bean.factory." + id); 601 ef.setFactoryComponent(eff); 602 ef.setFactoryMethod("call"); 603 ef.addProperty("blueprintContainer", createRef(context, "blueprintContainer")); 604 ef.setInitMethod("afterPropertiesSet"); 605 ef.setDestroyMethod("destroy"); 606 607 MutableBeanMetadata e = context.createMetadata(MutableBeanMetadata.class); 608 e.setId(id); 609 e.setRuntimeClass(fact.getObjectType()); 610 e.setFactoryComponent(ef); 611 e.setFactoryMethod("getObject"); 612 e.addDependsOn(".camelBlueprint.processor.bean." + contextId); 613 614 context.getComponentDefinitionRegistry().registerComponentDefinition(e); 615 } 616 617 protected BlueprintContainer getBlueprintContainer(ParserContext context) { 618 PassThroughMetadata ptm = (PassThroughMetadata) context.getComponentDefinitionRegistry().getComponentDefinition("blueprintContainer"); 619 return (BlueprintContainer) ptm.getObject(); 620 } 621 622 public ComponentMetadata decorate(Node node, ComponentMetadata component, ParserContext context) { 623 return null; 624 } 625 626 protected Object parseUsingJaxb(Element element, ParserContext parserContext, Binder<Node> binder) { 627 try { 628 return binder.unmarshal(element); 629 } catch (JAXBException e) { 630 throw new ComponentDefinitionException("Failed to parse JAXB element: " + e, e); 631 } 632 } 633 634 public JAXBContext getJaxbContext() throws JAXBException { 635 if (jaxbContext == null) { 636 jaxbContext = new BlueprintModelJAXBContextFactory(getClass().getClassLoader()).newJAXBContext(); 637 } 638 return jaxbContext; 639 } 640 641 private RefMetadata createRef(ParserContext context, String value) { 642 MutableRefMetadata r = context.createMetadata(MutableRefMetadata.class); 643 r.setComponentId(value); 644 return r; 645 } 646 647 private static ComponentMetadata getDataformatResolverReference(ParserContext context, String dataformat) { 648 ComponentDefinitionRegistry componentDefinitionRegistry = context.getComponentDefinitionRegistry(); 649 ComponentMetadata cm = componentDefinitionRegistry.getComponentDefinition(".camelBlueprint.dataformatResolver." + dataformat); 650 if (cm == null) { 651 MutableReferenceMetadata svc = context.createMetadata(MutableReferenceMetadata.class); 652 svc.setId(".camelBlueprint.dataformatResolver." + dataformat); 653 svc.setFilter("(dataformat=" + dataformat + ")"); 654 svc.setAvailability(componentDefinitionRegistry.containsComponentDefinition(dataformat) ? AVAILABILITY_OPTIONAL : AVAILABILITY_MANDATORY); 655 try { 656 // Try to set the runtime interface (only with aries blueprint > 0.1 657 svc.getClass().getMethod("setRuntimeInterface", Class.class).invoke(svc, DataFormatResolver.class); 658 } catch (Throwable t) { 659 // Check if the bundle can see the class 660 try { 661 PassThroughMetadata ptm = (PassThroughMetadata) componentDefinitionRegistry.getComponentDefinition("blueprintBundle"); 662 Bundle b = (Bundle) ptm.getObject(); 663 if (b.loadClass(DataFormatResolver.class.getName()) != DataFormatResolver.class) { 664 throw new UnsupportedOperationException(); 665 } 666 svc.setInterface(DataFormatResolver.class.getName()); 667 } catch (Throwable t2) { 668 throw new UnsupportedOperationException(); 669 } 670 } 671 componentDefinitionRegistry.registerComponentDefinition(svc); 672 cm = svc; 673 } 674 return cm; 675 } 676 677 private static ComponentMetadata getLanguageResolverReference(ParserContext context, String language) { 678 ComponentDefinitionRegistry componentDefinitionRegistry = context.getComponentDefinitionRegistry(); 679 ComponentMetadata cm = componentDefinitionRegistry.getComponentDefinition(".camelBlueprint.languageResolver." + language); 680 if (cm == null) { 681 MutableReferenceMetadata svc = context.createMetadata(MutableReferenceMetadata.class); 682 svc.setId(".camelBlueprint.languageResolver." + language); 683 svc.setFilter("(language=" + language + ")"); 684 svc.setAvailability(componentDefinitionRegistry.containsComponentDefinition(language) ? AVAILABILITY_OPTIONAL : AVAILABILITY_MANDATORY); 685 try { 686 // Try to set the runtime interface (only with aries blueprint > 0.1 687 svc.getClass().getMethod("setRuntimeInterface", Class.class).invoke(svc, LanguageResolver.class); 688 } catch (Throwable t) { 689 // Check if the bundle can see the class 690 try { 691 PassThroughMetadata ptm = (PassThroughMetadata) componentDefinitionRegistry.getComponentDefinition("blueprintBundle"); 692 Bundle b = (Bundle) ptm.getObject(); 693 if (b.loadClass(LanguageResolver.class.getName()) != LanguageResolver.class) { 694 throw new UnsupportedOperationException(); 695 } 696 svc.setInterface(LanguageResolver.class.getName()); 697 } catch (Throwable t2) { 698 throw new UnsupportedOperationException(); 699 } 700 } 701 componentDefinitionRegistry.registerComponentDefinition(svc); 702 cm = svc; 703 } 704 return cm; 705 } 706 707 private static ComponentMetadata getComponentResolverReference(ParserContext context, String component) { 708 ComponentDefinitionRegistry componentDefinitionRegistry = context.getComponentDefinitionRegistry(); 709 ComponentMetadata cm = componentDefinitionRegistry.getComponentDefinition(".camelBlueprint.componentResolver." + component); 710 if (cm == null) { 711 MutableReferenceMetadata svc = context.createMetadata(MutableReferenceMetadata.class); 712 svc.setId(".camelBlueprint.componentResolver." + component); 713 svc.setFilter("(component=" + component + ")"); 714 svc.setAvailability(componentDefinitionRegistry.containsComponentDefinition(component) ? AVAILABILITY_OPTIONAL : AVAILABILITY_MANDATORY); 715 try { 716 // Try to set the runtime interface (only with aries blueprint > 0.1 717 svc.getClass().getMethod("setRuntimeInterface", Class.class).invoke(svc, ComponentResolver.class); 718 } catch (Throwable t) { 719 // Check if the bundle can see the class 720 try { 721 PassThroughMetadata ptm = (PassThroughMetadata) componentDefinitionRegistry.getComponentDefinition("blueprintBundle"); 722 Bundle b = (Bundle) ptm.getObject(); 723 if (b.loadClass(ComponentResolver.class.getName()) != ComponentResolver.class) { 724 throw new UnsupportedOperationException(); 725 } 726 svc.setInterface(ComponentResolver.class.getName()); 727 } catch (Throwable t2) { 728 throw new UnsupportedOperationException(); 729 } 730 } 731 componentDefinitionRegistry.registerComponentDefinition(svc); 732 cm = svc; 733 } 734 return cm; 735 } 736 737 public static class PassThroughCallable<T> implements Callable<T> { 738 739 private T value; 740 741 public PassThroughCallable(T value) { 742 this.value = value; 743 } 744 745 public T call() throws Exception { 746 return value; 747 } 748 } 749 750 public static class CamelInjector extends CamelPostProcessorHelper implements BeanProcessor { 751 752 private final String camelContextName; 753 private BlueprintContainer blueprintContainer; 754 755 public CamelInjector(String camelContextName) { 756 this.camelContextName = camelContextName; 757 } 758 759 public void setBlueprintContainer(BlueprintContainer blueprintContainer) { 760 this.blueprintContainer = blueprintContainer; 761 } 762 763 @Override 764 public CamelContext getCamelContext() { 765 if (blueprintContainer != null) { 766 CamelContext answer = (CamelContext) blueprintContainer.getComponentInstance(camelContextName); 767 return answer; 768 } 769 return null; 770 } 771 772 public Object beforeInit(Object bean, String beanName, BeanCreator beanCreator, BeanMetadata beanMetadata) { 773 LOG.trace("Before init of bean: {} -> {}", beanName, bean); 774 // prefer to inject later in afterInit 775 return bean; 776 } 777 778 /** 779 * A strategy method to allow implementations to perform some custom JBI 780 * based injection of the POJO 781 * 782 * @param bean the bean to be injected 783 */ 784 protected void injectFields(final Object bean, final String beanName) { 785 Class<?> clazz = bean.getClass(); 786 do { 787 Field[] fields = clazz.getDeclaredFields(); 788 for (Field field : fields) { 789 PropertyInject propertyInject = field.getAnnotation(PropertyInject.class); 790 if (propertyInject != null && matchContext(propertyInject.context())) { 791 injectFieldProperty(field, propertyInject.value(), propertyInject.defaultValue(), bean, beanName); 792 } 793 794 BeanInject beanInject = field.getAnnotation(BeanInject.class); 795 if (beanInject != null && matchContext(beanInject.context())) { 796 injectFieldBean(field, beanInject.value(), bean, beanName); 797 } 798 799 EndpointInject endpointInject = field.getAnnotation(EndpointInject.class); 800 if (endpointInject != null && matchContext(endpointInject.context())) { 801 injectField(field, endpointInject.uri(), endpointInject.ref(), endpointInject.property(), bean, beanName); 802 } 803 804 Produce produce = field.getAnnotation(Produce.class); 805 if (produce != null && matchContext(produce.context())) { 806 injectField(field, produce.uri(), produce.ref(), produce.property(), bean, beanName); 807 } 808 } 809 clazz = clazz.getSuperclass(); 810 } while (clazz != null && clazz != Object.class); 811 } 812 813 protected void injectField(Field field, String endpointUri, String endpointRef, String endpointProperty, Object bean, String beanName) { 814 setField(field, bean, getInjectionValue(field.getType(), endpointUri, endpointRef, endpointProperty, field.getName(), bean, beanName)); 815 } 816 817 protected void injectFieldProperty(Field field, String propertyName, String propertyDefaultValue, Object bean, String beanName) { 818 setField(field, bean, getInjectionPropertyValue(field.getType(), propertyName, propertyDefaultValue, field.getName(), bean, beanName)); 819 } 820 821 public void injectFieldBean(Field field, String name, Object bean, String beanName) { 822 setField(field, bean, getInjectionBeanValue(field.getType(), name)); 823 } 824 825 protected static void setField(Field field, Object instance, Object value) { 826 try { 827 boolean oldAccessible = field.isAccessible(); 828 boolean shouldSetAccessible = !Modifier.isPublic(field.getModifiers()) && !oldAccessible; 829 if (shouldSetAccessible) { 830 field.setAccessible(true); 831 } 832 field.set(instance, value); 833 if (shouldSetAccessible) { 834 field.setAccessible(oldAccessible); 835 } 836 } catch (IllegalArgumentException ex) { 837 throw new UnsupportedOperationException("Cannot inject value of class: " + value.getClass() + " into: " + field); 838 } catch (IllegalAccessException ex) { 839 throw new IllegalStateException("Could not access method: " + ex.getMessage()); 840 } 841 } 842 843 protected void injectMethods(final Object bean, final String beanName) { 844 Class<?> clazz = bean.getClass(); 845 do { 846 Method[] methods = clazz.getDeclaredMethods(); 847 for (Method method : methods) { 848 setterInjection(method, bean, beanName); 849 consumerInjection(method, bean, beanName); 850 } 851 clazz = clazz.getSuperclass(); 852 } while (clazz != null && clazz != Object.class); 853 } 854 855 protected void setterInjection(Method method, Object bean, String beanName) { 856 PropertyInject propertyInject = method.getAnnotation(PropertyInject.class); 857 if (propertyInject != null && matchContext(propertyInject.context())) { 858 setterPropertyInjection(method, propertyInject.value(), propertyInject.defaultValue(), bean, beanName); 859 } 860 861 BeanInject beanInject = method.getAnnotation(BeanInject.class); 862 if (beanInject != null && matchContext(beanInject.context())) { 863 setterBeanInjection(method, beanInject.value(), bean, beanName); 864 } 865 866 EndpointInject endpointInject = method.getAnnotation(EndpointInject.class); 867 if (endpointInject != null && matchContext(endpointInject.context())) { 868 setterInjection(method, bean, beanName, endpointInject.uri(), endpointInject.ref(), endpointInject.property()); 869 } 870 871 Produce produce = method.getAnnotation(Produce.class); 872 if (produce != null && matchContext(produce.context())) { 873 setterInjection(method, bean, beanName, produce.uri(), produce.ref(), produce.property()); 874 } 875 } 876 877 protected void setterPropertyInjection(Method method, String propertyValue, String propertyDefaultValue, Object bean, String beanName) { 878 Class<?>[] parameterTypes = method.getParameterTypes(); 879 if (parameterTypes != null) { 880 if (parameterTypes.length != 1) { 881 LOG.warn("Ignoring badly annotated method for injection due to incorrect number of parameters: " + method); 882 } else { 883 String propertyName = ObjectHelper.getPropertyName(method); 884 Object value = getInjectionPropertyValue(parameterTypes[0], propertyValue, propertyDefaultValue, propertyName, bean, beanName); 885 ObjectHelper.invokeMethod(method, bean, value); 886 } 887 } 888 } 889 890 protected void setterBeanInjection(Method method, String name, Object bean, String beanName) { 891 Class<?>[] parameterTypes = method.getParameterTypes(); 892 if (parameterTypes != null) { 893 if (parameterTypes.length != 1) { 894 LOG.warn("Ignoring badly annotated method for injection due to incorrect number of parameters: " + method); 895 } else { 896 Object value = getInjectionBeanValue(parameterTypes[0], name); 897 ObjectHelper.invokeMethod(method, bean, value); 898 } 899 } 900 } 901 902 protected void setterInjection(Method method, Object bean, String beanName, String endpointUri, String endpointRef, String endpointProperty) { 903 Class<?>[] parameterTypes = method.getParameterTypes(); 904 if (parameterTypes != null) { 905 if (parameterTypes.length != 1) { 906 LOG.warn("Ignoring badly annotated method for injection due to incorrect number of parameters: " + method); 907 } else { 908 String propertyName = ObjectHelper.getPropertyName(method); 909 Object value = getInjectionValue(parameterTypes[0], endpointUri, endpointRef, endpointProperty, propertyName, bean, beanName); 910 ObjectHelper.invokeMethod(method, bean, value); 911 } 912 } 913 } 914 915 public Object afterInit(Object bean, String beanName, BeanCreator beanCreator, BeanMetadata beanMetadata) { 916 LOG.trace("After init of bean: {} -> {}", beanName, bean); 917 // we cannot inject CamelContextAware beans as the CamelContext may not be ready 918 injectFields(bean, beanName); 919 injectMethods(bean, beanName); 920 return bean; 921 } 922 923 public void beforeDestroy(Object bean, String beanName) { 924 } 925 926 public void afterDestroy(Object bean, String beanName) { 927 } 928 929 @Override 930 protected boolean isSingleton(Object bean, String beanName) { 931 ComponentMetadata meta = blueprintContainer.getComponentMetadata(beanName); 932 if (meta != null && meta instanceof BeanMetadata) { 933 String scope = ((BeanMetadata) meta).getScope(); 934 if (scope != null) { 935 return BeanMetadata.SCOPE_SINGLETON.equals(scope); 936 } 937 } 938 // fallback to super, which will assume singleton 939 // for beans not implementing Camel's IsSingleton interface 940 return super.isSingleton(bean, beanName); 941 } 942 } 943 944 public static class CamelDependenciesFinder implements ComponentDefinitionRegistryProcessor { 945 946 private final String camelContextName; 947 private final ParserContext context; 948 private BlueprintContainer blueprintContainer; 949 950 public CamelDependenciesFinder(String camelContextName, ParserContext context) { 951 this.camelContextName = camelContextName; 952 this.context = context; 953 } 954 955 public void setBlueprintContainer(BlueprintContainer blueprintContainer) { 956 this.blueprintContainer = blueprintContainer; 957 } 958 959 @SuppressWarnings("deprecation") 960 public void process(ComponentDefinitionRegistry componentDefinitionRegistry) { 961 CamelContextFactoryBean ccfb = (CamelContextFactoryBean) blueprintContainer.getComponentInstance(".camelBlueprint.factory." + camelContextName); 962 CamelContext camelContext = ccfb.getContext(); 963 964 Set<String> components = new HashSet<String>(); 965 Set<String> languages = new HashSet<String>(); 966 Set<String> dataformats = new HashSet<String>(); 967 968 // regular camel routes 969 for (RouteDefinition rd : camelContext.getRouteDefinitions()) { 970 findInputComponents(rd.getInputs(), components, languages, dataformats); 971 findOutputComponents(rd.getOutputs(), components, languages, dataformats); 972 } 973 974 // rest services can have embedded routes or a singular to 975 for (RestDefinition rd : camelContext.getRestDefinitions()) { 976 for (VerbDefinition vd : rd.getVerbs()) { 977 Object o = vd.getToOrRoute(); 978 if (o instanceof RouteDefinition) { 979 RouteDefinition route = (RouteDefinition) o; 980 findInputComponents(route.getInputs(), components, languages, dataformats); 981 findOutputComponents(route.getOutputs(), components, languages, dataformats); 982 } else if (o instanceof ToDefinition) { 983 findUriComponent(((ToDefinition) o).getUri(), components); 984 } 985 } 986 } 987 988 // We can only add service references to resolvers, but we can't make the factory depends on those 989 // because the factory has already been instantiated 990 try { 991 for (String component : components) { 992 getComponentResolverReference(context, component); 993 } 994 for (String language : languages) { 995 getLanguageResolverReference(context, language); 996 } 997 for (String dataformat : dataformats) { 998 getDataformatResolverReference(context, dataformat); 999 } 1000 } catch (UnsupportedOperationException e) { 1001 LOG.warn("Unable to add dependencies to Camel components OSGi services. " 1002 + "The Apache Aries blueprint implementation used is too old and the blueprint bundle can not see the org.apache.camel.spi package."); 1003 components.clear(); 1004 languages.clear(); 1005 dataformats.clear(); 1006 } 1007 1008 } 1009 1010 private void findInputComponents(List<FromDefinition> defs, Set<String> components, Set<String> languages, Set<String> dataformats) { 1011 if (defs != null) { 1012 for (FromDefinition def : defs) { 1013 findUriComponent(def.getUri(), components); 1014 findSchedulerUriComponent(def.getUri(), components); 1015 } 1016 } 1017 } 1018 1019 @SuppressWarnings({"rawtypes"}) 1020 private void findOutputComponents(List<ProcessorDefinition<?>> defs, Set<String> components, Set<String> languages, Set<String> dataformats) { 1021 if (defs != null) { 1022 for (ProcessorDefinition<?> def : defs) { 1023 if (def instanceof SendDefinition) { 1024 findUriComponent(((SendDefinition) def).getUri(), components); 1025 } 1026 if (def instanceof MarshalDefinition) { 1027 findDataFormat(((MarshalDefinition) def).getDataFormatType(), dataformats); 1028 } 1029 if (def instanceof UnmarshalDefinition) { 1030 findDataFormat(((UnmarshalDefinition) def).getDataFormatType(), dataformats); 1031 } 1032 if (def instanceof ExpressionNode) { 1033 findLanguage(((ExpressionNode) def).getExpression(), languages); 1034 } 1035 if (def instanceof ResequenceDefinition) { 1036 findLanguage(((ResequenceDefinition) def).getExpression(), languages); 1037 } 1038 if (def instanceof AggregateDefinition) { 1039 findLanguage(((AggregateDefinition) def).getExpression(), languages); 1040 findLanguage(((AggregateDefinition) def).getCorrelationExpression(), languages); 1041 findLanguage(((AggregateDefinition) def).getCompletionPredicate(), languages); 1042 findLanguage(((AggregateDefinition) def).getCompletionTimeoutExpression(), languages); 1043 findLanguage(((AggregateDefinition) def).getCompletionSizeExpression(), languages); 1044 } 1045 if (def instanceof CatchDefinition) { 1046 findLanguage(((CatchDefinition) def).getHandled(), languages); 1047 } 1048 if (def instanceof OnExceptionDefinition) { 1049 findLanguage(((OnExceptionDefinition) def).getRetryWhile(), languages); 1050 findLanguage(((OnExceptionDefinition) def).getHandled(), languages); 1051 findLanguage(((OnExceptionDefinition) def).getContinued(), languages); 1052 } 1053 if (def instanceof SortDefinition) { 1054 findLanguage(((SortDefinition) def).getExpression(), languages); 1055 } 1056 if (def instanceof WireTapDefinition) { 1057 findLanguage(((WireTapDefinition<?>) def).getNewExchangeExpression(), languages); 1058 } 1059 findOutputComponents(def.getOutputs(), components, languages, dataformats); 1060 } 1061 } 1062 } 1063 1064 private void findLanguage(ExpressionDefinition expression, Set<String> languages) { 1065 if (expression != null) { 1066 String lang = expression.getLanguage(); 1067 if (lang != null && lang.length() > 0) { 1068 languages.add(lang); 1069 } 1070 } 1071 } 1072 1073 private void findLanguage(ExpressionSubElementDefinition expression, Set<String> languages) { 1074 if (expression != null) { 1075 findLanguage(expression.getExpressionType(), languages); 1076 } 1077 } 1078 1079 private void findDataFormat(DataFormatDefinition dfd, Set<String> dataformats) { 1080 if (dfd != null && dfd.getDataFormatName() != null) { 1081 dataformats.add(dfd.getDataFormatName()); 1082 } 1083 } 1084 1085 private void findUriComponent(String uri, Set<String> components) { 1086 // if the uri is a placeholder then skip it 1087 if (uri != null && uri.startsWith(PropertiesComponent.DEFAULT_PREFIX_TOKEN)) { 1088 return; 1089 } 1090 1091 if (uri != null) { 1092 String splitURI[] = ObjectHelper.splitOnCharacter(uri, ":", 2); 1093 if (splitURI[1] != null) { 1094 String scheme = splitURI[0]; 1095 components.add(scheme); 1096 } 1097 } 1098 } 1099 1100 private void findSchedulerUriComponent(String uri, Set<String> components) { 1101 1102 // the input may use a scheduler which can be quartz or spring 1103 if (uri != null) { 1104 try { 1105 URI u = new URI(uri); 1106 Map<String, Object> parameters = URISupport.parseParameters(u); 1107 Object value = parameters.get("scheduler"); 1108 if (value == null) { 1109 value = parameters.get("consumer.scheduler"); 1110 } 1111 if (value != null) { 1112 // the scheduler can be quartz2 or spring based, so add reference to camel component 1113 // from these components os blueprint knows about the requirement 1114 String name = value.toString(); 1115 if ("quartz2".equals(name)) { 1116 components.add("quartz2"); 1117 } else if ("spring".equals(name)) { 1118 components.add("spring-event"); 1119 } 1120 } 1121 } catch (URISyntaxException e) { 1122 // ignore 1123 } 1124 } 1125 } 1126 1127 } 1128 1129}