1 28 29 package net.n3.nanoxml; 30 31 import java.io.CharArrayReader ; 32 import java.io.IOException ; 33 import java.io.Reader ; 34 35 41 class XMLUtil 42 { 43 44 52 static void skipComment(IXMLReader reader, IXMLEntityResolver entityResolver) 53 throws IOException , XMLParseException 54 { 55 if (reader.read() != '-') 56 { 57 XMLUtil.skipTag(reader, '\0', entityResolver); 58 return; 59 } 60 61 int dashesRead = 0; 62 63 for (;;) 64 { 65 char ch = reader.read(); 66 67 switch (ch) 68 { 69 case '-': 70 dashesRead++; 71 break; 72 73 case '>': 74 if (dashesRead == 2) { return; } 75 76 default: 77 dashesRead = 0; 78 } 79 } 80 } 81 82 91 static void skipTag(IXMLReader reader, char escapeChar, IXMLEntityResolver entityResolver) 92 throws IOException , XMLParseException 93 { 94 int level = 1; 95 96 while (level > 0) 97 { 98 char ch = XMLUtil.read(reader, null, escapeChar, entityResolver); 99 100 switch (ch) 101 { 102 case '<': 103 ++level; 104 break; 105 106 case '>': 107 --level; 108 break; 109 } 110 } 111 } 112 113 125 static String scanPublicID(StringBuffer publicID, IXMLReader reader, char escapeChar, 126 IXMLEntityResolver entityResolver) throws IOException , XMLParseException 127 { 128 if (!XMLUtil.checkLiteral(reader, escapeChar, entityResolver, "UBLIC")) { return null; } 129 130 XMLUtil.skipWhitespace(reader, escapeChar, null, null); 131 publicID.append(XMLUtil.scanString(reader, escapeChar, false, entityResolver)); 132 XMLUtil.skipWhitespace(reader, escapeChar, null, null); 133 return XMLUtil.scanString(reader, escapeChar, false, entityResolver); 134 } 135 136 147 static String scanSystemID(IXMLReader reader, char escapeChar, IXMLEntityResolver entityResolver) 148 throws IOException , XMLParseException 149 { 150 if (!XMLUtil.checkLiteral(reader, escapeChar, entityResolver, "YSTEM")) { return null; } 151 152 XMLUtil.skipWhitespace(reader, escapeChar, null, null); 153 return XMLUtil.scanString(reader, escapeChar, false, entityResolver); 154 } 155 156 165 static String scanIdentifier(IXMLReader reader, char escapeChar, 166 IXMLEntityResolver entityResolver) throws IOException , XMLParseException 167 { 168 StringBuffer result = new StringBuffer (); 169 170 for (;;) 171 { 172 char ch = XMLUtil.read(reader, null, escapeChar, entityResolver); 173 174 if ((ch == '_') || (ch == ':') || (ch == '-') || (ch == '.') 175 || ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) 176 || ((ch >= '0') && (ch <= '9')) || (ch > '\u007E')) 177 { 178 result.append(ch); 179 } 180 else 181 { 182 reader.unread(ch); 183 break; 184 } 185 } 186 187 return result.toString(); 188 } 189 190 200 static String scanString(IXMLReader reader, char escapeChar, boolean normalizeWhitespace, 201 IXMLEntityResolver entityResolver) throws IOException , XMLParseException 202 { 203 StringBuffer result = new StringBuffer (); 204 boolean isEntity[] = new boolean[1]; 205 char delim = XMLUtil.read(reader, null, escapeChar, entityResolver); 206 207 if ((delim != '\'') && (delim != '"')) 208 { 209 XMLUtil 210 .errorExpectedInput(reader.getSystemID(), reader.getLineNr(), 211 "delimited string"); 212 } 213 214 for (;;) 215 { 216 char ch = XMLUtil.read(reader, isEntity, escapeChar, entityResolver); 217 218 if ((!isEntity[0]) && (ch == escapeChar)) 219 { 220 reader.startNewStream(XMLUtil.scanEntity(isEntity, reader, escapeChar, 221 entityResolver)); 222 ch = reader.read(); 223 } 224 225 if ((!isEntity[0]) && (ch == delim)) 226 { 227 break; 228 } 229 else if (normalizeWhitespace && (ch < ' ')) 230 { 231 result.append(' '); 232 } 233 else 234 { 235 result.append(ch); 236 } 237 } 238 239 return result.toString(); 240 } 241 242 254 static Reader scanEntity(boolean[] isCharLiteral, IXMLReader reader, char escapeChar, 255 IXMLEntityResolver entityResolver) throws IOException , XMLParseException 256 { 257 char ch = reader.read(); 258 StringBuffer keyBuf = new StringBuffer (); 259 260 while (ch != ';') 261 { 262 keyBuf.append(ch); 263 ch = reader.read(); 264 } 265 266 String key = keyBuf.toString(); 267 268 if (key.charAt(0) == '#') 269 { 270 if (isCharLiteral != null) 271 { 272 isCharLiteral[0] = true; 273 } 274 275 char[] chArr = new char[1]; 276 277 if (key.charAt(1) == 'x') 278 { 279 chArr[0] = (char) Integer.parseInt(key.substring(2), 16); 280 } 281 else 282 { 283 chArr[0] = (char) Integer.parseInt(key.substring(1), 10); 284 } 285 286 return new CharArrayReader (chArr); 287 } 288 else 289 { 290 Reader entityReader = entityResolver.getEntity(reader, key); 291 292 if (entityReader == null) 293 { 294 XMLUtil.errorInvalidEntity(reader.getSystemID(), reader.getLineNr(), key); 295 } 296 297 return entityReader; 298 } 299 } 300 301 312 static void skipWhitespace(IXMLReader reader, char escapeChar, StringBuffer buffer, 313 boolean[] isEntity) throws IOException 314 { 315 char ch; 316 317 if (buffer == null) 318 { 319 do 320 { 321 ch = reader.read(); 322 } 323 while ((ch == ' ') || (ch == '\t') || (ch == '\n') || (ch == '\r')); 324 } 325 else 326 { 327 for (;;) 328 { 329 ch = reader.read(); 330 331 if ((ch != ' ') && (ch != '\t') && (ch != '\n') && (ch != '\r')) 332 { 333 break; 334 } 335 336 buffer.append(ch); 337 } 338 } 339 340 reader.unread(ch); 341 342 if (isEntity != null) 343 { 344 isEntity[0] = (ch == escapeChar); 345 } 346 } 347 348 358 static char read(IXMLReader reader, boolean[] isEntityValue, char escapeChar, 359 IXMLEntityResolver entityResolver) throws IOException , XMLParseException 360 { 361 char ch = reader.read(); 362 363 if (isEntityValue != null) 364 { 365 isEntityValue[0] = false; 366 } 367 368 if (ch == escapeChar) 369 { 370 boolean[] charLiteral = new boolean[1]; 371 reader.startNewStream(XMLUtil.scanEntity(charLiteral, reader, escapeChar, 372 entityResolver)); 373 374 if (charLiteral[0]) 375 { 376 ch = reader.read(); 377 378 if (isEntityValue != null) 379 { 380 isEntityValue[0] = true; 381 } 382 } 383 else 384 { 385 ch = XMLUtil.read(reader, null, escapeChar, entityResolver); 386 } 387 } 388 389 return ch; 390 } 391 392 403 static boolean checkLiteral(IXMLReader reader, char escapeChar, 404 IXMLEntityResolver entityResolver, String literal) throws IOException , 405 XMLParseException 406 { 407 for (int i = 0; i < literal.length(); i++) 408 { 409 char ch = XMLUtil.read(reader, null, escapeChar, entityResolver); 410 411 if (ch != literal.charAt(i)) { return false; } 412 } 413 414 return true; 415 } 416 417 424 static void errorExpectedInput(String systemID, int lineNr, String expectedString) 425 throws XMLParseException 426 { 427 throw new XMLParseException(systemID, lineNr, "Expected: " + expectedString); 428 } 429 430 437 static void errorInvalidEntity(String systemID, int lineNr, String key) 438 throws XMLParseException 439 { 440 throw new XMLParseException(systemID, lineNr, "Invalid entity: `&" + key + ";'"); 441 } 442 443 450 static void errorInvalidInput(String systemID, int lineNr, String unexpectedString) 451 throws XMLParseException 452 { 453 throw new XMLParseException(systemID, lineNr, "Invalid input: " + unexpectedString); 454 } 455 456 465 static void errorWrongClosingTag(String systemID, int lineNr, String expectedName, 466 String wrongName) throws XMLParseException 467 { 468 throw new XMLParseException(systemID, lineNr, "Closing tag does not match opening tag: `" 469 + wrongName + "' != `" + expectedName + "'"); 470 } 471 472 478 static void errorClosingTagNotEmpty(String systemID, int lineNr) throws XMLParseException 479 { 480 throw new XMLParseException(systemID, lineNr, "Closing tag must be empty"); 481 } 482 483 491 static void errorMissingElement(String systemID, int lineNr, String parentElementName, 492 String missingElementName) throws XMLValidationException 493 { 494 throw new XMLValidationException(XMLValidationException.MISSING_ELEMENT, systemID, lineNr, 495 missingElementName, 496 null, 497 null, "Element " + parentElementName + " expects to have a " 498 + missingElementName); 499 } 500 501 509 static void errorUnexpectedElement(String systemID, int lineNr, String parentElementName, 510 String unexpectedElementName) throws XMLValidationException 511 { 512 throw new XMLValidationException(XMLValidationException.UNEXPECTED_ELEMENT, systemID, 513 lineNr, unexpectedElementName, 514 null, 515 null, "Unexpected " + unexpectedElementName + " in a " 516 + parentElementName); 517 } 518 519 527 static void errorMissingAttribute(String systemID, int lineNr, String elementName, 528 String attributeName) throws XMLValidationException 529 { 530 throw new XMLValidationException(XMLValidationException.MISSING_ATTRIBUTE, systemID, 531 lineNr, elementName, attributeName, 532 null, "Element " + elementName 533 + " expects an attribute named " + attributeName); 534 } 535 536 544 static void errorUnexpectedAttribute(String systemID, int lineNr, String elementName, 545 String attributeName) throws XMLValidationException 546 { 547 throw new XMLValidationException(XMLValidationException.UNEXPECTED_ATTRIBUTE, systemID, 548 lineNr, elementName, attributeName, 549 null, "Element " + elementName 550 + " did not expect an attribute " + "named " + attributeName); 551 } 552 553 562 static void errorInvalidAttributeValue(String systemID, int lineNr, String elementName, 563 String attributeName, String attributeValue) throws XMLValidationException 564 { 565 throw new XMLValidationException(XMLValidationException.ATTRIBUTE_WITH_INVALID_VALUE, 566 systemID, lineNr, elementName, attributeName, attributeValue, 567 "Invalid value for attribute " + attributeName); 568 } 569 570 577 static void errorMissingPCData(String systemID, int lineNr, String parentElementName) 578 throws XMLValidationException 579 { 580 throw new XMLValidationException(XMLValidationException.MISSING_PCDATA, systemID, lineNr, 581 null, 582 null, 583 null, "Missing #PCDATA in element " + parentElementName); 584 } 585 586 593 static void errorUnexpectedPCData(String systemID, int lineNr, String parentElementName) 594 throws XMLValidationException 595 { 596 throw new XMLValidationException(XMLValidationException.UNEXPECTED_PCDATA, systemID, 597 lineNr, 598 null, 599 null, 600 null, "Unexpected #PCDATA in element " + parentElementName); 601 } 602 603 613 static void validationError(String systemID, int lineNr, String message, String elementName, 614 String attributeName, String attributeValue) throws XMLValidationException 615 { 616 throw new XMLValidationException(XMLValidationException.MISC_ERROR, systemID, lineNr, 617 elementName, attributeName, attributeValue, message); 618 } 619 620 } 621 | Popular Tags |