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.util; 018 019 import java.io.Closeable; 020 import java.io.IOException; 021 import java.io.InputStream; 022 import java.lang.annotation.Annotation; 023 import java.lang.reflect.AnnotatedElement; 024 import java.lang.reflect.InvocationTargetException; 025 import java.lang.reflect.Method; 026 import java.nio.charset.Charset; 027 import java.util.ArrayList; 028 import java.util.Arrays; 029 import java.util.Collection; 030 import java.util.Collections; 031 import java.util.Iterator; 032 import java.util.List; 033 import java.util.Scanner; 034 035 import org.w3c.dom.Node; 036 import org.w3c.dom.NodeList; 037 038 039 import org.apache.camel.RuntimeCamelException; 040 import org.apache.commons.logging.Log; 041 import org.apache.commons.logging.LogFactory; 042 043 044 /** 045 * A number of useful helper methods for working with Objects 046 * 047 * @version $Revision: 14157 $ 048 */ 049 public final class ObjectHelper { 050 private static final transient Log LOG = LogFactory.getLog(ObjectHelper.class); 051 052 /** 053 * Utility classes should not have a public constructor. 054 */ 055 private ObjectHelper() { 056 } 057 058 /** 059 * @deprecated use the equal method instead. Will be removed in Camel 2.0. 060 * 061 * @see #equal(Object, Object) 062 */ 063 @Deprecated 064 public static boolean equals(Object a, Object b) { 065 return equal(a, b); 066 } 067 068 /** 069 * A helper method for comparing objects for equality while handling nulls 070 */ 071 public static boolean equal(Object a, Object b) { 072 if (a == b) { 073 return true; 074 } 075 076 if (a instanceof byte[] && b instanceof byte[]) { 077 return equalByteArray((byte[]) a, (byte[]) b); 078 } 079 080 return a != null && b != null && a.equals(b); 081 } 082 083 /** 084 * A helper method for comparing byte arrays for equality while handling nulls 085 */ 086 public static boolean equalByteArray(byte[] a, byte[] b) { 087 if (a == b) { 088 return true; 089 } 090 091 // loop and compare each byte 092 if (a != null && b != null && a.length == b.length) { 093 for (int i = 0; i < a.length; i++) { 094 if (a[i] != b[i]) { 095 return false; 096 } 097 } 098 // all bytes are equal 099 return true; 100 } 101 102 return false; 103 } 104 105 /** 106 * Returns true if the given object is equal to any of the expected value 107 */ 108 public static boolean isEqualToAny(Object object, Object... values) { 109 for (Object value : values) { 110 if (equal(object, value)) { 111 return true; 112 } 113 } 114 return false; 115 } 116 117 /** 118 * A helper method for performing an ordered comparison on the objects 119 * handling nulls and objects which do not handle sorting gracefully 120 */ 121 public static int compare(Object a, Object b) { 122 if (a == b) { 123 return 0; 124 } 125 if (a == null) { 126 return -1; 127 } 128 if (b == null) { 129 return 1; 130 } 131 if (a instanceof Comparable) { 132 Comparable comparable = (Comparable)a; 133 return comparable.compareTo(b); 134 } else { 135 int answer = a.getClass().getName().compareTo(b.getClass().getName()); 136 if (answer == 0) { 137 answer = a.hashCode() - b.hashCode(); 138 } 139 return answer; 140 } 141 } 142 143 public static Boolean toBoolean(Object value) { 144 if (value instanceof Boolean) { 145 return (Boolean)value; 146 } 147 if (value instanceof String) { 148 return "true".equalsIgnoreCase(value.toString()) ? Boolean.TRUE : Boolean.FALSE; 149 } 150 if (value instanceof Integer) { 151 return (Integer)value > 0 ? Boolean.TRUE : Boolean.FALSE; 152 } 153 return null; 154 } 155 156 /** 157 * Asserts whether the value is <b>not</b> <tt>null</tt> 158 * 159 * @param value the value to test 160 * @param name the key that resolved the value 161 * @throws IllegalArgumentException is thrown if assertion fails 162 */ 163 public static void notNull(Object value, String name) { 164 if (value == null) { 165 throw new IllegalArgumentException(name + " must be specified"); 166 } 167 } 168 169 /** 170 * Asserts whether the value is <b>not</b> <tt>null</tt> 171 * 172 * @param value the value to test 173 * @param on additional description to indicate where this problem occured (appended as toString()) 174 * @param name the key that resolved the value 175 * @throws IllegalArgumentException is thrown if assertion fails 176 */ 177 public static void notNull(Object value, String name, Object on) { 178 if (on == null) { 179 notNull(value, name); 180 } else if (value == null) { 181 throw new IllegalArgumentException(name + " must be specified on: " + on); 182 } 183 } 184 185 /** 186 * Asserts whether the string is <b>not</b> empty. 187 * 188 * @param value the string to test 189 * @param name the key that resolved the value 190 * @throws IllegalArgumentException is thrown if assertion fails 191 */ 192 public static void notEmpty(String value, String name) { 193 if (isEmpty(value)) { 194 throw new IllegalArgumentException(name + " must be specified and not empty"); 195 } 196 } 197 198 /** 199 * Asserts whether the string is <b>not</b> empty. 200 * 201 * @param value the string to test 202 * @param on additional description to indicate where this problem occured (appended as toString()) 203 * @param name the key that resolved the value 204 * @throws IllegalArgumentException is thrown if assertion fails 205 */ 206 public static void notEmpty(String value, String name, Object on) { 207 if (on == null) { 208 notNull(value, name); 209 } else if (isEmpty(value)) { 210 throw new IllegalArgumentException(name + " must be specified and not empty on: " + on); 211 } 212 } 213 214 public static String[] splitOnCharacter(String value, String needle, int count) { 215 String rc[] = new String[count]; 216 rc[0] = value; 217 for (int i = 1; i < count; i++) { 218 String v = rc[i - 1]; 219 int p = v.indexOf(needle); 220 if (p < 0) { 221 return rc; 222 } 223 rc[i - 1] = v.substring(0, p); 224 rc[i] = v.substring(p + 1); 225 } 226 return rc; 227 } 228 229 /** 230 * Removes any starting characters on the given text which match the given 231 * character 232 * 233 * @param text the string 234 * @param ch the initial characters to remove 235 * @return either the original string or the new substring 236 */ 237 public static String removeStartingCharacters(String text, char ch) { 238 int idx = 0; 239 while (text.charAt(idx) == ch) { 240 idx++; 241 } 242 if (idx > 0) { 243 return text.substring(idx); 244 } 245 return text; 246 } 247 248 public static String capitalize(String text) { 249 if (text == null) { 250 return null; 251 } 252 int length = text.length(); 253 if (length == 0) { 254 return text; 255 } 256 String answer = text.substring(0, 1).toUpperCase(); 257 if (length > 1) { 258 answer += text.substring(1, length); 259 } 260 return answer; 261 } 262 263 264 /** 265 * Returns true if the collection contains the specified value 266 */ 267 @SuppressWarnings("unchecked") 268 public static boolean contains(Object collectionOrArray, Object value) { 269 if (collectionOrArray instanceof Collection) { 270 Collection collection = (Collection)collectionOrArray; 271 return collection.contains(value); 272 } else if (collectionOrArray instanceof String && value instanceof String) { 273 String str = (String) collectionOrArray; 274 String subStr = (String) value; 275 return str.contains(subStr); 276 } else { 277 Iterator iter = createIterator(collectionOrArray); 278 while (iter.hasNext()) { 279 if (equal(value, iter.next())) { 280 return true; 281 } 282 } 283 } 284 return false; 285 } 286 287 /** 288 * Creates an iterator over the value if the value is a collection, an 289 * Object[] or a primitive type array; otherwise to simplify the caller's 290 * code, we just create a singleton collection iterator over a single value 291 */ 292 @SuppressWarnings("unchecked") 293 public static Iterator createIterator(Object value) { 294 if (value == null) { 295 return Collections.EMPTY_LIST.iterator(); 296 } else if (value instanceof Iterator) { 297 return (Iterator) value; 298 } else if (value instanceof Collection) { 299 Collection collection = (Collection)value; 300 return collection.iterator(); 301 } else if (value.getClass().isArray()) { 302 // TODO we should handle primitive array types? 303 List<Object> list = Arrays.asList((Object[]) value); 304 return list.iterator(); 305 } else if (value instanceof NodeList) { 306 // lets iterate through DOM results after performing XPaths 307 final NodeList nodeList = (NodeList) value; 308 return new Iterator<Node>() { 309 int idx = -1; 310 311 public boolean hasNext() { 312 return ++idx < nodeList.getLength(); 313 } 314 315 public Node next() { 316 return nodeList.item(idx); 317 } 318 319 public void remove() { 320 throw new UnsupportedOperationException(); 321 } 322 }; 323 } else if (value instanceof String) { 324 final String s = (String) value; 325 326 // this code is optimized to only use a Scanner if needed, eg there is a delimiter 327 328 if (s.contains(",")) { 329 // use a scanner if it contains the delimtor 330 Scanner scanner = new Scanner((String)value); 331 scanner.useDelimiter(","); 332 return scanner; 333 } else { 334 // use a plain iterator that returns the value as is as there are only a single value 335 return new Iterator<String>() { 336 int idx = -1; 337 338 public boolean hasNext() { 339 // empty string should not be regarded as having next 340 return ++idx == 0 && ObjectHelper.isNotEmpty(s); 341 } 342 343 public String next() { 344 return s; 345 } 346 347 public void remove() { 348 throw new UnsupportedOperationException(); 349 } 350 }; 351 } 352 } else { 353 return Collections.singletonList(value).iterator(); 354 } 355 } 356 357 /** 358 * Returns the predicate matching boolean on a {@link List} result set where 359 * if the first element is a boolean its value is used otherwise this method 360 * returns true if the collection is not empty 361 * 362 * @return <tt>true</tt> if the first element is a boolean and its value is true or 363 * if the list is non empty 364 */ 365 public static boolean matches(List list) { 366 if (!list.isEmpty()) { 367 Object value = list.get(0); 368 if (value instanceof Boolean) { 369 Boolean flag = (Boolean)value; 370 return flag.booleanValue(); 371 } else { 372 // lets assume non-empty results are true 373 return true; 374 } 375 } 376 return false; 377 } 378 379 /** 380 * @deprecated will be removed in Camel 2.0 - use isNotEmpty() instead 381 */ 382 public static boolean isNotNullAndNonEmpty(String text) { 383 return isNotEmpty(text); 384 } 385 386 /** 387 * @deprecated will be removed in Camel 2.0 - use isEmpty() instead 388 */ 389 public static boolean isNullOrBlank(String text) { 390 return isEmpty(text); 391 } 392 393 /** 394 * Tests whether the value is <tt>null</tt> or an empty string. 395 * 396 * @param value the value, if its a String it will be tested for text length as well 397 * @return true if empty 398 */ 399 public static boolean isEmpty(Object value) { 400 return !isNotEmpty(value); 401 } 402 403 /** 404 * Tests whether the value is <b>not</b> <tt>null</tt> or an empty string. 405 * 406 * @param value the value, if its a String it will be tested for text length as well 407 * @return true if <b>not</b> empty 408 */ 409 public static boolean isNotEmpty(Object value) { 410 if (value == null) { 411 return false; 412 } else if (value instanceof String) { 413 String text = (String) value; 414 return text.trim().length() > 0; 415 } else { 416 return true; 417 } 418 } 419 420 /** 421 * A helper method to access a system property, catching any security 422 * exceptions 423 * 424 * @param name the name of the system property required 425 * @param defaultValue the default value to use if the property is not 426 * available or a security exception prevents access 427 * @return the system property value or the default value if the property is 428 * not available or security does not allow its access 429 */ 430 public static String getSystemProperty(String name, String defaultValue) { 431 try { 432 return System.getProperty(name, defaultValue); 433 } catch (Exception e) { 434 if (LOG.isDebugEnabled()) { 435 LOG.debug("Caught security exception accessing system property: " + name + ". Reason: " + e, 436 e); 437 } 438 return defaultValue; 439 } 440 } 441 442 /** 443 * A helper method to access a boolean system property, catching any security 444 * exceptions 445 * 446 * @param name the name of the system property required 447 * @param defaultValue the default value to use if the property is not 448 * available or a security exception prevents access 449 * @return the boolean representation of the system property value 450 * or the default value if the property is not available or 451 * security does not allow its access 452 */ 453 public static boolean getSystemProperty(String name, Boolean defaultValue) { 454 String result = getSystemProperty(name, defaultValue.toString()); 455 return Boolean.parseBoolean(result); 456 } 457 458 /** 459 * Returns the type name of the given type or null if the type variable is 460 * null 461 */ 462 public static String name(Class type) { 463 return type != null ? type.getName() : null; 464 } 465 466 /** 467 * Returns the type name of the given value 468 */ 469 public static String className(Object value) { 470 return name(value != null ? value.getClass() : null); 471 } 472 473 /** 474 * Returns the canonical type name of the given value 475 */ 476 public static String classCanonicalName(Object value) { 477 if (value != null) { 478 return value.getClass().getCanonicalName(); 479 } else { 480 return null; 481 } 482 } 483 484 /** 485 * Attempts to load the given class name using the thread context class 486 * loader or the class loader used to load this class 487 * 488 * @param name the name of the class to load 489 * @return the class or null if it could not be loaded 490 */ 491 public static Class<?> loadClass(String name) { 492 return loadClass(name, ObjectHelper.class.getClassLoader()); 493 } 494 495 /** 496 * Attempts to load the given class name using the thread context class 497 * loader or the given class loader 498 * 499 * @param name the name of the class to load 500 * @param loader the class loader to use after the thread context class 501 * loader 502 * @return the class or null if it could not be loaded 503 */ 504 public static Class<?> loadClass(String name, ClassLoader loader) { 505 // must clean the name so its pure java name, eg remoing \n or whatever people can do in the Spring XML 506 name = normalizeClassName(name); 507 508 // special for byte[] as its common to use 509 if ("java.lang.byte[]".equals(name) || "byte[]".equals(name)) { 510 return byte[].class; 511 } 512 513 // try context class loader first 514 Class clazz = doLoadClass(name, Thread.currentThread().getContextClassLoader()); 515 if (clazz == null) { 516 // then the provided loader 517 clazz = doLoadClass(name, loader); 518 } 519 if (clazz == null) { 520 // and fallback to the loader the loaded the ObjectHelper class 521 clazz = doLoadClass(name, ObjectHelper.class.getClassLoader()); 522 } 523 524 if (clazz == null) { 525 LOG.warn("Could not find class: " + name); 526 } 527 528 return clazz; 529 } 530 531 /** 532 * Loads the given class with the provided classloader (may be null). 533 * Will ignore any class not found and return null. 534 * 535 * @param name the name of the class to load 536 * @param loader a provided loader (may be null) 537 * @return the class, or null if it could not be loaded 538 */ 539 private static Class<?> doLoadClass(String name, ClassLoader loader) { 540 ObjectHelper.notEmpty(name, "name"); 541 if (loader == null) { 542 return null; 543 } 544 try { 545 return loader.loadClass(name); 546 } catch (ClassNotFoundException e) { 547 if (LOG.isTraceEnabled()) { 548 LOG.trace("Can not load class: " + name + " using classloader: " + loader, e); 549 } 550 551 } 552 return null; 553 } 554 555 /** 556 * Attempts to load the given resource as a stream using the thread context class 557 * loader or the class loader used to load this class 558 * 559 * @param name the name of the resource to load 560 * @return the stream or null if it could not be loaded 561 */ 562 public static InputStream loadResourceAsStream(String name) { 563 InputStream in = null; 564 565 ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); 566 if (contextClassLoader != null) { 567 in = contextClassLoader.getResourceAsStream(name); 568 } 569 if (in == null) { 570 in = ObjectHelper.class.getClassLoader().getResourceAsStream(name); 571 } 572 573 return in; 574 } 575 576 /** 577 * A helper method to invoke a method via reflection and wrap any exceptions 578 * as {@link RuntimeCamelException} instances 579 * 580 * @param method the method to invoke 581 * @param instance the object instance (or null for static methods) 582 * @param parameters the parameters to the method 583 * @return the result of the method invocation 584 */ 585 public static Object invokeMethod(Method method, Object instance, Object... parameters) { 586 try { 587 return method.invoke(instance, parameters); 588 } catch (IllegalAccessException e) { 589 throw new RuntimeCamelException(e); 590 } catch (InvocationTargetException e) { 591 throw new RuntimeCamelException(e.getCause()); 592 } 593 } 594 595 /** 596 * Returns a list of methods which are annotated with the given annotation 597 * 598 * @param type the type to reflect on 599 * @param annotationType the annotation type 600 * @return a list of the methods found 601 */ 602 public static List<Method> findMethodsWithAnnotation(Class<?> type, 603 Class<? extends Annotation> annotationType) { 604 return findMethodsWithAnnotation(type, annotationType, false); 605 } 606 607 /** 608 * Returns a list of methods which are annotated with the given annotation 609 * 610 * @param type the type to reflect on 611 * @param annotationType the annotation type 612 * @param checkMetaAnnotations check for meta annotations 613 * @return a list of the methods found 614 */ 615 public static List<Method> findMethodsWithAnnotation(Class<?> type, 616 Class<? extends Annotation> annotationType, boolean checkMetaAnnotations) { 617 List<Method> answer = new ArrayList<Method>(); 618 do { 619 Method[] methods = type.getDeclaredMethods(); 620 for (Method method : methods) { 621 if (hasAnnotation(method, annotationType, checkMetaAnnotations)) { 622 answer.add(method); 623 } 624 } 625 type = type.getSuperclass(); 626 } while (type != null); 627 return answer; 628 } 629 630 /** 631 * Checks if a Class or Method are annotated with the given annotation 632 * 633 * @param elem the Class or Method to reflect on 634 * @param annotationType the annotation type 635 * @param checkMetaAnnotations check for meta annotations 636 * @return true if annotations is present 637 */ 638 public static boolean hasAnnotation(AnnotatedElement elem, 639 Class<? extends Annotation> annotationType, boolean checkMetaAnnotations) { 640 if (elem.isAnnotationPresent(annotationType)) { 641 return true; 642 } 643 if (checkMetaAnnotations) { 644 for (Annotation a : elem.getAnnotations()) { 645 for (Annotation meta : a.annotationType().getAnnotations()) { 646 if (meta.annotationType().getName().equals(annotationType.getName())) { 647 return true; 648 } 649 } 650 } 651 } 652 return false; 653 } 654 655 /** 656 * Turns the given object arrays into a meaningful string 657 * 658 * @param objects an array of objects or null 659 * @return a meaningful string 660 */ 661 public static String asString(Object[] objects) { 662 if (objects == null) { 663 return "null"; 664 } else { 665 StringBuffer buffer = new StringBuffer("{"); 666 int counter = 0; 667 for (Object object : objects) { 668 if (counter++ > 0) { 669 buffer.append(", "); 670 } 671 String text = (object == null) ? "null" : object.toString(); 672 buffer.append(text); 673 } 674 buffer.append("}"); 675 return buffer.toString(); 676 } 677 } 678 679 /** 680 * Returns true if a class is assignable from another class like the 681 * {@link Class#isAssignableFrom(Class)} method but which also includes 682 * coercion between primitive types to deal with Java 5 primitive type 683 * wrapping 684 */ 685 public static boolean isAssignableFrom(Class a, Class b) { 686 a = convertPrimitiveTypeToWrapperType(a); 687 b = convertPrimitiveTypeToWrapperType(b); 688 return a.isAssignableFrom(b); 689 } 690 691 /** 692 * Converts primitive types such as int to its wrapper type like 693 * {@link Integer} 694 */ 695 public static Class convertPrimitiveTypeToWrapperType(Class type) { 696 Class rc = type; 697 if (type.isPrimitive()) { 698 if (type == int.class) { 699 rc = Integer.class; 700 } else if (type == long.class) { 701 rc = Long.class; 702 } else if (type == double.class) { 703 rc = Double.class; 704 } else if (type == float.class) { 705 rc = Float.class; 706 } else if (type == short.class) { 707 rc = Short.class; 708 } else if (type == byte.class) { 709 rc = Byte.class; 710 // TODO: Why is boolean disabled 711 /* 712 } else if (type == boolean.class) { 713 rc = Boolean.class; 714 */ 715 } 716 } 717 return rc; 718 } 719 720 /** 721 * Helper method to return the default character set name 722 */ 723 public static String getDefaultCharacterSet() { 724 return Charset.defaultCharset().name(); 725 } 726 727 /** 728 * Returns the Java Bean property name of the given method, if it is a setter 729 */ 730 public static String getPropertyName(Method method) { 731 String propertyName = method.getName(); 732 if (propertyName.startsWith("set") && method.getParameterTypes().length == 1) { 733 propertyName = propertyName.substring(3, 4).toLowerCase() + propertyName.substring(4); 734 } 735 return propertyName; 736 } 737 738 /** 739 * Returns true if the given collection of annotations matches the given type 740 */ 741 public static boolean hasAnnotation(Annotation[] annotations, Class<?> type) { 742 for (Annotation annotation : annotations) { 743 if (type.isInstance(annotation)) { 744 return true; 745 } 746 } 747 return false; 748 } 749 750 /** 751 * Closes the given resource if it is available, logging any closing exceptions to the given log 752 * 753 * @param closeable the object to close 754 * @param name the name of the resource 755 * @param log the log to use when reporting closure warnings 756 */ 757 public static void close(Closeable closeable, String name, Log log) { 758 if (closeable != null) { 759 try { 760 closeable.close(); 761 } catch (IOException e) { 762 if (log != null) { 763 log.warn("Could not close: " + name + ". Reason: " + e, e); 764 } 765 } 766 } 767 } 768 769 /** 770 * Converts the given value to the required type or throw a meaningful exception 771 */ 772 public static <T> T cast(Class<T> toType, Object value) { 773 if (toType == boolean.class) { 774 return (T)cast(Boolean.class, value); 775 } else if (toType.isPrimitive()) { 776 Class newType = convertPrimitiveTypeToWrapperType(toType); 777 if (newType != toType) { 778 return (T)cast(newType, value); 779 } 780 } 781 try { 782 return toType.cast(value); 783 } catch (ClassCastException e) { 784 throw new IllegalArgumentException("Failed to convert: " + value + " to type: " 785 + toType.getName() + " due to: " + e, e); 786 } 787 } 788 789 /** 790 * A helper method to create a new instance of a type using the default constructor arguments. 791 */ 792 public static <T> T newInstance(Class<T> type) { 793 try { 794 return type.newInstance(); 795 } catch (InstantiationException e) { 796 throw new RuntimeCamelException(e); 797 } catch (IllegalAccessException e) { 798 throw new RuntimeCamelException(e); 799 } 800 } 801 802 /** 803 * A helper method to create a new instance of a type using the default constructor arguments. 804 */ 805 public static <T> T newInstance(Class<?> actualType, Class<T> expectedType) { 806 try { 807 Object value = actualType.newInstance(); 808 return cast(expectedType, value); 809 } catch (InstantiationException e) { 810 throw new RuntimeCamelException(); 811 } catch (IllegalAccessException e) { 812 throw new RuntimeCamelException(e); 813 } 814 } 815 816 /** 817 * Returns true if the given name is a valid java identifier 818 */ 819 public static boolean isJavaIdentifier(String name) { 820 if (name == null) { 821 return false; 822 } 823 int size = name.length(); 824 if (size < 1) { 825 return false; 826 } 827 if (Character.isJavaIdentifierStart(name.charAt(0))) { 828 for (int i = 1; i < size; i++) { 829 if (!Character.isJavaIdentifierPart(name.charAt(i))) { 830 return false; 831 } 832 } 833 return true; 834 } 835 return false; 836 } 837 838 /** 839 * Returns the type of the given object or null if the value is null 840 */ 841 public static Object type(Object bean) { 842 return bean != null ? bean.getClass() : null; 843 } 844 845 /** 846 * Evaluate the value as a predicate which attempts to convert the value to 847 * a boolean otherwise true is returned if the value is not null 848 */ 849 public static boolean evaluateValuePredicate(Object value) { 850 if (value instanceof Boolean) { 851 Boolean aBoolean = (Boolean)value; 852 return aBoolean.booleanValue(); 853 } else if (value instanceof String) { 854 if ("true".equals(value)) { 855 return true; 856 } else if ("false".equals(value)) { 857 return false; 858 } 859 } 860 return value != null; 861 } 862 863 /** 864 * Wraps the caused exception in a {@link RuntimeCamelException} if its not already such an exception. 865 * 866 * @param e the caused exception 867 * @return the wrapper exception 868 */ 869 public static RuntimeCamelException wrapRuntimeCamelException(Throwable e) { 870 if (e instanceof RuntimeCamelException) { 871 // don't double wrap if already a RuntimeCamelException 872 return (RuntimeCamelException) e; 873 } else { 874 return new RuntimeCamelException(e); 875 } 876 } 877 878 /** 879 * Cleans the string to pure java identifier so we can use it for loading class names. 880 * <p/> 881 * Especially from Sping DSL people can have \n \t or other characters that otherwise 882 * would result in ClassNotFoundException 883 * 884 * @param name the class name 885 * @return normalized classname that can be load by a class loader. 886 */ 887 public static String normalizeClassName(String name) { 888 StringBuffer sb = new StringBuffer(name.length()); 889 for (char ch : name.toCharArray()) { 890 if (ch == '.' || ch == '[' || ch == ']' || Character.isJavaIdentifierPart(ch)) { 891 sb.append(ch); 892 } 893 } 894 return sb.toString(); 895 } 896 897 public static String after(String text, String after) { 898 if (!text.contains(after)) { 899 return null; 900 } 901 return text.substring(text.indexOf(after) + after.length()); 902 } 903 904 public static String before(String text, String before) { 905 if (!text.contains(before)) { 906 return null; 907 } 908 return text.substring(0, text.indexOf(before)); 909 } 910 911 public static String between(String text, String after, String before) { 912 text = after(text, after); 913 if (text == null) { 914 return null; 915 } 916 return before(text, before); 917 } 918 919 }