1 16 package org.directwebremoting.util; 17 18 import java.io.IOException ; 19 import java.io.InputStream ; 20 import java.io.RandomAccessFile ; 21 import java.lang.reflect.Field ; 22 import java.lang.reflect.InvocationTargetException ; 23 import java.lang.reflect.Method ; 24 import java.net.URLDecoder ; 25 import java.util.ArrayList ; 26 import java.util.Arrays ; 27 import java.util.HashSet ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import java.util.Locale ; 31 import java.util.Map ; 32 import java.util.Set ; 33 34 import javax.servlet.ServletConfig ; 35 import javax.servlet.ServletContext ; 36 import javax.servlet.http.HttpServletRequest ; 37 import javax.servlet.http.HttpServletResponse ; 38 import javax.servlet.http.HttpSession ; 39 import javax.xml.transform.TransformerFactoryConfigurationError ; 40 41 46 public final class LocalUtil 47 { 48 51 public static final int INBOUND_INDEX_TYPE = 0; 52 53 56 public static final int INBOUND_INDEX_VALUE = 1; 57 58 61 private LocalUtil() 62 { 63 } 64 65 72 public static String replace(String text, String repl, String with) 73 { 74 if (text == null || repl == null || with == null || repl.length() == 0) 75 { 76 return text; 77 } 78 79 StringBuffer buf = new StringBuffer (text.length()); 80 int searchFrom = 0; 81 while (true) 82 { 83 int foundAt = text.indexOf(repl, searchFrom); 84 if (foundAt == -1) 85 { 86 break; 87 } 88 89 buf.append(text.substring(searchFrom, foundAt)).append(with); 90 searchFrom = foundAt + repl.length(); 91 } 92 buf.append(text.substring(searchFrom)); 93 94 return buf.toString(); 95 } 96 97 107 public static boolean isJavaIdentifier(String test) 108 { 109 if (test == null || test.length() == 0) 110 { 111 return false; 112 } 113 114 if (!Character.isJavaIdentifierStart(test.charAt(0))) 115 { 116 return false; 117 } 118 119 for (int i = 1; i < test.length(); i++) 120 { 121 if (!Character.isJavaIdentifierPart(test.charAt(i))) 122 { 123 return false; 124 } 125 } 126 127 return true; 128 } 129 130 136 public static boolean isEquivalent(Class c1, Class c2) 137 { 138 if (c1 == Boolean .class || c1 == Boolean.TYPE) 139 { 140 return c2 == Boolean .class || c2 == Boolean.TYPE; 141 } 142 else if (c1 == Byte .class || c1 == Byte.TYPE) 143 { 144 return c2 == Byte .class || c2 == Byte.TYPE; 145 } 146 else if (c1 == Character .class || c1 == Character.TYPE) 147 { 148 return c2 == Character .class || c2 == Character.TYPE; 149 } 150 else if (c1 == Short .class || c1 == Short.TYPE) 151 { 152 return c2 == Short .class || c2 == Short.TYPE; 153 } 154 else if (c1 == Integer .class || c1 == Integer.TYPE) 155 { 156 return c2 == Integer .class || c2 == Integer.TYPE; 157 } 158 else if (c1 == Long .class || c1 == Long.TYPE) 159 { 160 return c2 == Long .class || c2 == Long.TYPE; 161 } 162 else if (c1 == Float .class || c1 == Float.TYPE) 163 { 164 return c2 == Float .class || c2 == Float.TYPE; 165 } 166 else if (c1 == Double .class || c1 == Double.TYPE) 167 { 168 return c2 == Double .class || c2 == Double.TYPE; 169 } 170 else if (c1 == Void .class || c1 == Void.TYPE) 171 { 172 return c2 == Void .class || c2 == Void.TYPE; 173 } 174 175 return false; 176 } 177 178 182 public static Class getNonPrimitiveType(Class type) 183 { 184 if (!type.isPrimitive()) 185 { 186 return type; 187 } 188 else if (type == Boolean.TYPE) 189 { 190 return Boolean .class; 191 } 192 else if (type == Byte.TYPE) 193 { 194 return Byte .class; 195 } 196 else if (type == Character.TYPE) 197 { 198 return Character .class; 199 } 200 else if (type == Short.TYPE) 201 { 202 return Short .class; 203 } 204 else if (type == Integer.TYPE) 205 { 206 return Integer .class; 207 } 208 else if (type == Long.TYPE) 209 { 210 return Long .class; 211 } 212 else if (type == Float.TYPE) 213 { 214 return Float .class; 215 } 216 else if (type == Double.TYPE) 217 { 218 return Double .class; 219 } 220 else if (type == Void.TYPE) 221 { 222 return Void .class; 223 } 224 225 return null; 226 } 227 228 232 public static void addNoCacheHeaders(HttpServletResponse resp) 233 { 234 resp.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); 236 237 resp.addHeader("Cache-Control", "post-check=0, pre-check=0"); 239 240 resp.setHeader("Pragma", "no-cache"); 242 243 resp.setHeader("Expires", "Sat, 6 May 1995 12:00:00 GMT"); 245 } 246 247 252 public static boolean isServletClass(Class paramType) 253 { 254 return paramType == HttpServletRequest .class || 255 paramType == HttpServletResponse .class || 256 paramType == ServletConfig .class || 257 paramType == ServletContext .class || 258 paramType == HttpSession .class; 259 } 260 261 267 public static String decode(String value) 268 { 269 if (!testedDecoder) 270 { 271 try 272 { 273 decode14 = URLDecoder .class.getMethod("decode", new Class [] { String .class, String .class }); 274 } 275 catch (Exception ex) 276 { 277 if (!warn13) 278 { 279 log.warn("URLDecoder.decode(String, String) is not available. Falling back to 1.3 variant."); 280 warn13 = true; 281 } 282 } 283 284 testedDecoder = true; 285 } 286 287 if (decode14 != null) 288 { 289 try 290 { 291 return (String ) decode14.invoke(null, new Object [] { value, "UTF-8" }); 292 } 293 catch (Exception ex) 294 { 295 log.warn("Failed to use JDK 1.4 decoder", ex); 296 } 297 } 298 299 return URLDecoder.decode(value); 300 } 301 302 310 public static void setParams(Object object, Map params, List ignore) 311 { 312 for (Iterator it = params.entrySet().iterator(); it.hasNext();) 313 { 314 Map.Entry entry = (Map.Entry ) it.next(); 315 String key = (String ) entry.getKey(); 316 Object value = entry.getValue(); 317 318 try 319 { 320 setProperty(object, key, value); 321 } 322 catch (NoSuchMethodException ex) 323 { 324 if (ignore != null && !ignore.contains(key)) 325 { 326 log.warn("No property '" + key + "' on " + object.getClass().getName()); 327 } 328 } 329 catch (InvocationTargetException ex) 330 { 331 log.warn("Error setting " + key + "=" + value + " on " + object.getClass().getName(), ex.getTargetException()); 332 } 333 catch (Exception ex) 334 { 335 log.warn("Error setting " + key + "=" + value + " on " + object.getClass().getName(), ex); 336 } 337 } 338 } 339 340 351 public static void setProperty(Object object, String key, Object value) throws NoSuchMethodException , SecurityException , IllegalAccessException , IllegalArgumentException , InvocationTargetException 352 { 353 Class real = object.getClass(); 354 355 String setterName = "set" + key.substring(0, 1).toUpperCase(Locale.ENGLISH) + key.substring(1); 356 357 try 358 { 359 Method method = real.getMethod(setterName, new Class [] { value.getClass() }); 361 method.invoke(object, new Object [] { value }); 362 return; 363 } 364 catch (NoSuchMethodException ex) 365 { 366 if (!(value instanceof String )) 369 { 370 throw ex; 371 } 372 } 373 374 Method [] methods = real.getMethods(); 375 for (int i = 0; i < methods.length; i++) 376 { 377 Method setter = methods[i]; 378 379 if (setter.getName().equals(setterName) && setter.getParameterTypes().length == 1) 380 { 381 Class propertyType = setter.getParameterTypes()[0]; 382 try 383 { 384 Object param = LocalUtil.simpleConvert((String ) value, propertyType); 385 setter.invoke(object, new Object [] { param }); 386 return; 387 } 388 catch (IllegalArgumentException ex) 389 { 390 } 393 } 394 } 395 396 throw new NoSuchMethodException ("Failed to find a property called: " + key + " on " + object.getClass().getName()); 397 } 398 399 404 public static boolean isTypeSimplyConvertable(Class paramType) 405 { 406 return paramType == String .class || 407 paramType == Integer .class || 408 paramType == Integer.TYPE || 409 paramType == Short .class || 410 paramType == Short.TYPE || 411 paramType == Byte .class || 412 paramType == Byte.TYPE || 413 paramType == Long .class || 414 paramType == Long.TYPE || 415 paramType == Float .class || 416 paramType == Float.TYPE || 417 paramType == Double .class || 418 paramType == Double.TYPE || 419 paramType == Character .class || 420 paramType == Character.TYPE || 421 paramType == Boolean .class || 422 paramType == Boolean.TYPE; 423 } 424 425 433 public static Object simpleConvert(String value, Class paramType) 434 { 435 if (paramType == String .class) 436 { 437 return value; 438 } 439 440 if (paramType == Character .class || paramType == Character.TYPE) 441 { 442 if (value.length() == 1) 443 { 444 return new Character (value.charAt(0)); 445 } 446 else 447 { 448 throw new IllegalArgumentException ("Can't more than one character in string - can't convert to char: '" + value + "'"); 449 } 450 } 451 452 String trimValue = value.trim(); 453 454 if (paramType == Boolean .class) 455 { 456 if (trimValue.length() == 0) 457 { 458 return null; 459 } 460 461 return Boolean.valueOf(trimValue); 462 } 463 464 if (paramType == Boolean.TYPE) 465 { 466 return Boolean.valueOf(trimValue); 467 } 468 469 if (paramType == Integer .class) 470 { 471 if (trimValue.length() == 0) 472 { 473 return null; 474 } 475 476 return Integer.valueOf(trimValue); 477 } 478 479 if (paramType == Integer.TYPE) 480 { 481 if (trimValue.length() == 0) 482 { 483 return new Integer (0); 484 } 485 486 return Integer.valueOf(trimValue); 487 } 488 489 if (paramType == Short .class) 490 { 491 if (trimValue.length() == 0) 492 { 493 return null; 494 } 495 496 return Short.valueOf(trimValue); 497 } 498 499 if (paramType == Short.TYPE) 500 { 501 if (trimValue.length() == 0) 502 { 503 return new Short ((short) 0); 504 } 505 506 return Short.valueOf(trimValue); 507 } 508 509 if (paramType == Byte .class) 510 { 511 if (trimValue.length() == 0) 512 { 513 return null; 514 } 515 516 return Byte.valueOf(trimValue); 517 } 518 519 if (paramType == Byte.TYPE) 520 { 521 if (trimValue.length() == 0) 522 { 523 return new Byte ((byte) 0); 524 } 525 526 return Byte.valueOf(trimValue); 527 } 528 529 if (paramType == Long .class) 530 { 531 if (trimValue.length() == 0) 532 { 533 return null; 534 } 535 536 return Long.valueOf(trimValue); 537 } 538 539 if (paramType == Long.TYPE) 540 { 541 if (trimValue.length() == 0) 542 { 543 return new Long (0); 544 } 545 546 return Long.valueOf(trimValue); 547 } 548 549 if (paramType == Float .class) 550 { 551 if (trimValue.length() == 0) 552 { 553 return null; 554 } 555 556 return Float.valueOf(trimValue); 557 } 558 559 if (paramType == Float.TYPE) 560 { 561 if (trimValue.length() == 0) 562 { 563 return new Float (0); 564 } 565 566 return Float.valueOf(trimValue); 567 } 568 569 if (paramType == Double .class) 570 { 571 if (trimValue.length() == 0) 572 { 573 return null; 574 } 575 576 return Double.valueOf(trimValue); 577 } 578 579 if (paramType == Double.TYPE) 580 { 581 if (trimValue.length() == 0) 582 { 583 return new Double (0); 584 } 585 586 return Double.valueOf(trimValue); 587 } 588 589 throw new IllegalArgumentException ("Unsupported conversion type: " + paramType.getName()); 590 } 591 592 597 public static String getShortClassName(Class clazz) 598 { 599 String className = clazz.getName(); 600 601 char[] chars = className.toCharArray(); 602 int lastDot = 0; 603 for (int i = 0; i < chars.length; i++) 604 { 605 if (chars[i] == '.') 606 { 607 lastDot = i + 1; 608 } 609 else if (chars[i] == '$') 610 { 611 chars[i] = '.'; 612 } 613 } 614 615 return new String (chars, lastDot, chars.length - lastDot); 618 } 619 620 627 public static boolean isSimpleName(String name) 628 { 629 if (name.length() == 0) 630 { 631 return false; 632 } 633 634 if (JavascriptUtil.isReservedWord(name)) 635 { 636 return false; 637 } 638 639 boolean isSimple = Character.isLetter(name.charAt(0)); 640 for (int i = 1; isSimple && i < name.length(); i++) 641 { 642 if (!Character.isLetterOrDigit(name.charAt(i))) 643 { 644 isSimple = false; 645 } 646 } 647 648 return isSimple; 649 } 650 651 660 public static Class classForName(String className) throws ClassNotFoundException 661 { 662 return Thread.currentThread().getContextClassLoader().loadClass(className); 664 } 665 666 675 public static Object invoke(Object object, Method method, Object [] params) throws IllegalStateException 676 { 677 Object reply = null; 678 if (method != null) 679 { 680 try 681 { 682 reply = method.invoke(object, params); 683 } 684 catch (InvocationTargetException ex) 685 { 686 throw new IllegalStateException ("InvocationTargetException calling " + method.getName() + ": " + ex.getTargetException().toString()); 687 } 688 catch (Exception ex) 689 { 690 throw new IllegalStateException ("Reflection error calling " + method.getName() + ": " + ex.toString()); 691 } 692 } 693 694 return reply; 695 } 696 697 706 public static Class classForName(String name, String className, Class impl) 707 { 708 Class clazz; 709 710 try 711 { 712 clazz = classForName(className); 713 } 714 catch (ClassNotFoundException ex) 715 { 716 log.debug("Skipping '" + name + "' due to ClassNotFoundException on " + className + ". Cause: " + ex.getMessage()); 718 return null; 719 } 720 catch (NoClassDefFoundError ex) 721 { 722 log.debug("Skipping '" + name + "' due to NoClassDefFoundError on " + className + ". Cause: " + ex.getMessage()); 724 return null; 725 } 726 catch (TransformerFactoryConfigurationError ex) 727 { 728 log.debug("Skipping '" + name + "' due to TransformerFactoryConfigurationError on " + className + ". Cause: " + ex.getMessage()); 730 log.debug("Maybe you need to add xalan.jar to your webserver?"); 731 return null; 732 } 733 734 if (!impl.isAssignableFrom(clazz)) 736 { 737 log.error("Class '" + clazz.getName() + "' does not implement '" + impl.getName() + "'."); 738 return null; 739 } 740 741 try 743 { 744 clazz.newInstance(); 745 } 746 catch (InstantiationException ex) 747 { 748 log.error("InstantiationException for '" + name + "' failed:", ex); 749 return null; 750 } 751 catch (IllegalAccessException ex) 752 { 753 log.error("IllegalAccessException for '" + name + "' failed:", ex); 754 return null; 755 } 756 catch (NoClassDefFoundError ex) 757 { 758 log.debug("Skipping '" + name + "' due to NoClassDefFoundError on " + className + ". Cause: " + ex.getMessage()); 760 return null; 761 } 762 catch (TransformerFactoryConfigurationError ex) 763 { 764 log.debug("Skipping '" + name + "' due to TransformerFactoryConfigurationError on " + className + ". Cause: " + ex.getMessage()); 766 log.debug("Maybe you need to add xalan.jar to your webserver?"); 767 return null; 768 } 769 catch (Exception ex) 770 { 771 if (ex instanceof ClassNotFoundException ) 773 { 774 log.debug("Skipping '" + name + "' due to ClassNotFoundException on " + className + ". Cause: " + ex.getMessage()); 776 return null; 777 } 778 else 779 { 780 log.error("Failed to load '" + name + "' (" + className + ")", ex); 781 return null; 782 } 783 } 784 785 return clazz; 786 } 787 788 797 public static Object classNewInstance(String name, String className, Class impl) 798 { 799 Class clazz; 800 801 try 802 { 803 clazz = LocalUtil.classForName(className); 804 } 805 catch (ClassNotFoundException ex) 806 { 807 log.debug("Skipping '" + name + "' due to ClassNotFoundException on " + className + ". Cause: " + ex.getMessage()); 809 return null; 810 } 811 catch (NoClassDefFoundError ex) 812 { 813 log.debug("Skipping '" + name + "' due to NoClassDefFoundError on " + className + ". Cause: " + ex.getMessage()); 815 return null; 816 } 817 catch (TransformerFactoryConfigurationError ex) 818 { 819 log.debug("Skipping '" + name + "' due to TransformerFactoryConfigurationError on " + className + ". Cause: " + ex.getMessage()); 821 return null; 822 } 823 824 if (!impl.isAssignableFrom(clazz)) 826 { 827 log.error("Class '" + clazz.getName() + "' does not implement '" + impl.getName() + "'."); 828 return null; 829 } 830 831 try 833 { 834 return clazz.newInstance(); 835 } 836 catch (InstantiationException ex) 837 { 838 log.error("InstantiationException for '" + name + "' failed:", ex); 839 return null; 840 } 841 catch (IllegalAccessException ex) 842 { 843 log.error("IllegalAccessException for '" + name + "' failed:", ex); 844 return null; 845 } 846 catch (TransformerFactoryConfigurationError ex) 847 { 848 log.error("TransformerFactoryConfigurationError for '" + name + "' failed:", ex); 849 return null; 850 } 851 catch (Exception ex) 852 { 853 log.error("Failed to load creator '" + name + "', classname=" + className + ": ", ex); 854 return null; 855 } 856 } 857 858 863 public static void close(InputStream in) 864 { 865 if (in == null) 866 { 867 return; 868 } 869 870 try 871 { 872 in.close(); 873 } 874 catch (IOException ex) 875 { 876 log.warn(ex.getMessage(), ex); 877 } 878 } 879 880 885 public static void close(RandomAccessFile in) 886 { 887 if (in == null) 888 { 889 return; 890 } 891 892 try 893 { 894 in.close(); 895 } 896 catch (IOException ex) 897 { 898 log.warn(ex.getMessage(), ex); 899 } 900 } 901 902 907 public static List getAllSuperclasses(Class clazz) 908 { 909 List classes = new ArrayList (); 910 911 Class superclass = clazz.getSuperclass(); 912 while (superclass != null) 913 { 914 classes.add(superclass); 915 superclass = superclass.getSuperclass(); 916 } 917 918 return classes; 919 } 920 921 930 public static Field [] getAllFields(Class clazz) 931 { 932 List classes = getAllSuperclasses(clazz); 933 classes.add(clazz); 934 return getAllFields(classes); 935 } 936 937 943 private static Field [] getAllFields(List classes) 944 { 945 Set fields = new HashSet (); 946 for (Iterator it = classes.iterator(); it.hasNext();) 947 { 948 Class clazz = (Class ) it.next(); 949 fields.addAll(Arrays.asList(clazz.getDeclaredFields())); 950 } 951 952 return (Field []) fields.toArray(new Field [fields.size()]); 953 } 954 955 958 private static final Logger log = Logger.getLogger(LocalUtil.class); 959 960 963 private static boolean warn13 = false; 964 965 968 private static boolean testedDecoder = false; 969 970 973 private static Method decode14 = null; 974 } 975 | Popular Tags |