1 10 11 package org.mmbase.util; 12 13 21 22 import java.util.*; 23 import java.text.*; 24 import java.io.*; 25 import javax.xml.parsers.*; 26 import javax.xml.transform.*; 27 import org.mmbase.bridge.Node; 28 import org.mmbase.bridge.Cloud; 29 import org.mmbase.bridge.ContextProvider; 30 import org.mmbase.bridge.util.NodeWrapper; 31 import org.mmbase.bridge.util.NodeMap; 32 import org.mmbase.bridge.util.MapNode; 33 import org.mmbase.util.transformers.CharTransformer; 34 import org.mmbase.util.logging.*; 35 import org.mmbase.util.xml.XMLWriter; 36 37 import org.w3c.dom.*; 38 39 public class Casting { 40 41 52 public final static DateFormat ISO_8601_LOOSE = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US); 53 54 62 public final static DateFormat ISO_8601_UTC = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); 63 static { 64 ISO_8601_UTC.setTimeZone(TimeZone.getTimeZone("UTC")); 65 } 66 67 public final static DateFormat ISO_8601_DATE = new SimpleDateFormat("yyyy-MM-dd", Locale.US); 68 public final static DateFormat ISO_8601_TIME = new SimpleDateFormat("HH:mm:ss", Locale.US); 69 70 71 72 private static final Logger log = Logging.getLoggerInstance(Casting.class); 73 74 83 public static boolean isType(Class type, Object value) { 84 if (type.isPrimitive()) { 85 return (type.equals(Boolean.TYPE) && value instanceof Boolean ) || 86 (type.equals(Byte.TYPE) && value instanceof Byte ) || 87 (type.equals(Character.TYPE) && value instanceof Character ) || 88 (type.equals(Short.TYPE) && value instanceof Short ) || 89 (type.equals(Integer.TYPE) && value instanceof Integer ) || 90 (type.equals(Long.TYPE) && value instanceof Long ) || 91 (type.equals(Float.TYPE) && value instanceof Float ) || 92 (type.equals(Double.TYPE) && value instanceof Double ); 93 } else { 94 return value == null || type.isInstance(value); 95 } 96 } 97 98 108 public static Object toType(Class type, Object value) { 109 return toType(type, null, value); 110 } 111 112 private static Cloud anonymousCloud = null; 113 114 125 public static Object toType(Class type, Cloud cloud, Object value) { 126 if (value != null && isType(type, value)) { 127 return value; 128 } else { 129 if (type.equals(Boolean.TYPE) || type.equals(Boolean .class)) { 130 return Boolean.valueOf(toBoolean(value)); 131 } else if (type.equals(Byte.TYPE) || type.equals(Byte .class)) { 132 return new Byte (toInteger(value).byteValue()); 133 } else if (type.equals(Character.TYPE) || type.equals(Character .class)) { 134 String chars = toString(value); 135 if (chars.length() > 0) { 136 return new Character (chars.charAt(0)); 137 } else { 138 return new Character (Character.MIN_VALUE); 139 } 140 } else if (type.equals(Short.TYPE) || type.equals(Short .class)) { 141 return new Short (toInteger(value).shortValue()); 142 } else if (type.equals(Integer.TYPE) || type.equals(Integer .class)) { 143 return toInteger(value); 144 } else if (type.equals(Long.TYPE) || type.equals(Long .class)) { 145 return new Long (toLong(value)); 146 } else if (type.equals(Float.TYPE) || type.equals(Float .class)) { 147 return new Float (toFloat(value)); 148 } else if (type.equals(Double.TYPE) || type.equals(Double .class)) { 149 return new Double (toDouble(value)); 150 } else if (type.equals(Number .class)) { 151 Number res; 152 try { 153 res = new Long ("" + value); 154 } catch (NumberFormatException nfe) { 155 try { 156 res = new Double ("" + value); 157 } catch (NumberFormatException nfe1) { 158 res = new Integer (-1); 159 } 160 } 161 return res; 162 } else if (type.equals(byte[].class)) { 163 return toByte(value); 164 } else if (type.equals(String .class)) { 165 return toString(value); 166 } else if (type.equals(Date.class)) { 167 return toDate(value); 168 } else if (type.equals(Node.class)) { 169 try { 170 if (cloud == null) { 171 if (anonymousCloud == null) anonymousCloud = ContextProvider.getDefaultCloudContext().getCloud("mmbase"); 172 cloud = anonymousCloud; 173 } 174 return toNode(value, cloud); 175 } catch (Exception e) { 176 return value instanceof Node ? value : null; 178 } 179 } else if (type.equals(Document.class)) { 180 return toXML(value); 181 } else if (type.equals(List.class)) { 182 return toList(value); 183 } else if (type.equals(Map.class)) { 184 return toMap(value); 185 } else if (type.equals(Collection.class)) { 186 return toCollection(value); 187 } else { 188 if (value == null || "".equals(value)) { 189 return null; 191 } 192 log.error("Dont now how to convert to " + type); 193 return value; 195 } 196 } 197 } 198 199 204 public static boolean isStringRepresentable(Class type) { 205 return 206 CharSequence .class.isAssignableFrom(type) || 207 Number .class.isAssignableFrom(type) || 208 Boolean.TYPE.isAssignableFrom(type) || 209 Boolean .class.isAssignableFrom(type) || 210 Character .class.isAssignableFrom(type) || 211 Node.class.isAssignableFrom(type) || 212 Document.class.isAssignableFrom(type) || 213 Collection.class.isAssignableFrom(type) || 214 Map.class.isAssignableFrom(type); 215 } 216 217 223 public static String toString(Object o) { 224 if (o instanceof String ) { 225 return (String )o; 226 } 227 if (o == null || "".equals(o)) { 228 return ""; 229 } 230 231 return toStringBuffer(new StringBuffer (), o).toString(); 232 } 233 234 241 public static StringBuffer toStringBuffer(StringBuffer buffer, Object o) { 242 if (o == null) { 243 return buffer; 244 } 245 try { 246 toWriter(new StringBufferWriter(buffer), o); 247 } catch (java.io.IOException e) {} 248 return buffer; 249 } 250 251 258 public static Writer toWriter(Writer writer, Object o) throws java.io.IOException { 259 if (o instanceof Writer) { 260 return writer; 261 } 262 Object s = wrap(o, null); 263 writer.write(s.toString()); 264 return writer; 265 } 266 267 279 280 public static Object wrap(final Object o, final CharTransformer escaper) { 281 if (o == null) { 282 return escape(escaper, ""); 283 } else if (o instanceof Node) { 284 return new NodeMap((Node)o) { 285 public Object getValue(String fieldName) { 286 switch(getNodeManager().getField(fieldName).getType()) { 287 case org.mmbase.bridge.Field.TYPE_NODE: return wrap(getNodeValue(fieldName), escaper); 288 case org.mmbase.bridge.Field.TYPE_DATETIME: return wrap(getDateValue(fieldName), escaper); 289 case org.mmbase.bridge.Field.TYPE_XML: return wrap(getXMLValue(fieldName), escaper); 290 default: return escape(escaper, super.getStringValue(fieldName)); 291 } 292 } 293 public String toString() { 294 return escape(escaper, "" + node.getNumber()); 295 } 296 }; 297 } else if (o instanceof Date) { 298 return new java.util.Date (((Date)o).getTime()) { 299 private static final long serialVersionUID = 1L; public String toString() { 301 long time = getTime(); 302 return time == -1 ? ("" + time) : ("" + time / 1000); 303 } 304 }; 305 } else if (o instanceof org.w3c.dom.Node ) { 306 return escape(escaper, XMLWriter.write((org.w3c.dom.Node ) o, false, true)); 308 } else if (o instanceof List) { 309 return new ListWrapper((List) o, escaper); 310 } else if (o instanceof byte[]) { 311 return escape(escaper, new String ((byte[])o)); 312 } else if (o instanceof String ) { 313 return escape(escaper, (String ) o); 314 } else if (o instanceof CharSequence ) { 315 return new StringWrapper((CharSequence ) o, escaper); 316 } else { 317 return o; 318 } 319 320 321 } 322 323 private static String escape(CharTransformer escaper, CharSequence string) { 324 if (escaper != null) { 325 return escaper.transform(string.toString()); 326 } else { 327 return string.toString(); 328 } 329 } 330 334 public static Object unWrap(final Object o) { 335 if (o instanceof NodeWrapper) { 336 return ((NodeWrapper)o).getNode(); 337 } else if (o instanceof ListWrapper) { 338 return ((ListWrapper)o).getList(); 339 } else if (o instanceof StringWrapper) { 340 return ((StringWrapper)o).getString(); 341 } else { 342 return o; 343 } 344 } 345 346 355 public static List toList(Object o) { 356 return toList(o, ","); 357 } 358 359 365 public static List toList(Object o, String delimiter) { 366 if (o instanceof List) { 367 return (List)o; 368 } else if (o instanceof Collection) { 369 return new ArrayList((Collection) o); 370 } else if (o instanceof String ) { 371 if ("".equals(delimiter) || delimiter == null) delimiter = ","; 372 return StringSplitter.split((String )o, delimiter); 373 } else if (o instanceof Map) { 374 return new ArrayList(((Map)o).entrySet()); 375 } else { 376 List l = new ArrayList(); 377 if (o != null) { 378 l.add(o); 379 } 380 return l; 381 } 382 } 383 384 385 388 public static Map toMap(Object o) { 389 if (o instanceof Map) { 390 return (Map) o; 391 } else if (o instanceof org.mmbase.util.functions.Parameters) { 392 return ((org.mmbase.util.functions.Parameters) o).toMap(); 393 } else if (o instanceof Collection) { 394 Map result = new HashMap(); 395 Iterator i = ((Collection)o).iterator(); 396 while (i.hasNext()) { 397 Object n = i.next(); 398 if (n instanceof Map.Entry) { 399 Map.Entry entry = (Map.Entry) n; 400 result.put(entry.getKey(), entry.getValue()); 401 } else { 402 result.put(n, n); 403 } 404 } 405 return result; 406 } else if (o instanceof Node) { 407 return new NodeMap((Node)o); 408 } else { 409 Map m = new HashMap(); 410 m.put(o, o); 411 return m; 412 } 413 } 414 415 422 public static Collection toCollection(Object o) { 423 if (o instanceof Collection) { 424 return (Collection)o; 425 } else if (o instanceof Map) { 426 return ((Map)o).entrySet(); 427 } else if (o instanceof String ) { 428 return StringSplitter.split((String )o); 429 } else { 430 List l = new ArrayList(); 431 if (o != null) { 432 l.add(o); 433 } 434 return l; 435 } 436 } 437 438 449 static public Document toXML(Object o) { 450 if (o == null) return null; 451 if (!(o instanceof Document)) { 452 String xmltext = toString(o); 456 if (log.isDebugEnabled()) { 457 String msg = xmltext; 458 if (msg.length() > 84) { 459 msg = msg.substring(0, 80) + "..."; 460 } 461 log.debug("Object '" + msg + "' is not a Document, but a " + o.getClass().getName() + ""); 462 } 463 return convertStringToXML(xmltext); 464 } 465 return (Document)o; 466 } 467 468 473 static public byte[] toByte(Object obj) { 474 if (obj == null) { 475 return new byte[] {}; 476 } else if (obj instanceof byte[]) { 477 return (byte[])obj; 479 } else if (obj instanceof org.apache.commons.fileupload.FileItem) { 480 return ((org.apache.commons.fileupload.FileItem) obj).get(); 481 } else { 482 return toString(obj).getBytes(); 483 } 484 } 485 486 static public InputStream toInputStream(Object obj) { 487 if (obj instanceof InputStream) { 488 return (InputStream) obj; 489 } else { 490 return new ByteArrayInputStream(toByte(obj)); 491 } 492 } 493 494 495 507 public static Node toNode(Object i, Cloud cloud) { 508 Node res = null; 509 if (i instanceof Node) { 510 res = (Node)i; 511 } else if (i instanceof Number ) { 512 int nodenumber = ((Number )i).intValue(); 513 if (nodenumber != -1) { 514 res = cloud.getNode(nodenumber); 515 } 516 } else if (i instanceof Map) { 517 res = new MapNode((Map)i, cloud); 518 } else if (i != null && !i.equals("")) { 519 res = cloud.getNode(i.toString()); 520 } 521 return res; 522 } 523 524 535 static public int toInt(Object i, int def) { 536 int res = def; 537 if (i instanceof Node) { 538 res = ((Node)i).getNumber(); 539 } else if (i instanceof Boolean ) { 540 res = ((Boolean )i).booleanValue() ? 1 : 0; 541 } else if (i instanceof Date) { 542 long timeValue = ((Date)i).getTime(); 543 if (timeValue !=-1) timeValue = timeValue / 1000; 544 if (timeValue > Integer.MAX_VALUE) { 545 timeValue = Integer.MAX_VALUE; 546 } 547 if (timeValue < Integer.MIN_VALUE) { 548 timeValue = Integer.MIN_VALUE; 549 } 550 res = (int) timeValue; 551 } else if (i instanceof Number ) { 552 long l = ((Number )i).longValue(); 553 if (l > Integer.MAX_VALUE) { 554 res = Integer.MAX_VALUE; 555 } else if (l < Integer.MIN_VALUE) { 556 res = Integer.MIN_VALUE; 557 } else { 558 res = (int) l; 559 } 560 } else if (i != null) { 561 try { 562 res = Integer.parseInt("" + i); 563 } catch (NumberFormatException e) { 564 try { 566 res = Double.valueOf("" + i).intValue(); 567 } catch (NumberFormatException ex) { 568 569 if(i instanceof String ){ 571 if(((String )i).toLowerCase().equals(("true"))){ 572 res = 1; 573 }else if(((String )i).toLowerCase().equals(("false"))){ 574 res = 0; 575 } 576 } 577 } 578 } 579 } 580 return res; 581 } 582 583 592 static public int toInt(Object i) { 593 return toInt(i, -1); 594 } 595 596 597 598 610 static public boolean toBoolean(Object b) { 611 if (b == null) { 612 return false; 613 } else if (b instanceof Boolean ) { 614 return ((Boolean )b).booleanValue(); 615 } else if (b instanceof Number ) { 616 return ((Number )b).doubleValue() > 0; 617 } else if (b instanceof Node) { 618 return true; } else if (b instanceof Date) { 620 return ((Date)b).getTime() != -1; 621 } else if (b instanceof Document) { 622 return false; } else if (b instanceof String ) { 624 String s = ((String )b).toLowerCase(); 627 return s.equals("true") || s.equals("yes") || s.equals("1"); 628 } else { 629 return false; 630 } 631 } 632 633 641 static public Integer toInteger(Object i) { 642 if (i instanceof Integer ) { 643 return (Integer )i; 644 } else { 645 return new Integer (toInt(i)); 646 } 647 } 648 649 659 static public long toLong(Object i, long def) { 660 long res = def; 661 if (i instanceof Boolean ) { 662 res = ((Boolean )i).booleanValue() ? 1 : 0; 663 } else if (i instanceof Number ) { 664 res = ((Number )i).longValue(); 665 } else if (i instanceof Date) { 666 res = ((Date)i).getTime(); 667 if (res !=- 1) res /= 1000; 668 } else if (i instanceof Node) { 669 res = ((Node)i).getNumber(); 670 } else if (i != null) { 671 if(i instanceof String ){ 672 if(((String )i).toLowerCase().equals("true")) return 1; 673 if(((String )i).toLowerCase().equals("false")) return 0; 674 } 675 try { 676 res = Long.parseLong("" + i); 677 } catch (NumberFormatException e) { 678 try { 680 res = Double.valueOf("" + i).longValue(); 681 } catch (NumberFormatException ex) { 682 } 684 } 685 } 686 return res; 687 } 688 689 698 static public long toLong(Object i) { 699 return toLong(i, -1); 700 } 701 702 711 static public float toFloat(Object i, float def) { 712 float res = def; 713 if (i instanceof Boolean ) { 714 res = ((Boolean )i).booleanValue() ? 1 : 0; 715 } else if (i instanceof Number ) { 716 res = ((Number )i).floatValue(); 717 } else if (i instanceof Date) { 718 res = ((Date)i).getTime(); 719 if (res!=-1) res = res / 1000; 720 } else if (i instanceof Node) { 721 res = ((Node)i).getNumber(); 722 } else if (i != null) { 723 if(i instanceof String ){ 724 if(((String )i).toLowerCase().equals("true")) { 725 res = 1; 726 } else if(((String )i).toLowerCase().equals("false")) { 727 res = 0; 728 } 729 } 730 try { 731 res = Float.parseFloat("" + i); 732 } catch (NumberFormatException e) { 733 if(i instanceof String ){ 735 if(((String )i).toLowerCase().equals(("true"))){ 736 res = 1; 737 } else if(((String )i).toLowerCase().equals(("false"))){ 738 res = 0; 739 } 740 } 741 } 742 } 743 return res; 744 } 745 746 754 static public float toFloat(Object i) { 755 return toFloat(i, -1); 756 } 757 758 767 static public double toDouble(Object i, double def) { 768 double res = def; 769 if (i instanceof Boolean ) { 770 res = ((Boolean )i).booleanValue() ? 1 : 0; 771 } else if (i instanceof Number ) { 772 res = ((Number )i).doubleValue(); 773 } else if (i instanceof Date) { 774 res = ((Date)i).getTime(); 775 if (res != -1) res = res / 1000; 776 } else if (i instanceof Node) { 777 res = ((Node)i).getNumber(); 778 } else if (i != null) { 779 try { 780 res = Double.parseDouble("" + i); 781 } catch (NumberFormatException e) { 782 if(i instanceof String ){ 784 if(((String )i).toLowerCase().equals(("true"))){ 785 res = 1; 786 }else if(((String )i).toLowerCase().equals(("false"))){ 787 res = 0; 788 } 789 } 790 } 791 } 792 return res; 793 } 794 795 803 static public double toDouble(Object i) { 804 return toDouble(i, -1); 805 } 806 807 808 809 818 static public Date toDate(Object d) { 819 if (d == null) return new Date(-1); 820 Date date = null; 821 822 if (d instanceof Date) { 823 date = (Date) d; 824 } else { 825 try { 826 long dateInSeconds = -1; 827 if (d instanceof Number ) { 828 dateInSeconds = ((Number )d).longValue(); 829 } else if (d instanceof Document) { 830 dateInSeconds = -1; 832 } else if (d instanceof Boolean ) { 833 dateInSeconds = -1; 834 } else if (d instanceof Collection) { 835 dateInSeconds = -1; 837 } else if (d instanceof Node) { 838 dateInSeconds = -1; 840 } else if (d != null) { 841 d = toString(d); 842 if (d.equals("")) { 843 return new Date(-1); 844 } 845 dateInSeconds = Long.parseLong((String ) d); 846 } else { 847 dateInSeconds = -1; 848 } 849 if (dateInSeconds == -1) { 850 date = new Date(-1); 851 } else if (dateInSeconds > Long.MAX_VALUE / 1000) { 852 date = new Date(Long.MAX_VALUE); } else if (dateInSeconds < Long.MIN_VALUE / 1000) { 854 date = new Date(Long.MIN_VALUE); } else { 856 date = new Date(dateInSeconds * 1000); 857 } 858 } catch (NumberFormatException e) { 859 try { 860 date = DynamicDate.getInstance((String ) d); 861 } catch (org.mmbase.util.dateparser.ParseException pe) { 862 log.error("Parser exception in " + d, pe); 863 return new Date(-1); 864 } catch (Error per) { 865 throw new Error ("Parser error in " + d, per); 866 } 867 } 868 } 869 return date; 870 } 871 872 static DocumentBuilder DOCUMENTBUILDER; 873 static { 874 try { 875 DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); 876 dfactory.setValidating(false); 877 dfactory.setNamespaceAware(true); 878 DOCUMENTBUILDER = dfactory.newDocumentBuilder(); 879 DOCUMENTBUILDER.setEntityResolver(new XMLEntityResolver(false)); 880 } catch (ParserConfigurationException pce) { 881 log.error("[sax parser]: " + pce.toString() + "\n" + Logging.stackTrace(pce)); 882 } 883 } 884 890 static private Document convertStringToXML(String value) { 891 if (value == null) { 892 return null; 893 } 894 if (log.isDebugEnabled()) { 895 log.trace("using xml string:\n" + value); 896 } 897 try { 898 Document doc; 899 final XMLErrorHandler errorHandler = new XMLErrorHandler(false, org.mmbase.util.XMLErrorHandler.NEVER); 900 synchronized(DOCUMENTBUILDER) { 901 DOCUMENTBUILDER.setErrorHandler(errorHandler); 903 doc = DOCUMENTBUILDER.parse(new java.io.ByteArrayInputStream (value.getBytes("UTF-8"))); 906 } 907 if (log.isDebugEnabled()) { 908 log.trace("parsed: " + XMLWriter.write(doc, false, true)); 909 } 910 if (!errorHandler.foundNothing()) { 911 throw new IllegalArgumentException ("xml invalid:\n" + errorHandler.getMessageBuffer() + "for xml:\n" + value); 912 } 913 return doc; 914 } catch (org.xml.sax.SAXException se) { 915 log.debug("[sax] not well formed xml: " + se.toString() + "(" + se.getMessage() + ")\n" + Logging.stackTrace(se)); 916 return convertStringToXML("<p>" + Encode.encode("ESCAPE_XML", value) + "</p>"); } catch (java.io.IOException ioe) { 918 String msg = "[io] not well formed xml: " + ioe.toString() + "\n" + Logging.stackTrace(ioe); 919 log.error(msg); 920 throw new IllegalArgumentException (msg); 921 } 922 } 923 924 925 929 public static class ListWrapper extends AbstractList{ 930 private final List list; 931 private final CharTransformer escaper; 932 ListWrapper (List l, CharTransformer e) { 933 list = l; 934 escaper = e; 935 } 936 public Object get(int index) { return Casting.wrap(list.get(index), escaper); } 937 public int size() { return list.size(); } 938 public Object set(int index, Object value) { return list.set(index, value); } 939 public void add(int index, Object value) { list.add(index, value); } 940 public Object remove(int index) { return list.remove(index); } 941 public boolean isEmpty() {return list.isEmpty();} 942 public boolean contains(Object o) {return list.contains(o);} 943 public Object [] toArray() {return list.toArray();} 944 public Object [] toArray(Object [] a) {return list.toArray(a);} 945 public Iterator iterator() { return list.iterator(); } 946 public ListIterator listIterator() { return list.listIterator(); } 947 public String toString() { 948 StringBuffer buf = new StringBuffer (); 949 Iterator i = list.iterator(); 950 boolean hasNext = i.hasNext(); 951 while (hasNext) { 952 Casting.toStringBuffer(buf, i.next()); 953 hasNext = i.hasNext(); 954 if (hasNext) { 955 buf.append(','); 956 } 957 } 958 return buf.toString(); 959 } 960 public List getList() { 961 return list; 962 } 963 } 964 965 969 public static class StringWrapper implements CharSequence { 970 private final CharTransformer escaper; 971 private final CharSequence string; 972 private String escaped = null; 973 StringWrapper(CharSequence s, CharTransformer e) { 974 escaper = e; 975 string = s; 976 977 } 978 979 public char charAt(int index) { 980 toString(); 981 return escaped.charAt(index); 982 } 983 public int length() { 984 toString(); 985 return escaped.length(); 986 } 987 988 public CharSequence subSequence(int start, int end) { 989 toString(); 990 return escaped.subSequence(start, end); 991 } 992 993 public String toString() { 994 if (escaped == null) escaped = escape(escaper, string); 995 return escaped; 996 } 997 public CharSequence getString() { 998 return string; 999 } 1000 } 1001 1002} 1003 1004 1005
| Popular Tags
|