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.util; 018 019import java.io.IOException; 020import java.io.InputStream; 021import java.net.URL; 022import java.util.Enumeration; 023import java.util.HashMap; 024import java.util.Iterator; 025import java.util.List; 026import java.util.Locale; 027import java.util.Map; 028import java.util.Properties; 029import java.util.Set; 030import java.util.SortedMap; 031import java.util.StringTokenizer; 032import java.util.TreeMap; 033 034import org.apache.camel.CamelContext; 035import org.apache.camel.Component; 036import org.apache.camel.Endpoint; 037import org.apache.camel.Exchange; 038import org.apache.camel.NoSuchBeanException; 039import org.apache.camel.NoSuchEndpointException; 040import org.apache.camel.component.properties.PropertiesComponent; 041import org.apache.camel.model.FromDefinition; 042import org.apache.camel.model.ProcessorDefinition; 043import org.apache.camel.model.ProcessorDefinitionHelper; 044import org.apache.camel.model.RouteDefinition; 045import org.apache.camel.spi.ClassResolver; 046import org.apache.camel.spi.RouteStartupOrder; 047import org.slf4j.Logger; 048import org.slf4j.LoggerFactory; 049 050import static org.apache.camel.util.ObjectHelper.isEmpty; 051import static org.apache.camel.util.ObjectHelper.isNotEmpty; 052import static org.apache.camel.util.ObjectHelper.notNull; 053 054/** 055 * A number of helper methods 056 * 057 * @version 058 */ 059public final class CamelContextHelper { 060 public static final String COMPONENT_BASE = "META-INF/services/org/apache/camel/component/"; 061 public static final String COMPONENT_DESCRIPTOR = "META-INF/services/org/apache/camel/component.properties"; 062 public static final String COMPONENT_DOCUMENTATION_PREFIX = "org/apache/camel/component/"; 063 public static final String MODEL_DESCRIPTOR = "META-INF/services/org/apache/camel/model.properties"; 064 public static final String MODEL_DOCUMENTATION_PREFIX = "org/apache/camel/model/"; 065 066 private static final Logger LOG = LoggerFactory.getLogger(CamelContextHelper.class); 067 068 /** 069 * Utility classes should not have a public constructor. 070 */ 071 private CamelContextHelper() { 072 } 073 074 /** 075 * Returns the mandatory endpoint for the given URI or the 076 * {@link org.apache.camel.NoSuchEndpointException} is thrown 077 */ 078 public static Endpoint getMandatoryEndpoint(CamelContext camelContext, String uri) 079 throws NoSuchEndpointException { 080 Endpoint endpoint = camelContext.getEndpoint(uri); 081 if (endpoint == null) { 082 throw new NoSuchEndpointException(uri); 083 } else { 084 return endpoint; 085 } 086 } 087 088 /** 089 * Returns the mandatory endpoint for the given URI and type or the 090 * {@link org.apache.camel.NoSuchEndpointException} is thrown 091 */ 092 public static <T extends Endpoint> T getMandatoryEndpoint(CamelContext camelContext, String uri, Class<T> type) { 093 Endpoint endpoint = getMandatoryEndpoint(camelContext, uri); 094 return ObjectHelper.cast(type, endpoint); 095 } 096 097 /** 098 * Converts the given value to the requested type 099 */ 100 public static <T> T convertTo(CamelContext context, Class<T> type, Object value) { 101 notNull(context, "camelContext"); 102 return context.getTypeConverter().convertTo(type, value); 103 } 104 105 /** 106 * Tried to convert the given value to the requested type 107 */ 108 public static <T> T tryConvertTo(CamelContext context, Class<T> type, Object value) { 109 notNull(context, "camelContext"); 110 return context.getTypeConverter().tryConvertTo(type, value); 111 } 112 113 /** 114 * Converts the given value to the specified type throwing an {@link IllegalArgumentException} 115 * if the value could not be converted to a non null value 116 */ 117 public static <T> T mandatoryConvertTo(CamelContext context, Class<T> type, Object value) { 118 T answer = convertTo(context, type, value); 119 if (answer == null) { 120 throw new IllegalArgumentException("Value " + value + " converted to " + type.getName() + " cannot be null"); 121 } 122 return answer; 123 } 124 125 /** 126 * Creates a new instance of the given type using the {@link org.apache.camel.spi.Injector} on the given 127 * {@link CamelContext} 128 */ 129 public static <T> T newInstance(CamelContext context, Class<T> beanType) { 130 return context.getInjector().newInstance(beanType); 131 } 132 133 /** 134 * Look up the given named bean in the {@link org.apache.camel.spi.Registry} on the 135 * {@link CamelContext} 136 */ 137 public static Object lookup(CamelContext context, String name) { 138 return context.getRegistry().lookupByName(name); 139 } 140 141 /** 142 * Look up the given named bean of the given type in the {@link org.apache.camel.spi.Registry} on the 143 * {@link CamelContext} 144 */ 145 public static <T> T lookup(CamelContext context, String name, Class<T> beanType) { 146 return context.getRegistry().lookupByNameAndType(name, beanType); 147 } 148 149 /** 150 * Look up the given named bean in the {@link org.apache.camel.spi.Registry} on the 151 * {@link CamelContext} and try to convert it to the given type. 152 */ 153 public static <T> T lookupAndConvert(CamelContext context, String name, Class<T> beanType) { 154 return tryConvertTo(context, beanType, lookup(context, name)); 155 } 156 157 /** 158 * Look up a bean of the give type in the {@link org.apache.camel.spi.Registry} on the 159 * {@link CamelContext} returning an instance if only one bean is present, 160 */ 161 public static <T> T findByType(CamelContext camelContext, Class<T> type) { 162 Set<T> set = camelContext.getRegistry().findByType(type); 163 if (set.size() == 1) { 164 return set.iterator().next(); 165 } 166 167 return null; 168 } 169 170 /** 171 * Look up the given named bean in the {@link org.apache.camel.spi.Registry} on the 172 * {@link CamelContext} or throws {@link NoSuchBeanException} if not found. 173 */ 174 public static Object mandatoryLookup(CamelContext context, String name) { 175 Object answer = lookup(context, name); 176 if (answer == null) { 177 throw new NoSuchBeanException(name); 178 } 179 return answer; 180 } 181 182 /** 183 * Look up the given named bean of the given type in the {@link org.apache.camel.spi.Registry} on the 184 * {@link CamelContext} or throws NoSuchBeanException if not found. 185 */ 186 public static <T> T mandatoryLookup(CamelContext context, String name, Class<T> beanType) { 187 T answer = lookup(context, name, beanType); 188 if (answer == null) { 189 throw new NoSuchBeanException(name, beanType.getName()); 190 } 191 return answer; 192 } 193 194 /** 195 * Look up the given named bean in the {@link org.apache.camel.spi.Registry} on the 196 * {@link CamelContext} and convert it to the given type or throws NoSuchBeanException if not found. 197 */ 198 public static <T> T mandatoryLookupAndConvert(CamelContext context, String name, Class<T> beanType) { 199 Object value = lookup(context, name); 200 if (value == null) { 201 throw new NoSuchBeanException(name, beanType.getName()); 202 } 203 return convertTo(context, beanType, value); 204 } 205 206 /** 207 * Evaluates the @EndpointInject annotation using the given context 208 */ 209 public static Endpoint getEndpointInjection(CamelContext camelContext, String uri, String ref, String injectionPointName, boolean mandatory) { 210 if (ObjectHelper.isNotEmpty(uri) && ObjectHelper.isNotEmpty(ref)) { 211 throw new IllegalArgumentException("Both uri and name is provided, only either one is allowed: uri=" + uri + ", ref=" + ref); 212 } 213 214 Endpoint endpoint; 215 if (isNotEmpty(uri)) { 216 endpoint = camelContext.getEndpoint(uri); 217 } else { 218 // if a ref is given then it should be possible to lookup 219 // otherwise we do not catch situations where there is a typo etc 220 if (isNotEmpty(ref)) { 221 endpoint = mandatoryLookup(camelContext, ref, Endpoint.class); 222 } else { 223 if (isEmpty(ref)) { 224 ref = injectionPointName; 225 } 226 if (mandatory) { 227 endpoint = mandatoryLookup(camelContext, ref, Endpoint.class); 228 } else { 229 endpoint = lookup(camelContext, ref, Endpoint.class); 230 } 231 } 232 } 233 return endpoint; 234 } 235 236 /** 237 * Gets the maximum cache pool size. 238 * <p/> 239 * Will use the property set on CamelContext with the key {@link Exchange#MAXIMUM_CACHE_POOL_SIZE}. 240 * If no property has been set, then it will fallback to return a size of 1000. 241 * 242 * @param camelContext the camel context 243 * @return the maximum cache size 244 * @throws IllegalArgumentException is thrown if the property is illegal 245 */ 246 public static int getMaximumCachePoolSize(CamelContext camelContext) throws IllegalArgumentException { 247 if (camelContext != null) { 248 String s = camelContext.getGlobalOption(Exchange.MAXIMUM_CACHE_POOL_SIZE); 249 if (s != null) { 250 try { 251 // we cannot use Camel type converters as they may not be ready this early 252 Integer size = Integer.valueOf(s); 253 if (size == null || size <= 0) { 254 throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_CACHE_POOL_SIZE + " must be a positive number, was: " + s); 255 } 256 return size; 257 } catch (NumberFormatException e) { 258 throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_CACHE_POOL_SIZE + " must be a positive number, was: " + s, e); 259 } 260 } 261 } 262 263 // 1000 is the default fallback 264 return 1000; 265 } 266 267 /** 268 * Gets the maximum endpoint cache size. 269 * <p/> 270 * Will use the property set on CamelContext with the key {@link Exchange#MAXIMUM_ENDPOINT_CACHE_SIZE}. 271 * If no property has been set, then it will fallback to return a size of 1000. 272 * 273 * @param camelContext the camel context 274 * @return the maximum cache size 275 * @throws IllegalArgumentException is thrown if the property is illegal 276 */ 277 public static int getMaximumEndpointCacheSize(CamelContext camelContext) throws IllegalArgumentException { 278 if (camelContext != null) { 279 String s = camelContext.getGlobalOption(Exchange.MAXIMUM_ENDPOINT_CACHE_SIZE); 280 if (s != null) { 281 // we cannot use Camel type converters as they may not be ready this early 282 try { 283 Integer size = Integer.valueOf(s); 284 if (size == null || size <= 0) { 285 throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_ENDPOINT_CACHE_SIZE + " must be a positive number, was: " + s); 286 } 287 return size; 288 } catch (NumberFormatException e) { 289 throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_ENDPOINT_CACHE_SIZE + " must be a positive number, was: " + s, e); 290 } 291 } 292 } 293 294 // 1000 is the default fallback 295 return 1000; 296 } 297 298 /** 299 * Gets the maximum simple cache size. 300 * <p/> 301 * Will use the property set on CamelContext with the key {@link Exchange#MAXIMUM_SIMPLE_CACHE_SIZE}. 302 * If no property has been set, then it will fallback to return a size of 1000. 303 * 304 * @param camelContext the camel context 305 * @return the maximum cache size 306 * @throws IllegalArgumentException is thrown if the property is illegal 307 */ 308 public static int getMaximumSimpleCacheSize(CamelContext camelContext) throws IllegalArgumentException { 309 if (camelContext != null) { 310 String s = camelContext.getGlobalOption(Exchange.MAXIMUM_SIMPLE_CACHE_SIZE); 311 if (s != null) { 312 // we cannot use Camel type converters as they may not be ready this early 313 try { 314 Integer size = Integer.valueOf(s); 315 if (size == null || size <= 0) { 316 throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_SIMPLE_CACHE_SIZE + " must be a positive number, was: " + s); 317 } 318 return size; 319 } catch (NumberFormatException e) { 320 throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_SIMPLE_CACHE_SIZE + " must be a positive number, was: " + s, e); 321 } 322 } 323 } 324 325 // 1000 is the default fallback 326 return 1000; 327 } 328 329 /** 330 * Gets the maximum transformer cache size. 331 * <p/> 332 * Will use the property set on CamelContext with the key {@link Exchange#MAXIMUM_TRANSFORMER_CACHE_SIZE}. 333 * If no property has been set, then it will fallback to return a size of 1000. 334 * 335 * @param camelContext the camel context 336 * @return the maximum cache size 337 * @throws IllegalArgumentException is thrown if the property is illegal 338 */ 339 public static int getMaximumTransformerCacheSize(CamelContext camelContext) throws IllegalArgumentException { 340 if (camelContext != null) { 341 String s = camelContext.getGlobalOption(Exchange.MAXIMUM_TRANSFORMER_CACHE_SIZE); 342 if (s != null) { 343 // we cannot use Camel type converters as they may not be ready this early 344 try { 345 Integer size = Integer.valueOf(s); 346 if (size == null || size <= 0) { 347 throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_TRANSFORMER_CACHE_SIZE + " must be a positive number, was: " + s); 348 } 349 return size; 350 } catch (NumberFormatException e) { 351 throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_TRANSFORMER_CACHE_SIZE + " must be a positive number, was: " + s, e); 352 } 353 } 354 } 355 356 // 1000 is the default fallback 357 return 1000; 358 } 359 360 /** 361 * Gets the maximum validator cache size. 362 * <p/> 363 * Will use the property set on CamelContext with the key {@link Exchange#MAXIMUM_VALIDATOR_CACHE_SIZE}. 364 * If no property has been set, then it will fallback to return a size of 1000. 365 * 366 * @param camelContext the camel context 367 * @return the maximum cache size 368 * @throws IllegalArgumentException is thrown if the property is illegal 369 */ 370 public static int getMaximumValidatorCacheSize(CamelContext camelContext) throws IllegalArgumentException { 371 if (camelContext != null) { 372 String s = camelContext.getGlobalOption(Exchange.MAXIMUM_VALIDATOR_CACHE_SIZE); 373 if (s != null) { 374 // we cannot use Camel type converters as they may not be ready this early 375 try { 376 Integer size = Integer.valueOf(s); 377 if (size == null || size <= 0) { 378 throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_VALIDATOR_CACHE_SIZE + " must be a positive number, was: " + s); 379 } 380 return size; 381 } catch (NumberFormatException e) { 382 throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_VALIDATOR_CACHE_SIZE + " must be a positive number, was: " + s, e); 383 } 384 } 385 } 386 387 // 1000 is the default fallback 388 return 1000; 389 } 390 391 /** 392 * Parses the given text and handling property placeholders as well 393 * 394 * @param camelContext the camel context 395 * @param text the text 396 * @return the parsed text, or <tt>null</tt> if the text was <tt>null</tt> 397 * @throws Exception is thrown if illegal argument 398 */ 399 public static String parseText(CamelContext camelContext, String text) throws Exception { 400 // ensure we support property placeholders 401 return camelContext.resolvePropertyPlaceholders(text); 402 } 403 404 /** 405 * Parses the given text and converts it to an Integer and handling property placeholders as well 406 * 407 * @param camelContext the camel context 408 * @param text the text 409 * @return the integer vale, or <tt>null</tt> if the text was <tt>null</tt> 410 * @throws Exception is thrown if illegal argument or type conversion not possible 411 */ 412 public static Integer parseInteger(CamelContext camelContext, String text) throws Exception { 413 // ensure we support property placeholders 414 String s = camelContext.resolvePropertyPlaceholders(text); 415 if (s != null) { 416 try { 417 return camelContext.getTypeConverter().mandatoryConvertTo(Integer.class, s); 418 } catch (NumberFormatException e) { 419 if (s.equals(text)) { 420 throw new IllegalArgumentException("Error parsing [" + s + "] as an Integer.", e); 421 } else { 422 throw new IllegalArgumentException("Error parsing [" + s + "] from property " + text + " as an Integer.", e); 423 } 424 } 425 } 426 return null; 427 } 428 429 /** 430 * Parses the given text and converts it to an Long and handling property placeholders as well 431 * 432 * @param camelContext the camel context 433 * @param text the text 434 * @return the long vale, or <tt>null</tt> if the text was <tt>null</tt> 435 * @throws Exception is thrown if illegal argument or type conversion not possible 436 */ 437 public static Long parseLong(CamelContext camelContext, String text) throws Exception { 438 // ensure we support property placeholders 439 String s = camelContext.resolvePropertyPlaceholders(text); 440 if (s != null) { 441 try { 442 return camelContext.getTypeConverter().mandatoryConvertTo(Long.class, s); 443 } catch (NumberFormatException e) { 444 if (s.equals(text)) { 445 throw new IllegalArgumentException("Error parsing [" + s + "] as a Long.", e); 446 } else { 447 throw new IllegalArgumentException("Error parsing [" + s + "] from property " + text + " as a Long.", e); 448 } 449 } 450 } 451 return null; 452 } 453 454 /** 455 * Parses the given text and converts it to a Double and handling property placeholders as well 456 * 457 * @param camelContext the camel context 458 * @param text the text 459 * @return the double vale, or <tt>null</tt> if the text was <tt>null</tt> 460 * @throws Exception is thrown if illegal argument or type conversion not possible 461 */ 462 public static Double parseDouble(CamelContext camelContext, String text) throws Exception { 463 // ensure we support property placeholders 464 String s = camelContext.resolvePropertyPlaceholders(text); 465 if (s != null) { 466 try { 467 return camelContext.getTypeConverter().mandatoryConvertTo(Double.class, s); 468 } catch (NumberFormatException e) { 469 if (s.equals(text)) { 470 throw new IllegalArgumentException("Error parsing [" + s + "] as an Integer.", e); 471 } else { 472 throw new IllegalArgumentException("Error parsing [" + s + "] from property " + text + " as an Integer.", e); 473 } 474 } 475 } 476 return null; 477 } 478 479 /** 480 * Parses the given text and converts it to an Boolean and handling property placeholders as well 481 * 482 * @param camelContext the camel context 483 * @param text the text 484 * @return the boolean vale, or <tt>null</tt> if the text was <tt>null</tt> 485 * @throws Exception is thrown if illegal argument or type conversion not possible 486 */ 487 public static Boolean parseBoolean(CamelContext camelContext, String text) throws Exception { 488 // ensure we support property placeholders 489 String s = camelContext.resolvePropertyPlaceholders(text); 490 if (s != null) { 491 s = s.trim().toLowerCase(Locale.ENGLISH); 492 if (s.equals("true") || s.equals("false")) { 493 return "true".equals(s) ? Boolean.TRUE : Boolean.FALSE; 494 } else { 495 if (s.equals(text)) { 496 throw new IllegalArgumentException("Error parsing [" + s + "] as a Boolean."); 497 } else { 498 throw new IllegalArgumentException("Error parsing [" + s + "] from property " + text + " as a Boolean."); 499 } 500 } 501 } 502 return null; 503 } 504 505 /** 506 * Finds all possible Components on the classpath, already registered in {@link org.apache.camel.CamelContext}, 507 * and from the {@link org.apache.camel.spi.Registry}. 508 */ 509 public static SortedMap<String, Properties> findComponents(CamelContext camelContext) throws LoadPropertiesException { 510 ClassResolver resolver = camelContext.getClassResolver(); 511 LOG.debug("Finding all components using class resolver: {} -> {}", new Object[]{resolver}); 512 Enumeration<URL> iter = resolver.loadAllResourcesAsURL(COMPONENT_DESCRIPTOR); 513 return findComponents(camelContext, iter); 514 } 515 516 public static SortedMap<String, Properties> findComponents(CamelContext camelContext, Enumeration<URL> componentDescriptionIter) 517 throws LoadPropertiesException { 518 519 SortedMap<String, Properties> map = new TreeMap<String, Properties>(); 520 while (componentDescriptionIter != null && componentDescriptionIter.hasMoreElements()) { 521 URL url = componentDescriptionIter.nextElement(); 522 LOG.trace("Finding components in url: {}", url); 523 try { 524 Properties properties = new Properties(); 525 properties.load(url.openStream()); 526 String names = properties.getProperty("components"); 527 if (names != null) { 528 StringTokenizer tok = new StringTokenizer(names); 529 while (tok.hasMoreTokens()) { 530 String name = tok.nextToken(); 531 532 // try to find the class name for this component 533 String className = null; 534 InputStream is = null; 535 try { 536 // now load the component name resource so we can grab its properties and the class name 537 Enumeration<URL> urls = camelContext.getClassResolver().loadAllResourcesAsURL(COMPONENT_BASE + name); 538 if (urls != null && urls.hasMoreElements()) { 539 is = urls.nextElement().openStream(); 540 } 541 if (is != null) { 542 Properties compProperties = new Properties(); 543 compProperties.load(is); 544 if (!compProperties.isEmpty()) { 545 className = compProperties.getProperty("class"); 546 } 547 } 548 } catch (Exception e) { 549 // ignore 550 } finally { 551 IOHelper.close(is); 552 } 553 554 // inherit properties we loaded first, as it has maven details 555 Properties prop = new Properties(); 556 prop.putAll(properties); 557 if (camelContext.hasComponent(name) != null) { 558 prop.put("component", camelContext.getComponent(name)); 559 } 560 if (className != null) { 561 prop.put("class", className); 562 } 563 prop.put("name", name); 564 map.put(name, prop); 565 } 566 } 567 } catch (IOException e) { 568 throw new LoadPropertiesException(url, e); 569 } 570 } 571 572 // lets see what other components are registered on camel context 573 List<String> names = camelContext.getComponentNames(); 574 for (String name : names) { 575 if (!map.containsKey(name)) { 576 Component component = camelContext.getComponent(name); 577 if (component != null) { 578 Properties properties = new Properties(); 579 properties.put("component", component); 580 properties.put("class", component.getClass().getName()); 581 properties.put("name", name); 582 // override default component if name clash 583 map.put(name, properties); 584 } 585 } 586 } 587 588 // lets see what other components are in the registry 589 Map<String, Component> beanMap = camelContext.getRegistry().findByTypeWithName(Component.class); 590 Set<Map.Entry<String, Component>> entries = beanMap.entrySet(); 591 for (Map.Entry<String, Component> entry : entries) { 592 String name = entry.getKey(); 593 if (!map.containsKey(name)) { 594 Component component = entry.getValue(); 595 if (component != null) { 596 Properties properties = new Properties(); 597 properties.put("component", component); 598 properties.put("class", component.getClass().getName()); 599 properties.put("name", name); 600 map.put(name, properties); 601 } 602 } 603 } 604 return map; 605 } 606 607 /** 608 * Find information about all the EIPs from camel-core. 609 */ 610 public static SortedMap<String, Properties> findEips(CamelContext camelContext) throws LoadPropertiesException { 611 SortedMap<String, Properties> answer = new TreeMap<String, Properties>(); 612 613 ClassResolver resolver = camelContext.getClassResolver(); 614 LOG.debug("Finding all EIPs using class resolver: {} -> {}", new Object[]{resolver}); 615 URL url = resolver.loadResourceAsURL(MODEL_DESCRIPTOR); 616 if (url != null) { 617 InputStream is = null; 618 try { 619 is = url.openStream(); 620 String all = IOHelper.loadText(is); 621 String[] lines = all.split("\n"); 622 for (String line : lines) { 623 if (line.startsWith("#")) { 624 continue; 625 } 626 627 Properties prop = new Properties(); 628 prop.put("name", line); 629 630 String description = null; 631 String label = null; 632 String javaType = null; 633 String title = null; 634 635 // enrich with more meta-data 636 String json = camelContext.explainEipJson(line, false); 637 if (json != null) { 638 List<Map<String, String>> rows = JsonSchemaHelper.parseJsonSchema("model", json, false); 639 640 for (Map<String, String> row : rows) { 641 if (row.get("title") != null) { 642 title = row.get("title"); 643 } 644 if (row.get("description") != null) { 645 description = row.get("description"); 646 } 647 if (row.get("label") != null) { 648 label = row.get("label"); 649 } 650 if (row.get("javaType") != null) { 651 javaType = row.get("javaType"); 652 } 653 } 654 } 655 656 if (title != null) { 657 prop.put("title", title); 658 } 659 if (description != null) { 660 prop.put("description", description); 661 } 662 if (label != null) { 663 prop.put("label", label); 664 } 665 if (javaType != null) { 666 prop.put("class", javaType); 667 } 668 669 answer.put(line, prop); 670 } 671 } catch (IOException e) { 672 throw new LoadPropertiesException(url, e); 673 } finally { 674 IOHelper.close(is); 675 } 676 } 677 678 return answer; 679 } 680 681 /** 682 * Gets the route startup order for the given route id 683 * 684 * @param camelContext the camel context 685 * @param routeId the id of the route 686 * @return the startup order, or <tt>0</tt> if not possible to determine 687 */ 688 public static int getRouteStartupOrder(CamelContext camelContext, String routeId) { 689 for (RouteStartupOrder order : camelContext.getRouteStartupOrder()) { 690 if (order.getRoute().getId().equals(routeId)) { 691 return order.getStartupOrder(); 692 } 693 } 694 return 0; 695 } 696 697 /** 698 * Lookup the {@link org.apache.camel.component.properties.PropertiesComponent} from the {@link org.apache.camel.CamelContext}. 699 * <p/> 700 * @param camelContext the camel context 701 * @param autoCreate whether to automatic create a new default {@link org.apache.camel.component.properties.PropertiesComponent} if no custom component 702 * has been configured. 703 * @return the properties component, or <tt>null</tt> if none has been defined, and auto create is <tt>false</tt>. 704 */ 705 public static Component lookupPropertiesComponent(CamelContext camelContext, boolean autoCreate) { 706 // no existing properties component so lookup and add as component if possible 707 PropertiesComponent answer = (PropertiesComponent) camelContext.hasComponent("properties"); 708 if (answer == null) { 709 // lookup what is stored under properties, as it may not be the Camel properties component 710 Object found = camelContext.getRegistry().lookupByName("properties"); 711 if (found != null && found instanceof PropertiesComponent) { 712 answer = (PropertiesComponent) found; 713 camelContext.addComponent("properties", answer); 714 } 715 } 716 if (answer == null && autoCreate) { 717 // create a default properties component to be used as there may be default values we can use 718 LOG.info("No existing PropertiesComponent has been configured, creating a new default PropertiesComponent with name: properties"); 719 // do not auto create using getComponent as spring auto-wire by constructor causes a side effect 720 answer = new PropertiesComponent(true); 721 camelContext.addComponent("properties", answer); 722 } 723 return answer; 724 } 725 726 /** 727 * Checks if any of the Camel routes is using an EIP with the given name 728 * 729 * @param camelContext the Camel context 730 * @param name the name of the EIP 731 * @return <tt>true</tt> if in use, <tt>false</tt> if not 732 */ 733 public static boolean isEipInUse(CamelContext camelContext, String name) { 734 for (RouteDefinition route : camelContext.getRouteDefinitions()) { 735 for (FromDefinition from : route.getInputs()) { 736 if (name.equals(from.getShortName())) { 737 return true; 738 } 739 } 740 Iterator<ProcessorDefinition> it = ProcessorDefinitionHelper.filterTypeInOutputs(route.getOutputs(), ProcessorDefinition.class); 741 while (it.hasNext()) { 742 ProcessorDefinition def = it.next(); 743 if (name.equals(def.getShortName())) { 744 return true; 745 } 746 } 747 } 748 return false; 749 } 750 751 /** 752 * Inspects the given object and resolves any property placeholders from its properties. 753 * <p/> 754 * This implementation will check all the getter/setter pairs on this instance and for all the values 755 * (which is a String type) will be property placeholder resolved. 756 * 757 * @param camelContext the Camel context 758 * @param target the object that should have the properties (eg getter/setter) resolved 759 * @throws Exception is thrown if property placeholders was used and there was an error resolving them 760 * @see org.apache.camel.CamelContext#resolvePropertyPlaceholders(String) 761 * @see org.apache.camel.component.properties.PropertiesComponent 762 */ 763 public static void resolvePropertyPlaceholders(CamelContext camelContext, Object target) throws Exception { 764 LOG.trace("Resolving property placeholders for: {}", target); 765 766 // find all getter/setter which we can use for property placeholders 767 Map<String, Object> properties = new HashMap<String, Object>(); 768 IntrospectionSupport.getProperties(target, properties, null); 769 770 Map<String, Object> changedProperties = new HashMap<String, Object>(); 771 if (!properties.isEmpty()) { 772 LOG.trace("There are {} properties on: {}", properties.size(), target); 773 // lookup and resolve properties for String based properties 774 for (Map.Entry<String, Object> entry : properties.entrySet()) { 775 // the name is always a String 776 String name = entry.getKey(); 777 Object value = entry.getValue(); 778 if (value instanceof String) { 779 // value must be a String, as a String is the key for a property placeholder 780 String text = (String) value; 781 text = camelContext.resolvePropertyPlaceholders(text); 782 if (text != value) { 783 // invoke setter as the text has changed 784 boolean changed = IntrospectionSupport.setProperty(camelContext.getTypeConverter(), target, name, text); 785 if (!changed) { 786 throw new IllegalArgumentException("No setter to set property: " + name + " to: " + text + " on: " + target); 787 } 788 changedProperties.put(name, value); 789 if (LOG.isDebugEnabled()) { 790 LOG.debug("Changed property [{}] from: {} to: {}", new Object[]{name, value, text}); 791 } 792 } 793 } 794 } 795 } 796 } 797}