1 16 19 20 package org.apache.xalan.xsltc.runtime; 21 22 import java.text.DecimalFormat ; 23 import java.text.FieldPosition ; 24 import java.text.MessageFormat ; 25 import java.text.NumberFormat ; 26 import java.util.Locale ; 27 import java.util.ResourceBundle ; 28 29 import javax.xml.parsers.DocumentBuilder ; 30 import javax.xml.parsers.DocumentBuilderFactory ; 31 import javax.xml.transform.dom.DOMSource ; 32 33 import org.apache.xalan.xsltc.DOM; 34 import org.apache.xalan.xsltc.Translet; 35 import org.apache.xalan.xsltc.dom.AbsoluteIterator; 36 import org.apache.xalan.xsltc.dom.Axis; 37 import org.apache.xalan.xsltc.dom.DOMAdapter; 38 import org.apache.xalan.xsltc.dom.MultiDOM; 39 import org.apache.xalan.xsltc.dom.SingletonIterator; 40 import org.apache.xalan.xsltc.dom.StepIterator; 41 import org.apache.xml.dtm.DTMAxisIterator; 42 import org.apache.xml.dtm.DTMManager; 43 import org.apache.xml.dtm.ref.DTMDefaultBase; 44 45 import org.w3c.dom.DOMException ; 46 import org.w3c.dom.Document ; 47 import org.w3c.dom.NodeList ; 48 import org.xml.sax.SAXException ; 49 import org.apache.xml.serializer.NamespaceMappings; 50 import org.apache.xml.serializer.SerializationHandler; 51 import org.apache.xml.utils.XMLChar; 52 53 57 public final class BasisLibrary implements Operators { 58 59 private final static String EMPTYSTRING = ""; 60 61 64 public static int countF(DTMAxisIterator iterator) { 65 return(iterator.getLast()); 66 } 67 68 73 public static int positionF(DTMAxisIterator iterator) { 74 return iterator.isReverse() 75 ? iterator.getLast() - iterator.getPosition() + 1 76 : iterator.getPosition(); 77 } 78 79 83 public static double sumF(DTMAxisIterator iterator, DOM dom) { 84 try { 85 double result = 0.0; 86 int node; 87 while ((node = iterator.next()) != DTMAxisIterator.END) { 88 result += Double.parseDouble(dom.getStringValueX(node)); 89 } 90 return result; 91 } 92 catch (NumberFormatException e) { 93 return Double.NaN; 94 } 95 } 96 97 100 public static String stringF(int node, DOM dom) { 101 return dom.getStringValueX(node); 102 } 103 104 107 public static String stringF(Object obj, DOM dom) { 108 if (obj instanceof DTMAxisIterator) { 109 return dom.getStringValueX(((DTMAxisIterator)obj).reset().next()); 110 } 111 else if (obj instanceof Node) { 112 return dom.getStringValueX(((Node)obj).node); 113 } 114 else if (obj instanceof DOM) { 115 return ((DOM)obj).getStringValue(); 116 } 117 else { 118 return obj.toString(); 119 } 120 } 121 122 125 public static String stringF(Object obj, int node, DOM dom) { 126 if (obj instanceof DTMAxisIterator) { 127 return dom.getStringValueX(((DTMAxisIterator)obj).reset().next()); 128 } 129 else if (obj instanceof Node) { 130 return dom.getStringValueX(((Node)obj).node); 131 } 132 else if (obj instanceof DOM) { 133 return ((DOM)obj).getStringValue(); 137 } 138 else if (obj instanceof Double ) { 139 Double d = (Double )obj; 140 final String result = d.toString(); 141 final int length = result.length(); 142 if ((result.charAt(length-2)=='.') && 143 (result.charAt(length-1) == '0')) 144 return result.substring(0, length-2); 145 else 146 return result; 147 } 148 else { 149 if (obj != null) 150 return obj.toString(); 151 else 152 return stringF(node, dom); 153 } 154 } 155 156 159 public static double numberF(int node, DOM dom) { 160 return stringToReal(dom.getStringValueX(node)); 161 } 162 163 166 public static double numberF(Object obj, DOM dom) { 167 if (obj instanceof Double ) { 168 return ((Double ) obj).doubleValue(); 169 } 170 else if (obj instanceof Integer ) { 171 return ((Integer ) obj).doubleValue(); 172 } 173 else if (obj instanceof Boolean ) { 174 return ((Boolean ) obj).booleanValue() ? 1.0 : 0.0; 175 } 176 else if (obj instanceof String ) { 177 return stringToReal((String ) obj); 178 } 179 else if (obj instanceof DTMAxisIterator) { 180 DTMAxisIterator iter = (DTMAxisIterator) obj; 181 return stringToReal(dom.getStringValueX(iter.reset().next())); 182 } 183 else if (obj instanceof Node) { 184 return stringToReal(dom.getStringValueX(((Node) obj).node)); 185 } 186 else if (obj instanceof DOM) { 187 return stringToReal(((DOM) obj).getStringValue()); 188 } 189 else { 190 final String className = obj.getClass().getName(); 191 runTimeError(INVALID_ARGUMENT_ERR, className, "number()"); 192 return 0.0; 193 } 194 } 195 196 199 public static double roundF(double d) { 200 return (d<-0.5 || d>0.0)?Math.floor(d+0.5):((d==0.0)? 201 d:(Double.isNaN(d)?Double.NaN:-0.0)); 202 } 203 204 207 public static boolean booleanF(Object obj) { 208 if (obj instanceof Double ) { 209 final double temp = ((Double ) obj).doubleValue(); 210 return temp != 0.0 && !Double.isNaN(temp); 211 } 212 else if (obj instanceof Integer ) { 213 return ((Integer ) obj).doubleValue() != 0; 214 } 215 else if (obj instanceof Boolean ) { 216 return ((Boolean ) obj).booleanValue(); 217 } 218 else if (obj instanceof String ) { 219 return !((String ) obj).equals(EMPTYSTRING); 220 } 221 else if (obj instanceof DTMAxisIterator) { 222 DTMAxisIterator iter = (DTMAxisIterator) obj; 223 return iter.reset().next() != DTMAxisIterator.END; 224 } 225 else if (obj instanceof Node) { 226 return true; 227 } 228 else if (obj instanceof DOM) { 229 String temp = ((DOM) obj).getStringValue(); 230 return !temp.equals(EMPTYSTRING); 231 } 232 else { 233 final String className = obj.getClass().getName(); 234 runTimeError(INVALID_ARGUMENT_ERR, className, "number()"); 235 } 236 return false; 237 } 238 239 243 public static String substringF(String value, double start) { 244 try { 245 final int strlen = value.length(); 246 int istart = (int)Math.round(start) - 1; 247 248 if (Double.isNaN(start)) return(EMPTYSTRING); 249 if (istart > strlen) return(EMPTYSTRING); 250 if (istart < 1) istart = 0; 251 252 return value.substring(istart); 253 } 254 catch (IndexOutOfBoundsException e) { 255 runTimeError(RUN_TIME_INTERNAL_ERR, "substring()"); 256 return null; 257 } 258 } 259 260 264 public static String substringF(String value, double start, double length) { 265 try { 266 final int strlen = value.length(); 267 int istart = (int)Math.round(start) - 1; 268 int isum = istart + (int)Math.round(length); 269 270 if (Double.isInfinite(length)) isum = Integer.MAX_VALUE; 271 272 if (Double.isNaN(start) || Double.isNaN(length)) 273 return(EMPTYSTRING); 274 if (Double.isInfinite(start)) return(EMPTYSTRING); 275 if (istart > strlen) return(EMPTYSTRING); 276 if (isum < 0) return(EMPTYSTRING); 277 if (istart < 0) istart = 0; 278 279 if (isum > strlen) 280 return value.substring(istart); 281 else 282 return value.substring(istart, isum); 283 } 284 catch (IndexOutOfBoundsException e) { 285 runTimeError(RUN_TIME_INTERNAL_ERR, "substring()"); 286 return null; 287 } 288 } 289 290 293 public static String substring_afterF(String value, String substring) { 294 final int index = value.indexOf(substring); 295 if (index >= 0) 296 return value.substring(index + substring.length()); 297 else 298 return EMPTYSTRING; 299 } 300 301 304 public static String substring_beforeF(String value, String substring) { 305 final int index = value.indexOf(substring); 306 if (index >= 0) 307 return value.substring(0, index); 308 else 309 return EMPTYSTRING; 310 } 311 312 315 public static String translateF(String value, String from, String to) { 316 final int tol = to.length(); 317 final int froml = from.length(); 318 final int valuel = value.length(); 319 320 final StringBuffer result = new StringBuffer (); 321 for (int j, i = 0; i < valuel; i++) { 322 final char ch = value.charAt(i); 323 for (j = 0; j < froml; j++) { 324 if (ch == from.charAt(j)) { 325 if (j < tol) 326 result.append(to.charAt(j)); 327 break; 328 } 329 } 330 if (j == froml) 331 result.append(ch); 332 } 333 return result.toString(); 334 } 335 336 339 public static String normalize_spaceF(int node, DOM dom) { 340 return normalize_spaceF(dom.getStringValueX(node)); 341 } 342 343 346 public static String normalize_spaceF(String value) { 347 int i = 0, n = value.length(); 348 StringBuffer result = new StringBuffer (); 349 350 while (i < n && isWhiteSpace(value.charAt(i))) 351 i++; 352 353 while (true) { 354 while (i < n && !isWhiteSpace(value.charAt(i))) { 355 result.append(value.charAt(i++)); 356 } 357 if (i == n) 358 break; 359 while (i < n && isWhiteSpace(value.charAt(i))) { 360 i++; 361 } 362 if (i < n) 363 result.append(' '); 364 } 365 return result.toString(); 366 } 367 368 371 public static String generate_idF(int node) { 372 if (node > 0) 373 return "N" + node; 375 else 376 return EMPTYSTRING; 378 } 379 380 383 public static String getLocalName(String value) { 384 int idx = value.lastIndexOf(':'); 385 if (idx >= 0) value = value.substring(idx + 1); 386 idx = value.lastIndexOf('@'); 387 if (idx >= 0) value = value.substring(idx + 1); 388 return(value); 389 } 390 391 400 public static void unresolved_externalF(String name) { 401 runTimeError(EXTERNAL_FUNC_ERR, name); 402 } 403 404 411 public static void unsupported_ElementF(String qname, boolean isExtension) { 412 if (isExtension) 413 runTimeError(UNSUPPORTED_EXT_ERR, qname); 414 else 415 runTimeError(UNSUPPORTED_XSL_ERR, qname); 416 } 417 418 421 public static String namespace_uriF(DTMAxisIterator iter, DOM dom) { 422 return namespace_uriF(iter.next(), dom); 423 } 424 425 428 public static String system_propertyF(String name) { 429 if (name.equals("xsl:version")) 430 return("1.0"); 431 if (name.equals("xsl:vendor")) 432 return("Apache Software Foundation (Xalan XSLTC)"); 433 if (name.equals("xsl:vendor-url")) 434 return("http://xml.apache.org/xalan-j"); 435 436 runTimeError(INVALID_ARGUMENT_ERR, name, "system-property()"); 437 return(EMPTYSTRING); 438 } 439 440 443 public static String namespace_uriF(int node, DOM dom) { 444 final String value = dom.getNodeName(node); 445 final int colon = value.lastIndexOf(':'); 446 if (colon >= 0) 447 return value.substring(0, colon); 448 else 449 return EMPTYSTRING; 450 } 451 452 457 public static String objectTypeF(Object obj) 458 { 459 if (obj instanceof String ) 460 return "string"; 461 else if (obj instanceof Boolean ) 462 return "boolean"; 463 else if (obj instanceof Number ) 464 return "number"; 465 else if (obj instanceof DOM) 466 return "RTF"; 467 else if (obj instanceof DTMAxisIterator) 468 return "node-set"; 469 else 470 return "unknown"; 471 } 472 473 476 public static DTMAxisIterator nodesetF(Object obj) { 477 if (obj instanceof DOM) { 478 final DOM dom = (DOM)obj; 480 return new SingletonIterator(dom.getDocument(), true); 481 } 482 else if (obj instanceof DTMAxisIterator) { 483 return (DTMAxisIterator) obj; 484 } 485 else { 486 final String className = obj.getClass().getName(); 487 runTimeError(DATA_CONVERSION_ERR, "node-set", className); 488 return null; 489 } 490 } 491 492 494 private static boolean isWhiteSpace(char ch) { 495 return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'; 496 } 497 498 private static boolean compareStrings(String lstring, String rstring, 499 int op, DOM dom) { 500 switch (op) { 501 case EQ: 502 return lstring.equals(rstring); 503 504 case NE: 505 return !lstring.equals(rstring); 506 507 case GT: 508 return numberF(lstring, dom) > numberF(rstring, dom); 509 510 case LT: 511 return numberF(lstring, dom) < numberF(rstring, dom); 512 513 case GE: 514 return numberF(lstring, dom) >= numberF(rstring, dom); 515 516 case LE: 517 return numberF(lstring, dom) <= numberF(rstring, dom); 518 519 default: 520 runTimeError(RUN_TIME_INTERNAL_ERR, "compare()"); 521 return false; 522 } 523 } 524 525 528 public static boolean compare(DTMAxisIterator left, DTMAxisIterator right, 529 int op, DOM dom) { 530 int lnode; 531 left.reset(); 532 533 while ((lnode = left.next()) != DTMAxisIterator.END) { 534 final String lvalue = dom.getStringValueX(lnode); 535 536 int rnode; 537 right.reset(); 538 while ((rnode = right.next()) != DTMAxisIterator.END) { 539 if (lnode == rnode) { 541 if (op == EQ) { 542 return true; 543 } else if (op == NE) { 544 continue; 545 } 546 } 547 if (compareStrings(lvalue, dom.getStringValueX(rnode), op, 548 dom)) { 549 return true; 550 } 551 } 552 } 553 return false; 554 } 555 556 public static boolean compare(int node, DTMAxisIterator iterator, 557 int op, DOM dom) { 558 560 int rnode; 561 String value; 562 563 switch(op) { 564 case EQ: 565 rnode = iterator.next(); 566 if (rnode != DTMAxisIterator.END) { 567 value = dom.getStringValueX(node); 568 do { 569 if (node == rnode 570 || value.equals(dom.getStringValueX(rnode))) { 571 return true; 572 } 573 } while ((rnode = iterator.next()) != DTMAxisIterator.END); 574 } 575 break; 576 case NE: 577 rnode = iterator.next(); 578 if (rnode != DTMAxisIterator.END) { 579 value = dom.getStringValueX(node); 580 do { 581 if (node != rnode 582 && !value.equals(dom.getStringValueX(rnode))) { 583 return true; 584 } 585 } while ((rnode = iterator.next()) != DTMAxisIterator.END); 586 } 587 break; 588 case LT: 589 while ((rnode = iterator.next()) != DTMAxisIterator.END) { 591 if (rnode > node) return true; 592 } 593 break; 594 case GT: 595 while ((rnode = iterator.next()) != DTMAxisIterator.END) { 597 if (rnode < node) return true; 598 } 599 break; 600 } 601 return(false); 602 } 603 604 607 public static boolean compare(DTMAxisIterator left, final double rnumber, 608 final int op, DOM dom) { 609 int node; 610 612 switch (op) { 613 case EQ: 614 while ((node = left.next()) != DTMAxisIterator.END) { 615 if (numberF(dom.getStringValueX(node), dom) == rnumber) 616 return true; 617 } 618 break; 619 620 case NE: 621 while ((node = left.next()) != DTMAxisIterator.END) { 622 if (numberF(dom.getStringValueX(node), dom) != rnumber) 623 return true; 624 } 625 break; 626 627 case GT: 628 while ((node = left.next()) != DTMAxisIterator.END) { 629 if (numberF(dom.getStringValueX(node), dom) > rnumber) 630 return true; 631 } 632 break; 633 634 case LT: 635 while ((node = left.next()) != DTMAxisIterator.END) { 636 if (numberF(dom.getStringValueX(node), dom) < rnumber) 637 return true; 638 } 639 break; 640 641 case GE: 642 while ((node = left.next()) != DTMAxisIterator.END) { 643 if (numberF(dom.getStringValueX(node), dom) >= rnumber) 644 return true; 645 } 646 break; 647 648 case LE: 649 while ((node = left.next()) != DTMAxisIterator.END) { 650 if (numberF(dom.getStringValueX(node), dom) <= rnumber) 651 return true; 652 } 653 break; 654 655 default: 656 runTimeError(RUN_TIME_INTERNAL_ERR, "compare()"); 657 } 658 659 return false; 660 } 661 662 665 public static boolean compare(DTMAxisIterator left, final String rstring, 666 int op, DOM dom) { 667 int node; 668 while ((node = left.next()) != DTMAxisIterator.END) { 670 if (compareStrings(dom.getStringValueX(node), rstring, op, dom)) { 671 return true; 672 } 673 } 674 return false; 675 } 676 677 678 public static boolean compare(Object left, Object right, 679 int op, DOM dom) 680 { 681 boolean result = false; 682 boolean hasSimpleArgs = hasSimpleType(left) && hasSimpleType(right); 683 684 if (op != EQ && op != NE) { 685 if (left instanceof Node || right instanceof Node) { 687 if (left instanceof Boolean ) { 688 right = new Boolean (booleanF(right)); 689 hasSimpleArgs = true; 690 } 691 if (right instanceof Boolean ) { 692 left = new Boolean (booleanF(left)); 693 hasSimpleArgs = true; 694 } 695 } 696 697 if (hasSimpleArgs) { 698 switch (op) { 699 case GT: 700 return numberF(left, dom) > numberF(right, dom); 701 702 case LT: 703 return numberF(left, dom) < numberF(right, dom); 704 705 case GE: 706 return numberF(left, dom) >= numberF(right, dom); 707 708 case LE: 709 return numberF(left, dom) <= numberF(right, dom); 710 711 default: 712 runTimeError(RUN_TIME_INTERNAL_ERR, "compare()"); 713 } 714 } 715 } 717 718 if (hasSimpleArgs) { 719 if (left instanceof Boolean || right instanceof Boolean ) { 720 result = booleanF(left) == booleanF(right); 721 } 722 else if (left instanceof Double || right instanceof Double || 723 left instanceof Integer || right instanceof Integer ) { 724 result = numberF(left, dom) == numberF(right, dom); 725 } 726 else { result = stringF(left, dom).equals(stringF(right, dom)); 728 } 729 730 if (op == Operators.NE) { 731 result = !result; 732 } 733 } 734 else { 735 if (left instanceof Node) { 736 left = new SingletonIterator(((Node)left).node); 737 } 738 if (right instanceof Node) { 739 right = new SingletonIterator(((Node)right).node); 740 } 741 742 if (hasSimpleType(left) || 743 left instanceof DOM && right instanceof DTMAxisIterator) { 744 final Object temp = right; right = left; left = temp; 746 } 747 748 if (left instanceof DOM) { 749 if (right instanceof Boolean ) { 750 result = ((Boolean )right).booleanValue(); 751 return result == (op == Operators.EQ); 752 } 753 754 final String sleft = ((DOM)left).getStringValue(); 755 756 if (right instanceof Number ) { 757 result = ((Number )right).doubleValue() == 758 stringToReal(sleft); 759 } 760 else if (right instanceof String ) { 761 result = sleft.equals((String )right); 762 } 763 else if (right instanceof DOM) { 764 result = sleft.equals(((DOM)right).getStringValue()); 765 } 766 767 if (op == Operators.NE) { 768 result = !result; 769 } 770 return result; 771 } 772 773 775 DTMAxisIterator iter = ((DTMAxisIterator)left).reset(); 776 777 if (right instanceof DTMAxisIterator) { 778 result = compare(iter, (DTMAxisIterator)right, op, dom); 779 } 780 else if (right instanceof String ) { 781 result = compare(iter, (String )right, op, dom); 782 } 783 else if (right instanceof Number ) { 784 final double temp = ((Number )right).doubleValue(); 785 result = compare(iter, temp, op, dom); 786 } 787 else if (right instanceof Boolean ) { 788 boolean temp = ((Boolean )right).booleanValue(); 789 result = (iter.reset().next() != DTMAxisIterator.END) == temp; 790 } 791 else if (right instanceof DOM) { 792 result = compare(iter, ((DOM)right).getStringValue(), 793 op, dom); 794 } 795 else if (right == null) { 796 return(false); 797 } 798 else { 799 final String className = right.getClass().getName(); 800 runTimeError(INVALID_ARGUMENT_ERR, className, "compare()"); 801 } 802 } 803 return result; 804 } 805 806 809 public static boolean testLanguage(String testLang, DOM dom, int node) { 810 String nodeLang = dom.getLanguage(node); 812 if (nodeLang == null) 813 return(false); 814 else 815 nodeLang = nodeLang.toLowerCase(); 816 817 testLang = testLang.toLowerCase(); 819 if (testLang.length() == 2) { 820 return(nodeLang.startsWith(testLang)); 821 } 822 else { 823 return(nodeLang.equals(testLang)); 824 } 825 } 826 827 private static boolean hasSimpleType(Object obj) { 828 return obj instanceof Boolean || obj instanceof Double || 829 obj instanceof Integer || obj instanceof String || 830 obj instanceof Node || obj instanceof DOM; 831 } 832 833 836 public static double stringToReal(String s) { 837 try { 838 return Double.valueOf(s).doubleValue(); 839 } 840 catch (NumberFormatException e) { 841 return Double.NaN; 842 } 843 } 844 845 848 public static int stringToInt(String s) { 849 try { 850 return Integer.parseInt(s); 851 } 852 catch (NumberFormatException e) { 853 return(-1); } 855 } 856 857 private static final int DOUBLE_FRACTION_DIGITS = 340; 858 private static final double lowerBounds = 0.001; 859 private static final double upperBounds = 10000000; 860 private static DecimalFormat defaultFormatter; 861 private static String defaultPattern = ""; 862 863 static { 864 NumberFormat f = NumberFormat.getInstance(Locale.getDefault()); 865 defaultFormatter = (f instanceof DecimalFormat ) ? 866 (DecimalFormat ) f : new DecimalFormat (); 867 defaultFormatter.setMaximumFractionDigits(DOUBLE_FRACTION_DIGITS); 870 defaultFormatter.setMinimumFractionDigits(0); 871 defaultFormatter.setMinimumIntegerDigits(1); 872 defaultFormatter.setGroupingUsed(false); 873 } 874 875 879 public static String realToString(double d) { 880 final double m = Math.abs(d); 881 if ((m >= lowerBounds) && (m < upperBounds)) { 882 final String result = Double.toString(d); 883 final int length = result.length(); 884 if ((result.charAt(length-2) == '.') && 886 (result.charAt(length-1) == '0')) 887 return result.substring(0, length-2); 888 else 889 return result; 890 } 891 else { 892 if (Double.isNaN(d) || Double.isInfinite(d)) 893 return(Double.toString(d)); 894 return formatNumber(d, defaultPattern, defaultFormatter); 895 } 896 } 897 898 901 public static int realToInt(double d) { 902 return (int)d; 903 } 904 905 910 private static FieldPosition _fieldPosition = new FieldPosition (0); 911 912 public static String formatNumber(double number, String pattern, 913 DecimalFormat formatter) { 914 if (formatter == null) { 916 formatter = defaultFormatter; 917 } 918 try { 919 StringBuffer result = new StringBuffer (); 920 if (pattern != defaultPattern) { 921 formatter.applyLocalizedPattern(pattern); 922 } 923 formatter.format(number, result, _fieldPosition); 924 return result.toString(); 925 } 926 catch (IllegalArgumentException e) { 927 runTimeError(FORMAT_NUMBER_ERR, Double.toString(number), pattern); 928 return(EMPTYSTRING); 929 } 930 } 931 932 936 public static DTMAxisIterator referenceToNodeSet(Object obj) { 937 if (obj instanceof Node) { 939 return(new SingletonIterator(((Node)obj).node)); 940 } 941 else if (obj instanceof DTMAxisIterator) { 943 return(((DTMAxisIterator)obj).cloneIterator()); 944 } 945 else { 946 final String className = obj.getClass().getName(); 947 runTimeError(DATA_CONVERSION_ERR, className, "node-set"); 948 return null; 949 } 950 } 951 952 955 public static NodeList referenceToNodeList(Object obj, DOM dom) { 956 if (obj instanceof Node || obj instanceof DTMAxisIterator) { 957 DTMAxisIterator iter = referenceToNodeSet(obj); 958 return dom.makeNodeList(iter); 959 } 960 else if (obj instanceof DOM) { 961 dom = (DOM)obj; 962 return dom.makeNodeList(DTMDefaultBase.ROOTNODE); 963 } 964 else { 965 final String className = obj.getClass().getName(); 966 runTimeError(DATA_CONVERSION_ERR, className, 967 "org.w3c.dom.NodeList"); 968 return null; 969 } 970 } 971 972 975 public static org.w3c.dom.Node referenceToNode(Object obj, DOM dom) { 976 if (obj instanceof Node || obj instanceof DTMAxisIterator) { 977 DTMAxisIterator iter = referenceToNodeSet(obj); 978 return dom.makeNode(iter); 979 } 980 else if (obj instanceof DOM) { 981 dom = (DOM)obj; 982 DTMAxisIterator iter = dom.getChildren(DTMDefaultBase.ROOTNODE); 983 return dom.makeNode(iter); 984 } 985 else { 986 final String className = obj.getClass().getName(); 987 runTimeError(DATA_CONVERSION_ERR, className, "org.w3c.dom.Node"); 988 return null; 989 } 990 } 991 992 995 public static long referenceToLong(Object obj) { 996 if (obj instanceof Number ) { 997 return ((Number ) obj).longValue(); } 999 else { 1000 final String className = obj.getClass().getName(); 1001 runTimeError(DATA_CONVERSION_ERR, className, Long.TYPE); 1002 return 0; 1003 } 1004 } 1005 1006 1009 public static double referenceToDouble(Object obj) { 1010 if (obj instanceof Number ) { 1011 return ((Number ) obj).doubleValue(); } 1013 else { 1014 final String className = obj.getClass().getName(); 1015 runTimeError(DATA_CONVERSION_ERR, className, Double.TYPE); 1016 return 0; 1017 } 1018 } 1019 1020 1023 public static boolean referenceToBoolean(Object obj) { 1024 if (obj instanceof Boolean ) { 1025 return ((Boolean ) obj).booleanValue(); 1026 } 1027 else { 1028 final String className = obj.getClass().getName(); 1029 runTimeError(DATA_CONVERSION_ERR, className, Boolean.TYPE); 1030 return false; 1031 } 1032 } 1033 1034 1037 public static String referenceToString(Object obj, DOM dom) { 1038 if (obj instanceof String ) { 1039 return (String ) obj; 1040 } 1041 else if (obj instanceof DTMAxisIterator) { 1042 return dom.getStringValueX(((DTMAxisIterator)obj).reset().next()); 1043 } 1044 else if (obj instanceof Node) { 1045 return dom.getStringValueX(((Node)obj).node); 1046 } 1047 else if (obj instanceof DOM) { 1048 return ((DOM) obj).getStringValue(); 1049 } 1050 else { 1051 final String className = obj.getClass().getName(); 1052 runTimeError(DATA_CONVERSION_ERR, className, String .class); 1053 return null; 1054 } 1055 } 1056 1057 1060 public static DTMAxisIterator node2Iterator(org.w3c.dom.Node node, 1061 Translet translet, DOM dom) 1062 { 1063 final org.w3c.dom.Node inNode = node; 1064 org.w3c.dom.NodeList nodelist = new org.w3c.dom.NodeList () { 1067 public int getLength() { 1068 return 1; 1069 } 1070 1071 public org.w3c.dom.Node item(int index) { 1072 if (index == 0) 1073 return inNode; 1074 else 1075 return null; 1076 } 1077 }; 1078 1079 return nodeList2Iterator(nodelist, translet, dom); 1080 } 1081 1082 1085 private static void copyNodes(org.w3c.dom.NodeList nodeList, 1086 org.w3c.dom.Document doc, org.w3c.dom.Node parent) 1087 { 1088 final int size = nodeList.getLength(); 1089 1090 for (int i = 0; i < size; i++) 1092 { 1093 org.w3c.dom.Node curr = nodeList.item(i); 1094 int nodeType = curr.getNodeType(); 1095 String value = null; 1096 try { 1097 value = curr.getNodeValue(); 1098 } catch (DOMException ex) { 1099 runTimeError(RUN_TIME_INTERNAL_ERR, ex.getMessage()); 1100 return; 1101 } 1102 1103 String nodeName = curr.getNodeName(); 1104 org.w3c.dom.Node newNode = null; 1105 switch (nodeType){ 1106 case org.w3c.dom.Node.ATTRIBUTE_NODE: 1107 newNode = doc.createAttributeNS(curr.getNamespaceURI(), 1108 nodeName); 1109 break; 1110 case org.w3c.dom.Node.CDATA_SECTION_NODE: 1111 newNode = doc.createCDATASection(value); 1112 break; 1113 case org.w3c.dom.Node.COMMENT_NODE: 1114 newNode = doc.createComment(value); 1115 break; 1116 case org.w3c.dom.Node.DOCUMENT_FRAGMENT_NODE: 1117 newNode = doc.createDocumentFragment(); 1118 break; 1119 case org.w3c.dom.Node.DOCUMENT_NODE: 1120 newNode = doc.createElementNS(null, "__document__"); 1121 copyNodes(curr.getChildNodes(), doc, newNode); 1122 break; 1123 case org.w3c.dom.Node.DOCUMENT_TYPE_NODE: 1124 break; 1126 case org.w3c.dom.Node.ELEMENT_NODE: 1127 org.w3c.dom.Element element = doc.createElementNS( 1130 curr.getNamespaceURI(), nodeName); 1131 if (curr.hasAttributes()) 1132 { 1133 org.w3c.dom.NamedNodeMap attributes = curr.getAttributes(); 1134 for (int k = 0; k < attributes.getLength(); k++) { 1135 org.w3c.dom.Node attr = attributes.item(k); 1136 element.setAttributeNS(attr.getNamespaceURI(), 1137 attr.getNodeName(), attr.getNodeValue()); 1138 } 1139 } 1140 copyNodes(curr.getChildNodes(), doc, element); 1141 newNode = element; 1142 break; 1143 case org.w3c.dom.Node.ENTITY_NODE: 1144 break; 1146 case org.w3c.dom.Node.ENTITY_REFERENCE_NODE: 1147 newNode = doc.createEntityReference(nodeName); 1148 break; 1149 case org.w3c.dom.Node.NOTATION_NODE: 1150 break; 1152 case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: 1153 newNode = doc.createProcessingInstruction(nodeName, 1154 value); 1155 break; 1156 case org.w3c.dom.Node.TEXT_NODE: 1157 newNode = doc.createTextNode(value); 1158 break; 1159 } 1160 try { 1161 parent.appendChild(newNode); 1162 } catch (DOMException e) { 1163 runTimeError(RUN_TIME_INTERNAL_ERR, e.getMessage()); 1164 return; 1165 } 1166 } 1167 } 1168 1169 1173 public static DTMAxisIterator nodeList2Iterator( 1174 org.w3c.dom.NodeList nodeList, 1175 Translet translet, DOM dom) 1176 { 1177 DocumentBuilderFactory dfac = DocumentBuilderFactory.newInstance(); 1179 DocumentBuilder docbldr = null; 1180 try { 1181 docbldr = dfac.newDocumentBuilder(); 1182 } catch (javax.xml.parsers.ParserConfigurationException e) { 1183 runTimeError(RUN_TIME_INTERNAL_ERR, e.getMessage()); 1184 return null; 1185 1186 } 1187 Document doc = docbldr.newDocument(); 1189 org.w3c.dom.Node topElementNode = 1190 doc.appendChild(doc.createElementNS("", "__top__")); 1191 1192 copyNodes(nodeList, doc, topElementNode); 1194 1195 if (dom instanceof MultiDOM) { 1197 final MultiDOM multiDOM = (MultiDOM) dom; 1198 1199 DTMDefaultBase dtm = (DTMDefaultBase)((DOMAdapter)multiDOM.getMain()).getDOMImpl(); 1200 DTMManager dtmManager = dtm.getManager(); 1201 1202 DOM idom = (DOM)dtmManager.getDTM(new DOMSource (doc), false, 1203 null, true, false); 1204 DOMAdapter domAdapter = new DOMAdapter(idom, 1206 translet.getNamesArray(), 1207 translet.getUrisArray(), 1208 translet.getTypesArray(), 1209 translet.getNamespaceArray()); 1210 multiDOM.addDOMAdapter(domAdapter); 1211 1212 DTMAxisIterator iter1 = idom.getAxisIterator(Axis.CHILD); 1213 DTMAxisIterator iter2 = idom.getAxisIterator(Axis.CHILD); 1214 DTMAxisIterator iter = new AbsoluteIterator( 1215 new StepIterator(iter1, iter2)); 1216 1217 iter.setStartNode(DTMDefaultBase.ROOTNODE); 1218 return iter; 1219 } 1220 else { 1221 runTimeError(RUN_TIME_INTERNAL_ERR, "nodeList2Iterator()"); 1222 return null; 1223 } 1224 } 1225 1226 1229 public static DOM referenceToResultTree(Object obj) { 1230 try { 1231 return ((DOM) obj); 1232 } 1233 catch (IllegalArgumentException e) { 1234 final String className = obj.getClass().getName(); 1235 runTimeError(DATA_CONVERSION_ERR, "reference", className); 1236 return null; 1237 } 1238 } 1239 1240 1244 public static DTMAxisIterator getSingleNode(DTMAxisIterator iterator) { 1245 int node = iterator.next(); 1246 return(new SingletonIterator(node)); 1247 } 1248 1249 1252 private static char[] _characterArray = new char[32]; 1253 1254 public static void copy(Object obj, 1255 SerializationHandler handler, 1256 int node, 1257 DOM dom) { 1258 try { 1259 if (obj instanceof DTMAxisIterator) 1260 { 1261 DTMAxisIterator iter = (DTMAxisIterator) obj; 1262 dom.copy(iter.reset(), handler); 1263 } 1264 else if (obj instanceof Node) { 1265 dom.copy(((Node) obj).node, handler); 1266 } 1267 else if (obj instanceof DOM) { 1268 DOM newDom = (DOM)obj; 1270 newDom.copy(newDom.getDocument(), handler); 1271 } 1272 else { 1273 String string = obj.toString(); final int length = string.length(); 1275 if (length > _characterArray.length) 1276 _characterArray = new char[length]; 1277 string.getChars(0, length, _characterArray, 0); 1278 handler.characters(_characterArray, 0, length); 1279 } 1280 } 1281 catch (SAXException e) { 1282 runTimeError(RUN_TIME_COPY_ERR); 1283 } 1284 } 1285 1286 1290 public static void checkAttribQName(String name) { 1291 final int firstOccur = name.indexOf(":"); 1292 final int lastOccur = name.lastIndexOf(":"); 1293 final String localName = name.substring(lastOccur + 1); 1294 1295 if (firstOccur > 0) { 1296 final String newPrefix = name.substring(0, firstOccur); 1297 1298 if (firstOccur != lastOccur) { 1299 final String oriPrefix = name.substring(firstOccur+1, lastOccur); 1300 if (!XMLChar.isValidNCName(oriPrefix)) { 1301 runTimeError(INVALID_QNAME_ERR,oriPrefix+":"+localName); 1303 } 1304 } 1305 1306 if (!XMLChar.isValidNCName(newPrefix)) { 1308 runTimeError(INVALID_QNAME_ERR,newPrefix+":"+localName); 1309 } 1310 } 1311 1312 if ((!XMLChar.isValidNCName(localName))||(localName.equals(Constants.XMLNS_PREFIX))) { 1314 runTimeError(INVALID_QNAME_ERR,localName); 1315 } 1316 } 1317 1318 1322 public static void checkNCName(String name) { 1323 if (!XMLChar.isValidNCName(name)) { 1324 runTimeError(INVALID_NCNAME_ERR,name); 1325 } 1326 } 1327 1328 1332 public static void checkQName(String name) { 1333 if (!XMLChar.isValidQName(name)) { 1334 runTimeError(INVALID_QNAME_ERR,name); 1335 } 1336 } 1337 1338 1341 public static String startXslElement(String qname, String namespace, 1342 SerializationHandler handler, DOM dom, int node) 1343 { 1344 try { 1345 String prefix; 1347 final int index = qname.indexOf(':'); 1348 1349 if (index > 0) { 1350 prefix = qname.substring(0, index); 1351 1352 if (namespace == null || namespace.length() == 0) { 1354 try { 1355 namespace = dom.lookupNamespace(node, prefix); 1357 } 1358 catch(RuntimeException e) { 1359 handler.flushPending(); NamespaceMappings nm = handler.getNamespaceMappings(); 1361 namespace = nm.lookupNamespace(prefix); 1362 if (namespace == null) { 1363 runTimeError(NAMESPACE_PREFIX_ERR,prefix); 1364 } 1365 } 1366 } 1367 1368 handler.startElement(namespace, qname.substring(index+1), 1369 qname); 1370 handler.namespaceAfterStartElement(prefix, namespace); 1371 } 1372 else { 1373 if (namespace != null && namespace.length() > 0) { 1375 prefix = generatePrefix(); 1376 qname = prefix + ':' + qname; 1377 handler.startElement(namespace, qname, qname); 1378 handler.namespaceAfterStartElement(prefix, namespace); 1379 } 1380 else { 1381 handler.startElement(null, null, qname); 1382 } 1383 } 1384 } 1385 catch (SAXException e) { 1386 throw new RuntimeException (e.getMessage()); 1387 } 1388 1389 return qname; 1390 } 1391 1392 1395 public static String getPrefix(String qname) { 1396 final int index = qname.indexOf(':'); 1397 return (index > 0) ? qname.substring(0, index) : null; 1398 } 1399 1400 1403 private static int prefixIndex = 0; public static String generatePrefix() { 1405 return ("ns" + prefixIndex++); 1406 } 1407 1408 public static final String RUN_TIME_INTERNAL_ERR = 1409 "RUN_TIME_INTERNAL_ERR"; 1410 public static final String RUN_TIME_COPY_ERR = 1411 "RUN_TIME_COPY_ERR"; 1412 public static final String DATA_CONVERSION_ERR = 1413 "DATA_CONVERSION_ERR"; 1414 public static final String EXTERNAL_FUNC_ERR = 1415 "EXTERNAL_FUNC_ERR"; 1416 public static final String EQUALITY_EXPR_ERR = 1417 "EQUALITY_EXPR_ERR"; 1418 public static final String INVALID_ARGUMENT_ERR = 1419 "INVALID_ARGUMENT_ERR"; 1420 public static final String FORMAT_NUMBER_ERR = 1421 "FORMAT_NUMBER_ERR"; 1422 public static final String ITERATOR_CLONE_ERR = 1423 "ITERATOR_CLONE_ERR"; 1424 public static final String AXIS_SUPPORT_ERR = 1425 "AXIS_SUPPORT_ERR"; 1426 public static final String TYPED_AXIS_SUPPORT_ERR = 1427 "TYPED_AXIS_SUPPORT_ERR"; 1428 public static final String STRAY_ATTRIBUTE_ERR = 1429 "STRAY_ATTRIBUTE_ERR"; 1430 public static final String STRAY_NAMESPACE_ERR = 1431 "STRAY_NAMESPACE_ERR"; 1432 public static final String NAMESPACE_PREFIX_ERR = 1433 "NAMESPACE_PREFIX_ERR"; 1434 public static final String DOM_ADAPTER_INIT_ERR = 1435 "DOM_ADAPTER_INIT_ERR"; 1436 public static final String PARSER_DTD_SUPPORT_ERR = 1437 "PARSER_DTD_SUPPORT_ERR"; 1438 public static final String NAMESPACES_SUPPORT_ERR = 1439 "NAMESPACES_SUPPORT_ERR"; 1440 public static final String CANT_RESOLVE_RELATIVE_URI_ERR = 1441 "CANT_RESOLVE_RELATIVE_URI_ERR"; 1442 public static final String UNSUPPORTED_XSL_ERR = 1443 "UNSUPPORTED_XSL_ERR"; 1444 public static final String UNSUPPORTED_EXT_ERR = 1445 "UNSUPPORTED_EXT_ERR"; 1446 public static final String UNKNOWN_TRANSLET_VERSION_ERR = 1447 "UNKNOWN_TRANSLET_VERSION_ERR"; 1448 public static final String INVALID_QNAME_ERR = "INVALID_QNAME_ERR"; 1449 public static final String INVALID_NCNAME_ERR = "INVALID_NCNAME_ERR"; 1450 1451 protected static ResourceBundle m_bundle; 1453 1454 public final static String ERROR_MESSAGES_KEY = "error-messages"; 1455 1456 static { 1457 String resource = "org.apache.xalan.xsltc.runtime.ErrorMessages"; 1458 m_bundle = ResourceBundle.getBundle(resource); 1459 } 1460 1461 1464 public static void runTimeError(String code) { 1465 throw new RuntimeException (m_bundle.getString(code)); 1466 } 1467 1468 public static void runTimeError(String code, Object [] args) { 1469 final String message = MessageFormat.format(m_bundle.getString(code), 1470 args); 1471 throw new RuntimeException (message); 1472 } 1473 1474 public static void runTimeError(String code, Object arg0) { 1475 runTimeError(code, new Object []{ arg0 } ); 1476 } 1477 1478 public static void runTimeError(String code, Object arg0, Object arg1) { 1479 runTimeError(code, new Object []{ arg0, arg1 } ); 1480 } 1481 1482 public static void consoleOutput(String msg) { 1483 System.out.println(msg); 1484 } 1485 1486 1489 public static String replace(String base, char ch, String str) { 1490 return (base.indexOf(ch) < 0) ? base : 1491 replace(base, String.valueOf(ch), new String [] { str }); 1492 } 1493 1494 public static String replace(String base, String delim, String [] str) { 1495 final int len = base.length(); 1496 final StringBuffer result = new StringBuffer (); 1497 1498 for (int i = 0; i < len; i++) { 1499 final char ch = base.charAt(i); 1500 final int k = delim.indexOf(ch); 1501 1502 if (k >= 0) { 1503 result.append(str[k]); 1504 } 1505 else { 1506 result.append(ch); 1507 } 1508 } 1509 return result.toString(); 1510 } 1511 1512 1513 1522 public static String mapQNameToJavaName (String base ) { 1523 return replace(base, ".-:/{}?#%*", 1524 new String [] { "$dot$", "$dash$" ,"$colon$", "$slash$", 1525 "","$colon$","$ques$","$hash$","$per$", 1526 "$aster$"}); 1527 1528 } 1529 1530 } 1532 | Popular Tags |