Clover coverage report - Clover results for XOM 1.2d1
Coverage timestamp: Wed Feb 8 2006 08:31:33 EST
file stats: LOC: 3,307   Methods: 172
NCLOC: 2,409   Classes: 15
Warning
The source file used to generate this report was changed after Clover generated coverage information. The coverage reported may not match the source lines. You should regenerate the coverage information and the report to ensure the files are in sync.
 
 Source file Conditionals Statements Methods TOTAL
BuilderTest.java 71.2% 93.3% 98.8% 92.8%
coverage coverage
 1    /* Copyright 2002-2005 Elliotte Rusty Harold
 2   
 3    This library is free software; you can redistribute it and/or modify
 4    it under the terms of version 2.1 of the GNU Lesser General Public
 5    License as published by the Free Software Foundation.
 6   
 7    This library is distributed in the hope that it will be useful,
 8    but WITHOUT ANY WARRANTY; without even the implied warranty of
 9    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 10    GNU Lesser General Public License for more details.
 11   
 12    You should have received a copy of the GNU Lesser General Public
 13    License along with this library; if not, write to the
 14    Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 15    Boston, MA 02111-1307 USA
 16   
 17    You can contact Elliotte Rusty Harold by sending e-mail to
 18    elharo@metalab.unc.edu. Please include the word "XOM" in the
 19    subject line. The XOM home page is located at http://www.xom.nu/
 20    */
 21   
 22    package nu.xom.tests;
 23   
 24    import java.io.ByteArrayOutputStream;
 25    import java.io.CharConversionException;
 26    import java.io.File;
 27    import java.io.FileNotFoundException;
 28    import java.io.FileOutputStream;
 29    import java.io.IOException;
 30    import java.io.OutputStreamWriter;
 31    import java.io.PrintStream;
 32    import java.io.Reader;
 33    import java.io.StringReader;
 34    import java.io.ByteArrayInputStream;
 35    import java.io.InputStream;
 36    import java.io.UTFDataFormatException;
 37    import java.io.Writer;
 38    import java.lang.ref.WeakReference;
 39    import java.lang.reflect.Constructor;
 40    import java.lang.reflect.InvocationTargetException;
 41   
 42    import org.xml.sax.Attributes;
 43    import org.xml.sax.InputSource;
 44    import org.xml.sax.Locator;
 45    import org.xml.sax.SAXException;
 46    import org.xml.sax.SAXNotRecognizedException;
 47    import org.xml.sax.SAXNotSupportedException;
 48    import org.xml.sax.SAXParseException;
 49    import org.xml.sax.XMLFilter;
 50    import org.xml.sax.XMLReader;
 51    import org.xml.sax.helpers.AttributesImpl;
 52    import org.xml.sax.helpers.LocatorImpl;
 53    import org.xml.sax.helpers.XMLFilterImpl;
 54    import org.xml.sax.helpers.XMLReaderFactory;
 55   
 56    import nu.xom.Attribute;
 57    import nu.xom.Builder;
 58    import nu.xom.Comment;
 59    import nu.xom.DocType;
 60    import nu.xom.Document;
 61    import nu.xom.Element;
 62    import nu.xom.Elements;
 63    import nu.xom.NodeFactory;
 64    import nu.xom.ParsingException;
 65    import nu.xom.ProcessingInstruction;
 66    import nu.xom.Serializer;
 67    import nu.xom.ValidityException;
 68    import nu.xom.WellformednessException;
 69    import nu.xom.XMLException;
 70   
 71   
 72    /**
 73    * <p>
 74    * Tests building documents from streams, strings, files,
 75    * and other input sources.
 76    * </p>
 77    *
 78    * @author Elliotte Rusty Harold
 79    * @version 1.2b1
 80    *
 81    */
 82    public class BuilderTest extends XOMTestCase {
 83   
 84   
 85    private File inputDir = new File("data");
 86   
 87    // This class tests error conditions, which Xerces
 88    // annoyingly logs to System.err. So we hide System.err
 89    // before each test and restore it after each test.
 90    private PrintStream systemErr = System.err;
 91   
 92  143 protected void setUp() {
 93  143 System.setErr(new PrintStream(new ByteArrayOutputStream()));
 94    }
 95   
 96   
 97  143 protected void tearDown() {
 98  143 System.setErr(systemErr);
 99    }
 100   
 101   
 102    // Custom parser to test what happens when parser supplies
 103    // malformed data
 104    private static class CustomReader extends XMLFilterImpl {
 105   
 106  25 public void setFeature(String name, boolean value) {};
 107   
 108  1 public void parse(InputSource in) throws SAXException {
 109  1 this.getContentHandler().startDocument();
 110  1 this.getContentHandler().startElement("87", "87", "87", new AttributesImpl());
 111  0 this.getContentHandler().endElement("87", "87", "87");
 112  0 this.getContentHandler().endDocument();
 113    }
 114   
 115    }
 116   
 117   
 118    private static class DoNothingReader extends CustomReader {
 119   
 120  1 public void parse(InputSource in) throws SAXException {}
 121   
 122    }
 123   
 124   
 125    private static class StartAndEndReader extends CustomReader {
 126   
 127  1 public void parse(InputSource in) throws SAXException {
 128  1 this.getContentHandler().startDocument();
 129  1 this.getContentHandler().endDocument();
 130    }
 131   
 132    }
 133   
 134   
 135    private static class StartOnlyReader extends CustomReader {
 136   
 137  1 public void parse(InputSource in) throws SAXException {
 138  1 this.getContentHandler().startDocument();
 139    }
 140   
 141    }
 142   
 143   
 144    private static class EndOnlyReader extends CustomReader {
 145   
 146  1 public void parse(InputSource in) throws SAXException {
 147  1 this.getContentHandler().endDocument();
 148    }
 149   
 150    }
 151   
 152   
 153  143 public BuilderTest(String name) {
 154  143 super(name);
 155    }
 156   
 157   
 158    // flag to turn on and off tests based on
 159    // http://nagoya.apache.org/bugzilla/show_bug.cgi?id=24124
 160    private boolean xercesBroken = false;
 161   
 162    private String elementDeclaration = "<!ELEMENT root (#PCDATA)>";
 163    private String defaultAttributeDeclaration
 164    = "<!ATTLIST test name CDATA \"value\">";
 165    private String attributeDeclaration
 166    = "<!ATTLIST root anattribute CDATA #REQUIRED>";
 167    private String attributeDeclaration2
 168    = "<!ATTLIST root anotherattribute CDATA \"value\">";
 169    private String unparsedEntityDeclaration
 170    = "<!ENTITY hatch-pic SYSTEM " +
 171    "\"http://www.example.com/images/cup.gif\" NDATA gif>";
 172    private String unparsedEntityDeclarationPublic
 173    = "<!ENTITY public-pic PUBLIC \"public ID\" " +
 174    "\"http://www.example.com/images/cup.gif\" NDATA gif>";
 175    private String internalEntityDeclaration
 176    = "<!ENTITY Pub-Status \"" +
 177    "This is a pre-release of the specification.\">";
 178    private String externalEntityDeclarationPublic =
 179    "<!ENTITY open-hatch "
 180    + "PUBLIC \"-//Textuality//TEXT Standard " +
 181    "open-hatch boilerplate//EN\" "
 182    + "\"http://www.textuality.com/boilerplate/OpenHatch.xml\">";
 183    private String externalEntityDeclarationSystem =
 184    "<!ENTITY test SYSTEM " +
 185    "\"http://www.textuality.com/boilerplate/OpenHatch.xml\">";
 186    private String notationDeclarationSystem
 187    = "<!NOTATION ISODATE SYSTEM "
 188    + "\"http://www.iso.ch/cate/d15903.html\">";
 189    private String notationDeclarationPublicAndSystem
 190    = "<!NOTATION DATE PUBLIC \"DATE PUBLIC ID\" "
 191    + "\"http://www.iso.ch/cate/d15903.html\">";
 192    private String notationDeclarationPublic = "<!NOTATION gif PUBLIC "
 193    + "\"-//Textuality//TEXT Standard open-hatch boilerplate//EN\">";
 194   
 195    private String source = "<!DOCTYPE test [\r\n"
 196    + elementDeclaration + "\n"
 197    + attributeDeclaration + "\n"
 198    + defaultAttributeDeclaration + "\n"
 199    + attributeDeclaration2 + "\n"
 200    + internalEntityDeclaration + "\n"
 201    + externalEntityDeclarationPublic + "\n"
 202    + externalEntityDeclarationSystem + "\n"
 203    + unparsedEntityDeclaration + "\n"
 204    + unparsedEntityDeclarationPublic + "\n"
 205    + notationDeclarationPublic + "\n"
 206    + notationDeclarationSystem + "\n"
 207    + notationDeclarationPublicAndSystem + "\n"
 208    + "]>\r\n"
 209    + "<?xml-stylesheet href=\"file.css\" type=\"text/css\"?>"
 210    + "<!-- test -->"
 211    + "<test xmlns:xlink='http://www.w3.org/TR/1999/xlink'>Hello dear"
 212    + "\r\n<em id=\"p1\" xmlns:none=\"http://www.example.com\">"
 213    + "very important</em>"
 214    + "<span xlink:type='simple'>here&apos;s the link</span>\r\n"
 215    + "<svg:svg xmlns:svg='http://www.w3.org/TR/2000/svg'>"
 216    + "<svg:text>text in a namespace</svg:text></svg:svg>\r\n"
 217    + "<svg xmlns='http://www.w3.org/TR/2000/svg'><text>text in a "
 218    + "namespace</text></svg></test>\r\n<!--epilog-->";
 219   
 220    private String validDoc = "<!DOCTYPE test [\r\n"
 221    + "<!ELEMENT test (#PCDATA)>\n"
 222    + "]>\r\n"
 223    + "<?xml-stylesheet href=\"file.css\" type=\"text/css\"?>"
 224    + "<!-- test -->"
 225    + "<test>Hello dear</test>"
 226    + "<!--epilog-->";
 227   
 228    private Builder builder = new Builder();
 229    private Builder validator = new Builder(true);
 230    private String base = "http://www.example.com/";
 231   
 232    private String attributeDoc = "<!DOCTYPE test [\n"
 233    + "<!ELEMENT test (#PCDATA)>\n"
 234    + "<!NOTATION GIF SYSTEM \"text/gif\">\n"
 235    + "<!ENTITY data SYSTEM \"http://www.example.org/cup.gif\">\n"
 236    + "<!ATTLIST test notationatt NOTATION (GIF) \"GIF\">\n"
 237    + "<!ATTLIST test cdataatt CDATA \"GIF\">\n"
 238    + "<!ATTLIST test entityatt ENTITY \"data\">\n"
 239    + "<!ATTLIST test entitiesatt ENTITIES \"data\">\n"
 240    + "<!ATTLIST test nmtokenatt NMTOKEN \" 1 \">\n"
 241    + "<!ATTLIST test nmtokensatt NMTOKENS \" 1 2 3 \">\n"
 242    + "<!ATTLIST test idatt ID \" p1 \">\n"
 243    + "<!ATTLIST test idrefatt IDREF \" p1 \">\n"
 244    + "<!ATTLIST test idrefsatt IDREFS \" p1 p2 \">\n"
 245    + "]>\r\n"
 246    + "<test>Hello dear</test>";
 247   
 248   
 249  1 public void testDoNothingParser()
 250    throws ParsingException, IOException {
 251   
 252  1 try {
 253  1 XMLReader parser = new DoNothingReader();
 254  1 Builder builder = new Builder(parser);
 255  1 builder.build("http://www.example.org/");
 256  0 fail("built from bad data");
 257    }
 258    catch (ParsingException success) {
 259  1 assertNotNull(success.getMessage());
 260  1 assertEquals("http://www.example.org/", success.getURI());
 261    }
 262   
 263    }
 264   
 265   
 266  1 public void testStartAndEndParser()
 267    throws ParsingException, IOException {
 268   
 269  1 XMLReader parser = new StartAndEndReader();
 270  1 Builder builder = new Builder(parser);
 271  1 Document doc = builder.build("http://www.example.org/");
 272  1 assertNotNull(doc.getRootElement());
 273   
 274    }
 275   
 276   
 277  1 public void testStartOnlyParser()
 278    throws ParsingException, IOException {
 279   
 280  1 XMLReader parser = new StartOnlyReader();
 281  1 Builder builder = new Builder(parser);
 282  1 Document doc = builder.build("http://www.example.org/");
 283  1 assertNotNull(doc.getRootElement());
 284   
 285    }
 286   
 287   
 288  1 public void testEndOnlyParser()
 289    throws ParsingException, IOException {
 290   
 291  1 try {
 292  1 XMLReader parser = new EndOnlyReader();
 293  1 Builder builder = new Builder(parser);
 294  1 builder.build("http://www.example.org/");
 295  0 fail("built from bad data");
 296    }
 297    catch (ParsingException success) {
 298  1 assertTrue(success.getCause() instanceof NullPointerException);
 299    }
 300   
 301    }
 302   
 303   
 304  1 public void testBuildInternalDTDSubsetWithFixedDefaultAttributeValue()
 305    throws ParsingException, IOException {
 306   
 307  1 String doctype = "<!DOCTYPE xsl:stylesheet [\n"
 308    + "<!ATTLIST a b CDATA #FIXED \"c\">]>";
 309  1 String document = doctype + "\n<root/>";
 310  1 Builder builder = new Builder();
 311  1 Document doc = builder.build(document, null);
 312  1 DocType dt = doc.getDocType();
 313  1 String internalDTDSubset = dt.getInternalDTDSubset();
 314  1 assertTrue(internalDTDSubset.indexOf("#FIXED \"c\"") > 0);
 315   
 316    }
 317   
 318   
 319  1 public void testNotationAttributeType()
 320    throws IOException, ParsingException {
 321   
 322  1 Reader reader = new StringReader(attributeDoc);
 323  1 Document document = builder.build(reader);
 324  1 Element root = document.getRootElement();
 325  1 Attribute att = root.getAttribute("notationatt");
 326  1 assertEquals(Attribute.Type.NOTATION, att.getType());
 327   
 328    }
 329   
 330   
 331  1 public void testCDATAAttributeType()
 332    throws IOException, ParsingException {
 333   
 334  1 Reader reader = new StringReader(attributeDoc);
 335  1 Document document = builder.build(reader);
 336  1 Element root = document.getRootElement();
 337  1 Attribute att = root.getAttribute("cdataatt");
 338  1 assertEquals(Attribute.Type.CDATA, att.getType());
 339   
 340    }
 341   
 342   
 343  1 public void testEntityAttributeType()
 344    throws IOException, ParsingException {
 345   
 346  1 Reader reader = new StringReader(attributeDoc);
 347  1 Document document = builder.build(reader);
 348  1 Element root = document.getRootElement();
 349  1 Attribute att = root.getAttribute("entityatt");
 350  1 assertEquals(Attribute.Type.ENTITY, att.getType());
 351   
 352    }
 353   
 354   
 355  1 public void testEntitiesAttributeType()
 356    throws IOException, ParsingException {
 357   
 358  1 Reader reader = new StringReader(attributeDoc);
 359  1 Document document = builder.build(reader);
 360  1 Element root = document.getRootElement();
 361  1 Attribute att = root.getAttribute("entitiesatt");
 362  1 assertEquals(Attribute.Type.ENTITIES, att.getType());
 363   
 364    }
 365   
 366   
 367  1 public void testNameTokenAttributeType()
 368    throws IOException, ParsingException {
 369   
 370  1 Reader reader = new StringReader(attributeDoc);
 371  1 Document document = builder.build(reader);
 372  1 Element root = document.getRootElement();
 373  1 Attribute att = root.getAttribute("nmtokenatt");
 374  1 assertEquals(Attribute.Type.NMTOKEN, att.getType());
 375  1 assertEquals("1", att.getValue());
 376   
 377    }
 378   
 379   
 380    // I'm specifically worried about a Xerces runtime MalformedURIException here
 381  1 public void testIllegalSystemIDThrowsRightException() {
 382   
 383  1 String document = "<!DOCTYPE root SYSTEM \"This is not a URI\"><root/>";
 384  1 try{
 385  1 builder.build(document, null);
 386    }
 387    catch (Exception ex) {
 388  1 assertTrue(ex instanceof ParsingException);
 389    }
 390   
 391    }
 392   
 393   
 394  1 public void testNameTokensAttributeType()
 395    throws IOException, ParsingException {
 396   
 397  1 Reader reader = new StringReader(attributeDoc);
 398  1 Document document = builder.build(reader);
 399  1 Element root = document.getRootElement();
 400  1 Attribute att = root.getAttribute("nmtokensatt");
 401  1 assertEquals(Attribute.Type.NMTOKENS, att.getType());
 402  1 assertEquals("1 2 3", att.getValue());
 403   
 404    }
 405   
 406   
 407    // verify that XML 1.1 is not supported
 408  1 public void testXML11() throws IOException {
 409   
 410  1 String data = "<?xml version='1.1'?><root/>";
 411  1 try {
 412  1 builder.build(data, "http://www.example.com");
 413  0 fail("XML 1.1 allowed");
 414    }
 415    catch (ParsingException ex) {
 416  1 assertNotNull(ex.getMessage());
 417    }
 418   
 419    }
 420   
 421   
 422    // verify that XML 1.2 is not supported
 423  1 public void testXML12() throws IOException {
 424   
 425  1 String data = "<?xml version='1.2'?><root/>";
 426  1 try {
 427  1 builder.build(data, "http://www.example.com");
 428  0 fail("XML 1.2 allowed");
 429    }
 430    catch (ParsingException ex) {
 431  1 assertNotNull(ex.getMessage());
 432    }
 433   
 434    }
 435   
 436   
 437    // verify that XML 2.0 is not supported
 438  1 public void testXML20() throws IOException {
 439   
 440  1 String data = "<?xml version='2.0'?><root/>";
 441  1 try {
 442  1 builder.build(data, "http://www.example.com");
 443  0 fail("XML 2.0 allowed");
 444    }
 445    catch (ParsingException ex) {
 446  1 assertNotNull(ex.getMessage());
 447    }
 448   
 449    }
 450   
 451   
 452  1 public void testIDAttributeType()
 453    throws IOException, ParsingException {
 454   
 455  1 Reader reader = new StringReader(attributeDoc);
 456  1 Document document = builder.build(reader);
 457  1 Element root = document.getRootElement();
 458  1 Attribute att = root.getAttribute("idatt");
 459  1 assertEquals(Attribute.Type.ID, att.getType());
 460  1 assertEquals("p1", att.getValue());
 461   
 462    }
 463   
 464   
 465  1 public void testIDREFAttributeType()
 466    throws IOException, ParsingException {
 467   
 468  1 Reader reader = new StringReader(attributeDoc);
 469  1 Document document = builder.build(reader);
 470  1 Element root = document.getRootElement();
 471  1 Attribute att = root.getAttribute("idrefatt");
 472  1 assertEquals(Attribute.Type.IDREF, att.getType());
 473  1 assertEquals("p1", att.getValue());
 474   
 475    }
 476   
 477   
 478  1 public void testIDREFSAttributeType()
 479    throws IOException, ParsingException {
 480   
 481  1 Reader reader = new StringReader(attributeDoc);
 482  1 Document document = builder.build(reader);
 483  1 Element root = document.getRootElement();
 484  1 Attribute att = root.getAttribute("idrefsatt");
 485  1 assertEquals(Attribute.Type.IDREFS, att.getType());
 486  1 assertEquals("p1 p2", att.getValue());
 487   
 488    }
 489   
 490   
 491  1 public void testBuildFromReader()
 492    throws IOException, ParsingException {
 493   
 494  1 Reader reader = new StringReader(source);
 495  1 Document document = builder.build(reader);
 496  1 verify(document);
 497  1 assertEquals("", document.getBaseURI());
 498   
 499    }
 500   
 501   
 502  1 public void testBuildFromReaderWithBase()
 503    throws IOException, ParsingException {
 504   
 505  1 Reader reader = new StringReader(source);
 506  1 Document document = builder.build(reader, base);
 507  1 verify(document);
 508  1 assertEquals(base, document.getBaseURI());
 509   
 510    }
 511   
 512   
 513    private static class NoLocator extends XMLFilterImpl {
 514   
 515  1 public NoLocator(XMLReader reader) {
 516  1 super(reader);
 517    }
 518   
 519  1 public void setDocumentLocator(Locator locator) {}
 520   
 521    }
 522   
 523   
 524  1 public void testBuildWithoutLocator()
 525    throws IOException, ParsingException, SAXException {
 526   
 527  1 XMLReader xerces = XMLReaderFactory.createXMLReader(
 528    "org.apache.xerces.parsers.SAXParser");
 529  1 XMLReader filter = new NoLocator(xerces);
 530   
 531  1 Builder builder = new Builder(filter);
 532  1 Document document = builder.build(source, "http://www.example.org/");
 533  1 verify(document);
 534  1 assertEquals("http://www.example.org/", document.getBaseURI());
 535   
 536    }
 537   
 538   
 539    private static class WeirdAttributeTypes extends XMLFilterImpl {
 540   
 541  1 public WeirdAttributeTypes(XMLReader reader) {
 542  1 super(reader);
 543    }
 544   
 545  1 public void startElement(String uri, String localName,
 546    String qualifiedName, Attributes atts) throws SAXException {
 547   
 548  1 AttributesImpl newAtts = new AttributesImpl(atts);
 549  1 for (int i = 0; i < newAtts.getLength(); i++) {
 550  9 newAtts.setType(i, "WEIRD");
 551    }
 552   
 553  1 super.startElement(uri, localName, qualifiedName, newAtts);
 554   
 555    }
 556   
 557    }
 558   
 559   
 560  1 public void testWeirdAttributeTypes()
 561    throws IOException, ParsingException, SAXException {
 562   
 563  1 XMLReader xerces = XMLReaderFactory.createXMLReader(
 564    "org.apache.xerces.parsers.SAXParser");
 565  1 XMLReader filter = new WeirdAttributeTypes(xerces);
 566   
 567  1 Builder builder = new Builder(filter);
 568  1 Document document = builder.build(attributeDoc, "http://www.example.org/");
 569  1 Element root = document.getRootElement();
 570  1 assertTrue(root.getAttributeCount() > 0);
 571  1 for (int i = 0; i < root.getAttributeCount(); i++) {
 572  9 assertEquals(Attribute.Type.UNDECLARED, root.getAttribute(i).getType());
 573    }
 574   
 575    }
 576   
 577   
 578    // Here we're faking the non-standard behavior of some older parsers
 579    private static class ParenthesizedEnumeratedAttributeTypes extends XMLFilterImpl {
 580   
 581  1 public ParenthesizedEnumeratedAttributeTypes(XMLReader reader) {
 582  1 super(reader);
 583    }
 584   
 585  1 public void startElement(String uri, String localName,
 586    String qualifiedName, Attributes atts) throws SAXException {
 587   
 588  1 AttributesImpl newAtts = new AttributesImpl(atts);
 589  1 for (int i = 0; i < newAtts.getLength(); i++) {
 590  9 newAtts.setType(i, "(test, data, value)");
 591    }
 592   
 593  1 super.startElement(uri, localName, qualifiedName, newAtts);
 594   
 595    }
 596   
 597    }
 598   
 599   
 600  1 public void testParenthesizedEnumeratedAttributeTypes()
 601    throws IOException, ParsingException, SAXException {
 602   
 603  1 XMLReader xerces = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
 604  1 XMLReader filter = new ParenthesizedEnumeratedAttributeTypes(xerces);
 605   
 606  1 Builder builder = new Builder(filter);
 607  1 Document document = builder.build(attributeDoc, "http://www.example.org/");
 608  1 Element root = document.getRootElement();
 609  1 assertTrue(root.getAttributeCount() > 0);
 610  1 for (int i = 0; i < root.getAttributeCount(); i++) {
 611  9 assertEquals(Attribute.Type.ENUMERATION, root.getAttribute(i).getType());
 612    }
 613   
 614    }
 615   
 616   
 617  1 public void testBuildFromInputStreamWithBase()
 618    throws IOException, ParsingException {
 619  1 InputStream in = new ByteArrayInputStream(source.getBytes("UTF-8"));
 620  1 Document document = builder.build(in, base);
 621  1 verify(document);
 622  1 assertEquals(base, document.getBaseURI());
 623    }
 624   
 625   
 626  1 public void testBuildFromInputStreamWithoutBase()
 627    throws IOException, ParsingException {
 628  1 InputStream in = new ByteArrayInputStream(source.getBytes("UTF-8"));
 629  1 Document document = builder.build(in);
 630  1 verify(document);
 631  1 assertEquals("", document.getBaseURI());
 632    }
 633   
 634   
 635  1 public void testBuildFromStringWithBase()
 636    throws IOException, ParsingException {
 637  1 Document document = builder.build(source, base);
 638  1 verify(document);
 639  1 assertEquals(base, document.getBaseURI());
 640    }
 641   
 642   
 643  1 public void testBuildDocumentThatUsesDoubleQuoteNumericCharacterReferenceInEntityDeclaration()
 644    throws IOException, ParsingException {
 645   
 646  1 String data = "<!DOCTYPE doc [\n"
 647    + "<!ELEMENT doc (#PCDATA)>"
 648    + " <!ENTITY e \"&#34;\">\n"
 649    + "]><root />";
 650   
 651  1 Document document = builder.build(data, null);
 652   
 653  1 Document roundtrip = builder.build(document.toXML(), null);
 654  1 assertEquals(document, roundtrip);
 655   
 656    }
 657   
 658   
 659  1 public void testBuildDocumentThatDeclaresStandardEntityReferences()
 660    throws IOException, ParsingException {
 661   
 662  1 String data = "<!DOCTYPE doc [\n"
 663    + "<!ELEMENT doc (#PCDATA)>"
 664    + "<!ENTITY lt \"&#38;#60;\">\n"
 665    + "<!ENTITY gt \"&#62;\">\n"
 666    + "<!ENTITY amp \"&#38;#38;\">\n"
 667    + "<!ENTITY apos \"&#39;\">\n"
 668    + "<!ENTITY quot \"&#34;\">\n"
 669    + "]><root />";
 670   
 671  1 Document document = builder.build(data, null);
 672  1 Document roundtrip = builder.build(document.toXML(), null);
 673  1 assertEquals(document, roundtrip);
 674   
 675    }
 676   
 677   
 678  1 public void testBuildDocumentThatUsesAmpersandNumericCharacterReferenceInEntityDeclaration()
 679    throws IOException, ParsingException {
 680   
 681  1 String data = "<!DOCTYPE doc [\n"
 682    + "<!ELEMENT doc (#PCDATA)>"
 683    + " <!ENTITY e \"&#x26;\">\n"
 684    + "]><root />";
 685   
 686  1 Document document = builder.build(data, null);
 687   
 688  1 Document roundtrip = builder.build(document.toXML(), null);
 689  1 assertEquals(document, roundtrip);
 690   
 691    }
 692   
 693   
 694  1 public void testBuildDocumentThatUsesDoubleQuoteNumericCharacterReferenceInAttributeDeclaration()
 695    throws IOException, ParsingException {
 696   
 697  1 String data = "<!DOCTYPE doc [\n"
 698    + "<!ATTLIST root test (CDATA) \"&#x34;\">\n"
 699    + "]><root />";
 700   
 701  1 Document document = builder.build(data, null);
 702   
 703  1 Document roundtrip = builder.build(document.toXML(), null);
 704  1 assertEquals(document, roundtrip);
 705   
 706    }
 707   
 708   
 709  1 public void testMemoryFreedByBuilder()
 710    throws IOException, ParsingException, InterruptedException {
 711   
 712  1 String data = "<root />";
 713   
 714  1 Document document = builder.build(data, null);
 715  1 WeakReference ref = new WeakReference(document);
 716  1 document = null;
 717  1 System.gc();
 718  1 System.gc();
 719  1 System.gc();
 720  1 Thread.sleep(1000);
 721  1 assertNull(ref.get());
 722   
 723    }
 724   
 725   
 726  1 public void testBuildFromInvalidDoc()
 727    throws IOException, ParsingException {
 728   
 729  1 try {
 730  1 validator.build(source, base);
 731  0 fail("Built invalid doc");
 732    }
 733    catch (ValidityException ex) {
 734  1 Document document = ex.getDocument();
 735    // Can't do a full verify just yet due to bugs in Xerces
 736    // verify(ex.getDocument());
 737  1 assertTrue(document.getChild(1) instanceof ProcessingInstruction);
 738  1 assertTrue(document.getChild(2) instanceof Comment);
 739  1 DocType doctype = document.getDocType();
 740  1 Element root = document.getRootElement();
 741   
 742    // assertEquals(1, root.getAttributeCount());
 743    // assertEquals("value", root.getAttributeValue("name"));
 744  1 assertEquals("test", root.getQualifiedName());
 745  1 assertEquals("test", root.getLocalName());
 746  1 assertEquals("", root.getNamespaceURI());
 747   
 748  1 assertTrue(doctype != null);
 749  1 assertTrue(document.getChild(0) instanceof DocType);
 750  1 assertTrue(document.getChild(4) instanceof Comment);
 751  1 assertTrue(document.getChild(2) instanceof Comment);
 752  1 assertEquals(" test ", document.getChild(2).getValue());
 753  1 assertEquals("epilog", document.getChild(4).getValue());
 754  1 assertTrue(document.getChild(1) instanceof ProcessingInstruction);
 755  1 assertEquals("test", doctype.getRootElementName());
 756  1 assertNull(doctype.getPublicID());
 757  1 assertNull(doctype.getSystemID());
 758   
 759  1 String internalDTDSubset = doctype.getInternalDTDSubset();
 760  1 assertTrue(
 761    internalDTDSubset,
 762    internalDTDSubset.indexOf(elementDeclaration) > 0
 763    );
 764  1 assertTrue(
 765    internalDTDSubset,
 766    internalDTDSubset.indexOf(attributeDeclaration) > 0
 767    );
 768  1 assertTrue(
 769    internalDTDSubset,
 770    internalDTDSubset.indexOf(attributeDeclaration2) > 0
 771    );
 772  1 assertTrue(
 773    internalDTDSubset,
 774    internalDTDSubset.indexOf(internalEntityDeclaration) > 0
 775    );
 776  1 assertTrue(
 777    internalDTDSubset,
 778    internalDTDSubset.indexOf(externalEntityDeclarationPublic) > 0
 779    );
 780  1 assertTrue(
 781    internalDTDSubset,
 782    internalDTDSubset.indexOf(externalEntityDeclarationSystem) > 0
 783    );
 784  1 assertTrue(
 785    internalDTDSubset,
 786    internalDTDSubset.indexOf(unparsedEntityDeclaration) > 0
 787    );
 788  1 assertTrue(
 789    internalDTDSubset,
 790    internalDTDSubset.indexOf(unparsedEntityDeclarationPublic) > 0
 791    );
 792  1 assertTrue(
 793    internalDTDSubset,
 794    internalDTDSubset.indexOf(notationDeclarationPublic) > 0
 795    );
 796  1 assertTrue(
 797    internalDTDSubset,
 798    internalDTDSubset.indexOf(notationDeclarationSystem) > 0
 799    );
 800  1 assertTrue(
 801    internalDTDSubset,
 802    internalDTDSubset.indexOf(notationDeclarationPublicAndSystem) > 0
 803    );
 804   
 805    }
 806   
 807    }
 808   
 809   
 810  1 public void testBuildFromStringWithNullBase()
 811    throws IOException, ParsingException {
 812  1 Document document = builder.build(source, null);
 813  1 verify(document);
 814  1 assertEquals("", document.getBaseURI());
 815    }
 816   
 817   
 818  13 private void verify(Document document) {
 819   
 820  13 assertTrue(document.getChild(1) instanceof ProcessingInstruction);
 821  13 assertTrue(document.getChild(2) instanceof Comment);
 822  13 DocType doctype = document.getDocType();
 823  13 Element root = document.getRootElement();
 824   
 825  13 assertEquals(1, root.getAttributeCount());
 826  13 assertEquals("value", root.getAttributeValue("name"));
 827  13 assertEquals("test", root.getQualifiedName());
 828  13 assertEquals("test", root.getLocalName());
 829  13 assertEquals("", root.getNamespaceURI());
 830   
 831  13 assertTrue(doctype != null);
 832  13 assertTrue(document.getChild(0) instanceof DocType);
 833  13 assertTrue(document.getChild(4) instanceof Comment);
 834  13 assertTrue(document.getChild(2) instanceof Comment);
 835  13 assertEquals(" test ", document.getChild(2).getValue());
 836  13 assertEquals("epilog", document.getChild(4).getValue());
 837  13 assertTrue(document.getChild(1) instanceof ProcessingInstruction);
 838  13 assertEquals("test", doctype.getRootElementName());
 839  13 assertNull(doctype.getPublicID());
 840  13 assertNull(doctype.getSystemID());
 841   
 842  13 String internalDTDSubset = doctype.getInternalDTDSubset();
 843  13 assertTrue(
 844    internalDTDSubset,
 845    internalDTDSubset.indexOf(elementDeclaration) > 0
 846    );
 847  13 assertTrue(
 848    internalDTDSubset,
 849    internalDTDSubset.indexOf(attributeDeclaration) > 0
 850    );
 851  13 assertTrue(
 852    internalDTDSubset,
 853    internalDTDSubset.indexOf(attributeDeclaration2) > 0
 854    );
 855  13 assertTrue(
 856    internalDTDSubset,
 857    internalDTDSubset.indexOf(internalEntityDeclaration) > 0
 858    );
 859  13 assertTrue(
 860    internalDTDSubset,
 861    internalDTDSubset.indexOf(externalEntityDeclarationPublic) > 0
 862    );
 863  13 assertTrue(
 864    internalDTDSubset,
 865    internalDTDSubset.indexOf(externalEntityDeclarationSystem) > 0
 866    );
 867  13 assertTrue(
 868    internalDTDSubset,
 869    internalDTDSubset.indexOf(unparsedEntityDeclaration) > 0
 870    );
 871  13 assertTrue(
 872    internalDTDSubset,
 873    internalDTDSubset.indexOf(unparsedEntityDeclarationPublic) > 0
 874    );
 875  13 assertTrue(
 876    internalDTDSubset,
 877    internalDTDSubset.indexOf(notationDeclarationPublic) > 0
 878    );
 879  13 assertTrue(
 880    internalDTDSubset,
 881    internalDTDSubset.indexOf(notationDeclarationSystem) > 0
 882    );
 883  13 assertTrue(
 884    internalDTDSubset,
 885    internalDTDSubset.indexOf(notationDeclarationPublicAndSystem) > 0
 886    );
 887   
 888    }
 889   
 890   
 891  1 public void testValidateFromReader()
 892    throws IOException, ParsingException {
 893   
 894  1 Reader reader1 = new StringReader(validDoc);
 895  1 Document document1 = validator.build(reader1);
 896  1 assertEquals("", document1.getBaseURI());
 897  1 Reader reader2 = new StringReader(validDoc);
 898  1 Document document2 = builder.build(reader2);
 899  1 assertEquals(document2, document1);
 900   
 901    }
 902   
 903   
 904  1 public void testDocumentWithDefaultNamespaceOnPrefixedElement()
 905    throws IOException, ParsingException {
 906   
 907  1 Reader reader = new StringReader("<pre:root " +
 908    "xmlns='http://www.example.org/' " +
 909    "xmlns:pre='http://www.cafeconleche.org/'/>");
 910  1 Document document = builder.build(reader);
 911  1 Element root = document.getRootElement();
 912  1 assertEquals("http://www.example.org/", root.getNamespaceURI(""));
 913  1 assertEquals("http://www.cafeconleche.org/", root.getNamespaceURI("pre"));
 914  1 assertEquals("http://www.cafeconleche.org/", root.getNamespaceURI());
 915   
 916    }
 917   
 918   
 919  1 public void testValidateFromReaderWithBase()
 920    throws IOException, ParsingException {
 921   
 922  1 Reader reader = new StringReader(validDoc);
 923  1 Document document = validator.build(reader, base);
 924  1 assertEquals(base, document.getBaseURI());
 925  1 Reader reader2 = new StringReader(validDoc);
 926  1 Document document2 = builder.build(reader2);
 927  1 assertEquals(document2, document);
 928   
 929    }
 930   
 931   
 932  1 public void testValidateFromInputStreamWithBase()
 933    throws IOException, ParsingException {
 934   
 935  1 InputStream in = new ByteArrayInputStream(validDoc.getBytes("UTF-8"));
 936  1 Document document = validator.build(in, base);
 937  1 assertEquals(base, document.getBaseURI());
 938  1 Reader reader2 = new StringReader(validDoc);
 939  1 Document document2 = builder.build(reader2);
 940  1 assertEquals(document2, document);
 941   
 942    }
 943   
 944   
 945  1 public void testValidateInSeries()
 946    throws IOException, ParsingException {
 947   
 948  1 try {
 949  1 Reader reader = new StringReader(source);
 950  1 validator.build(reader);
 951  0 fail("Allowed invalid doc");
 952    }
 953    catch (ValidityException success) {
 954  1 assertNotNull(success.getMessage());
 955    }
 956    // now make sure validating a valid document doesn't
 957    // throw an exception
 958  1 InputStream in = new ByteArrayInputStream(validDoc.getBytes("UTF-8"));
 959  1 validator.build(in, base);
 960   
 961    }
 962   
 963   
 964  1 public void testValidateFromInputStreamWithoutBase()
 965    throws IOException, ParsingException {
 966   
 967  1 InputStream in = new ByteArrayInputStream(validDoc.getBytes("UTF-8"));
 968  1 Document document = validator.build(in);
 969  1 assertEquals("", document.getBaseURI());
 970  1 Reader reader2 = new StringReader(validDoc);
 971  1 Document document2 = builder.build(reader2);
 972  1 assertEquals(document2, document);
 973   
 974    }
 975   
 976   
 977  1 public void testValidateFromStringWithBase()
 978    throws IOException, ParsingException {
 979   
 980  1 Document document = validator.build(validDoc, base);
 981  1 assertEquals(base, document.getBaseURI());
 982  1 Reader reader2 = new StringReader(validDoc);
 983  1 Document document2 = builder.build(reader2);
 984  1 assertEquals(document2, document);
 985   
 986    }
 987   
 988   
 989  1 public void testValidateWithCrimson()
 990    throws IOException, ParsingException {
 991   
 992  1 XMLReader crimson;
 993  1 try {
 994  1 crimson = XMLReaderFactory.createXMLReader(
 995    "org.apache.crimson.parser.XMLReaderImpl");
 996    }
 997    catch (SAXException ex) {
 998    // can't test Crimson if you can't load it
 999  0 return;
 1000    }
 1001  1 Builder validator = new Builder(crimson, true);
 1002  1 Document document = validator.build(validDoc, base);
 1003  1 assertEquals(base, document.getBaseURI());
 1004  1 Reader reader2 = new StringReader(validDoc);
 1005  1 Document document2 = builder.build(reader2);
 1006  1 assertEquals(document2, document);
 1007   
 1008    }
 1009   
 1010   
 1011  1 public void testNotationAttributeTypeWithCrimson()
 1012    throws IOException, ParsingException {
 1013   
 1014  1 XMLReader crimson;
 1015  1 try {
 1016  1 crimson = XMLReaderFactory.createXMLReader(
 1017    "org.apache.crimson.parser.XMLReaderImpl");
 1018    }
 1019    catch (SAXException ex) {
 1020    // can't test Crimson if you can't load it
 1021  0 return;
 1022    }
 1023   
 1024  1 String data = " <!DOCTYPE doc [\n"
 1025    + "<!ATTLIST e a NOTATION (n) #IMPLIED>\n"
 1026    + "<!ELEMENT document (e)*>\n"
 1027    + "<!ELEMENT e (#PCDATA)>\n"
 1028    + "<!NOTATION n PUBLIC \"whatever\">"
 1029    + "]><document />";
 1030   
 1031  1 Builder builder = new Builder(crimson);
 1032  1 Document document = builder.build(data, base);
 1033   
 1034  1 String s = document.toXML();
 1035  1 Document roundTrip = builder.build(s, base);
 1036  1 assertEquals(document, roundTrip);
 1037   
 1038    }
 1039   
 1040   
 1041  1 public void testEnumerationAttributeType()
 1042    throws IOException, ParsingException {
 1043   
 1044  1 XMLReader crimson;
 1045  1 try {
 1046  1 crimson = XMLReaderFactory.createXMLReader(
 1047    "org.apache.crimson.parser.XMLReaderImpl");
 1048    }
 1049    catch (SAXException ex) {
 1050    // can't test Crimson if you can't load it
 1051  0 return;
 1052    }
 1053  1 Builder builder = new Builder(crimson, false);
 1054  1 String doc = "<!DOCTYPE root [" +
 1055    "<!ATTLIST root att (yes | no) #IMPLIED>" +
 1056    "]><root att='yes'/>";
 1057  1 Document document = builder.build(doc, base);
 1058  1 Element root = document.getRootElement();
 1059  1 Attribute att = root.getAttribute(0);
 1060  1 assertEquals(Attribute.Type.ENUMERATION, att.getType());
 1061   
 1062    }
 1063   
 1064   
 1065  1 public void testWarningDoesNotStopBuild()
 1066    throws IOException, ParsingException, SAXException {
 1067   
 1068  1 XMLReader xerces;
 1069  1 try {
 1070  1 xerces = XMLReaderFactory.createXMLReader(
 1071    "org.apache.xerces.parsers.SAXParser");
 1072    }
 1073    catch (SAXException ex) {
 1074    // can't test Xerces if you can't load it
 1075  0 return;
 1076    }
 1077    // This document generates a warning due to the duplicate
 1078    // attribute declaration
 1079  1 xerces.setFeature(
 1080    "http://apache.org/xml/features/validation/warn-on-duplicate-attdef",
 1081    true);
 1082  1 Builder builder = new Builder(xerces, true);
 1083  1 Document document = builder.build("<!DOCTYPE root [" +
 1084    "<!ELEMENT root ANY>" +
 1085    "<!ATTLIST root b CDATA #IMPLIED>" +
 1086    "<!ATTLIST root b NMTOKEN #REQUIRED>" +
 1087    "]><root b='test'/>", base);
 1088    // The main test is that the document is built successfully.
 1089  1 assertEquals(2, document.getChildCount());
 1090  1 assertEquals("root", document.getRootElement().getQualifiedName());
 1091   
 1092    }
 1093   
 1094   
 1095    private static class EntitySkipper extends XMLFilterImpl {
 1096   
 1097  1 public EntitySkipper(XMLReader reader) {
 1098  1 super(reader);
 1099    }
 1100   
 1101  1 public void characters(char[] data, int start, int length)
 1102    throws SAXException {
 1103  1 super.skippedEntity("name");
 1104    }
 1105   
 1106    }
 1107   
 1108   
 1109  1 public void testSkippedEntityThrowsParsingException()
 1110    throws IOException, ParsingException, SAXException {
 1111   
 1112  1 XMLReader xerces = XMLReaderFactory.createXMLReader(
 1113    "org.apache.xerces.parsers.SAXParser");
 1114  1 XMLReader filter = new EntitySkipper(xerces);
 1115   
 1116  1 Builder builder = new Builder(filter, true);
 1117  1 try {
 1118  1 builder.build("<root>replace</root>", base);
 1119  0 fail("Allowed skipped entity");
 1120    }
 1121    catch (ParsingException success) {
 1122  1 assertNotNull(success.getMessage());
 1123    }
 1124   
 1125    }
 1126   
 1127   
 1128  1 public void testValidateFromStringWithNullBase()
 1129    throws IOException, ParsingException {
 1130  1 Document document = validator.build(validDoc, null);
 1131  1 assertEquals("", document.getBaseURI());
 1132  1 Reader reader2 = new StringReader(validDoc);
 1133  1 Document document2 = builder.build(reader2);
 1134  1 assertEquals(document2, document);
 1135    }
 1136   
 1137   
 1138  1 public void testCannotBuildNamespaceMalformedDocument()
 1139    throws IOException {
 1140   
 1141  1 try {
 1142  1 builder.build("<root:root/>", null);
 1143  0 fail("Builder allowed undeclared prefix");
 1144    }
 1145    catch (ParsingException success) {
 1146  1 assertNotNull(success.getMessage());
 1147    }
 1148   
 1149    }
 1150   
 1151   
 1152  1 public void testInvalidDocFromReader()
 1153    throws IOException, ParsingException {
 1154   
 1155  1 Reader reader = new StringReader(source);
 1156  1 try {
 1157  1 validator.build(reader);
 1158  0 fail("Allowed invalid doc");
 1159    }
 1160    catch (ValidityException success) {
 1161  1 assertNotNull(success.getMessage());
 1162  1 assertTrue(success.getErrorCount() > 0);
 1163  1 for (int i = 0; i < success.getErrorCount(); i++) {
 1164  8 assertNotNull(success.getValidityError(i));
 1165  8 assertTrue(success.getLineNumber(i) >= -1);
 1166  8 assertTrue(success.getColumnNumber(i) >= -1);
 1167    }
 1168  1 if (!xercesBroken) {
 1169  1 Document doc = builder.build(new StringReader(source));
 1170  1 this.verify(success.getDocument());
 1171  1 assertEquals(doc, success.getDocument());
 1172    }
 1173    }
 1174   
 1175    }
 1176   
 1177   
 1178  1 public void testNamespaceMalformedDocumentWithCrimson()
 1179    throws IOException {
 1180   
 1181  1 StringReader reader = new StringReader("<root:root/>");
 1182  1 XMLReader crimson;
 1183  1 try {
 1184  1 crimson = XMLReaderFactory.createXMLReader(
 1185    "org.apache.crimson.parser.XMLReaderImpl");
 1186    }
 1187    catch (SAXException ex) {
 1188    // No Crimson in classpath; therefore can't test it
 1189  0 return;
 1190    }
 1191  1 Builder builder = new Builder(crimson);
 1192  1 try {
 1193  1 builder.build(reader);
 1194  0 fail("Crimson allowed namespace malformed doc");
 1195    }
 1196    catch (ParsingException success) {
 1197  1 assertNotNull(success.getMessage());
 1198    }
 1199   
 1200    }
 1201   
 1202   
 1203  1 public void testValidateNamespaceMalformedInvalidDocumentWithCrimson()
 1204    throws IOException {
 1205   
 1206  1 StringReader reader = new StringReader("<!DOCTYPE root [" +
 1207    "<!ELEMENT root (a)>\n" +
 1208    "<!ELEMENT a (#PCDATA)> \n" +
 1209    "]>\n" +
 1210    "<root><b:b /></root>");
 1211  1 XMLReader crimson;
 1212  1 try {
 1213  1 crimson = XMLReaderFactory.createXMLReader(
 1214    "org.apache.crimson.parser.XMLReaderImpl");
 1215    }
 1216    catch (SAXException ex) {
 1217    // No Crimson in classpath; therefore can't test it
 1218  0 return;
 1219    }
 1220  1 Builder builder = new Builder(crimson);
 1221  1 try {
 1222  1 builder.build(reader);
 1223  0 fail("Crimson allowed namespace malformed doc");
 1224    }
 1225    catch (ValidityException ex) {
 1226  0 fail("Crimson should have thrown ParsingException instead");
 1227    }
 1228    catch (ParsingException success) {
 1229  1 assertNotNull(success.getMessage());
 1230    }
 1231   
 1232    }
 1233   
 1234   
 1235  1 public void testInvalidDocFromReaderWithBase()
 1236    throws IOException, ParsingException {
 1237   
 1238  1 Reader reader1 = new StringReader(source);
 1239  1 try {
 1240  1 validator.build(reader1, base);
 1241  0 fail("Allowed invalid doc");
 1242    }
 1243    catch (ValidityException ex) {
 1244  1 assertNotNull(ex.getMessage());
 1245  1 assertEquals(base, ex.getURI());
 1246  1 assertTrue(ex.getErrorCount() > 0);
 1247  1 for (int i = 0; i < ex.getErrorCount(); i++) {
 1248  8 assertNotNull(ex.getValidityError(i));
 1249  8 assertTrue(ex.getLineNumber(i) >= -1);
 1250  8 assertTrue(ex.getColumnNumber(i) >= -1);
 1251    }
 1252  1 if (!xercesBroken) {
 1253  1 Document doc = builder.build(new StringReader(source), base);
 1254  1 this.verify(ex.getDocument());
 1255  1 assertEquals(doc, ex.getDocument());
 1256    }
 1257    }
 1258   
 1259    }
 1260   
 1261   
 1262  1 public void testInvalidDocFromInputStreamWithBase()
 1263    throws IOException, ParsingException {
 1264   
 1265  1 InputStream in = new ByteArrayInputStream(source.getBytes("UTF-8"));
 1266  1 try {
 1267  1 validator.build(in, base);
 1268  0 fail("Allowed invalid doc");
 1269    }
 1270    catch (ValidityException ex) {
 1271  1 assertNotNull(ex.getMessage());
 1272  1 assertEquals(base, ex.getURI());
 1273  1 assertTrue(ex.getErrorCount() > 0);
 1274  1 for (int i = 0; i < ex.getErrorCount(); i++) {
 1275  8 assertNotNull(ex.getValidityError(i));
 1276  8 assertTrue(ex.getLineNumber(i) >= -1);
 1277  8 assertTrue(ex.getColumnNumber(i) >= -1);
 1278    }
 1279  1 if (!xercesBroken) {
 1280  1 Document doc = builder.build(
 1281    new ByteArrayInputStream(source.getBytes("UTF-8")), base
 1282    );
 1283  1 this.verify(ex.getDocument());
 1284  1 assertEquals(doc, ex.getDocument());
 1285    }
 1286    }
 1287   
 1288    }
 1289   
 1290   
 1291  1 public void testInvalidDocFromInputStreamWithoutBase()
 1292    throws IOException, ParsingException {
 1293   
 1294  1 InputStream in = new ByteArrayInputStream(source.getBytes("UTF-8"));
 1295  1 try {
 1296  1 validator.build(in);
 1297  0 fail("Allowed invalid doc");
 1298    }
 1299    catch (ValidityException ex) {
 1300  1 assertNotNull(ex.getMessage());
 1301  1 assertTrue(ex.getErrorCount() > 0);
 1302  1 for (int i = 0; i < ex.getErrorCount(); i++) {
 1303  8 assertNotNull(ex.getValidityError(i));
 1304  8 assertTrue(ex.getLineNumber(i) >= -1);
 1305  8 assertTrue(ex.getColumnNumber(i) >= -1);
 1306    }
 1307  1 if (!xercesBroken) {
 1308  1 Document doc = builder.build(
 1309    new ByteArrayInputStream(source.getBytes("UTF-8"))
 1310    );
 1311  1 this.verify(ex.getDocument());
 1312  1 assertEquals(doc, ex.getDocument());
 1313    }
 1314    }
 1315   
 1316    }
 1317   
 1318   
 1319  1 public void testInvalidDocFromStringWithBase()
 1320    throws IOException, ParsingException {
 1321   
 1322  1 try {
 1323  1 validator.build(source, base);
 1324  0 fail("Allowed invalid doc");
 1325    }
 1326    catch (ValidityException ex) {
 1327  1 assertNotNull(ex.getMessage());
 1328  1 assertEquals(base, ex.getURI());
 1329  1 assertTrue(ex.getErrorCount() > 0);
 1330  1 for (int i = 0; i < ex.getErrorCount(); i++) {
 1331  8 assertNotNull(ex.getValidityError(i));
 1332  8 assertTrue(ex.getLineNumber(i) >= -1);
 1333  8 assertTrue(ex.getColumnNumber(i) >= -1);
 1334    }
 1335  1 if (!xercesBroken) {
 1336  1 Document doc = builder.build(source, base);
 1337  1 this.verify(ex.getDocument());
 1338  1 assertEquals(doc, ex.getDocument());
 1339    }
 1340    }
 1341   
 1342    }
 1343   
 1344   
 1345  1 public void testInvalidDocWithCrimson()
 1346    throws IOException, ParsingException {
 1347   
 1348  1 XMLReader crimson;
 1349  1 try {
 1350  1 crimson = XMLReaderFactory.createXMLReader(
 1351    "org.apache.crimson.parser.XMLReaderImpl");
 1352    }
 1353    catch (SAXException ex) {
 1354    // can't test Crimson if you can't load it
 1355  0 return;
 1356    }
 1357  1 Builder validator = new Builder(crimson, true);
 1358  1 try {
 1359  1 validator.build(source, null);
 1360  0 fail("Allowed invalid doc");
 1361    }
 1362    catch (ValidityException ex) {
 1363  1 assertTrue(ex.getErrorCount() > 0);
 1364  1 assertNull(ex.getURI());
 1365  1 for (int i = 0; i < ex.getErrorCount(); i++) {
 1366  13 assertNotNull(ex.getValidityError(i));
 1367    }
 1368    }
 1369   
 1370    }
 1371   
 1372   
 1373  1 public void testInvalidDocFromStringWithNullBase()
 1374    throws IOException, ParsingException {
 1375   
 1376  1 try {
 1377  1 validator.build(source, null);
 1378  0 fail("Allowed invalid doc");
 1379    }
 1380    catch (ValidityException ex) {
 1381  1 assertTrue(ex.getErrorCount() > 0);
 1382  1 assertNull(ex.getURI());
 1383  1 for (int i = 0; i < ex.getErrorCount(); i++) {
 1384  8 assertNotNull(ex.getValidityError(i));
 1385    }
 1386  1 if (!xercesBroken) {
 1387  1 Document doc = builder.build(source, null);
 1388  1 this.verify(ex.getDocument());
 1389  1 assertEquals(doc, ex.getDocument());
 1390    }
 1391    }
 1392   
 1393    }
 1394   
 1395   
 1396  1 public void testJavaEncodings()
 1397    throws IOException, ParsingException {
 1398   
 1399  1 String str = "<?xml version='1.0' encoding='ISO8859_1'?>" +
 1400    "<root>é</root>";
 1401  1 byte[] data = str.getBytes("8859_1");
 1402  1 InputStream in = new ByteArrayInputStream(data);
 1403  1 Document doc = builder.build(in);
 1404  1 assertEquals("é", doc.getValue());
 1405   
 1406    }
 1407   
 1408   
 1409    // Crimson improperly converts 0x0D and 0x0A to spaces
 1410    // even when the attribute type is not CDATA.
 1411    // This bug explains why the canonicalizer tests fail
 1412    // with Crimson
 1413  1 public void testCrimsonCharacterReferenceBug()
 1414    throws IOException, ParsingException {
 1415   
 1416  1 String data =
 1417    "<!DOCTYPE test [<!ATTLIST test name ID #IMPLIED>]>"
 1418    + "<test name='&#x0D;'/>";
 1419  1 InputStream in = new ByteArrayInputStream(
 1420    data.getBytes("UTF8"));
 1421  1 Document document = builder.build(in, null);
 1422  1 assertEquals("\r",
 1423    document.getRootElement().getAttributeValue("name"));
 1424   
 1425    }
 1426   
 1427   
 1428  1 public void testBaseRelativeResolution()
 1429    throws IOException, ParsingException {
 1430  1 builder.build(new File(inputDir, "baserelative/test.xml"));
 1431    }
 1432   
 1433   
 1434    // make sure transcoders on input are using normalization
 1435    // form C when converting from other encodings
 1436  1 public void testNFC()
 1437    throws IOException, ParsingException {
 1438   
 1439  1 Document doc = builder.build(new File(inputDir, "nfctest.xml"));
 1440  1 Element root = doc.getRootElement();
 1441  1 String s = root.getValue();
 1442  1 assertEquals(1, s.length());
 1443  1 assertEquals(0xE9, s.charAt(0));
 1444   
 1445    }
 1446   
 1447   
 1448    // This tests XOM's workaround for a bug in Crimson, Xerces,
 1449    // and possibly other parsers
 1450  1 public void testBaseRelativeResolutionRemotely()
 1451    throws IOException, ParsingException {
 1452  1 builder.build("http://www.cafeconleche.org");
 1453    }
 1454   
 1455   
 1456  1 public void testExternalEntityResolution()
 1457    throws IOException, ParsingException {
 1458   
 1459  1 File input = new File(inputDir, "entitytest.xml");
 1460  1 Builder builder = new Builder(false);
 1461  1 Document doc = builder.build(input);
 1462  1 Element root = doc.getRootElement();
 1463  1 Element external = root.getFirstChildElement("external");
 1464  1 assertEquals("Hello from an entity!", external.getValue());
 1465   
 1466    }
 1467   
 1468   
 1469    // This test exposes a bug in Crimson but not Xerces.
 1470    // It's testing whether the external DTD subset is read,
 1471    // default attribute values applied, and comments and
 1472    // processing instructions in the external DTD subset are not
 1473    // reported.
 1474  1 public void testExternalDTDSubset()
 1475    throws IOException, ParsingException {
 1476   
 1477  1 File input = new File(inputDir, "externalDTDtest.xml");
 1478  1 Builder builder = new Builder(false);
 1479  1 Document doc = builder.build(input);
 1480  1 assertEquals(2, doc.getChildCount());
 1481  1 Element root = doc.getRootElement();
 1482  1 Attribute name = root.getAttribute("name");
 1483  1 assertEquals("value", name.getValue());
 1484  1 DocType doctype = doc.getDocType();
 1485  1 assertEquals("", doctype.getInternalDTDSubset());
 1486   
 1487    }
 1488   
 1489   
 1490    /* <?xml version="1.0"?>
 1491    <!DOCTYPE root [
 1492    <!ELEMENT root (#PCDATA)>
 1493    <!-- comment -->
 1494    <?target PI data?>
 1495    <!NOTATION JPEG SYSTEM "image/jpeg">
 1496    <!ATTLIST root source ENTITY #REQUIRED>
 1497    <!ENTITY picture SYSTEM "picture.jpg" NDATA JPEG>
 1498    ]>
 1499    <root source="picture">
 1500    This document is intended to test the building of
 1501    various constructs in the internal DTD subset.
 1502    </root>
 1503    */
 1504  1 public void testInternalDTDSubset()
 1505    throws ValidityException, ParsingException, IOException {
 1506   
 1507  1 File input = new File(inputDir, "internaldtdsubsettest.xml");
 1508  1 Builder builder = new Builder(false);
 1509  1 Document doc = builder.build(input);
 1510  1 String internalSubset = doc.getDocType().getInternalDTDSubset();
 1511  1 assertTrue(internalSubset.indexOf("<!-- comment -->") > 0);
 1512  1 assertTrue(internalSubset.indexOf("<?target PI data?>") > 0);
 1513  1 assertTrue(internalSubset.indexOf("<!ELEMENT root (#PCDATA)>") > 0);
 1514  1 assertTrue(internalSubset.indexOf("<!ATTLIST root source ENTITY #REQUIRED>") > 0);
 1515    // some confusion in the parser resolving these as relative URLs.
 1516    // This is in accordance with the SAX spec, see
 1517    // http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html#notationDecl(java.lang.String,%20java.lang.String,%20java.lang.String)
 1518    // but how does it know the notation system ID is really a URL?
 1519  1 assertTrue(internalSubset.indexOf("<!ENTITY picture SYSTEM ") > 0);
 1520  1 assertTrue(internalSubset.indexOf("picture.jpg\" NDATA JPEG>") > 0);
 1521  1 assertTrue(internalSubset.indexOf("<!NOTATION JPEG SYSTEM ") > 0);
 1522  1 assertTrue(internalSubset.indexOf("image/jpeg\">") > 0);
 1523   
 1524    }
 1525   
 1526   
 1527  1 public void testInternalEntityDeclDollarSign()
 1528    throws ValidityException, ParsingException, IOException {
 1529   
 1530  1 String input = "<!DOCTYPE root [<!ENTITY test '$!@#$^'>] ><root />";
 1531  1 Builder builder = new Builder(false);
 1532  1 Document doc = builder.build(input, null);
 1533  1 String internalSubset = doc.getDocType().getInternalDTDSubset();
 1534  1 assertTrue(internalSubset.indexOf("<!ENTITY test \"$!@#$^\">") > 0);
 1535   
 1536    }
 1537   
 1538   
 1539  1 public void testInternalDTDSubset5To9()
 1540    throws ValidityException, ParsingException, IOException {
 1541   
 1542  1 String input = "<!DOCTYPE root [<!ATTLIST root source CDATA '56789'>] ><root />";
 1543  1 Builder builder = new Builder(false);
 1544  1 Document doc = builder.build(input, null);
 1545  1 String internalSubset = doc.getDocType().getInternalDTDSubset();
 1546  1 assertTrue(internalSubset.indexOf("<!ATTLIST root source CDATA \"56789\">") > 0);
 1547   
 1548    }
 1549   
 1550   
 1551  1 public void testInternalDTDSubsetPunctuation()
 1552    throws ValidityException, ParsingException, IOException {
 1553   
 1554  1 String input = "<!DOCTYPE root [<!ATTLIST root source CDATA '+,()!'>] ><root />";
 1555  1 Builder builder = new Builder(false);
 1556  1 Document doc = builder.build(input, null);
 1557  1 String internalSubset = doc.getDocType().getInternalDTDSubset();
 1558  1 assertTrue(internalSubset.indexOf("<!ATTLIST root source CDATA \"+,()!\">") > 0);
 1559   
 1560    }
 1561   
 1562   
 1563    /*<!ELEMENT test (#PCDATA)>
 1564    <!-- comment should not be here -->
 1565    <?processing instruction should not be here?>
 1566    <!ATTLIST test name (CDATA) #FIXED "value">
 1567    <!ATTLIST test name CDATA "value">
 1568    <!ATTLIST root anattribute CDATA #REQUIRED>
 1569    <!ATTLIST root anotherattribute CDATA "value">
 1570    <!ENTITY hatch-pic SYSTEM "http://www.example.com/images/cup.gif" NDATA gif>
 1571    <!ENTITY public-pic PUBLIC "public ID" "http://www.example.com/images/cup.gif" NDATA gif>
 1572    <!ENTITY Pub-Status "This is a pre-release of the specification.">
 1573    <!ENTITY open-hatch PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN" "http://www.textuality.com/boilerplate/OpenHatch.xml">
 1574    <!ENTITY test SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">
 1575    <!NOTATION ISODATE SYSTEM "http://www.iso.ch/cate/d15903.html">
 1576    <!NOTATION DATE PUBLIC "DATE PUBLIC ID" "http://www.iso.ch/cate/d15903.html">
 1577    <!NOTATION gif PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN"> */
 1578  1 public void testInternalAndExternalDTDSubset()
 1579    throws ValidityException, ParsingException, IOException {
 1580   
 1581  1 File input = new File(inputDir, "internalandexternaldtdsubsettest.xml");
 1582  1 Builder builder = new Builder(false);
 1583  1 Document doc = builder.build(input);
 1584  1 String internalSubset = doc.getDocType().getInternalDTDSubset();
 1585  1 assertTrue(internalSubset.indexOf("<!-- comment -->") > 0);
 1586  1 assertTrue(internalSubset.indexOf("<?target PI data?>") > 0);
 1587  1 assertTrue(internalSubset.indexOf("<!ELEMENT root (#PCDATA)>") > 0);
 1588  1 assertTrue(internalSubset.indexOf("<!ATTLIST root source ENTITY #REQUIRED>") > 0);
 1589  1 assertTrue(internalSubset.indexOf("<!ENTITY picture SYSTEM ") > 0);
 1590  1 assertTrue(internalSubset.indexOf("picture.jpg\" NDATA JPEG>") > 0);
 1591  1 assertTrue(internalSubset.indexOf("<!NOTATION JPEG SYSTEM ") > 0);
 1592  1 assertTrue(internalSubset.indexOf("image/jpeg\">") > 0);
 1593   
 1594  1 assertEquals(-1, internalSubset.indexOf("comment should not be here"));
 1595  1 assertEquals(-1, internalSubset.indexOf("processing instruction should not be here"));
 1596  1 assertEquals(-1, internalSubset.indexOf("anattribute"));
 1597  1 assertEquals(-1, internalSubset.indexOf("anotherattribute"));
 1598  1 assertEquals(-1, internalSubset.indexOf("hatch-pic"));
 1599  1 assertEquals(-1, internalSubset.indexOf("public-pic"));
 1600  1 assertEquals(-1, internalSubset.indexOf("open-hatch"));
 1601  1 assertEquals(-1, internalSubset.indexOf("Pub-Status-pic"));
 1602  1 assertEquals(-1, internalSubset.indexOf("Textuality"));
 1603  1 assertEquals(-1, internalSubset.indexOf("15903"));
 1604   
 1605    }
 1606   
 1607   
 1608  1 public void testInternalAndExternalDTDSubsetWithCrimson()
 1609    throws ValidityException, ParsingException, IOException {
 1610   
 1611  1 XMLReader crimson;
 1612  1 try {
 1613  1 crimson = XMLReaderFactory.createXMLReader(
 1614    "org.apache.crimson.parser.XMLReaderImpl");
 1615    }
 1616    catch (SAXException ex) {
 1617    // can't test Crimson if you can't load it
 1618  0 return;
 1619    }
 1620   
 1621  1 Builder builder = new Builder(crimson);
 1622  1 File input = new File(inputDir, "internalandexternaldtdsubsettest.xml");
 1623  1 Document doc = builder.build(input);
 1624  1 String internalSubset = doc.getDocType().getInternalDTDSubset();
 1625  1 assertTrue(internalSubset.indexOf("<!-- comment -->") > 0);
 1626  1 assertTrue(internalSubset.indexOf("<?target PI data?>") > 0);
 1627  1 assertTrue(internalSubset.indexOf("<!ELEMENT root (#PCDATA)>") > 0);
 1628  1 assertTrue(internalSubset.indexOf("<!ATTLIST root source ENTITY #REQUIRED>") > 0);
 1629  1 assertTrue(internalSubset.indexOf("<!ENTITY picture SYSTEM ") > 0);
 1630  1 assertTrue(internalSubset.indexOf("picture.jpg\" NDATA JPEG>") > 0);
 1631  1 assertTrue(internalSubset.indexOf("<!NOTATION JPEG SYSTEM ") > 0);
 1632  1 assertTrue(internalSubset.indexOf("image/jpeg\">") > 0);
 1633   
 1634  1 assertEquals(-1, internalSubset.indexOf("comment should not be here"));
 1635  1 assertEquals(-1, internalSubset.indexOf("processing instruction should not be here"));
 1636  1 assertEquals(-1, internalSubset.indexOf("anattribute"));
 1637  1 assertEquals(-1, internalSubset.indexOf("anotherattribute"));
 1638  1 assertEquals(-1, internalSubset.indexOf("hatch-pic"));
 1639  1 assertEquals(-1, internalSubset.indexOf("public-pic"));
 1640  1 assertEquals(-1, internalSubset.indexOf("open-hatch"));
 1641  1 assertEquals(-1, internalSubset.indexOf("Pub-Status-pic"));
 1642  1 assertEquals(-1, internalSubset.indexOf("Textuality"));
 1643  1 assertEquals(-1, internalSubset.indexOf("15903"));
 1644   
 1645    }
 1646   
 1647   
 1648    // This test exposes a bug in Crimson, Xerces 2.5 and earlier,
 1649    // and possibly other parsers. I've reported the bug in Xerces,
 1650    // and it is fixed in Xerces 2.6.
 1651  1 public void testBaseRelativeResolutionRemotelyWithDirectory()
 1652    throws IOException, ParsingException {
 1653  1 builder.build("http://www.ibiblio.org/xml");
 1654    }
 1655   
 1656   
 1657    // This test exposes a bug in Crimson, Xerces 2.5 and earlier,
 1658    // and possibly other parsers. I've reported the bug in Xerces,
 1659    // and it should be fixed in Xerces 2.6.
 1660  1 public void testRelativeURIResolutionAgainstARedirectedBase()
 1661    throws IOException, ParsingException {
 1662  1 builder.build("http://www.ibiblio.org/xml/redirecttest.xml");
 1663    }
 1664   
 1665   
 1666  1 public void testDontGetNodeFactory() {
 1667   
 1668  1 Builder builder = new Builder();
 1669  1 NodeFactory factory = builder.getNodeFactory();
 1670  1 if (factory != null) {
 1671  0 assertFalse(
 1672    factory.getClass().getName().endsWith("NonVerifyingFactory")
 1673    );
 1674    }
 1675   
 1676    }
 1677   
 1678   
 1679  1 public void testGetNodeFactory() {
 1680  1 NodeFactory factory = new NodeFactory();
 1681  1 Builder builder = new Builder(factory);
 1682  1 assertEquals(factory, builder.getNodeFactory());
 1683    }
 1684   
 1685   
 1686    // Make sure additional namespaces aren't added for
 1687    // attributes. This test is flaky because it assumes
 1688    // the parser reports attributes in the correct order,
 1689    // which is not guaranteed. I use a custom SAX Filter to
 1690    // make sure the namespace declaration comes before the attribute.
 1691  1 public void testAttributesVsNamespaces()
 1692    throws ParsingException, IOException, SAXException {
 1693   
 1694  1 XMLFilter filter = new OrderingFilter();
 1695  1 filter.setParent(
 1696    XMLReaderFactory.createXMLReader(
 1697    "org.apache.xerces.parsers.SAXParser"
 1698    )
 1699    );
 1700  1 Builder builder = new Builder(filter);
 1701  1 String data ="<a/>";
 1702  1 Document doc = builder.build(data, null);
 1703  1 Element root = doc.getRootElement();
 1704  1 root.removeAttribute(root.getAttribute(0));
 1705  1 assertNull(root.getNamespaceURI("pre"));
 1706   
 1707    }
 1708   
 1709   
 1710    private static class OrderingFilter extends XMLFilterImpl {
 1711   
 1712  1 public void startElement(String namespaceURI, String localName,
 1713    String qualifiedName, Attributes atts) throws SAXException {
 1714   
 1715  1 AttributesImpl newAttributes = new AttributesImpl();
 1716  1 newAttributes.addAttribute(
 1717    "",
 1718    "pre",
 1719    "xmlns:pre",
 1720    "CDATA",
 1721    "http://www.example.com/");
 1722  1 newAttributes.addAttribute(
 1723    "http://www.example.com/",
 1724    "name",
 1725    "pre:name",
 1726    "CDATA",
 1727    "value");
 1728  1 super.startElement(namespaceURI, localName, qualifiedName,
 1729    newAttributes);
 1730    }
 1731   
 1732    }
 1733   
 1734   
 1735  1 public void testValidateMalformedDocument()
 1736    throws IOException {
 1737   
 1738  1 Reader reader = new StringReader("<!DOCTYPE root [" +
 1739    "<!ELEMENT root (a, b)>" +
 1740    "<!ELEMENT a (EMPTY)>" +
 1741    "<!ELEMENT b (PCDATA)>" +
 1742    "]><root><a/><b></b>");
 1743  1 try {
 1744  1 validator.build(reader);
 1745  0 fail("Allowed malformed doc");
 1746    }
 1747    catch (ValidityException ex) {
 1748  0 fail("Threw validity error instead of well-formedness error");
 1749    }
 1750    catch (ParsingException ex) {
 1751  1 assertNotNull(ex.getMessage());
 1752  1 assertNull(ex.getURI());
 1753    }
 1754   
 1755    }
 1756   
 1757   
 1758    /* Test for particular bug in Crimson with mixed content declarations */
 1759  1 public void testBuildInternalDTDSubsetWithCrimson()
 1760    throws ParsingException, IOException {
 1761   
 1762  1 String dtd = " <!ELEMENT doc (#PCDATA|a)*>\n";
 1763   
 1764  1 String document = "<!DOCTYPE a [\n" + dtd + "]>\n<a/>";
 1765  1 XMLReader crimson;
 1766  1 try {
 1767  1 crimson = XMLReaderFactory.createXMLReader(
 1768    "org.apache.crimson.parser.XMLReaderImpl");
 1769    }
 1770    catch (SAXException ex) {
 1771    // can't test Crimson if you can't load it
 1772  0 return;
 1773    }
 1774   
 1775  1 Builder builder = new Builder(crimson);
 1776  1 Document doc = builder.build(document, null);
 1777   
 1778  1 String parsedDTD = doc.getDocType().getInternalDTDSubset();
 1779  1 assertEquals(dtd, parsedDTD);
 1780   
 1781    }
 1782   
 1783   
 1784    /* Test for particular bug in Crimson with mixed content declarations */
 1785  1 public void testBuildXMLNamespaceDeclarationWithCrimson()
 1786    throws ParsingException, IOException {
 1787   
 1788  1 String document = "<doc xmlns:xml='http://www.w3.org/XML/1998/namespace' />";
 1789  1 XMLReader crimson;
 1790  1 try {
 1791  1 crimson = XMLReaderFactory.createXMLReader(
 1792    "org.apache.crimson.parser.XMLReaderImpl");
 1793    }
 1794    catch (SAXException ex) {
 1795    // can't test Crimson if you can't load it
 1796  0 return;
 1797    }
 1798   
 1799  1 Builder builder = new Builder(crimson);
 1800  1 Document doc = builder.build(document, null);
 1801   
 1802  1 assertEquals("<doc />", doc.getRootElement().toXML());
 1803   
 1804    }
 1805   
 1806   
 1807  1 public void testBuildIllegalXMLNamespaceDeclarationWithCrimson()
 1808    throws ParsingException, IOException {
 1809   
 1810  1 String document = "<doc xmlns:xml='http://www.w3.org/XML/2005/namespace' />";
 1811  1 XMLReader crimson;
 1812  1 try {
 1813  1 crimson = XMLReaderFactory.createXMLReader(
 1814    "org.apache.crimson.parser.XMLReaderImpl");
 1815    }
 1816    catch (SAXException ex) {
 1817    // can't test Crimson if you can't load it
 1818  0 return;
 1819    }
 1820   
 1821  1 Builder builder = new Builder(crimson);
 1822  1 try {
 1823  1 builder.build(document, null);
 1824  0 fail("Allowed wrong namespace URI for xml prefix");
 1825    }
 1826    catch (ParsingException success) {
 1827  1 assertNotNull(success.getMessage());
 1828    }
 1829   
 1830    }
 1831   
 1832   
 1833  1 public void testATTLISTDeclaresXMLSpacePreserveOnlyWithCrimson()
 1834    throws ParsingException, IOException {
 1835   
 1836  1 String dtd = "<!DOCTYPE a [<!ATTLIST doc xml:space (preserve) 'preserve'>]\n>";
 1837   
 1838  1 String data = dtd + "<doc />";
 1839  1 XMLReader crimson;
 1840  1 try {
 1841  1 crimson = XMLReaderFactory.createXMLReader(
 1842    "org.apache.crimson.parser.XMLReaderImpl");
 1843    }
 1844    catch (SAXException ex) {
 1845    // can't test Crimson if you can't load it
 1846  0 return;
 1847    }
 1848   
 1849  1 Builder builder = new Builder(crimson);
 1850  1 Document doc = builder.build(data, null);
 1851  1 assertEquals(1, doc.getRootElement().getAttributeCount());
 1852   
 1853    }
 1854   
 1855   
 1856  1 public void testNoInternalSubsetWithCrimson()
 1857    throws ParsingException, IOException {
 1858   
 1859  1 XMLReader crimson;
 1860  1 try {
 1861  1 crimson = XMLReaderFactory.createXMLReader(
 1862    "org.apache.crimson.parser.XMLReaderImpl");
 1863    }
 1864    catch (SAXException ex) {
 1865    // can't test Crimson if you can't load it
 1866  0 return;
 1867    }
 1868   
 1869  1 File input = new File(inputDir, "externalDTDtest.xml");
 1870  1 Builder builder = new Builder(crimson);
 1871  1 Document doc = builder.build(input);
 1872  1 String subset = doc.getDocType().getInternalDTDSubset();
 1873  1 assertEquals("", subset);
 1874   
 1875    }
 1876   
 1877   
 1878  1 public void testValidateMalformedDocumentWithCrimson()
 1879    throws IOException {
 1880   
 1881  1 Reader reader = new StringReader("<!DOCTYPE root [" +
 1882    "<!ELEMENT root (a, b)>" +
 1883    "<!ELEMENT a (EMPTY)>" +
 1884    "<!ELEMENT b (PCDATA)>" +
 1885    "]><root><a/><b></b>");
 1886  1 XMLReader crimson;
 1887  1 try {
 1888  1 crimson = XMLReaderFactory.createXMLReader(
 1889    "org.apache.crimson.parser.XMLReaderImpl");
 1890    }
 1891    catch (SAXException ex) {
 1892    // can't test Crimson if you can't load it
 1893  0 return;
 1894    }
 1895  1 Builder validator = new Builder(crimson, true);
 1896  1 try {
 1897  1 validator.build(reader);
 1898  0 fail("Allowed malformed doc");
 1899    }
 1900    catch (ValidityException ex) {
 1901  0 fail("Crimson threw validity error instead of well-formedness error");
 1902    }
 1903    catch (ParsingException success) {
 1904  1 assertNotNull(success.getMessage());
 1905  1 assertNull(success.getURI());
 1906    }
 1907   
 1908    }
 1909   
 1910   
 1911    // This is testing a work-around for a Xerces bug
 1912    // http://nagoya.apache.org/bugzilla/show_bug.cgi?id=27583
 1913    // that reports this as an IOException rather than a SAXException
 1914  1 public void testBuildMalformedDocumentWithUnpairedSurrogate()
 1915    throws IOException {
 1916   
 1917  1 String doc = "<doc>A\uD800A</doc>";
 1918  1 try {
 1919  1 builder.build(doc, "http://www.example.com");
 1920  0 fail("Allowed malformed doc");
 1921    }
 1922    catch (ParsingException success) {
 1923  1 assertNotNull(success.getMessage());
 1924  1 assertEquals("http://www.example.com/", success.getUR