0001: /* Copyright 2002-2005 Elliotte Rusty Harold
0002:
0003: This library is free software; you can redistribute it and/or modify
0004: it under the terms of version 2.1 of the GNU Lesser General Public
0005: License as published by the Free Software Foundation.
0006:
0007: This library is distributed in the hope that it will be useful,
0008: but WITHOUT ANY WARRANTY; without even the implied warranty of
0009: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0010: GNU Lesser General Public License for more details.
0011:
0012: You should have received a copy of the GNU Lesser General Public
0013: License along with this library; if not, write to the
0014: Free Software Foundation, Inc., 59 Temple Place, Suite 330,
0015: Boston, MA 02111-1307 USA
0016:
0017: You can contact Elliotte Rusty Harold by sending e-mail to
0018: elharo@metalab.unc.edu. Please include the word "XOM" in the
0019: subject line. The XOM home page is located at http://www.xom.nu/
0020: */
0021:
0022: package nu.xom.tests;
0023:
0024: import java.io.ByteArrayOutputStream;
0025: import java.io.CharConversionException;
0026: import java.io.File;
0027: import java.io.FileNotFoundException;
0028: import java.io.FileOutputStream;
0029: import java.io.IOException;
0030: import java.io.OutputStreamWriter;
0031: import java.io.PrintStream;
0032: import java.io.Reader;
0033: import java.io.StringReader;
0034: import java.io.ByteArrayInputStream;
0035: import java.io.InputStream;
0036: import java.io.UTFDataFormatException;
0037: import java.io.Writer;
0038: import java.lang.ref.WeakReference;
0039: import java.lang.reflect.Constructor;
0040: import java.lang.reflect.InvocationTargetException;
0041:
0042: import org.xml.sax.Attributes;
0043: import org.xml.sax.InputSource;
0044: import org.xml.sax.Locator;
0045: import org.xml.sax.SAXException;
0046: import org.xml.sax.SAXNotRecognizedException;
0047: import org.xml.sax.SAXNotSupportedException;
0048: import org.xml.sax.SAXParseException;
0049: import org.xml.sax.XMLFilter;
0050: import org.xml.sax.XMLReader;
0051: import org.xml.sax.helpers.AttributesImpl;
0052: import org.xml.sax.helpers.LocatorImpl;
0053: import org.xml.sax.helpers.XMLFilterImpl;
0054: import org.xml.sax.helpers.XMLReaderFactory;
0055:
0056: import nu.xom.Attribute;
0057: import nu.xom.Builder;
0058: import nu.xom.Comment;
0059: import nu.xom.DocType;
0060: import nu.xom.Document;
0061: import nu.xom.Element;
0062: import nu.xom.Elements;
0063: import nu.xom.NodeFactory;
0064: import nu.xom.ParsingException;
0065: import nu.xom.ProcessingInstruction;
0066: import nu.xom.Serializer;
0067: import nu.xom.ValidityException;
0068: import nu.xom.WellformednessException;
0069: import nu.xom.XMLException;
0070:
0071: /**
0072: * <p>
0073: * Tests building documents from streams, strings, files,
0074: * and other input sources.
0075: * </p>
0076: *
0077: * @author Elliotte Rusty Harold
0078: * @version 1.1b7
0079: *
0080: */
0081: public class BuilderTest extends XOMTestCase {
0082:
0083: private File inputDir = new File("data");
0084:
0085: // This class tests error conditions, which Xerces
0086: // annoyingly logs to System.err. So we hide System.err
0087: // before each test and restore it after each test.
0088: private PrintStream systemErr = System.err;
0089:
0090: protected void setUp() {
0091: System.setErr(new PrintStream(new ByteArrayOutputStream()));
0092: }
0093:
0094: protected void tearDown() {
0095: System.setErr(systemErr);
0096: }
0097:
0098: // Custom parser to test what happens when parser supplies
0099: // malformed data
0100: private static class CustomReader extends XMLFilterImpl {
0101:
0102: public void setFeature(String name, boolean value) {
0103: };
0104:
0105: public void parse(InputSource in) throws SAXException {
0106: this .getContentHandler().startDocument();
0107: this .getContentHandler().startElement("87", "87", "87",
0108: new AttributesImpl());
0109: this .getContentHandler().endElement("87", "87", "87");
0110: this .getContentHandler().endDocument();
0111: }
0112:
0113: }
0114:
0115: private static class DoNothingReader extends CustomReader {
0116:
0117: public void parse(InputSource in) throws SAXException {
0118: }
0119:
0120: }
0121:
0122: private static class StartAndEndReader extends CustomReader {
0123:
0124: public void parse(InputSource in) throws SAXException {
0125: this .getContentHandler().startDocument();
0126: this .getContentHandler().endDocument();
0127: }
0128:
0129: }
0130:
0131: private static class StartOnlyReader extends CustomReader {
0132:
0133: public void parse(InputSource in) throws SAXException {
0134: this .getContentHandler().startDocument();
0135: }
0136:
0137: }
0138:
0139: private static class EndOnlyReader extends CustomReader {
0140:
0141: public void parse(InputSource in) throws SAXException {
0142: this .getContentHandler().endDocument();
0143: }
0144:
0145: }
0146:
0147: public BuilderTest(String name) {
0148: super (name);
0149: }
0150:
0151: // flag to turn on and off tests based on
0152: // http://nagoya.apache.org/bugzilla/show_bug.cgi?id=24124
0153: private boolean xercesBroken = false;
0154:
0155: private String elementDeclaration = "<!ELEMENT root (#PCDATA)>";
0156: private String defaultAttributeDeclaration = "<!ATTLIST test name CDATA \"value\">";
0157: private String attributeDeclaration = "<!ATTLIST root anattribute CDATA #REQUIRED>";
0158: private String attributeDeclaration2 = "<!ATTLIST root anotherattribute CDATA \"value\">";
0159: private String unparsedEntityDeclaration = "<!ENTITY hatch-pic SYSTEM "
0160: + "\"http://www.example.com/images/cup.gif\" NDATA gif>";
0161: private String unparsedEntityDeclarationPublic = "<!ENTITY public-pic PUBLIC \"public ID\" "
0162: + "\"http://www.example.com/images/cup.gif\" NDATA gif>";
0163: private String internalEntityDeclaration = "<!ENTITY Pub-Status \""
0164: + "This is a pre-release of the specification.\">";
0165: private String externalEntityDeclarationPublic = "<!ENTITY open-hatch "
0166: + "PUBLIC \"-//Textuality//TEXT Standard "
0167: + "open-hatch boilerplate//EN\" "
0168: + "\"http://www.textuality.com/boilerplate/OpenHatch.xml\">";
0169: private String externalEntityDeclarationSystem = "<!ENTITY test SYSTEM "
0170: + "\"http://www.textuality.com/boilerplate/OpenHatch.xml\">";
0171: private String notationDeclarationSystem = "<!NOTATION ISODATE SYSTEM "
0172: + "\"http://www.iso.ch/cate/d15903.html\">";
0173: private String notationDeclarationPublicAndSystem = "<!NOTATION DATE PUBLIC \"DATE PUBLIC ID\" "
0174: + "\"http://www.iso.ch/cate/d15903.html\">";
0175: private String notationDeclarationPublic = "<!NOTATION gif PUBLIC "
0176: + "\"-//Textuality//TEXT Standard open-hatch boilerplate//EN\">";
0177:
0178: private String source = "<!DOCTYPE test [\r\n"
0179: + elementDeclaration
0180: + "\n"
0181: + attributeDeclaration
0182: + "\n"
0183: + defaultAttributeDeclaration
0184: + "\n"
0185: + attributeDeclaration2
0186: + "\n"
0187: + internalEntityDeclaration
0188: + "\n"
0189: + externalEntityDeclarationPublic
0190: + "\n"
0191: + externalEntityDeclarationSystem
0192: + "\n"
0193: + unparsedEntityDeclaration
0194: + "\n"
0195: + unparsedEntityDeclarationPublic
0196: + "\n"
0197: + notationDeclarationPublic
0198: + "\n"
0199: + notationDeclarationSystem
0200: + "\n"
0201: + notationDeclarationPublicAndSystem
0202: + "\n"
0203: + "]>\r\n"
0204: + "<?xml-stylesheet href=\"file.css\" type=\"text/css\"?>"
0205: + "<!-- test -->"
0206: + "<test xmlns:xlink='http://www.w3.org/TR/1999/xlink'>Hello dear"
0207: + "\r\n<em id=\"p1\" xmlns:none=\"http://www.example.com\">"
0208: + "very important</em>"
0209: + "<span xlink:type='simple'>here's the link</span>\r\n"
0210: + "<svg:svg xmlns:svg='http://www.w3.org/TR/2000/svg'>"
0211: + "<svg:text>text in a namespace</svg:text></svg:svg>\r\n"
0212: + "<svg xmlns='http://www.w3.org/TR/2000/svg'><text>text in a "
0213: + "namespace</text></svg></test>\r\n<!--epilog-->";
0214:
0215: private String validDoc = "<!DOCTYPE test [\r\n"
0216: + "<!ELEMENT test (#PCDATA)>\n" + "]>\r\n"
0217: + "<?xml-stylesheet href=\"file.css\" type=\"text/css\"?>"
0218: + "<!-- test -->" + "<test>Hello dear</test>"
0219: + "<!--epilog-->";
0220:
0221: private Builder builder = new Builder();
0222: private Builder validator = new Builder(true);
0223: private String base = "http://www.example.com/";
0224:
0225: private String attributeDoc = "<!DOCTYPE test [\n"
0226: + "<!ELEMENT test (#PCDATA)>\n"
0227: + "<!NOTATION GIF SYSTEM \"text/gif\">\n"
0228: + "<!ENTITY data SYSTEM \"http://www.example.org/cup.gif\">\n"
0229: + "<!ATTLIST test notationatt NOTATION (GIF) \"GIF\">\n"
0230: + "<!ATTLIST test cdataatt CDATA \"GIF\">\n"
0231: + "<!ATTLIST test entityatt ENTITY \"data\">\n"
0232: + "<!ATTLIST test entitiesatt ENTITIES \"data\">\n"
0233: + "<!ATTLIST test nmtokenatt NMTOKEN \" 1 \">\n"
0234: + "<!ATTLIST test nmtokensatt NMTOKENS \" 1 2 3 \">\n"
0235: + "<!ATTLIST test idatt ID \" p1 \">\n"
0236: + "<!ATTLIST test idrefatt IDREF \" p1 \">\n"
0237: + "<!ATTLIST test idrefsatt IDREFS \" p1 p2 \">\n"
0238: + "]>\r\n" + "<test>Hello dear</test>";
0239:
0240: public void testDoNothingParser() throws ParsingException,
0241: IOException {
0242:
0243: try {
0244: XMLReader parser = new DoNothingReader();
0245: Builder builder = new Builder(parser);
0246: builder.build("http://www.example.org/");
0247: fail("built from bad data");
0248: } catch (ParsingException success) {
0249: assertNotNull(success.getMessage());
0250: assertEquals("http://www.example.org/", success.getURI());
0251: }
0252:
0253: }
0254:
0255: public void testStartAndEndParser() throws ParsingException,
0256: IOException {
0257:
0258: XMLReader parser = new StartAndEndReader();
0259: Builder builder = new Builder(parser);
0260: Document doc = builder.build("http://www.example.org/");
0261: assertNotNull(doc.getRootElement());
0262:
0263: }
0264:
0265: public void testStartOnlyParser() throws ParsingException,
0266: IOException {
0267:
0268: XMLReader parser = new StartOnlyReader();
0269: Builder builder = new Builder(parser);
0270: Document doc = builder.build("http://www.example.org/");
0271: assertNotNull(doc.getRootElement());
0272:
0273: }
0274:
0275: public void testEndOnlyParser() throws ParsingException,
0276: IOException {
0277:
0278: try {
0279: XMLReader parser = new EndOnlyReader();
0280: Builder builder = new Builder(parser);
0281: builder.build("http://www.example.org/");
0282: fail("built from bad data");
0283: } catch (ParsingException success) {
0284: assertTrue(success.getCause() instanceof NullPointerException);
0285: }
0286:
0287: }
0288:
0289: public void testBuildInternalDTDSubsetWithFixedDefaultAttributeValue()
0290: throws ParsingException, IOException {
0291:
0292: String doctype = "<!DOCTYPE xsl:stylesheet [\n"
0293: + "<!ATTLIST a b CDATA #FIXED \"c\">]>";
0294: String document = doctype + "\n<root/>";
0295: Builder builder = new Builder();
0296: Document doc = builder.build(document, null);
0297: DocType dt = doc.getDocType();
0298: String internalDTDSubset = dt.getInternalDTDSubset();
0299: assertTrue(internalDTDSubset.indexOf("#FIXED \"c\"") > 0);
0300:
0301: }
0302:
0303: public void testNotationAttributeType() throws IOException,
0304: ParsingException {
0305:
0306: Reader reader = new StringReader(attributeDoc);
0307: Document document = builder.build(reader);
0308: Element root = document.getRootElement();
0309: Attribute att = root.getAttribute("notationatt");
0310: assertEquals(Attribute.Type.NOTATION, att.getType());
0311:
0312: }
0313:
0314: public void testCDATAAttributeType() throws IOException,
0315: ParsingException {
0316:
0317: Reader reader = new StringReader(attributeDoc);
0318: Document document = builder.build(reader);
0319: Element root = document.getRootElement();
0320: Attribute att = root.getAttribute("cdataatt");
0321: assertEquals(Attribute.Type.CDATA, att.getType());
0322:
0323: }
0324:
0325: public void testEntityAttributeType() throws IOException,
0326: ParsingException {
0327:
0328: Reader reader = new StringReader(attributeDoc);
0329: Document document = builder.build(reader);
0330: Element root = document.getRootElement();
0331: Attribute att = root.getAttribute("entityatt");
0332: assertEquals(Attribute.Type.ENTITY, att.getType());
0333:
0334: }
0335:
0336: public void testEntitiesAttributeType() throws IOException,
0337: ParsingException {
0338:
0339: Reader reader = new StringReader(attributeDoc);
0340: Document document = builder.build(reader);
0341: Element root = document.getRootElement();
0342: Attribute att = root.getAttribute("entitiesatt");
0343: assertEquals(Attribute.Type.ENTITIES, att.getType());
0344:
0345: }
0346:
0347: public void testNameTokenAttributeType() throws IOException,
0348: ParsingException {
0349:
0350: Reader reader = new StringReader(attributeDoc);
0351: Document document = builder.build(reader);
0352: Element root = document.getRootElement();
0353: Attribute att = root.getAttribute("nmtokenatt");
0354: assertEquals(Attribute.Type.NMTOKEN, att.getType());
0355: assertEquals("1", att.getValue());
0356:
0357: }
0358:
0359: // I'm specifically worried about a Xerces runtime MalformedURIException here
0360: public void testIllegalSystemIDThrowsRightException() {
0361:
0362: String document = "<!DOCTYPE root SYSTEM \"This is not a URI\"><root/>";
0363: try {
0364: builder.build(document, null);
0365: } catch (Exception ex) {
0366: assertTrue(ex instanceof ParsingException);
0367: }
0368:
0369: }
0370:
0371: public void testNameTokensAttributeType() throws IOException,
0372: ParsingException {
0373:
0374: Reader reader = new StringReader(attributeDoc);
0375: Document document = builder.build(reader);
0376: Element root = document.getRootElement();
0377: Attribute att = root.getAttribute("nmtokensatt");
0378: assertEquals(Attribute.Type.NMTOKENS, att.getType());
0379: assertEquals("1 2 3", att.getValue());
0380:
0381: }
0382:
0383: // verify that XML 1.1 is not supported
0384: public void testXML11() throws IOException {
0385:
0386: String data = "<?xml version='1.1'?><root/>";
0387: try {
0388: builder.build(data, "http://www.example.com");
0389: fail("XML 1.1 allowed");
0390: } catch (ParsingException ex) {
0391: assertNotNull(ex.getMessage());
0392: }
0393:
0394: }
0395:
0396: // verify that XML 1.2 is not supported
0397: public void testXML12() throws IOException {
0398:
0399: String data = "<?xml version='1.2'?><root/>";
0400: try {
0401: builder.build(data, "http://www.example.com");
0402: fail("XML 1.2 allowed");
0403: } catch (ParsingException ex) {
0404: assertNotNull(ex.getMessage());
0405: }
0406:
0407: }
0408:
0409: // verify that XML 2.0 is not supported
0410: public void testXML20() throws IOException {
0411:
0412: String data = "<?xml version='2.0'?><root/>";
0413: try {
0414: builder.build(data, "http://www.example.com");
0415: fail("XML 2.0 allowed");
0416: } catch (ParsingException ex) {
0417: assertNotNull(ex.getMessage());
0418: }
0419:
0420: }
0421:
0422: public void testIDAttributeType() throws IOException,
0423: ParsingException {
0424:
0425: Reader reader = new StringReader(attributeDoc);
0426: Document document = builder.build(reader);
0427: Element root = document.getRootElement();
0428: Attribute att = root.getAttribute("idatt");
0429: assertEquals(Attribute.Type.ID, att.getType());
0430: assertEquals("p1", att.getValue());
0431:
0432: }
0433:
0434: public void testIDREFAttributeType() throws IOException,
0435: ParsingException {
0436:
0437: Reader reader = new StringReader(attributeDoc);
0438: Document document = builder.build(reader);
0439: Element root = document.getRootElement();
0440: Attribute att = root.getAttribute("idrefatt");
0441: assertEquals(Attribute.Type.IDREF, att.getType());
0442: assertEquals("p1", att.getValue());
0443:
0444: }
0445:
0446: public void testIDREFSAttributeType() throws IOException,
0447: ParsingException {
0448:
0449: Reader reader = new StringReader(attributeDoc);
0450: Document document = builder.build(reader);
0451: Element root = document.getRootElement();
0452: Attribute att = root.getAttribute("idrefsatt");
0453: assertEquals(Attribute.Type.IDREFS, att.getType());
0454: assertEquals("p1 p2", att.getValue());
0455:
0456: }
0457:
0458: public void testBuildFromReader() throws IOException,
0459: ParsingException {
0460:
0461: Reader reader = new StringReader(source);
0462: Document document = builder.build(reader);
0463: verify(document);
0464: assertEquals("", document.getBaseURI());
0465:
0466: }
0467:
0468: public void testBuildFromReaderWithBase() throws IOException,
0469: ParsingException {
0470:
0471: Reader reader = new StringReader(source);
0472: Document document = builder.build(reader, base);
0473: verify(document);
0474: assertEquals(base, document.getBaseURI());
0475:
0476: }
0477:
0478: private static class NoLocator extends XMLFilterImpl {
0479:
0480: public NoLocator(XMLReader reader) {
0481: super (reader);
0482: }
0483:
0484: public void setDocumentLocator(Locator locator) {
0485: }
0486:
0487: }
0488:
0489: public void testBuildWithoutLocator() throws IOException,
0490: ParsingException, SAXException {
0491:
0492: XMLReader xerces = XMLReaderFactory
0493: .createXMLReader("org.apache.xerces.parsers.SAXParser");
0494: XMLReader filter = new NoLocator(xerces);
0495:
0496: Builder builder = new Builder(filter);
0497: Document document = builder.build(source,
0498: "http://www.example.org/");
0499: verify(document);
0500: assertEquals("http://www.example.org/", document.getBaseURI());
0501:
0502: }
0503:
0504: private static class WeirdAttributeTypes extends XMLFilterImpl {
0505:
0506: public WeirdAttributeTypes(XMLReader reader) {
0507: super (reader);
0508: }
0509:
0510: public void startElement(String uri, String localName,
0511: String qualifiedName, Attributes atts)
0512: throws SAXException {
0513:
0514: AttributesImpl newAtts = new AttributesImpl(atts);
0515: for (int i = 0; i < newAtts.getLength(); i++) {
0516: newAtts.setType(i, "WEIRD");
0517: }
0518:
0519: super .startElement(uri, localName, qualifiedName, newAtts);
0520:
0521: }
0522:
0523: }
0524:
0525: public void testWeirdAttributeTypes() throws IOException,
0526: ParsingException, SAXException {
0527:
0528: XMLReader xerces = XMLReaderFactory
0529: .createXMLReader("org.apache.xerces.parsers.SAXParser");
0530: XMLReader filter = new WeirdAttributeTypes(xerces);
0531:
0532: Builder builder = new Builder(filter);
0533: Document document = builder.build(attributeDoc,
0534: "http://www.example.org/");
0535: Element root = document.getRootElement();
0536: assertTrue(root.getAttributeCount() > 0);
0537: for (int i = 0; i < root.getAttributeCount(); i++) {
0538: assertEquals(Attribute.Type.UNDECLARED, root
0539: .getAttribute(i).getType());
0540: }
0541:
0542: }
0543:
0544: // Here we're faking the non-standard behavior of some older parsers
0545: private static class ParenthesizedEnumeratedAttributeTypes extends
0546: XMLFilterImpl {
0547:
0548: public ParenthesizedEnumeratedAttributeTypes(XMLReader reader) {
0549: super (reader);
0550: }
0551:
0552: public void startElement(String uri, String localName,
0553: String qualifiedName, Attributes atts)
0554: throws SAXException {
0555:
0556: AttributesImpl newAtts = new AttributesImpl(atts);
0557: for (int i = 0; i < newAtts.getLength(); i++) {
0558: newAtts.setType(i, "(test, data, value)");
0559: }
0560:
0561: super .startElement(uri, localName, qualifiedName, newAtts);
0562:
0563: }
0564:
0565: }
0566:
0567: public void testParenthesizedEnumeratedAttributeTypes()
0568: throws IOException, ParsingException, SAXException {
0569:
0570: XMLReader xerces = XMLReaderFactory
0571: .createXMLReader("org.apache.xerces.parsers.SAXParser");
0572: XMLReader filter = new ParenthesizedEnumeratedAttributeTypes(
0573: xerces);
0574:
0575: Builder builder = new Builder(filter);
0576: Document document = builder.build(attributeDoc,
0577: "http://www.example.org/");
0578: Element root = document.getRootElement();
0579: assertTrue(root.getAttributeCount() > 0);
0580: for (int i = 0; i < root.getAttributeCount(); i++) {
0581: assertEquals(Attribute.Type.ENUMERATION, root.getAttribute(
0582: i).getType());
0583: }
0584:
0585: }
0586:
0587: public void testBuildFromInputStreamWithBase() throws IOException,
0588: ParsingException {
0589: InputStream in = new ByteArrayInputStream(source
0590: .getBytes("UTF-8"));
0591: Document document = builder.build(in, base);
0592: verify(document);
0593: assertEquals(base, document.getBaseURI());
0594: }
0595:
0596: public void testBuildFromInputStreamWithoutBase()
0597: throws IOException, ParsingException {
0598: InputStream in = new ByteArrayInputStream(source
0599: .getBytes("UTF-8"));
0600: Document document = builder.build(in);
0601: verify(document);
0602: assertEquals("", document.getBaseURI());
0603: }
0604:
0605: public void testBuildFromStringWithBase() throws IOException,
0606: ParsingException {
0607: Document document = builder.build(source, base);
0608: verify(document);
0609: assertEquals(base, document.getBaseURI());
0610: }
0611:
0612: public void testBuildDocumentThatUsesDoubleQuoteNumericCharacterReferenceInEntityDeclaration()
0613: throws IOException, ParsingException {
0614:
0615: String data = "<!DOCTYPE doc [\n" + "<!ELEMENT doc (#PCDATA)>"
0616: + " <!ENTITY e \""\">\n" + "]><root />";
0617:
0618: Document document = builder.build(data, null);
0619:
0620: Document roundtrip = builder.build(document.toXML(), null);
0621: assertEquals(document, roundtrip);
0622:
0623: }
0624:
0625: public void testBuildDocumentThatDeclaresStandardEntityReferences()
0626: throws IOException, ParsingException {
0627:
0628: String data = "<!DOCTYPE doc [\n" + "<!ELEMENT doc (#PCDATA)>"
0629: + "<!ENTITY lt \"&#60;\">\n"
0630: + "<!ENTITY gt \">\">\n"
0631: + "<!ENTITY amp \"&#38;\">\n"
0632: + "<!ENTITY apos \"'\">\n"
0633: + "<!ENTITY quot \""\">\n" + "]><root />";
0634:
0635: Document document = builder.build(data, null);
0636: Document roundtrip = builder.build(document.toXML(), null);
0637: assertEquals(document, roundtrip);
0638:
0639: }
0640:
0641: public void testBuildDocumentThatUsesAmpersandNumericCharacterReferenceInEntityDeclaration()
0642: throws IOException, ParsingException {
0643:
0644: String data = "<!DOCTYPE doc [\n" + "<!ELEMENT doc (#PCDATA)>"
0645: + " <!ENTITY e \"&\">\n" + "]><root />";
0646:
0647: Document document = builder.build(data, null);
0648:
0649: Document roundtrip = builder.build(document.toXML(), null);
0650: assertEquals(document, roundtrip);
0651:
0652: }
0653:
0654: public void testBuildDocumentThatUsesDoubleQuoteNumericCharacterReferenceInAttributeDeclaration()
0655: throws IOException, ParsingException {
0656:
0657: String data = "<!DOCTYPE doc [\n"
0658: + "<!ATTLIST root test (CDATA) \"4\">\n"
0659: + "]><root />";
0660:
0661: Document document = builder.build(data, null);
0662:
0663: Document roundtrip = builder.build(document.toXML(), null);
0664: assertEquals(document, roundtrip);
0665:
0666: }
0667:
0668: public void testMemoryFreedByBuilder() throws IOException,
0669: ParsingException, InterruptedException {
0670:
0671: String data = "<root />";
0672:
0673: Document document = builder.build(data, null);
0674: WeakReference ref = new WeakReference(document);
0675: document = null;
0676: System.gc();
0677: System.gc();
0678: System.gc();
0679: Thread.sleep(1000);
0680: assertNull(ref.get());
0681:
0682: }
0683:
0684: public void testBuildFromInvalidDoc() throws IOException,
0685: ParsingException {
0686:
0687: try {
0688: validator.build(source, base);
0689: fail("Built invalid doc");
0690: } catch (ValidityException ex) {
0691: Document document = ex.getDocument();
0692: // Can't do a full verify just yet due to bugs in Xerces
0693: // verify(ex.getDocument());
0694: assertTrue(document.getChild(1) instanceof ProcessingInstruction);
0695: assertTrue(document.getChild(2) instanceof Comment);
0696: DocType doctype = document.getDocType();
0697: Element root = document.getRootElement();
0698:
0699: // assertEquals(1, root.getAttributeCount());
0700: // assertEquals("value", root.getAttributeValue("name"));
0701: assertEquals("test", root.getQualifiedName());
0702: assertEquals("test", root.getLocalName());
0703: assertEquals("", root.getNamespaceURI());
0704:
0705: assertTrue(doctype != null);
0706: assertTrue(document.getChild(0) instanceof DocType);
0707: assertTrue(document.getChild(4) instanceof Comment);
0708: assertTrue(document.getChild(2) instanceof Comment);
0709: assertEquals(" test ", document.getChild(2).getValue());
0710: assertEquals("epilog", document.getChild(4).getValue());
0711: assertTrue(document.getChild(1) instanceof ProcessingInstruction);
0712: assertEquals("test", doctype.getRootElementName());
0713: assertNull(doctype.getPublicID());
0714: assertNull(doctype.getSystemID());
0715:
0716: String internalDTDSubset = doctype.getInternalDTDSubset();
0717: assertTrue(internalDTDSubset, internalDTDSubset
0718: .indexOf(elementDeclaration) > 0);
0719: assertTrue(internalDTDSubset, internalDTDSubset
0720: .indexOf(attributeDeclaration) > 0);
0721: assertTrue(internalDTDSubset, internalDTDSubset
0722: .indexOf(attributeDeclaration2) > 0);
0723: assertTrue(internalDTDSubset, internalDTDSubset
0724: .indexOf(internalEntityDeclaration) > 0);
0725: assertTrue(internalDTDSubset, internalDTDSubset
0726: .indexOf(externalEntityDeclarationPublic) > 0);
0727: assertTrue(internalDTDSubset, internalDTDSubset
0728: .indexOf(externalEntityDeclarationSystem) > 0);
0729: assertTrue(internalDTDSubset, internalDTDSubset
0730: .indexOf(unparsedEntityDeclaration) > 0);
0731: assertTrue(internalDTDSubset, internalDTDSubset
0732: .indexOf(unparsedEntityDeclarationPublic) > 0);
0733: assertTrue(internalDTDSubset, internalDTDSubset
0734: .indexOf(notationDeclarationPublic) > 0);
0735: assertTrue(internalDTDSubset, internalDTDSubset
0736: .indexOf(notationDeclarationSystem) > 0);
0737: assertTrue(internalDTDSubset, internalDTDSubset
0738: .indexOf(notationDeclarationPublicAndSystem) > 0);
0739:
0740: }
0741:
0742: }
0743:
0744: public void testBuildFromStringWithNullBase() throws IOException,
0745: ParsingException {
0746: Document document = builder.build(source, null);
0747: verify(document);
0748: assertEquals("", document.getBaseURI());
0749: }
0750:
0751: private void verify(Document document) {
0752:
0753: assertTrue(document.getChild(1) instanceof ProcessingInstruction);
0754: assertTrue(document.getChild(2) instanceof Comment);
0755: DocType doctype = document.getDocType();
0756: Element root = document.getRootElement();
0757:
0758: assertEquals(1, root.getAttributeCount());
0759: assertEquals("value", root.getAttributeValue("name"));
0760: assertEquals("test", root.getQualifiedName());
0761: assertEquals("test", root.getLocalName());
0762: assertEquals("", root.getNamespaceURI());
0763:
0764: assertTrue(doctype != null);
0765: assertTrue(document.getChild(0) instanceof DocType);
0766: assertTrue(document.getChild(4) instanceof Comment);
0767: assertTrue(document.getChild(2) instanceof Comment);
0768: assertEquals(" test ", document.getChild(2).getValue());
0769: assertEquals("epilog", document.getChild(4).getValue());
0770: assertTrue(document.getChild(1) instanceof ProcessingInstruction);
0771: assertEquals("test", doctype.getRootElementName());
0772: assertNull(doctype.getPublicID());
0773: assertNull(doctype.getSystemID());
0774:
0775: String internalDTDSubset = doctype.getInternalDTDSubset();
0776: assertTrue(internalDTDSubset, internalDTDSubset
0777: .indexOf(elementDeclaration) > 0);
0778: assertTrue(internalDTDSubset, internalDTDSubset
0779: .indexOf(attributeDeclaration) > 0);
0780: assertTrue(internalDTDSubset, internalDTDSubset
0781: .indexOf(attributeDeclaration2) > 0);
0782: assertTrue(internalDTDSubset, internalDTDSubset
0783: .indexOf(internalEntityDeclaration) > 0);
0784: assertTrue(internalDTDSubset, internalDTDSubset
0785: .indexOf(externalEntityDeclarationPublic) > 0);
0786: assertTrue(internalDTDSubset, internalDTDSubset
0787: .indexOf(externalEntityDeclarationSystem) > 0);
0788: assertTrue(internalDTDSubset, internalDTDSubset
0789: .indexOf(unparsedEntityDeclaration) > 0);
0790: assertTrue(internalDTDSubset, internalDTDSubset
0791: .indexOf(unparsedEntityDeclarationPublic) > 0);
0792: assertTrue(internalDTDSubset, internalDTDSubset
0793: .indexOf(notationDeclarationPublic) > 0);
0794: assertTrue(internalDTDSubset, internalDTDSubset
0795: .indexOf(notationDeclarationSystem) > 0);
0796: assertTrue(internalDTDSubset, internalDTDSubset
0797: .indexOf(notationDeclarationPublicAndSystem) > 0);
0798:
0799: }
0800:
0801: public void testValidateFromReader() throws IOException,
0802: ParsingException {
0803:
0804: Reader reader1 = new StringReader(validDoc);
0805: Document document1 = validator.build(reader1);
0806: assertEquals("", document1.getBaseURI());
0807: Reader reader2 = new StringReader(validDoc);
0808: Document document2 = builder.build(reader2);
0809: assertEquals(document2, document1);
0810:
0811: }
0812:
0813: public void testDocumentWithDefaultNamespaceOnPrefixedElement()
0814: throws IOException, ParsingException {
0815:
0816: Reader reader = new StringReader("<pre:root "
0817: + "xmlns='http://www.example.org/' "
0818: + "xmlns:pre='http://www.cafeconleche.org/'/>");
0819: Document document = builder.build(reader);
0820: Element root = document.getRootElement();
0821: assertEquals("http://www.example.org/", root
0822: .getNamespaceURI(""));
0823: assertEquals("http://www.cafeconleche.org/", root
0824: .getNamespaceURI("pre"));
0825: assertEquals("http://www.cafeconleche.org/", root
0826: .getNamespaceURI());
0827:
0828: }
0829:
0830: public void testValidateFromReaderWithBase() throws IOException,
0831: ParsingException {
0832:
0833: Reader reader = new StringReader(validDoc);
0834: Document document = validator.build(reader, base);
0835: assertEquals(base, document.getBaseURI());
0836: Reader reader2 = new StringReader(validDoc);
0837: Document document2 = builder.build(reader2);
0838: assertEquals(document2, document);
0839:
0840: }
0841:
0842: public void testValidateFromInputStreamWithBase()
0843: throws IOException, ParsingException {
0844:
0845: InputStream in = new ByteArrayInputStream(validDoc
0846: .getBytes("UTF-8"));
0847: Document document = validator.build(in, base);
0848: assertEquals(base, document.getBaseURI());
0849: Reader reader2 = new StringReader(validDoc);
0850: Document document2 = builder.build(reader2);
0851: assertEquals(document2, document);
0852:
0853: }
0854:
0855: public void testValidateInSeries() throws IOException,
0856: ParsingException {
0857:
0858: try {
0859: Reader reader = new StringReader(source);
0860: validator.build(reader);
0861: fail("Allowed invalid doc");
0862: } catch (ValidityException success) {
0863: assertNotNull(success.getMessage());
0864: }
0865: // now make sure validating a valid document doesn't
0866: // throw an exception
0867: InputStream in = new ByteArrayInputStream(validDoc
0868: .getBytes("UTF-8"));
0869: validator.build(in, base);
0870:
0871: }
0872:
0873: public void testValidateFromInputStreamWithoutBase()
0874: throws IOException, ParsingException {
0875:
0876: InputStream in = new ByteArrayInputStream(validDoc
0877: .getBytes("UTF-8"));
0878: Document document = validator.build(in);
0879: assertEquals("", document.getBaseURI());
0880: Reader reader2 = new StringReader(validDoc);
0881: Document document2 = builder.build(reader2);
0882: assertEquals(document2, document);
0883:
0884: }
0885:
0886: public void testValidateFromStringWithBase() throws IOException,
0887: ParsingException {
0888:
0889: Document document = validator.build(validDoc, base);
0890: assertEquals(base, document.getBaseURI());
0891: Reader reader2 = new StringReader(validDoc);
0892: Document document2 = builder.build(reader2);
0893: assertEquals(document2, document);
0894:
0895: }
0896:
0897: public void testValidateWithCrimson() throws IOException,
0898: ParsingException {
0899:
0900: XMLReader crimson;
0901: try {
0902: crimson = XMLReaderFactory
0903: .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
0904: } catch (SAXException ex) {
0905: // can't test Crimson if you can't load it
0906: return;
0907: }
0908: Builder validator = new Builder(crimson, true);
0909: Document document = validator.build(validDoc, base);
0910: assertEquals(base, document.getBaseURI());
0911: Reader reader2 = new StringReader(validDoc);
0912: Document document2 = builder.build(reader2);
0913: assertEquals(document2, document);
0914:
0915: }
0916:
0917: public void testNotationAttributeTypeWithCrimson()
0918: throws IOException, ParsingException {
0919:
0920: XMLReader crimson;
0921: try {
0922: crimson = XMLReaderFactory
0923: .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
0924: } catch (SAXException ex) {
0925: // can't test Crimson if you can't load it
0926: return;
0927: }
0928:
0929: String data = " <!DOCTYPE doc [\n"
0930: + "<!ATTLIST e a NOTATION (n) #IMPLIED>\n"
0931: + "<!ELEMENT document (e)*>\n"
0932: + "<!ELEMENT e (#PCDATA)>\n"
0933: + "<!NOTATION n PUBLIC \"whatever\">"
0934: + "]><document />";
0935:
0936: Builder builder = new Builder(crimson);
0937: Document document = builder.build(data, base);
0938:
0939: String s = document.toXML();
0940: Document roundTrip = builder.build(s, base);
0941: assertEquals(document, roundTrip);
0942:
0943: }
0944:
0945: public void testEnumerationAttributeType() throws IOException,
0946: ParsingException {
0947:
0948: XMLReader crimson;
0949: try {
0950: crimson = XMLReaderFactory
0951: .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
0952: } catch (SAXException ex) {
0953: // can't test Crimson if you can't load it
0954: return;
0955: }
0956: Builder builder = new Builder(crimson, false);
0957: String doc = "<!DOCTYPE root ["
0958: + "<!ATTLIST root att (yes | no) #IMPLIED>"
0959: + "]><root att='yes'/>";
0960: Document document = builder.build(doc, base);
0961: Element root = document.getRootElement();
0962: Attribute att = root.getAttribute(0);
0963: assertEquals(Attribute.Type.ENUMERATION, att.getType());
0964:
0965: }
0966:
0967: public void testWarningDoesNotStopBuild() throws IOException,
0968: ParsingException, SAXException {
0969:
0970: XMLReader xerces;
0971: try {
0972: xerces = XMLReaderFactory
0973: .createXMLReader("org.apache.xerces.parsers.SAXParser");
0974: } catch (SAXException ex) {
0975: // can't test Xerces if you can't load it
0976: return;
0977: }
0978: // This document generates a warning due to the duplicate
0979: // attribute declaration
0980: xerces
0981: .setFeature(
0982: "http://apache.org/xml/features/validation/warn-on-duplicate-attdef",
0983: true);
0984: Builder builder = new Builder(xerces, true);
0985: Document document = builder.build("<!DOCTYPE root ["
0986: + "<!ELEMENT root ANY>"
0987: + "<!ATTLIST root b CDATA #IMPLIED>"
0988: + "<!ATTLIST root b NMTOKEN #REQUIRED>"
0989: + "]><root b='test'/>", base);
0990: // The main test is that the document is built successfully.
0991: assertEquals(2, document.getChildCount());
0992: assertEquals("root", document.getRootElement()
0993: .getQualifiedName());
0994:
0995: }
0996:
0997: private static class EntitySkipper extends XMLFilterImpl {
0998:
0999: public EntitySkipper(XMLReader reader) {
1000: super (reader);
1001: }
1002:
1003: public void characters(char[] data, int start, int length)
1004: throws SAXException {
1005: super .skippedEntity("name");
1006: }
1007:
1008: }
1009:
1010: public void testSkippedEntityThrowsParsingException()
1011: throws IOException, ParsingException, SAXException {
1012:
1013: XMLReader xerces = XMLReaderFactory
1014: .createXMLReader("org.apache.xerces.parsers.SAXParser");
1015: XMLReader filter = new EntitySkipper(xerces);
1016:
1017: Builder builder = new Builder(filter, true);
1018: try {
1019: builder.build("<root>replace</root>", base);
1020: fail("Allowed skipped entity");
1021: } catch (ParsingException success) {
1022: assertNotNull(success.getMessage());
1023: }
1024:
1025: }
1026:
1027: public void testValidateFromStringWithNullBase()
1028: throws IOException, ParsingException {
1029: Document document = validator.build(validDoc, null);
1030: assertEquals("", document.getBaseURI());
1031: Reader reader2 = new StringReader(validDoc);
1032: Document document2 = builder.build(reader2);
1033: assertEquals(document2, document);
1034: }
1035:
1036: public void testCannotBuildNamespaceMalformedDocument()
1037: throws IOException {
1038:
1039: try {
1040: builder.build("<root:root/>", null);
1041: fail("Builder allowed undeclared prefix");
1042: } catch (ParsingException success) {
1043: assertNotNull(success.getMessage());
1044: }
1045:
1046: }
1047:
1048: public void testInvalidDocFromReader() throws IOException,
1049: ParsingException {
1050:
1051: Reader reader = new StringReader(source);
1052: try {
1053: validator.build(reader);
1054: fail("Allowed invalid doc");
1055: } catch (ValidityException success) {
1056: assertNotNull(success.getMessage());
1057: assertTrue(success.getErrorCount() > 0);
1058: for (int i = 0; i < success.getErrorCount(); i++) {
1059: assertNotNull(success.getValidityError(i));
1060: assertTrue(success.getLineNumber(i) >= -1);
1061: assertTrue(success.getColumnNumber(i) >= -1);
1062: }
1063: if (!xercesBroken) {
1064: Document doc = builder.build(new StringReader(source));
1065: this .verify(success.getDocument());
1066: assertEquals(doc, success.getDocument());
1067: }
1068: }
1069:
1070: }
1071:
1072: public void testNamespaceMalformedDocumentWithCrimson()
1073: throws IOException {
1074:
1075: StringReader reader = new StringReader("<root:root/>");
1076: XMLReader crimson;
1077: try {
1078: crimson = XMLReaderFactory
1079: .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
1080: } catch (SAXException ex) {
1081: // No Crimson in classpath; therefore can't test it
1082: return;
1083: }
1084: Builder builder = new Builder(crimson);
1085: try {
1086: builder.build(reader);
1087: fail("Crimson allowed namespace malformed doc");
1088: } catch (ParsingException success) {
1089: assertNotNull(success.getMessage());
1090: }
1091:
1092: }
1093:
1094: public void testValidateNamespaceMalformedInvalidDocumentWithCrimson()
1095: throws IOException {
1096:
1097: StringReader reader = new StringReader("<!DOCTYPE root ["
1098: + "<!ELEMENT root (a)>\n" + "<!ELEMENT a (#PCDATA)> \n"
1099: + "]>\n" + "<root><b:b /></root>");
1100: XMLReader crimson;
1101: try {
1102: crimson = XMLReaderFactory
1103: .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
1104: } catch (SAXException ex) {
1105: // No Crimson in classpath; therefore can't test it
1106: return;
1107: }
1108: Builder builder = new Builder(crimson);
1109: try {
1110: builder.build(reader);
1111: fail("Crimson allowed namespace malformed doc");
1112: } catch (ValidityException ex) {
1113: fail("Crimson should have thrown ParsingException instead");
1114: } catch (ParsingException success) {
1115: assertNotNull(success.getMessage());
1116: }
1117:
1118: }
1119:
1120: public void testInvalidDocFromReaderWithBase() throws IOException,
1121: ParsingException {
1122:
1123: Reader reader1 = new StringReader(source);
1124: try {
1125: validator.build(reader1, base);
1126: fail("Allowed invalid doc");
1127: } catch (ValidityException ex) {
1128: assertNotNull(ex.getMessage());
1129: assertEquals(base, ex.getURI());
1130: assertTrue(ex.getErrorCount() > 0);
1131: for (int i = 0; i < ex.getErrorCount(); i++) {
1132: assertNotNull(ex.getValidityError(i));
1133: assertTrue(ex.getLineNumber(i) >= -1);
1134: assertTrue(ex.getColumnNumber(i) >= -1);
1135: }
1136: if (!xercesBroken) {
1137: Document doc = builder.build(new StringReader(source),
1138: base);
1139: this .verify(ex.getDocument());
1140: assertEquals(doc, ex.getDocument());
1141: }
1142: }
1143:
1144: }
1145:
1146: public void testInvalidDocFromInputStreamWithBase()
1147: throws IOException, ParsingException {
1148:
1149: InputStream in = new ByteArrayInputStream(source
1150: .getBytes("UTF-8"));
1151: try {
1152: validator.build(in, base);
1153: fail("Allowed invalid doc");
1154: } catch (ValidityException ex) {
1155: assertNotNull(ex.getMessage());
1156: assertEquals(base, ex.getURI());
1157: assertTrue(ex.getErrorCount() > 0);
1158: for (int i = 0; i < ex.getErrorCount(); i++) {
1159: assertNotNull(ex.getValidityError(i));
1160: assertTrue(ex.getLineNumber(i) >= -1);
1161: assertTrue(ex.getColumnNumber(i) >= -1);
1162: }
1163: if (!xercesBroken) {
1164: Document doc = builder.build(new ByteArrayInputStream(
1165: source.getBytes("UTF-8")), base);
1166: this .verify(ex.getDocument());
1167: assertEquals(doc, ex.getDocument());
1168: }
1169: }
1170:
1171: }
1172:
1173: public void testInvalidDocFromInputStreamWithoutBase()
1174: throws IOException, ParsingException {
1175:
1176: InputStream in = new ByteArrayInputStream(source
1177: .getBytes("UTF-8"));
1178: try {
1179: validator.build(in);
1180: fail("Allowed invalid doc");
1181: } catch (ValidityException ex) {
1182: assertNotNull(ex.getMessage());
1183: assertTrue(ex.getErrorCount() > 0);
1184: for (int i = 0; i < ex.getErrorCount(); i++) {
1185: assertNotNull(ex.getValidityError(i));
1186: assertTrue(ex.getLineNumber(i) >= -1);
1187: assertTrue(ex.getColumnNumber(i) >= -1);
1188: }
1189: if (!xercesBroken) {
1190: Document doc = builder.build(new ByteArrayInputStream(
1191: source.getBytes("UTF-8")));
1192: this .verify(ex.getDocument());
1193: assertEquals(doc, ex.getDocument());
1194: }
1195: }
1196:
1197: }
1198:
1199: public void testInvalidDocFromStringWithBase() throws IOException,
1200: ParsingException {
1201:
1202: try {
1203: validator.build(source, base);
1204: fail("Allowed invalid doc");
1205: } catch (ValidityException ex) {
1206: assertNotNull(ex.getMessage());
1207: assertEquals(base, ex.getURI());
1208: assertTrue(ex.getErrorCount() > 0);
1209: for (int i = 0; i < ex.getErrorCount(); i++) {
1210: assertNotNull(ex.getValidityError(i));
1211: assertTrue(ex.getLineNumber(i) >= -1);
1212: assertTrue(ex.getColumnNumber(i) >= -1);
1213: }
1214: if (!xercesBroken) {
1215: Document doc = builder.build(source, base);
1216: this .verify(ex.getDocument());
1217: assertEquals(doc, ex.getDocument());
1218: }
1219: }
1220:
1221: }
1222:
1223: public void testInvalidDocWithCrimson() throws IOException,
1224: ParsingException {
1225:
1226: XMLReader crimson;
1227: try {
1228: crimson = XMLReaderFactory
1229: .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
1230: } catch (SAXException ex) {
1231: // can't test Crimson if you can't load it
1232: return;
1233: }
1234: Builder validator = new Builder(crimson, true);
1235: try {
1236: validator.build(source, null);
1237: fail("Allowed invalid doc");
1238: } catch (ValidityException ex) {
1239: assertTrue(ex.getErrorCount() > 0);
1240: assertNull(ex.getURI());
1241: for (int i = 0; i < ex.getErrorCount(); i++) {
1242: assertNotNull(ex.getValidityError(i));
1243: }
1244: }
1245:
1246: }
1247:
1248: public void testInvalidDocFromStringWithNullBase()
1249: throws IOException, ParsingException {
1250:
1251: try {
1252: validator.build(source, null);
1253: fail("Allowed invalid doc");
1254: } catch (ValidityException ex) {
1255: assertTrue(ex.getErrorCount() > 0);
1256: assertNull(ex.getURI());
1257: for (int i = 0; i < ex.getErrorCount(); i++) {
1258: assertNotNull(ex.getValidityError(i));
1259: }
1260: if (!xercesBroken) {
1261: Document doc = builder.build(source, null);
1262: this .verify(ex.getDocument());
1263: assertEquals(doc, ex.getDocument());
1264: }
1265: }
1266:
1267: }
1268:
1269: public void testJavaEncodings() throws IOException,
1270: ParsingException {
1271:
1272: String str = "<?xml version='1.0' encoding='ISO8859_1'?>"
1273: + "<root>é</root>";
1274: byte[] data = str.getBytes("8859_1");
1275: InputStream in = new ByteArrayInputStream(data);
1276: Document doc = builder.build(in);
1277: assertEquals("é", doc.getValue());
1278:
1279: }
1280:
1281: // Crimson improperly converts 0x0D and 0x0A to spaces
1282: // even when the attribute type is not CDATA.
1283: // This bug explains why the canonicalizer tests fail
1284: // with Crimson
1285: public void testCrimsonCharacterReferenceBug() throws IOException,
1286: ParsingException {
1287:
1288: String data = "<!DOCTYPE test [<!ATTLIST test name ID #IMPLIED>]>"
1289: + "<test name='
'/>";
1290: InputStream in = new ByteArrayInputStream(data.getBytes("UTF8"));
1291: Document document = builder.build(in, null);
1292: assertEquals("\r", document.getRootElement().getAttributeValue(
1293: "name"));
1294:
1295: }
1296:
1297: public void testBaseRelativeResolution() throws IOException,
1298: ParsingException {
1299: builder.build(new File(inputDir, "baserelative/test.xml"));
1300: }
1301:
1302: // make sure transcoders on input are using normalization
1303: // form C when converting from other encodings
1304: public void testNFC() throws IOException, ParsingException {
1305:
1306: Document doc = builder.build(new File(inputDir, "nfctest.xml"));
1307: Element root = doc.getRootElement();
1308: String s = root.getValue();
1309: assertEquals(1, s.length());
1310: assertEquals(0xE9, s.charAt(0));
1311:
1312: }
1313:
1314: // This tests XOM's workaround for a bug in Crimson, Xerces,
1315: // and possibly other parsers
1316: public void testBaseRelativeResolutionRemotely()
1317: throws IOException, ParsingException {
1318: builder.build("http://www.cafeconleche.org");
1319: }
1320:
1321: public void testExternalEntityResolution() throws IOException,
1322: ParsingException {
1323:
1324: File input = new File(inputDir, "entitytest.xml");
1325: Builder builder = new Builder(false);
1326: Document doc = builder.build(input);
1327: Element root = doc.getRootElement();
1328: Element external = root.getFirstChildElement("external");
1329: assertEquals("Hello from an entity!", external.getValue());
1330:
1331: }
1332:
1333: // This test exposes a bug in Crimson but not Xerces.
1334: // It's testing whether the external DTD subset is read,
1335: // default attribute values applied, and comments and
1336: // processing instructions in the external DTD subset are not
1337: // reported.
1338: public void testExternalDTDSubset() throws IOException,
1339: ParsingException {
1340:
1341: File input = new File(inputDir, "externalDTDtest.xml");
1342: Builder builder = new Builder(false);
1343: Document doc = builder.build(input);
1344: assertEquals(2, doc.getChildCount());
1345: Element root = doc.getRootElement();
1346: Attribute name = root.getAttribute("name");
1347: assertEquals("value", name.getValue());
1348: DocType doctype = doc.getDocType();
1349: assertEquals("", doctype.getInternalDTDSubset());
1350:
1351: }
1352:
1353: /* <?xml version="1.0"?>
1354: <!DOCTYPE root [
1355: <!ELEMENT root (#PCDATA)>
1356: <!-- comment -->
1357: <?target PI data?>
1358: <!NOTATION JPEG SYSTEM "image/jpeg">
1359: <!ATTLIST root source ENTITY #REQUIRED>
1360: <!ENTITY picture SYSTEM "picture.jpg" NDATA JPEG>
1361: ]>
1362: <root source="picture">
1363: This document is intended to test the building of
1364: various constructs in the internal DTD subset.
1365: </root>
1366: */
1367: public void testInternalDTDSubset() throws ValidityException,
1368: ParsingException, IOException {
1369:
1370: File input = new File(inputDir, "internaldtdsubsettest.xml");
1371: Builder builder = new Builder(false);
1372: Document doc = builder.build(input);
1373: String internalSubset = doc.getDocType().getInternalDTDSubset();
1374: assertTrue(internalSubset.indexOf("<!-- comment -->") > 0);
1375: assertTrue(internalSubset.indexOf("<?target PI data?>") > 0);
1376: assertTrue(internalSubset.indexOf("<!ELEMENT root (#PCDATA)>") > 0);
1377: assertTrue(internalSubset
1378: .indexOf("<!ATTLIST root source ENTITY #REQUIRED>") > 0);
1379: // some confusion in the parser resolving these as relative URLs.
1380: // This is in accordance with the SAX spec, see
1381: // http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html#notationDecl(java.lang.String,%20java.lang.String,%20java.lang.String)
1382: // but how does it know the notation system ID is really a URL?
1383: assertTrue(internalSubset.indexOf("<!ENTITY picture SYSTEM ") > 0);
1384: assertTrue(internalSubset.indexOf("picture.jpg\" NDATA JPEG>") > 0);
1385: assertTrue(internalSubset.indexOf("<!NOTATION JPEG SYSTEM ") > 0);
1386: assertTrue(internalSubset.indexOf("image/jpeg\">") > 0);
1387:
1388: }
1389:
1390: public void testInternalEntityDeclDollarSign()
1391: throws ValidityException, ParsingException, IOException {
1392:
1393: String input = "<!DOCTYPE root [<!ENTITY test '$!@#$^'>] ><root />";
1394: Builder builder = new Builder(false);
1395: Document doc = builder.build(input, null);
1396: String internalSubset = doc.getDocType().getInternalDTDSubset();
1397: assertTrue(internalSubset.indexOf("<!ENTITY test \"$!@#$^\">") > 0);
1398:
1399: }
1400:
1401: public void testInternalDTDSubset5To9() throws ValidityException,
1402: ParsingException, IOException {
1403:
1404: String input = "<!DOCTYPE root [<!ATTLIST root source CDATA '56789'>] ><root />";
1405: Builder builder = new Builder(false);
1406: Document doc = builder.build(input, null);
1407: String internalSubset = doc.getDocType().getInternalDTDSubset();
1408: assertTrue(internalSubset
1409: .indexOf("<!ATTLIST root source CDATA \"56789\">") > 0);
1410:
1411: }
1412:
1413: public void testInternalDTDSubsetPunctuation()
1414: throws ValidityException, ParsingException, IOException {
1415:
1416: String input = "<!DOCTYPE root [<!ATTLIST root source CDATA '+,()!'>] ><root />";
1417: Builder builder = new Builder(false);
1418: Document doc = builder.build(input, null);
1419: String internalSubset = doc.getDocType().getInternalDTDSubset();
1420: assertTrue(internalSubset
1421: .indexOf("<!ATTLIST root source CDATA \"+,()!\">") > 0);
1422:
1423: }
1424:
1425: /*<!ELEMENT test (#PCDATA)>
1426: <!-- comment should not be here -->
1427: <?processing instruction should not be here?>
1428: <!ATTLIST test name (CDATA) #FIXED "value">
1429: <!ATTLIST test name CDATA "value">
1430: <!ATTLIST root anattribute CDATA #REQUIRED>
1431: <!ATTLIST root anotherattribute CDATA "value">
1432: <!ENTITY hatch-pic SYSTEM "http://www.example.com/images/cup.gif" NDATA gif>
1433: <!ENTITY public-pic PUBLIC "public ID" "http://www.example.com/images/cup.gif" NDATA gif>
1434: <!ENTITY Pub-Status "This is a pre-release of the specification.">
1435: <!ENTITY open-hatch PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN" "http://www.textuality.com/boilerplate/OpenHatch.xml">
1436: <!ENTITY test SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">
1437: <!NOTATION ISODATE SYSTEM "http://www.iso.ch/cate/d15903.html">
1438: <!NOTATION DATE PUBLIC "DATE PUBLIC ID" "http://www.iso.ch/cate/d15903.html">
1439: <!NOTATION gif PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN"> */
1440: public void testInternalAndExternalDTDSubset()
1441: throws ValidityException, ParsingException, IOException {
1442:
1443: File input = new File(inputDir,
1444: "internalandexternaldtdsubsettest.xml");
1445: Builder builder = new Builder(false);
1446: Document doc = builder.build(input);
1447: String internalSubset = doc.getDocType().getInternalDTDSubset();
1448: assertTrue(internalSubset.indexOf("<!-- comment -->") > 0);
1449: assertTrue(internalSubset.indexOf("<?target PI data?>") > 0);
1450: assertTrue(internalSubset.indexOf("<!ELEMENT root (#PCDATA)>") > 0);
1451: assertTrue(internalSubset
1452: .indexOf("<!ATTLIST root source ENTITY #REQUIRED>") > 0);
1453: assertTrue(internalSubset.indexOf("<!ENTITY picture SYSTEM ") > 0);
1454: assertTrue(internalSubset.indexOf("picture.jpg\" NDATA JPEG>") > 0);
1455: assertTrue(internalSubset.indexOf("<!NOTATION JPEG SYSTEM ") > 0);
1456: assertTrue(internalSubset.indexOf("image/jpeg\">") > 0);
1457:
1458: assertEquals(-1, internalSubset
1459: .indexOf("comment should not be here"));
1460: assertEquals(-1, internalSubset
1461: .indexOf("processing instruction should not be here"));
1462: assertEquals(-1, internalSubset.indexOf("anattribute"));
1463: assertEquals(-1, internalSubset.indexOf("anotherattribute"));
1464: assertEquals(-1, internalSubset.indexOf("hatch-pic"));
1465: assertEquals(-1, internalSubset.indexOf("public-pic"));
1466: assertEquals(-1, internalSubset.indexOf("open-hatch"));
1467: assertEquals(-1, internalSubset.indexOf("Pub-Status-pic"));
1468: assertEquals(-1, internalSubset.indexOf("Textuality"));
1469: assertEquals(-1, internalSubset.indexOf("15903"));
1470:
1471: }
1472:
1473: public void testInternalAndExternalDTDSubsetWithCrimson()
1474: throws ValidityException, ParsingException, IOException {
1475:
1476: XMLReader crimson;
1477: try {
1478: crimson = XMLReaderFactory
1479: .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
1480: } catch (SAXException ex) {
1481: // can't test Crimson if you can't load it
1482: return;
1483: }
1484:
1485: Builder builder = new Builder(crimson);
1486: File input = new File(inputDir,
1487: "internalandexternaldtdsubsettest.xml");
1488: Document doc = builder.build(input);
1489: String internalSubset = doc.getDocType().getInternalDTDSubset();
1490: assertTrue(internalSubset.indexOf("<!-- comment -->") > 0);
1491: assertTrue(internalSubset.indexOf("<?target PI data?>") > 0);
1492: assertTrue(internalSubset.indexOf("<!ELEMENT root (#PCDATA)>") > 0);
1493: assertTrue(internalSubset
1494: .indexOf("<!ATTLIST root source ENTITY #REQUIRED>") > 0);
1495: assertTrue(internalSubset.indexOf("<!ENTITY picture SYSTEM ") > 0);
1496: assertTrue(internalSubset.indexOf("picture.jpg\" NDATA JPEG>") > 0);
1497: assertTrue(internalSubset.indexOf("<!NOTATION JPEG SYSTEM ") > 0);
1498: assertTrue(internalSubset.indexOf("image/jpeg\">") > 0);
1499:
1500: assertEquals(-1, internalSubset
1501: .indexOf("comment should not be here"));
1502: assertEquals(-1, internalSubset
1503: .indexOf("processing instruction should not be here"));
1504: assertEquals(-1, internalSubset.indexOf("anattribute"));
1505: assertEquals(-1, internalSubset.indexOf("anotherattribute"));
1506: assertEquals(-1, internalSubset.indexOf("hatch-pic"));
1507: assertEquals(-1, internalSubset.indexOf("public-pic"));
1508: assertEquals(-1, internalSubset.indexOf("open-hatch"));
1509: assertEquals(-1, internalSubset.indexOf("Pub-Status-pic"));
1510: assertEquals(-1, internalSubset.indexOf("Textuality"));
1511: assertEquals(-1, internalSubset.indexOf("15903"));
1512:
1513: }
1514:
1515: // This test exposes a bug in Crimson, Xerces 2.5 and earlier,
1516: // and possibly other parsers. I've reported the bug in Xerces,
1517: // and it is fixed in Xerces 2.6.
1518: public void testBaseRelativeResolutionRemotelyWithDirectory()
1519: throws IOException, ParsingException {
1520: builder.build("http://www.ibiblio.org/xml");
1521: }
1522:
1523: // This test exposes a bug in Crimson, Xerces 2.5 and earlier,
1524: // and possibly other parsers. I've reported the bug in Xerces,
1525: // and it should be fixed in Xerces 2.6.
1526: public void testRelativeURIResolutionAgainstARedirectedBase()
1527: throws IOException, ParsingException {
1528: builder.build("http://www.ibiblio.org/xml/redirecttest.xml");
1529: }
1530:
1531: public void testDontGetNodeFactory() {
1532:
1533: Builder builder = new Builder();
1534: NodeFactory factory = builder.getNodeFactory();
1535: if (factory != null) {
1536: assertFalse(factory.getClass().getName().endsWith(
1537: "NonVerifyingFactory"));
1538: }
1539:
1540: }
1541:
1542: public void testGetNodeFactory() {
1543: NodeFactory factory = new NodeFactory();
1544: Builder builder = new Builder(factory);
1545: assertEquals(factory, builder.getNodeFactory());
1546: }
1547:
1548: // Make sure additional namespaces aren't added for
1549: // attributes. This test is flaky because it assumes
1550: // the parser reports attributes in the correct order,
1551: // which is not guaranteed. I use a custom SAX Filter to
1552: // make sure the namespace declaration comes before the attribute.
1553: public void testAttributesVsNamespaces() throws ParsingException,
1554: IOException, SAXException {
1555:
1556: XMLFilter filter = new OrderingFilter();
1557: filter
1558: .setParent(XMLReaderFactory
1559: .createXMLReader("org.apache.xerces.parsers.SAXParser"));
1560: Builder builder = new Builder(filter);
1561: String data = "<a/>";
1562: Document doc = builder.build(data, null);
1563: Element root = doc.getRootElement();
1564: root.removeAttribute(root.getAttribute(0));
1565: assertNull(root.getNamespaceURI("pre"));
1566:
1567: }
1568:
1569: private static class OrderingFilter extends XMLFilterImpl {
1570:
1571: public void startElement(String namespaceURI, String localName,
1572: String qualifiedName, Attributes atts)
1573: throws SAXException {
1574:
1575: AttributesImpl newAttributes = new AttributesImpl();
1576: newAttributes.addAttribute("", "pre", "xmlns:pre", "CDATA",
1577: "http://www.example.com/");
1578: newAttributes.addAttribute("http://www.example.com/",
1579: "name", "pre:name", "CDATA", "value");
1580: super .startElement(namespaceURI, localName, qualifiedName,
1581: newAttributes);
1582: }
1583:
1584: }
1585:
1586: public void testValidateMalformedDocument() throws IOException {
1587:
1588: Reader reader = new StringReader("<!DOCTYPE root ["
1589: + "<!ELEMENT root (a, b)>" + "<!ELEMENT a (EMPTY)>"
1590: + "<!ELEMENT b (PCDATA)>" + "]><root><a/><b></b>");
1591: try {
1592: validator.build(reader);
1593: fail("Allowed malformed doc");
1594: } catch (ValidityException ex) {
1595: fail("Threw validity error instead of well-formedness error");
1596: } catch (ParsingException ex) {
1597: assertNotNull(ex.getMessage());
1598: assertNull(ex.getURI());
1599: }
1600:
1601: }
1602:
1603: /* Test for particular bug in Crimson with mixed content declarations */
1604: public void testBuildInternalDTDSubsetWithCrimson()
1605: throws ParsingException, IOException {
1606:
1607: String dtd = " <!ELEMENT doc (#PCDATA|a)*>\n";
1608:
1609: String document = "<!DOCTYPE a [\n" + dtd + "]>\n<a/>";
1610: XMLReader crimson;
1611: try {
1612: crimson = XMLReaderFactory
1613: .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
1614: } catch (SAXException ex) {
1615: // can't test Crimson if you can't load it
1616: return;
1617: }
1618:
1619: Builder builder = new Builder(crimson);
1620: Document doc = builder.build(document, null);
1621:
1622: String parsedDTD = doc.getDocType().getInternalDTDSubset();
1623: assertEquals(dtd, parsedDTD);
1624:
1625: }
1626:
1627: /* Test for particular bug in Crimson with mixed content declarations */
1628: public void testBuildXMLNamespaceDeclarationWithCrimson()
1629: throws ParsingException, IOException {
1630:
1631: String document = "<doc xmlns:xml='http://www.w3.org/XML/1998/namespace' />";
1632: XMLReader crimson;
1633: try {
1634: crimson = XMLReaderFactory
1635: .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
1636: } catch (SAXException ex) {
1637: // can't test Crimson if you can't load it
1638: return;
1639: }
1640:
1641: Builder builder = new Builder(crimson);
1642: Document doc = builder.build(document, null);
1643:
1644: assertEquals("<doc />", doc.getRootElement().toXML());
1645:
1646: }
1647:
1648: public void testBuildIllegalXMLNamespaceDeclarationWithCrimson()
1649: throws ParsingException, IOException {
1650:
1651: String document = "<doc xmlns:xml='http://www.w3.org/XML/2005/namespace' />";
1652: XMLReader crimson;
1653: try {
1654: crimson = XMLReaderFactory
1655: .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
1656: } catch (SAXException ex) {
1657: // can't test Crimson if you can't load it
1658: return;
1659: }
1660:
1661: Builder builder = new Builder(crimson);
1662: try {
1663: builder.build(document, null);
1664: fail("Allowed wrong namespace URI for xml prefix");
1665: } catch (ParsingException success) {
1666: assertNotNull(success.getMessage());
1667: }
1668:
1669: }
1670:
1671: public void testATTLISTDeclaresXMLSpacePreserveOnlyWithCrimson()
1672: throws ParsingException, IOException {
1673:
1674: String dtd = "<!DOCTYPE a [<!ATTLIST doc xml:space (preserve) 'preserve'>]\n>";
1675:
1676: String data = dtd + "<doc />";
1677: XMLReader crimson;
1678: try {
1679: crimson = XMLReaderFactory
1680: .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
1681: } catch (SAXException ex) {
1682: // can't test Crimson if you can't load it
1683: return;
1684: }
1685:
1686: Builder builder = new Builder(crimson);
1687: Document doc = builder.build(data, null);
1688: assertEquals(1, doc.getRootElement().getAttributeCount());
1689:
1690: }
1691:
1692: public void testNoInternalSubsetWithCrimson()
1693: throws ParsingException, IOException {
1694:
1695: XMLReader crimson;
1696: try {
1697: crimson = XMLReaderFactory
1698: .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
1699: } catch (SAXException ex) {
1700: // can't test Crimson if you can't load it
1701: return;
1702: }
1703:
1704: File input = new File(inputDir, "externalDTDtest.xml");
1705: Builder builder = new Builder(crimson);
1706: Document doc = builder.build(input);
1707: String subset = doc.getDocType().getInternalDTDSubset();
1708: assertEquals("", subset);
1709:
1710: }
1711:
1712: public void testValidateMalformedDocumentWithCrimson()
1713: throws IOException {
1714:
1715: Reader reader = new StringReader("<!DOCTYPE root ["
1716: + "<!ELEMENT root (a, b)>" + "<!ELEMENT a (EMPTY)>"
1717: + "<!ELEMENT b (PCDATA)>" + "]><root><a/><b></b>");
1718: XMLReader crimson;
1719: try {
1720: crimson = XMLReaderFactory
1721: .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
1722: } catch (SAXException ex) {
1723: // can't test Crimson if you can't load it
1724: return;
1725: }
1726: Builder validator = new Builder(crimson, true);
1727: try {
1728: validator.build(reader);
1729: fail("Allowed malformed doc");
1730: } catch (ValidityException ex) {
1731: fail("Crimson threw validity error instead of well-formedness error");
1732: } catch (ParsingException success) {
1733: assertNotNull(success.getMessage());
1734: assertNull(success.getURI());
1735: }
1736:
1737: }
1738:
1739: // This is testing a work-around for a Xerces bug
1740: // http://nagoya.apache.org/bugzilla/show_bug.cgi?id=27583
1741: // that reports this as an IOException rather than a SAXException
1742: public void testBuildMalformedDocumentWithUnpairedSurrogate()
1743: throws IOException {
1744:
1745: String doc = "<doc>A\uD800A</doc>";
1746: try {
1747: builder.build(doc, "http://www.example.com");
1748: fail("Allowed malformed doc");
1749: } catch (ParsingException success) {
1750: assertNotNull(success.getMessage());
1751: assertEquals("http://www.example.com/", success.getURI());
1752: }
1753:
1754: }
1755:
1756: public void testBuildMalformedDocumentWithBadUnicodeData()
1757: throws IOException {
1758:
1759: File f = new File(inputDir, "xmlconf");
1760: f = new File(f, "xmltest");
1761: f = new File(f, "not-wf");
1762: f = new File(f, "sa");
1763: f = new File(f, "170.xml");
1764: if (f.exists()) {
1765: try {
1766: builder.build(f);
1767: fail("Allowed malformed doc");
1768: } catch (ParsingException success) {
1769: assertNotNull(success.getMessage());
1770: assertTrue(success.getURI().endsWith(
1771: "data/xmlconf/xmltest/not-wf/sa/170.xml"));
1772: assertTrue(success.getURI().startsWith("file:/"));
1773: }
1774: }
1775:
1776: }
1777:
1778: public void testBuildAnotherMalformedDocumentWithBadUnicodeData()
1779: throws IOException {
1780:
1781: String filename = "data/oasis/p02fail30.xml";
1782: File f = new File(inputDir, "oasis");
1783: f = new File(f, "p02fail30.xml");
1784: if (f.exists()) {
1785: try {
1786: builder.build(f);
1787: fail("Allowed malformed doc");
1788: } catch (ParsingException success) {
1789: assertNotNull(success.getMessage());
1790: assertTrue(success.getURI().endsWith(filename));
1791: assertTrue(success.getURI().startsWith("file:/"));
1792: }
1793: }
1794:
1795: }
1796:
1797: public void testBuildMalformedDocumentWithBadParser()
1798: throws ParsingException, IOException {
1799:
1800: try {
1801: XMLReader parser = new CustomReader();
1802: Builder builder = new Builder(parser);
1803: builder.build("http://www.example.org/");
1804: fail("built from bad data");
1805: } catch (ParsingException success) {
1806: assertNotNull(success.getMessage());
1807: assertTrue(success.getCause() instanceof WellformednessException);
1808: }
1809:
1810: }
1811:
1812: public void testBuildMalformedDocumentWithCrimson()
1813: throws IOException {
1814:
1815: Reader reader = new StringReader("<!DOCTYPE root ["
1816: + "<!ELEMENT root (a, b)>" + "<!ELEMENT a (EMPTY)>"
1817: + "<!ELEMENT b (PCDATA)>" + "]><root><a/><b></b>");
1818: XMLReader crimson;
1819: try {
1820: crimson = XMLReaderFactory
1821: .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
1822: } catch (SAXException ex) {
1823: // can't test Crimson if you can't load it
1824: return;
1825: }
1826: Builder builder = new Builder(crimson);
1827: try {
1828: builder.build(reader);
1829: fail("Allowed malformed doc");
1830: } catch (ValidityException ex) {
1831: fail("Crimson threw validity error instead of well-formedness error");
1832: } catch (ParsingException ex) {
1833: assertNotNull(ex.getMessage());
1834: assertNull(ex.getURI());
1835: }
1836:
1837: }
1838:
1839: public void testNestedExceptionWithSAXParseException()
1840: throws IOException {
1841:
1842: Reader reader = new StringReader("<root ");
1843: Builder builder = new Builder();
1844: try {
1845: builder.build(reader);
1846: fail("Allowed malformed doc");
1847: } catch (ValidityException ex) {
1848: fail("Parser threw validity error instead of well-formedness error");
1849: } catch (ParsingException ex) {
1850: assertNotNull(ex.getCause());
1851: }
1852:
1853: }
1854:
1855: public void testBuildFunkyNamespacesWithUntrustedParser()
1856: throws ParsingException, IOException, SAXException {
1857:
1858: Reader reader = new StringReader(
1859: "<root xmlns='http://example.org/'>"
1860: + "<pre:a xmlns:pre='http://www.root.org/' "
1861: + "xmlns='http://www.red.com'>" + "<b/>"
1862: + "</pre:a></root>");
1863: XMLReader parser = XMLReaderFactory
1864: .createXMLReader("org.apache.xerces.parsers.SAXParser");
1865: XMLFilter filter = new XMLFilterImpl();
1866: filter.setParent(parser);
1867: Builder builder = new Builder(filter);
1868: Document doc = builder.build(reader);
1869: Element root = doc.getRootElement();
1870: Element prea = (Element) root.getChild(0);
1871: Element b = (Element) prea.getChild(0);
1872: assertEquals("http://www.red.com", b.getNamespaceURI());
1873:
1874: }
1875:
1876: // from XML Conformance Test Suite; James Clark test
1877: // valid 097
1878: public void testLineBreaksInInternalDTDSubset()
1879: throws ParsingException, IOException {
1880:
1881: Document doc = builder.build(new File(inputDir, "097.xml"));
1882: String expectedResult = "<?xml version=\"1.0\"?>\n"
1883: + "<!DOCTYPE doc [\n" + " <!ELEMENT doc (#PCDATA)>\n"
1884: + " <!ENTITY % e SYSTEM \"097.ent\">\n"
1885: + " <!ATTLIST doc a1 CDATA \"v1\">\n"
1886: + " <!ATTLIST doc a2 CDATA #IMPLIED>\n" + "]>\n"
1887: + "<doc a1=\"v1\" />\n";
1888: String actual = doc.toXML();
1889: assertEquals(expectedResult, actual);
1890:
1891: }
1892:
1893: public void testBuildDocumentThatUndeclaresDefaultNamespace()
1894: throws ParsingException, IOException {
1895:
1896: Document doc = builder
1897: .build(new File(inputDir, "undeclare.xml"));
1898: String expectedResult = "<?xml version=\"1.0\"?>\n"
1899: + "<root xmlns=\"http://www.example.org\" "
1900: + "xmlns:pre=\"http://www.red.com/\" test=\"test\" "
1901: + "pre:red=\"value\">some data<something xmlns=\"\" />"
1902: + "</root>\n";
1903: String actual = doc.toXML();
1904: assertEquals(expectedResult, actual);
1905:
1906: }
1907:
1908: public void testBuildFromFileThatContainsNonASCIICharacterInName()
1909: throws ParsingException, IOException {
1910:
1911: File f = new File(inputDir, "resumé.xml");
1912: try {
1913: Writer out = new OutputStreamWriter(
1914: new FileOutputStream(f), "UTF8");
1915: out.write("<resumé />");
1916: out.flush();
1917: out.close();
1918: Document doc = builder.build(f);
1919: String expectedResult = "<?xml version=\"1.0\"?>\n"
1920: + "<resumé />\n";
1921: String actual = doc.toXML();
1922: assertEquals(expectedResult, actual);
1923: assertTrue(doc.getBaseURI().startsWith("file:/"));
1924: assertTrue(doc.getBaseURI()
1925: .endsWith("data/resum%C3%A9.xml"));
1926: } finally {
1927: if (f.exists())
1928: f.delete();
1929: }
1930:
1931: }
1932:
1933: // This test fails on Mac OS X. It passes on Linux.
1934: public void testBuildFromFileThatContainsPlane1CharacterInName()
1935: throws ParsingException, IOException {
1936:
1937: int gclef = 0x1D120;
1938: char high = (char) ((gclef - 0x10000) / 0x400 + 0xD800);
1939: char low = (char) ((gclef - 0x10000) % 0x400 + 0xDC00);
1940: File f = new File(inputDir, "music" + high + "" + low + ".xml");
1941: try {
1942: Writer out = new OutputStreamWriter(
1943: new FileOutputStream(f), "UTF8");
1944: out.write("<resumé />");
1945: out.flush();
1946: out.close();
1947: Document doc = builder.build(f);
1948: String expectedResult = "<?xml version=\"1.0\"?>\n"
1949: + "<resumé />\n";
1950: String actual = doc.toXML();
1951: assertEquals(expectedResult, actual);
1952: } finally {
1953: if (f.exists())
1954: f.delete();
1955: }
1956:
1957: }
1958:
1959: private File makeFile(String name) throws IOException {
1960:
1961: File f = new File(inputDir, "" + name);
1962: Writer out = new OutputStreamWriter(new FileOutputStream(f),
1963: "UTF8");
1964: out.write("<data/>");
1965: out.flush();
1966: out.close();
1967: return f;
1968:
1969: }
1970:
1971: public void testBuildFromFileThatContainsAmpersandInName()
1972: throws ParsingException, IOException {
1973:
1974: Document doc = builder.build(new File(inputDir, "&file.xml"));
1975: String expectedResult = "<?xml version=\"1.0\"?>\n"
1976: + "<data />\n";
1977: String actual = doc.toXML();
1978: assertEquals(expectedResult, actual);
1979: assertTrue(doc.getBaseURI().startsWith("file:/"));
1980: assertTrue(doc.getBaseURI().endsWith("data/&file.xml"));
1981:
1982: }
1983:
1984: public void testBuildFromFileThatContainsSpaceInName()
1985: throws ParsingException, IOException {
1986:
1987: File f = makeFile("space file.xml");
1988: Document doc = builder.build(f);
1989: String expectedResult = "<?xml version=\"1.0\"?>\n"
1990: + "<data />\n";
1991: String actual = doc.toXML();
1992: f.delete();
1993: assertEquals(expectedResult, actual);
1994: assertTrue(doc.getBaseURI().startsWith("file:/"));
1995: assertTrue(doc.getBaseURI().endsWith(
1996: "data/space%" + Integer.toHexString(' ') + "file.xml"));
1997:
1998: }
1999:
2000: public void testBuildFromFileThatContainsSharpInName()
2001: throws ParsingException, IOException {
2002:
2003: File f = new File(inputDir, "#file.xml");
2004: try {
2005: Writer out = new OutputStreamWriter(
2006: new FileOutputStream(f), "UTF8");
2007: out.write("<data />");
2008: out.flush();
2009: out.close();
2010: Document doc = builder.build(f);
2011: String expectedResult = "<?xml version=\"1.0\"?>\n"
2012: + "<data />\n";
2013: String actual = doc.toXML();
2014: assertEquals(expectedResult, actual);
2015: assertTrue(doc.getBaseURI().startsWith("file:/"));
2016: assertTrue(doc.getBaseURI().endsWith("data/%23file.xml"));
2017: } finally {
2018: if (f.exists())
2019: f.delete();
2020: }
2021:
2022: }
2023:
2024: public void testBuildFromFileThatContainsExclamationPointInName()
2025: throws ParsingException, IOException {
2026:
2027: Document doc = builder.build(new File(inputDir, "!file.xml"));
2028: String expectedResult = "<?xml version=\"1.0\"?>\n"
2029: + "<data />\n";
2030: String actual = doc.toXML();
2031: assertEquals(expectedResult, actual);
2032: assertTrue(doc.getBaseURI().startsWith("file:/"));
2033: assertTrue(doc.getBaseURI().endsWith("data/!file.xml"));
2034:
2035: }
2036:
2037: public void testBuildFromFileThatContainsDoubleQuoteInName()
2038: throws ParsingException, IOException {
2039:
2040: File f = makeFile("\"file\".xml");
2041: try {
2042: Document doc = builder.build(f);
2043: f.delete();
2044: String expectedResult = "<?xml version=\"1.0\"?>\n<data />\n";
2045: String actual = doc.toXML();
2046: assertEquals(expectedResult, actual);
2047: assertTrue(doc.getBaseURI().startsWith("file:/"));
2048: assertTrue(doc.getBaseURI().endsWith("data/%22file%22.xml"));
2049: } catch (FileNotFoundException ex) {
2050: // This platform doesn't allow double quotes in file names
2051: }
2052:
2053: }
2054:
2055: public void testBuildFromFileThatContainsSingleQuoteInName()
2056: throws ParsingException, IOException {
2057:
2058: File f = makeFile("'file'.xml");
2059: Document doc = builder.build(f);
2060: f.delete();
2061: String expectedResult = "<?xml version=\"1.0\"?>\n"
2062: + "<data />\n";
2063: String actual = doc.toXML();
2064: assertEquals(expectedResult, actual);
2065: assertTrue(doc.getBaseURI().startsWith("file:/"));
2066: assertTrue(doc.getBaseURI().endsWith("data/'file'.xml"));
2067:
2068: }
2069:
2070: public void testBuildFromFileThatContainsParenthesesInName()
2071: throws ParsingException, IOException {
2072:
2073: Document doc = builder.build(new File(inputDir, "()file.xml"));
2074: String expectedResult = "<?xml version=\"1.0\"?>\n"
2075: + "<data />\n";
2076: String actual = doc.toXML();
2077: assertEquals(expectedResult, actual);
2078: assertTrue(doc.getBaseURI().startsWith("file:/"));
2079: assertTrue(doc.getBaseURI().endsWith("data/()file.xml"));
2080:
2081: }
2082:
2083: public void testBuildFromFileThatContainsCurlyBracesInName()
2084: throws ParsingException, IOException {
2085:
2086: Document doc = builder.build(new File(inputDir, "{file}.xml"));
2087: String expectedResult = "<?xml version=\"1.0\"?>\n"
2088: + "<data />\n";
2089: String actual = doc.toXML();
2090: assertEquals(expectedResult, actual);
2091: assertTrue(doc.getBaseURI().startsWith("file:/"));
2092: assertTrue(doc.getBaseURI().endsWith(
2093: "data/%" + Integer.toHexString('{').toUpperCase()
2094: + "file%"
2095: + Integer.toHexString('}').toUpperCase()
2096: + ".xml"));
2097:
2098: }
2099:
2100: public void testBuildFromFileThatContainsSquareBracketsInName()
2101: throws ParsingException, IOException {
2102:
2103: Document doc = builder.build(new File(inputDir, "[file].xml"));
2104: String expectedResult = "<?xml version=\"1.0\"?>\n"
2105: + "<data />\n";
2106: String actual = doc.toXML();
2107: assertEquals(expectedResult, actual);
2108: assertTrue(doc.getBaseURI().startsWith("file:/"));
2109: assertTrue(doc.getBaseURI().endsWith(
2110: "data/%" + Integer.toHexString('[').toUpperCase()
2111: + "file%"
2112: + Integer.toHexString(']').toUpperCase()
2113: + ".xml"));
2114:
2115: }
2116:
2117: public void testBuildFromFileThatContainsVerticalBarInName()
2118: throws ParsingException, IOException {
2119:
2120: File f = makeFile("|file.xml");
2121: try {
2122: Document doc = builder.build(f);
2123: f.delete();
2124: String expectedResult = "<?xml version=\"1.0\"?>\n"
2125: + "<data />\n";
2126: String actual = doc.toXML();
2127: assertEquals(expectedResult, actual);
2128: assertTrue(doc.getBaseURI().startsWith("file:/"));
2129: assertTrue(doc.getBaseURI().endsWith(
2130: "data/%" + Integer.toHexString('|').toUpperCase()
2131: + "file.xml"));
2132: } catch (FileNotFoundException ex) {
2133: // This platform doesn't allow vertical bars in file names
2134: }
2135:
2136: }
2137:
2138: public void testBuildFromFileThatContainsColonInName()
2139: throws ParsingException, IOException {
2140:
2141: File f = makeFile(":file.xml");
2142: try {
2143: Document doc = builder.build(f);
2144: f.delete();
2145: String expectedResult = "<?xml version=\"1.0\"?>\n"
2146: + "<data />\n";
2147: String actual = doc.toXML();
2148: assertEquals(expectedResult, actual);
2149: assertTrue(doc.getBaseURI().startsWith("file:/"));
2150: assertTrue(doc.getBaseURI().endsWith("data/:file.xml"));
2151: } catch (FileNotFoundException ex) {
2152: // This platform doesn't allow colons in file names
2153: }
2154:
2155: }
2156:
2157: public void testBuildFromFileThatContainsUnderscoreInName()
2158: throws ParsingException, IOException {
2159:
2160: File f = makeFile("_file.xml");
2161: Document doc = builder.build(f);
2162: f.delete();
2163: String expectedResult = "<?xml version=\"1.0\"?>\n"
2164: + "<data />\n";
2165: String actual = doc.toXML();
2166: assertEquals(expectedResult, actual);
2167: assertTrue(doc.getBaseURI().startsWith("file:/"));
2168: assertTrue(doc.getBaseURI().endsWith("data/_file.xml"));
2169:
2170: }
2171:
2172: public void testBuildFromFileThatContainsUppercaseASCIIInName()
2173: throws ParsingException, IOException {
2174:
2175: File f = makeFile("ABCDEFGHIJKLMONPQRSTUVWXYZ.xml");
2176: Document doc = builder.build(f);
2177: f.delete();
2178: String expectedResult = "<?xml version=\"1.0\"?>\n"
2179: + "<data />\n";
2180: String actual = doc.toXML();
2181: assertEquals(expectedResult, actual);
2182: assertTrue(doc.getBaseURI().startsWith("file:/"));
2183: assertTrue(doc.getBaseURI().endsWith(
2184: "data/ABCDEFGHIJKLMONPQRSTUVWXYZ.xml"));
2185:
2186: }
2187:
2188: public void testBuildFromFileThatContainsAsteriskInName()
2189: throws ParsingException, IOException {
2190:
2191: File f = makeFile("*file.xml");
2192: try {
2193: Document doc = builder.build(f);
2194: f.delete();
2195: String expectedResult = "<?xml version=\"1.0\"?>\n"
2196: + "<data />\n";
2197: String actual = doc.toXML();
2198: assertEquals(expectedResult, actual);
2199: assertTrue(doc.getBaseURI().startsWith("file:/"));
2200: assertTrue(doc.getBaseURI().endsWith("data/*file.xml"));
2201: } catch (FileNotFoundException ex) {
2202: // This platform doesn't allow asterisks in file names
2203: }
2204:
2205: }
2206:
2207: public void testBuildFromFileThatContainsSemicolonInName()
2208: throws ParsingException, IOException {
2209:
2210: Document doc = builder.build(new File(inputDir, ";file.xml"));
2211: String expectedResult = "<?xml version=\"1.0\"?>\n"
2212: + "<data />\n";
2213: String actual = doc.toXML();
2214: assertEquals(expectedResult, actual);
2215: assertTrue(doc.getBaseURI().startsWith("file:/"));
2216: assertTrue(doc.getBaseURI().endsWith("data/;file.xml"));
2217:
2218: }
2219:
2220: public void testBuildFromFileThatContainsPlusSignInName()
2221: throws ParsingException, IOException {
2222:
2223: Document doc = builder.build(new File(inputDir, "+file.xml"));
2224: String expectedResult = "<?xml version=\"1.0\"?>\n"
2225: + "<data />\n";
2226: String actual = doc.toXML();
2227: assertEquals(expectedResult, actual);
2228: assertTrue(doc.getBaseURI().startsWith("file:/"));
2229: assertTrue(doc.getBaseURI().endsWith(
2230: "data/%" + Integer.toHexString('+').toUpperCase()
2231: + "file.xml"));
2232:
2233: }
2234:
2235: public void testBuildFromFileThatContainsCommaInName()
2236: throws ParsingException, IOException {
2237:
2238: File f = new File(inputDir, ",file.xml");
2239: try {
2240: Writer out = new OutputStreamWriter(
2241: new FileOutputStream(f), "UTF8");
2242: out.write("<data />");
2243: out.flush();
2244: out.close();
2245: Document doc = builder.build(f);
2246: String expectedResult = "<?xml version=\"1.0\"?>\n"
2247: + "<data />\n";
2248: String actual = doc.toXML();
2249: assertEquals(expectedResult, actual);
2250: assertTrue(doc.getBaseURI().startsWith("file:/"));
2251: assertTrue(doc.getBaseURI().endsWith("data/,file.xml"));
2252: } finally {
2253: if (f.exists())
2254: f.delete();
2255: }
2256:
2257: }
2258:
2259: public void testBuildFromFileThatContainsBackslashInName()
2260: throws ParsingException, IOException {
2261:
2262: String os = System.getProperty("os.name", "Unix");
2263: if (os.indexOf("Windows") >= 0)
2264: return;
2265:
2266: File f = new File(inputDir, "\\file.xml");
2267: try {
2268: Writer out = new OutputStreamWriter(
2269: new FileOutputStream(f), "UTF8");
2270: out.write("<data />");
2271: out.flush();
2272: out.close();
2273: Document doc = builder.build(f);
2274: String expectedResult = "<?xml version=\"1.0\"?>\n"
2275: + "<data />\n";
2276: String actual = doc.toXML();
2277: assertEquals(expectedResult, actual);
2278: assertTrue(doc.getBaseURI().startsWith("file:/"));
2279: assertTrue(doc.getBaseURI().endsWith("data/%5Cfile.xml"));
2280: } finally {
2281: if (f.exists())
2282: f.delete();
2283: }
2284:
2285: }
2286:
2287: public void testBuildFromFileThatContainsC0ControlCharacterInName()
2288: throws ParsingException, IOException {
2289:
2290: File f = new File(inputDir, "\u0019file.xml");
2291: try {
2292: Writer out = new OutputStreamWriter(
2293: new FileOutputStream(f), "UTF8");
2294: out.write("<data />");
2295: out.flush();
2296: out.close();
2297: Document doc = builder.build(f);
2298: String expectedResult = "<?xml version=\"1.0\"?>\n"
2299: + "<data />\n";
2300: String actual = doc.toXML();
2301: assertEquals(expectedResult, actual);
2302: assertTrue(doc.getBaseURI().startsWith("file:/"));
2303: assertTrue(doc.getBaseURI().endsWith("data/%19file.xml"));
2304: } catch (FileNotFoundException ex) {
2305: // This platform doesn't allow C0 controls in file names
2306: } finally {
2307: if (f.exists())
2308: f.delete();
2309: }
2310:
2311: }
2312:
2313: public void testBuildFromFileThatContainsTabCharacterInName()
2314: throws ParsingException, IOException {
2315:
2316: File f = new File(inputDir, "\tfile.xml");
2317: try {
2318: Writer out = new OutputStreamWriter(
2319: new FileOutputStream(f), "UTF8");
2320: out.write("<data />");
2321: out.flush();
2322: out.close();
2323: Document doc = builder.build(f);
2324: String expectedResult = "<?xml version=\"1.0\"?>\n"
2325: + "<data />\n";
2326: String actual = doc.toXML();
2327: assertEquals(expectedResult, actual);
2328: assertTrue(doc.getBaseURI().startsWith("file:/"));
2329: assertTrue(doc.getBaseURI().endsWith("data/%09file.xml"));
2330: } catch (FileNotFoundException ex) {
2331: // This platform doesn't allow tabs in file names
2332: } finally {
2333: if (f.exists())
2334: f.delete();
2335: }
2336:
2337: }
2338:
2339: public void testBuildFromFileThatContainsTildeInName()
2340: throws ParsingException, IOException {
2341:
2342: File f = new File(inputDir, "~file.xml");
2343: try {
2344: Writer out = new OutputStreamWriter(
2345: new FileOutputStream(f), "UTF8");
2346: out.write("<data />");
2347: out.flush();
2348: out.close();
2349: Document doc = builder.build(f);
2350: String expectedResult = "<?xml version=\"1.0\"?>\n"
2351: + "<data />\n";
2352: String actual = doc.toXML();
2353: assertEquals(expectedResult, actual);
2354: assertTrue(doc.getBaseURI().startsWith("file:/"));
2355: assertTrue(doc.getBaseURI().endsWith("data/~file.xml"));
2356: } finally {
2357: if (f.exists())
2358: f.delete();
2359: }
2360:
2361: }
2362:
2363: public void testBuildFromFileThatContainsAngleBracketsInName()
2364: throws ParsingException, IOException {
2365:
2366: File f = makeFile("<file>.xml");
2367: try {
2368: Document doc = builder.build(f);
2369: f.delete();
2370: String expectedResult = "<?xml version=\"1.0\"?>\n"
2371: + "<data />\n";
2372: String actual = doc.toXML();
2373: assertEquals(expectedResult, actual);
2374: assertTrue(doc.getBaseURI().startsWith("file:/"));
2375: assertTrue(doc.getBaseURI().endsWith(
2376: "data/%" + Integer.toHexString('<').toUpperCase()
2377: + "file%"
2378: + Integer.toHexString('>').toUpperCase()
2379: + ".xml"));
2380: } catch (FileNotFoundException ex) {
2381: // This platform doesn't allow < and > in file names
2382: }
2383:
2384: }
2385:
2386: public void testBuildFromFileThatContainsDollarSignInName()
2387: throws ParsingException, IOException {
2388:
2389: Document doc = builder.build(new File(inputDir, "$file.xml"));
2390: String expectedResult = "<?xml version=\"1.0\"?>\n"
2391: + "<data />\n";
2392: String actual = doc.toXML();
2393: assertEquals(expectedResult, actual);
2394: assertTrue(doc.getBaseURI().startsWith("file:/"));
2395: assertTrue(doc.getBaseURI().endsWith("data/$file.xml"));
2396:
2397: }
2398:
2399: public void testBuildFromFileThatContainsPercentSignInName()
2400: throws ParsingException, IOException {
2401:
2402: Document doc = builder.build(new File(inputDir, "%file.xml"));
2403: String expectedResult = "<?xml version=\"1.0\"?>\n"
2404: + "<data />\n";
2405: String actual = doc.toXML();
2406: assertEquals(expectedResult, actual);
2407: assertTrue(doc.getBaseURI().startsWith("file:/"));
2408: assertTrue(doc.getBaseURI().endsWith(
2409: "data/%" + Integer.toHexString('%') + "file.xml"));
2410:
2411: }
2412:
2413: public void testBuildFromFileThatContainsQuestionMarkInName()
2414: throws ParsingException, IOException {
2415:
2416: File f = makeFile("?file.xml");
2417: try {
2418: Document doc = builder.build(f);
2419: f.delete();
2420: String expectedResult = "<?xml version=\"1.0\"?>\n"
2421: + "<data />\n";
2422: String actual = doc.toXML();
2423: assertEquals(expectedResult, actual);
2424: assertTrue(doc.getBaseURI().startsWith("file:/"));
2425: assertTrue(doc.getBaseURI().endsWith(
2426: "data/%" + Integer.toHexString('?').toUpperCase()
2427: + "file.xml"));
2428: } catch (FileNotFoundException ex) {
2429: // This platform doesn't allow question marks in file names
2430: }
2431:
2432: }
2433:
2434: public void testBuildFromFileThatContainsAtSignInName()
2435: throws ParsingException, IOException {
2436:
2437: Document doc = builder.build(new File(inputDir, "@file.xml"));
2438: String expectedResult = "<?xml version=\"1.0\"?>\n"
2439: + "<data />\n";
2440: String actual = doc.toXML();
2441: assertEquals(expectedResult, actual);
2442: assertTrue(doc.getBaseURI().startsWith("file:/"));
2443: assertTrue(doc.getBaseURI().endsWith(
2444: "data/%" + Integer.toHexString('@') + "file.xml"));
2445:
2446: }
2447:
2448: public void testBuildFromFileThatContainsEqualsSignInName()
2449: throws ParsingException, IOException {
2450:
2451: Document doc = builder.build(new File(inputDir, "=file.xml"));
2452: String expectedResult = "<?xml version=\"1.0\"?>\n"
2453: + "<data />\n";
2454: String actual = doc.toXML();
2455: assertEquals(expectedResult, actual);
2456: assertTrue(doc.getBaseURI().startsWith("file:/"));
2457: assertTrue(doc.getBaseURI().endsWith("data/=file.xml"));
2458:
2459: }
2460:
2461: public void testBuildFromFileThatContainsCaretInName()
2462: throws ParsingException, IOException {
2463:
2464: Document doc = builder.build(new File(inputDir, "^file.xml"));
2465: String expectedResult = "<?xml version=\"1.0\"?>\n"
2466: + "<data />\n";
2467: String actual = doc.toXML();
2468: assertEquals(expectedResult, actual);
2469: assertTrue(doc.getBaseURI().startsWith("file:/"));
2470: assertTrue(doc.getBaseURI().endsWith(
2471: "data/%" + Integer.toHexString('^').toUpperCase()
2472: + "file.xml"));
2473:
2474: }
2475:
2476: public void testBuildFromFileThatContainsBactickInName()
2477: throws ParsingException, IOException {
2478:
2479: Document doc = builder.build(new File(inputDir, "`file.xml"));
2480: String expectedResult = "<?xml version=\"1.0\"?>\n"
2481: + "<data />\n";
2482: String actual = doc.toXML();
2483: assertEquals(expectedResult, actual);
2484: assertTrue(doc.getBaseURI().startsWith("file:/"));
2485: assertTrue(doc.getBaseURI().endsWith(
2486: "data/%" + Integer.toHexString('`') + "file.xml"));
2487:
2488: }
2489:
2490: private static class NonValidatingFilter extends XMLFilterImpl {
2491:
2492: public void setFeature(String uri, boolean value)
2493: throws SAXNotRecognizedException,
2494: SAXNotSupportedException {
2495:
2496: if ("http://xml.org/sax/features/validation".equals(uri)
2497: && value) {
2498: throw new SAXNotSupportedException("");
2499: }
2500: super .setFeature(uri, value);
2501:
2502: }
2503:
2504: public boolean getFeature(String uri)
2505: throws SAXNotRecognizedException,
2506: SAXNotSupportedException {
2507:
2508: if ("http://xml.org/sax/features/validation".equals(uri)) {
2509: return false;
2510: }
2511: return super .getFeature(uri);
2512:
2513: }
2514:
2515: }
2516:
2517: public void testNonValidatingParserException() throws SAXException {
2518:
2519: XMLReader parser = XMLReaderFactory
2520: .createXMLReader("org.apache.xerces.parsers.SAXParser");
2521: XMLFilter filter = new NonValidatingFilter();
2522: filter.setParent(parser);
2523:
2524: try {
2525: new Builder(filter, true, null);
2526: fail("Validating with a non-validating parser");
2527: } catch (XMLException success) {
2528: assertNotNull(success.getMessage());
2529: }
2530:
2531: }
2532:
2533: private static class NonEntityResolvingFilter extends XMLFilterImpl {
2534:
2535: public void setFeature(String uri, boolean value)
2536: throws SAXNotRecognizedException,
2537: SAXNotSupportedException {
2538:
2539: if (value
2540: && ("http://xml.org/sax/features/validation"
2541: .equals(uri) || "http://xml.org/sax/features/external-general-entities"
2542: .equals(uri))
2543: || "http://xml.org/sax/features/external-parameter-entities"
2544: .equals(uri)) {
2545: throw new SAXNotSupportedException("");
2546: }
2547: super .setFeature(uri, value);
2548:
2549: }
2550:
2551: public boolean getFeature(String uri)
2552: throws SAXNotRecognizedException,
2553: SAXNotSupportedException {
2554:
2555: if ("http://xml.org/sax/features/validation".equals(uri)
2556: || "http://xml.org/sax/features/external-general-entities"
2557: .equals(uri)
2558: || "http://xml.org/sax/features/external-parameter-entities"
2559: .equals(uri)) {
2560: return false;
2561: }
2562: return super .getFeature(uri);
2563:
2564: }
2565:
2566: }
2567:
2568: public void testNonEntityResolvingParserException()
2569: throws SAXException {
2570:
2571: XMLReader parser = XMLReaderFactory
2572: .createXMLReader("org.apache.xerces.parsers.SAXParser");
2573: XMLFilter filter = new NonEntityResolvingFilter();
2574: filter.setParent(parser);
2575:
2576: try {
2577: new Builder(filter, false, null);
2578: fail("Accepted a non-entity resolving parser");
2579: } catch (XMLException success) {
2580: assertNotNull(success.getMessage());
2581: }
2582:
2583: }
2584:
2585: // Fake certain errors to test workarounds for bugs in certain
2586: // parsers, especially Piccolo.
2587: private static class ExceptionTester extends XMLFilterImpl {
2588:
2589: private Exception ex;
2590:
2591: ExceptionTester(Exception ex) {
2592: this .ex = ex;
2593: }
2594:
2595: public void parse(InputSource in) throws IOException,
2596: SAXException {
2597: if (ex instanceof IOException)
2598: throw (IOException) ex;
2599: else if (ex instanceof SAXException)
2600: throw (SAXException) ex;
2601: else
2602: throw (RuntimeException) ex;
2603: }
2604:
2605: }
2606:
2607: public void testParserThrowsNullPointerException()
2608: throws SAXException, IOException {
2609:
2610: XMLReader parser = XMLReaderFactory
2611: .createXMLReader("org.apache.xerces.parsers.SAXParser");
2612: Exception cause = new NullPointerException();
2613: XMLFilter filter = new ExceptionTester(cause);
2614: filter.setParent(parser);
2615: Builder builder = new Builder(filter);
2616:
2617: try {
2618: builder.build("<data/>");
2619: } catch (ParsingException success) {
2620: assertEquals(cause, success.getCause());
2621: }
2622:
2623: }
2624:
2625: public void testParserThrowsNegativeArraySizeException()
2626: throws SAXException, IOException {
2627:
2628: XMLReader parser = XMLReaderFactory
2629: .createXMLReader("org.apache.xerces.parsers.SAXParser");
2630: Exception cause = new NegativeArraySizeException();
2631: XMLFilter filter = new ExceptionTester(cause);
2632: filter.setParent(parser);
2633: Builder builder = new Builder(filter);
2634:
2635: try {
2636: builder.build("<data/>");
2637: } catch (ParsingException success) {
2638: assertEquals(cause, success.getCause());
2639: }
2640:
2641: }
2642:
2643: public void testParserThrowsArrayIndexOutOfBoundsException()
2644: throws SAXException, IOException {
2645:
2646: XMLReader parser = XMLReaderFactory
2647: .createXMLReader("org.apache.xerces.parsers.SAXParser");
2648: Exception cause = new ArrayIndexOutOfBoundsException();
2649: XMLFilter filter = new ExceptionTester(cause);
2650: filter.setParent(parser);
2651: Builder builder = new Builder(filter);
2652:
2653: try {
2654: builder.build("<data/>");
2655: } catch (ParsingException success) {
2656: assertEquals(cause, success.getCause());
2657: }
2658:
2659: }
2660:
2661: public void testParserThrowsUTFDataFormatException()
2662: throws SAXException, IOException {
2663:
2664: XMLReader parser = XMLReaderFactory
2665: .createXMLReader("org.apache.xerces.parsers.SAXParser");
2666: Exception cause = new UTFDataFormatException();
2667: XMLFilter filter = new ExceptionTester(cause);
2668: filter.setParent(parser);
2669: Builder builder = new Builder(filter);
2670:
2671: try {
2672: builder.build("<data/>");
2673: } catch (ParsingException success) {
2674: assertEquals(cause, success.getCause());
2675: }
2676:
2677: }
2678:
2679: public void testParserThrowsCharConversionException()
2680: throws SAXException, IOException {
2681:
2682: XMLReader parser = XMLReaderFactory
2683: .createXMLReader("org.apache.xerces.parsers.SAXParser");
2684: Exception cause = new CharConversionException();
2685: XMLFilter filter = new ExceptionTester(cause);
2686: filter.setParent(parser);
2687: Builder builder = new Builder(filter);
2688:
2689: try {
2690: builder.build("<data/>");
2691: } catch (ParsingException success) {
2692: assertEquals(cause, success.getCause());
2693: }
2694:
2695: }
2696:
2697: public void testParserThrowsPlainSAXException()
2698: throws SAXException, IOException {
2699:
2700: XMLReader parser = XMLReaderFactory
2701: .createXMLReader("org.apache.xerces.parsers.SAXParser");
2702: Exception cause = new SAXException(
2703: "What happened to no-args constructor?");
2704: XMLFilter filter = new ExceptionTester(cause);
2705: filter.setParent(parser);
2706: Builder builder = new Builder(filter);
2707:
2708: try {
2709: builder.build("<data/>");
2710: } catch (ParsingException success) {
2711: assertEquals(cause, success.getCause());
2712: }
2713:
2714: }
2715:
2716: public void testParserThrowsUnexpectedRuntimeException()
2717: throws SAXException, IOException {
2718:
2719: XMLReader parser = XMLReaderFactory
2720: .createXMLReader("org.apache.xerces.parsers.SAXParser");
2721: Exception cause = new RuntimeException();
2722: XMLFilter filter = new ExceptionTester(cause);
2723: filter.setParent(parser);
2724: Builder builder = new Builder(filter);
2725:
2726: try {
2727: builder.build("<data/>");
2728: } catch (ParsingException success) {
2729: assertEquals(cause, success.getCause());
2730: }
2731:
2732: }
2733:
2734: public void testParserThrowsIOException() throws SAXException,
2735: ParsingException {
2736:
2737: XMLReader parser = XMLReaderFactory
2738: .createXMLReader("org.apache.xerces.parsers.SAXParser");
2739: Exception cause = new IOException();
2740: XMLFilter filter = new ExceptionTester(cause);
2741: filter.setParent(parser);
2742: Builder builder = new Builder(filter);
2743:
2744: try {
2745: builder.build("<data/>");
2746: } catch (IOException success) {
2747: assertEquals(cause, success);
2748: }
2749:
2750: }
2751:
2752: public void testCrimsonIgnoresWarning() throws SAXException,
2753: ParsingException, IOException {
2754:
2755: XMLReader parser;
2756: try {
2757: parser = XMLReaderFactory
2758: .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
2759: } catch (SAXException ex) {
2760: // Can't test Crimson if you can't load it
2761: return;
2762: }
2763: XMLFilter filter = new WarningFilter();
2764: filter.setParent(parser);
2765: Builder builder = new Builder(filter);
2766:
2767: Document doc = builder.build("<data/>", null);
2768: assertEquals("<?xml version=\"1.0\"?>\n<data />\n", doc.toXML());
2769:
2770: }
2771:
2772: private static class WarningFilter extends XMLFilterImpl {
2773:
2774: public void startElement(String namespaceURI, String localName,
2775: String qualifiedName, Attributes atts)
2776: throws SAXException {
2777:
2778: this .getErrorHandler()
2779: .warning(
2780: new SAXParseException("Warning",
2781: new LocatorImpl()));
2782: super .startElement(namespaceURI, localName, qualifiedName,
2783: atts);
2784:
2785: }
2786:
2787: }
2788:
2789: public void testSaxonsAElfredIsVerified() throws SAXException,
2790: IOException {
2791:
2792: XMLReader parser;
2793: try {
2794: parser = XMLReaderFactory
2795: .createXMLReader("com.icl.saxon.aelfred.SAXDriver");
2796: } catch (SAXException ex) {
2797: // Can't test SAXON if you can't load it
2798: return;
2799: }
2800: Builder builder = new Builder(parser);
2801:
2802: try {
2803: // known bug in Saxon; doesn't catch
2804: // colon in processing instruction targets
2805: builder.build("<?test:data ?><data/>", null);
2806: fail("Didn't verify Saxon's input");
2807: } catch (ParsingException success) {
2808: assertNotNull(success.getMessage());
2809: }
2810:
2811: }
2812:
2813: public void testSaxon7sAElfredIsVerified() throws SAXException,
2814: IOException {
2815:
2816: XMLReader parser;
2817: try {
2818: parser = XMLReaderFactory
2819: .createXMLReader("net.sf.saxon.aelfred.SAXDriver");
2820: } catch (SAXException ex) {
2821: // Can't test SAXON if you can't load it
2822: return;
2823: }
2824: Builder builder = new Builder(parser);
2825:
2826: try {
2827: // known bug in Saxon: doesn't catch
2828: // colon in processing instruction targets
2829: builder.build("<?test:data ?><data/>", null);
2830: fail("Didn't verify Saxon's input");
2831: } catch (ParsingException success) {
2832: assertNotNull(success.getMessage());
2833: }
2834:
2835: }
2836:
2837: public void testGNUJAXPIsVerified() throws SAXException,
2838: IOException {
2839:
2840: XMLReader parser;
2841: try {
2842: parser = XMLReaderFactory
2843: .createXMLReader("gnu.xml.aelfred2.XmlReader");
2844: } catch (SAXException ex) {
2845: // Can't test GNU JAXP if you can't load it
2846: return;
2847: }
2848: Builder builder = new Builder(parser);
2849:
2850: try {
2851: // known bug in GNUJAXP: doesn't catch
2852: // colon in processing instruction targets
2853: builder.build("<?test:data ?><data/>", null);
2854: fail("Didn't verify GNU JAXP's input");
2855: } catch (ParsingException success) {
2856: assertNotNull(success.getMessage());
2857: }
2858:
2859: }
2860:
2861: public void testCatalogOnTopOfTrustedParserIsTrusted()
2862: throws NoSuchMethodException, InstantiationException,
2863: IllegalAccessException, InvocationTargetException {
2864:
2865: try {
2866: XMLReader parser = XMLReaderFactory
2867: .createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
2868:
2869: Class filter = Class
2870: .forName("org.apache.xml.resolver.tools.ResolvingXMLFilter");
2871: Class[] types = { XMLReader.class };
2872: Constructor constructor = filter.getConstructor(types);
2873: Object[] args = { parser };
2874: XMLReader reader = (XMLReader) constructor
2875: .newInstance(args);
2876: Builder builder = new Builder(reader);
2877: // If the factory is a nonverifying factory, then
2878: // getNodeFactory() won't return it.
2879: assertNull(builder.getNodeFactory());
2880: } catch (ClassNotFoundException ex) {
2881: // Can't test if we can't find the class
2882: } catch (SAXException ex) {
2883: // Need a trusted parser to test this
2884: }
2885:
2886: }
2887:
2888: // XML conformance test case xmlconf/xmltest/valid/not-sa/014.ent
2889: // shows how this can be necessary. In brief, the internal DTD
2890: // subset can define or override parameter entities used in the
2891: // external DTD subset, and that the external DTD subset depends
2892: // on for well-formedness
2893: public void testPreserveParameterEntitiesInInternalDTDSubset()
2894: throws ParsingException, IOException {
2895:
2896: String data = "<!DOCTYPE doc [\n"
2897: + "<!ENTITY % e 'INCLUDE'>]><doc />";
2898: Document doc = builder.build(data, null);
2899: String subset = doc.getDocType().getInternalDTDSubset();
2900: assertEquals(" <!ENTITY % e \"INCLUDE\">\n", subset);
2901:
2902: }
2903:
2904: public void testTrickyCaseFromAppendixA2OfXMLSpec()
2905: throws ParsingException, IOException {
2906:
2907: String data = "<?xml version='1.0'?>\n"
2908: + "<!DOCTYPE test [\n"
2909: + "<!ELEMENT test (#PCDATA) >\n"
2910: + "<!ENTITY % xx '%zz;'>\n"
2911: + "<!ENTITY % zz '<!ENTITY tricky \"error-prone\" >' >\n"
2912: + "%xx;\n" + "]>\n"
2913: + "<test>This sample shows a &tricky; method.</test>\n";
2914:
2915: Document doc = builder.build(data, null);
2916: String s = doc.toXML();
2917: Document roundTrip = builder.build(s, null);
2918: assertEquals(doc, roundTrip);
2919:
2920: }
2921:
2922: // This is an example of case where preserving external entity
2923: // declaration in internal DTD subset is necessary to maintain
2924: // well-formedness
2925: public void testPreserveExternalGeneralEntityDeclaration()
2926: throws ParsingException, IOException {
2927:
2928: Document doc = builder.build(new File(inputDir, "ge.xml"));
2929: DocType doctype = doc.getDocType();
2930: assertEquals(" <!ENTITY ccl SYSTEM \"ge.txt\">\n", doctype
2931: .getInternalDTDSubset());
2932: }
2933:
2934: // This is an example of case where preserving external entity
2935: // declaration in internal DTD subset is necessary to maintain
2936: // validity
2937: public void testPreserveExternalParameterEntityDeclaration()
2938: throws ParsingException, IOException {
2939:
2940: Document doc = builder.build(new File(inputDir, "pe.xml"));
2941: DocType doctype = doc.getDocType();
2942: assertEquals(" <!ENTITY % ccl SYSTEM \"pe.txt\">\n", doctype
2943: .getInternalDTDSubset());
2944: }
2945:
2946: public void testNMTOKENSNormalizationOfCarriageReturnLineFeedEntityReferences()
2947: throws ParsingException, IOException {
2948:
2949: String data = "<!DOCTYPE attributes [\n"
2950: + "<!ATTLIST attributes nmtokens NMTOKENS #IMPLIED>]>\n"
2951: + "<attributes nmtokens = \" this
 also gets  normalized \" />";
2952:
2953: Document doc = builder.build(data, null);
2954: String s = doc.toXML();
2955: Document roundTrip = builder.build(s, null);
2956: assertEquals(doc, roundTrip);
2957:
2958: }
2959:
2960: public void testXMLConformanceTestSuiteDocuments()
2961: throws ParsingException, IOException {
2962:
2963: File data = new File("data");
2964: File canonical = new File(data, "canonical");
2965: File masterList = new File(canonical, "xmlconf");
2966: masterList = new File(masterList, "xmlconf.xml");
2967: if (masterList.exists()) {
2968: Document xmlconf = builder.build(masterList);
2969: Elements testcases = xmlconf.getRootElement()
2970: .getChildElements("TESTCASES");
2971: processTestCases(testcases);
2972: }
2973:
2974: }
2975:
2976: // xmlconf/xmltest/valid/sa/097.xml appears to be screwed up by a lot
2977: // of parsers
2978: private void processTestCases(Elements testcases)
2979: throws ParsingException, IOException {
2980:
2981: for (int i = 0; i < testcases.size(); i++) {
2982: Element testcase = testcases.get(i);
2983: Elements tests = testcase.getChildElements("TEST");
2984: processTests(tests);
2985: Elements level2 = testcase.getChildElements("TESTCASES");
2986: // need to be recursive to handle recursive IBM test cases
2987: processTestCases(level2);
2988: }
2989:
2990: }
2991:
2992: private void processTests(Elements tests) throws ParsingException,
2993: IOException {
2994:
2995: Element parent = new Element("e");
2996: Element child = new Element("a");
2997: parent.appendChild(child);
2998:
2999: int size = tests.size();
3000: for (int i = 0; i < size; i++) {
3001: Element test = tests.get(i);
3002: String namespace = test.getAttributeValue("NAMESPACE");
3003: if ("no".equals(namespace))
3004: continue;
3005: String type = test.getAttributeValue("TYPE");
3006: if ("not-wf".equals(type))
3007: continue;
3008: String uri = test.getAttributeValue("URI");
3009: String base = test.getBaseURI();
3010: // Hack because URIUtil isn't public; and I don't want to
3011: // depend on 1.4 only java.net.URI
3012: parent.setBaseURI(base);
3013: child.addAttribute(new Attribute("xml:base",
3014: "http://www.w3.org/XML/1998/namespace", uri));
3015: String resolvedURI = child.getBaseURI();
3016:
3017: Document doc = builder.build(resolvedURI);
3018: ByteArrayOutputStream out = new ByteArrayOutputStream();
3019: try {
3020: Serializer serializer = new Serializer(out);
3021: serializer.write(doc);
3022: } finally {
3023: out.close();
3024: }
3025: byte[] actual = out.toByteArray();
3026:
3027: InputStream in = new ByteArrayInputStream(actual);
3028: try {
3029: Document roundTrip = builder.build(in, resolvedURI);
3030: assertEquals("Failed to roundtrip " + uri, doc,
3031: roundTrip);
3032: } catch (ParsingException ex) {
3033: System.out.println(ex.getURI());
3034: System.out.println(doc.toXML());
3035: throw ex;
3036: } finally {
3037: in.close();
3038: }
3039: }
3040:
3041: }
3042:
3043: }
|