1 16 19 package org.apache.xpath.objects; 20 21 import java.util.Locale ; 22 23 import org.apache.xml.dtm.DTM; 24 import org.apache.xml.utils.XMLCharacterRecognizer; 25 import org.apache.xml.utils.XMLString; 26 import org.apache.xml.utils.XMLStringFactory; 27 import org.apache.xpath.ExpressionOwner; 28 import org.apache.xpath.XPathContext; 29 import org.apache.xpath.XPathVisitor; 30 31 36 public class XString extends XObject implements XMLString 37 { 38 39 40 public static XString EMPTYSTRING = new XString(""); 41 42 47 protected XString(Object val) 48 { 49 super(val); 50 } 51 52 57 public XString(String val) 58 { 59 super(val); 60 } 61 62 67 public int getType() 68 { 69 return CLASS_STRING; 70 } 71 72 78 public String getTypeString() 79 { 80 return "#STRING"; 81 } 82 83 88 public boolean hasString() 89 { 90 return true; 91 } 92 93 99 public double num() 100 { 101 return toDouble(); 102 } 103 104 111 public double toDouble() 112 { 113 int end = length(); 114 115 if(0 == end) 116 return Double.NaN; 117 118 double result = 0.0; 119 int start = 0; 120 int punctPos = end-1; 121 122 for (int i = start; i < end; i++) 124 { 125 char c = charAt(i); 126 127 if (!XMLCharacterRecognizer.isWhiteSpace(c)) 128 { 129 break; 130 } 131 else 132 start++; 133 } 134 135 double sign = 1.0; 136 137 if (start < end && charAt(start) == '-') 138 { 139 sign = -1.0; 140 141 start++; 142 } 143 144 int digitsFound = 0; 145 146 for (int i = start; i < end; i++) { 148 char c = charAt(i); 149 150 if (c != '.') 151 { 152 if (XMLCharacterRecognizer.isWhiteSpace(c)) 153 break; 154 else if (Character.isDigit(c)) 155 { 156 result = result * 10.0 + (c - 0x30); 157 158 digitsFound++; 159 } 160 else 161 { 162 return Double.NaN; 163 } 164 } 165 else 166 { 167 punctPos = i; 168 169 break; 170 } 171 } 172 173 if (charAt(punctPos) == '.') { 175 double fractPart = 0.0; 176 177 for (int i = end - 1; i > punctPos; i--) 178 { 179 char c = charAt(i); 180 181 if (XMLCharacterRecognizer.isWhiteSpace(c)) 182 break; 183 else if (Character.isDigit(c)) 184 { 185 fractPart = fractPart / 10.0 + (c - 0x30); 186 187 digitsFound++; 188 } 189 else 190 { 191 return Double.NaN; 192 } 193 } 194 195 result += fractPart / 10.0; 196 } 197 198 if (0 == digitsFound) 199 return Double.NaN; 200 201 return result * sign; 202 } 203 204 210 public boolean bool() 211 { 212 return str().length() > 0; 213 } 214 215 220 public XMLString xstr() 221 { 222 return this; 223 } 224 225 230 public String str() 231 { 232 return (null != m_obj) ? ((String ) m_obj) : ""; 233 } 234 235 242 public int rtf(XPathContext support) 243 { 244 245 DTM frag = support.createDocumentFragment(); 246 247 frag.appendTextChild(str()); 248 249 return frag.getDocument(); 250 } 251 252 263 public void dispatchCharactersEvents(org.xml.sax.ContentHandler ch) 264 throws org.xml.sax.SAXException 265 { 266 267 String str = str(); 268 269 ch.characters(str.toCharArray(), 0, str.length()); 270 } 271 272 281 public void dispatchAsComment(org.xml.sax.ext.LexicalHandler lh) 282 throws org.xml.sax.SAXException 283 { 284 285 String str = str(); 286 287 lh.comment(str.toCharArray(), 0, str.length()); 288 } 289 290 296 public int length() 297 { 298 return str().length(); 299 } 300 301 314 public char charAt(int index) 315 { 316 return str().charAt(index); 317 } 318 319 340 public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) 341 { 342 str().getChars(srcBegin, srcEnd, dst, dstBegin); 343 } 344 345 354 public boolean equals(XObject obj2) 355 { 356 357 int t = obj2.getType(); 361 try 362 { 363 if (XObject.CLASS_NODESET == t) 364 return obj2.equals(this); 365 else if(XObject.CLASS_BOOLEAN == t) 369 return obj2.bool() == bool(); 370 else if(XObject.CLASS_NUMBER == t) 373 return obj2.num() == num(); 374 } 375 catch(javax.xml.transform.TransformerException te) 376 { 377 throw new org.apache.xml.utils.WrappedRuntimeException(te); 378 } 379 380 return xstr().equals(obj2.xstr()); 383 } 384 385 398 public boolean equals(XMLString obj2) 399 { 400 401 if (!obj2.hasString()) 402 return obj2.equals(this); 403 else 404 return str().equals(obj2.toString()); 405 } 406 407 422 public boolean equals(Object obj2) 423 { 424 425 if (null == obj2) 426 return false; 427 428 else if (obj2 instanceof XNodeSet) 432 return obj2.equals(this); 433 else if(obj2 instanceof XNumber) 434 return obj2.equals(this); 435 else 436 return str().equals(obj2.toString()); 437 } 438 439 454 public boolean equalsIgnoreCase(String anotherString) 455 { 456 return str().equalsIgnoreCase(anotherString); 457 } 458 459 473 public int compareTo(XMLString xstr) 474 { 475 476 int len1 = this.length(); 477 int len2 = xstr.length(); 478 int n = Math.min(len1, len2); 479 int i = 0; 480 int j = 0; 481 482 while (n-- != 0) 483 { 484 char c1 = this.charAt(i); 485 char c2 = xstr.charAt(j); 486 487 if (c1 != c2) 488 { 489 return c1 - c2; 490 } 491 492 i++; 493 j++; 494 } 495 496 return len1 - len2; 497 } 498 499 517 public int compareToIgnoreCase(XMLString str) 518 { 519 527 throw new org.apache.xml.utils.WrappedRuntimeException( 528 new java.lang.NoSuchMethodException ( 529 "Java 1.2 method, not yet implemented")); 530 } 531 532 551 public boolean startsWith(String prefix, int toffset) 552 { 553 return str().startsWith(prefix, toffset); 554 } 555 556 570 public boolean startsWith(String prefix) 571 { 572 return startsWith(prefix, 0); 573 } 574 575 594 public boolean startsWith(XMLString prefix, int toffset) 595 { 596 597 int to = toffset; 598 int tlim = this.length(); 599 int po = 0; 600 int pc = prefix.length(); 601 602 if ((toffset < 0) || (toffset > tlim - pc)) 604 { 605 return false; 606 } 607 608 while (--pc >= 0) 609 { 610 if (this.charAt(to) != prefix.charAt(po)) 611 { 612 return false; 613 } 614 615 to++; 616 po++; 617 } 618 619 return true; 620 } 621 622 636 public boolean startsWith(XMLString prefix) 637 { 638 return startsWith(prefix, 0); 639 } 640 641 654 public boolean endsWith(String suffix) 655 { 656 return str().endsWith(suffix); 657 } 658 659 672 public int hashCode() 673 { 674 return str().hashCode(); 675 } 676 677 694 public int indexOf(int ch) 695 { 696 return str().indexOf(ch); 697 } 698 699 727 public int indexOf(int ch, int fromIndex) 728 { 729 return str().indexOf(ch, fromIndex); 730 } 731 732 747 public int lastIndexOf(int ch) 748 { 749 return str().lastIndexOf(ch); 750 } 751 752 775 public int lastIndexOf(int ch, int fromIndex) 776 { 777 return str().lastIndexOf(ch, fromIndex); 778 } 779 780 797 public int indexOf(String str) 798 { 799 return str().indexOf(str); 800 } 801 802 819 public int indexOf(XMLString str) 820 { 821 return str().indexOf(str.toString()); 822 } 823 824 850 public int indexOf(String str, int fromIndex) 851 { 852 return str().indexOf(str, fromIndex); 853 } 854 855 873 public int lastIndexOf(String str) 874 { 875 return str().lastIndexOf(str); 876 } 877 878 898 public int lastIndexOf(String str, int fromIndex) 899 { 900 return str().lastIndexOf(str, fromIndex); 901 } 902 903 920 public XMLString substring(int beginIndex) 921 { 922 return new XString(str().substring(beginIndex)); 923 } 924 925 941 public XMLString substring(int beginIndex, int endIndex) 942 { 943 return new XString(str().substring(beginIndex, endIndex)); 944 } 945 946 956 public XMLString concat(String str) 957 { 958 959 return new XString(str().concat(str)); 961 } 962 963 972 public XMLString toLowerCase(Locale locale) 973 { 974 return new XString(str().toLowerCase(locale)); 975 } 976 977 987 public XMLString toLowerCase() 988 { 989 return new XString(str().toLowerCase()); 990 } 991 992 1000 public XMLString toUpperCase(Locale locale) 1001 { 1002 return new XString(str().toUpperCase(locale)); 1003 } 1004 1005 1031 public XMLString toUpperCase() 1032 { 1033 return new XString(str().toUpperCase()); 1034 } 1035 1036 1041 public XMLString trim() 1042 { 1043 return new XString(str().trim()); 1044 } 1045 1046 1053 private static boolean isSpace(char ch) 1054 { 1055 return XMLCharacterRecognizer.isWhiteSpace(ch); } 1057 1058 1072 public XMLString fixWhiteSpace(boolean trimHead, boolean trimTail, 1073 boolean doublePunctuationSpaces) 1074 { 1075 1076 int len = this.length(); 1078 char[] buf = new char[len]; 1079 1080 this.getChars(0, len, buf, 0); 1081 1082 boolean edit = false; 1083 int s; 1084 1085 for (s = 0; s < len; s++) 1086 { 1087 if (isSpace(buf[s])) 1088 { 1089 break; 1090 } 1091 } 1092 1093 1094 int d = s; 1095 boolean pres = false; 1096 1097 for (; s < len; s++) 1098 { 1099 char c = buf[s]; 1100 1101 if (isSpace(c)) 1102 { 1103 if (!pres) 1104 { 1105 if (' ' != c) 1106 { 1107 edit = true; 1108 } 1109 1110 buf[d++] = ' '; 1111 1112 if (doublePunctuationSpaces && (s != 0)) 1113 { 1114 char prevChar = buf[s - 1]; 1115 1116 if (!((prevChar == '.') || (prevChar == '!') 1117 || (prevChar == '?'))) 1118 { 1119 pres = true; 1120 } 1121 } 1122 else 1123 { 1124 pres = true; 1125 } 1126 } 1127 else 1128 { 1129 edit = true; 1130 pres = true; 1131 } 1132 } 1133 else 1134 { 1135 buf[d++] = c; 1136 pres = false; 1137 } 1138 } 1139 1140 if (trimTail && 1 <= d && ' ' == buf[d - 1]) 1141 { 1142 edit = true; 1143 1144 d--; 1145 } 1146 1147 int start = 0; 1148 1149 if (trimHead && 0 < d && ' ' == buf[0]) 1150 { 1151 edit = true; 1152 1153 start++; 1154 } 1155 1156 XMLStringFactory xsf = XMLStringFactoryImpl.getFactory(); 1157 1158 return edit ? xsf.newstr(new String (buf, start, d - start)) : this; 1159 } 1160 1161 1164 public void callVisitors(ExpressionOwner owner, XPathVisitor visitor) 1165 { 1166 visitor.visitStringLiteral(owner, this); 1167 } 1168 1169} 1170 | Popular Tags |