1 /* Copyright 2002-2005, 2011, 2018 Elliotte Rusty Harold
2 
3    This library is free software; you can redistribute it and/or modify
4    it under the terms of version 2.1 of the GNU Lesser General Public
5    License as published by the Free Software Foundation.
6 
7    This library is distributed in the hope that it will be useful,
8    but WITHOUT ANY WARRANTY; without even the implied warranty of
9    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10    GNU Lesser General Public License for more details.
11 
12    You should have received a copy of the GNU Lesser General Public
13    License along with this library; if not, write to the
14    Free Software Foundation, Inc., 59 Temple Place, Suite 330,
15    Boston, MA 02111-1307  USA
16 
17    You can contact Elliotte Rusty Harold by sending e-mail to
18    elharo@ibiblio.org. Please include the word "XOM" in the
19    subject line. The XOM home page is located at http://www.xom.nu/
20 */
21 
22 package nu.xom.tests;
23 
24 import java.io.ByteArrayOutputStream;
25 import java.io.File;
26 import java.io.FileNotFoundException;
27 import java.io.FileOutputStream;
28 import java.io.IOException;
29 import java.io.OutputStreamWriter;
30 import java.io.PrintStream;
31 import java.io.Reader;
32 import java.io.StringReader;
33 import java.io.Writer;
34 import java.net.URI;
35 import java.net.URISyntaxException;
36 
37 import nu.xom.Attribute;
38 import nu.xom.Builder;
39 import nu.xom.Comment;
40 import nu.xom.Document;
41 import nu.xom.Element;
42 import nu.xom.Namespace;
43 import nu.xom.Node;
44 import nu.xom.NodeFactory;
45 import nu.xom.Nodes;
46 import nu.xom.ParsingException;
47 import nu.xom.Serializer;
48 import nu.xom.Text;
49 import nu.xom.xinclude.BadEncodingAttributeException;
50 import nu.xom.xinclude.BadHTTPHeaderException;
51 import nu.xom.xinclude.BadHrefAttributeException;
52 import nu.xom.xinclude.BadParseAttributeException;
53 import nu.xom.xinclude.InclusionLoopException;
54 import nu.xom.xinclude.NoIncludeLocationException;
55 import nu.xom.xinclude.XIncludeException;
56 import nu.xom.xinclude.XIncluder;
57 
58 /**
59  * <p>
60  * Unit tests for the XInclude and XPointer engines.
61  * </p>
62  *
63  * @author Elliotte Rusty Harold
64  * @version 1.2.11
65  *
66  */
67 public class XIncludeTest extends XOMTestCase {
68 
69     private static boolean windows
70       = System.getProperty("os.name", "Unix").indexOf("Windows") >= 0;
71 
72 
XIncludeTest(String name)73     public XIncludeTest(String name) {
74         super(name);
75     }
76 
77 
78     private Builder builder = new Builder();
79     private File inputDir;
80     private File outputDir;
81 
82     // This class tests error conditions, which Xerces
83     // annoyingly logs to System.err. This hides System.err
84     // before each test and restores it after each test.
85     private PrintStream systemErr = System.err;
86 
87 
setUp()88     protected void setUp() {
89 
90         System.setErr(new PrintStream(new ByteArrayOutputStream()));
91 
92         inputDir = new File("data");
93         inputDir = new File(inputDir, "xinclude");
94         inputDir = new File(inputDir, "input");
95 
96         outputDir = new File("data");
97         outputDir = new File(outputDir, "xinclude");
98         outputDir = new File(outputDir, "output");
99 
100     }
101 
102 
tearDown()103     protected void tearDown() {
104         System.setErr(systemErr);
105     }
106 
107 
dumpResult(File original, Document result)108     private void dumpResult(File original, Document result)
109       throws IOException {
110 
111         String name = original.getName();
112         File debug = new File("data");
113         debug = new File(debug, "xinclude");
114         debug = new File(debug, "debug");
115         File output = new File(debug, name);
116         FileOutputStream out = new FileOutputStream(output);
117         Serializer serializer = new Serializer(out);
118         serializer.write(result);
119 
120     }
121 
122 
testXPointersResolvedAgainstAcquiredInfoset()123     public void testXPointersResolvedAgainstAcquiredInfoset()
124       throws ParsingException, IOException, XIncludeException {
125 
126         File input = new File(inputDir, "tobintop.xml");
127         Document doc = builder.build(input);
128         Document result = XIncluder.resolve(doc);
129         Document expected = builder.build(
130           new File(outputDir, "tobintop.xml")
131         );
132         assertEquals(expected, result);
133 
134     }
135 
136 
testXMLBaseUsedToResolveHref()137     public void testXMLBaseUsedToResolveHref()
138       throws ParsingException, IOException, XIncludeException {
139 
140         File input = new File(inputDir, "xmlbasetest.xml");
141         Document doc = builder.build(input);
142         Document result = XIncluder.resolve(doc);
143         Document expected = builder.build(
144           new File(outputDir, "xmlbasetest.xml")
145         );
146         assertEquals(expected, result);
147 
148     }
149 
150 
151     // Tests that use XPointer to
152     // grab a part of the document that contains an include element
153     // and make sure that's fully resolved too
testResolveThroughXPointer()154     public void testResolveThroughXPointer()
155       throws ParsingException, IOException, XIncludeException {
156 
157         File input = new File(inputDir, "resolvethruxpointer.xml");
158         Document doc = builder.build(input);
159         Document result = XIncluder.resolve(doc);
160         Document expectedResult = builder.build(
161           new File(outputDir, "resolvethruxpointer.xml")
162         );
163         assertEquals(expectedResult, result);
164 
165     }
166 
167 
testXMLBaseOnIncludeElementUsedToResolveHref()168     public void testXMLBaseOnIncludeElementUsedToResolveHref()
169       throws ParsingException, IOException, XIncludeException {
170 
171         File input = new File(inputDir, "xmlbasetest2.xml");
172         Document doc = builder.build(input);
173         Document result = XIncluder.resolve(doc);
174         Document expected = builder.build(
175           new File(outputDir, "xmlbasetest2.xml")
176         );
177         assertEquals(expected, result);
178 
179     }
180 
181 
testXMLBaseRetainedFromUnincludedElement()182     public void testXMLBaseRetainedFromUnincludedElement()
183       throws ParsingException, IOException, XIncludeException {
184 
185         File input = new File(inputDir, "xmlbasetest3.xml");
186         Document doc = builder.build(input);
187         Document result = XIncluder.resolve(doc);
188         Document expected = builder.build(
189           new File(outputDir, "xmlbasetest3.xml")
190         );
191         assertEquals(expected, result);
192 
193     }
194 
195 
testMarsh()196     public void testMarsh()
197       throws ParsingException, IOException, XIncludeException {
198 
199         File input = new File(inputDir, "marshtest.xml");
200         Document doc = builder.build(input);
201         Document result = XIncluder.resolve(doc);
202         Document expectedResult = builder.build(
203           new File(outputDir, "marshtest.xml")
204         );
205         assertEquals(expectedResult, result);
206 
207     }
208 
209 
testIncludeDocumentThatUsesIntradocumentReferences()210     public void testIncludeDocumentThatUsesIntradocumentReferences()
211       throws ParsingException, IOException, XIncludeException {
212 
213         File input = new File(inputDir, "includedocumentwithintradocumentreferences.xml");
214         Document doc = builder.build(input);
215         Document result = XIncluder.resolve(doc);
216         Document expectedResult = builder.build(
217           new File(outputDir, "includedocumentwithintradocumentreferences.xml")
218         );
219         assertEquals(expectedResult, result);
220 
221     }
222 
223 
testXMLLangAttributes()224     public void testXMLLangAttributes()
225       throws ParsingException, IOException, XIncludeException {
226 
227         File input = new File(inputDir, "langtest1.xml");
228         Document doc = builder.build(input);
229         Document result = XIncluder.resolve(doc);
230         Document expectedResult = builder.build(
231           new File(outputDir, "langtest1.xml")
232         );
233         assertEquals(expectedResult, result);
234 
235     }
236 
237 
testInheritedXMLLangAttributes()238     public void testInheritedXMLLangAttributes()
239       throws ParsingException, IOException, XIncludeException {
240 
241         File input = new File(inputDir, "langtest2.xml");
242         Document doc = builder.build(input);
243         Document result = XIncluder.resolve(doc);
244         Document expectedResult = builder.build(
245           new File(outputDir, "langtest2.xml")
246         );
247         assertEquals(expectedResult, result);
248 
249     }
250 
251 
testNoLanguageSpecified()252     public void testNoLanguageSpecified()
253       throws ParsingException, IOException, XIncludeException {
254 
255         File input = new File(inputDir, "langtest3.xml");
256         Document doc = builder.build(input);
257         Document result = XIncluder.resolve(doc);
258         Document expectedResult = builder.build(
259           new File(outputDir, "langtest3.xml")
260         );
261         assertEquals(expectedResult, result);
262 
263     }
264 
265 
266     // According to RFC 2396 empty string URI always refers to the
267     // current document irrespective of base URI
testXMLBaseNotUsedToResolveMissingHref()268     public void testXMLBaseNotUsedToResolveMissingHref()
269       throws ParsingException, IOException, XIncludeException {
270 
271         File input = new File(inputDir, "marshtestwithxmlbase.xml");
272         Document doc = builder.build(input);
273         Document result = XIncluder.resolve(doc);
274         Document expectedResult = builder.build(
275           new File(outputDir, "marshtestwithxmlbase.xml")
276         );
277         assertEquals(expectedResult, result);
278 
279     }
280 
281 
testEmptyHrefTreatedSameAsMissingHref()282     public void testEmptyHrefTreatedSameAsMissingHref()
283       throws ParsingException, IOException, XIncludeException {
284 
285         File input = new File(inputDir, "marshtestwithxmlbaseandemptyhref.xml");
286         Document doc = builder.build(input);
287         Document result = XIncluder.resolve(doc);
288         Document expectedResult = builder.build(
289           new File(outputDir, "marshtestwithxmlbase.xml")
290         );
291         assertEquals(expectedResult, result);
292 
293     }
294 
295 
testBaselessDocument()296     public void testBaselessDocument()
297       throws IOException, ParsingException, XIncludeException {
298 
299         Element root = new Element("root");
300         Element child1 = new Element("xi:include", XIncluder.XINCLUDE_NS);
301         child1.addAttribute(new Attribute("xpointer", "p1"));
302         Element child2 = new Element("child2");
303         root.appendChild(child1);
304         root.appendChild(child2);
305         child2.addAttribute(new Attribute("id", "p1", Attribute.Type.ID));
306         Document in = new Document(root);
307         Document out = XIncluder.resolve(in);
308         String result = out.toXML();
309         assertEquals("<?xml version=\"1.0\"?>\n" +
310            "<root><child2 id=\"p1\" /><child2 id=\"p1\" /></root>\n", result);
311 
312     }
313 
314 
testRelativeURLInBaselessDocument()315     public void testRelativeURLInBaselessDocument()
316       throws IOException, ParsingException, XIncludeException {
317 
318         Element root = new Element("root");
319         Element child1 = new Element("xi:include", XIncluder.XINCLUDE_NS);
320         child1.addAttribute(new Attribute("href", "test.xml"));
321         Element child2 = new Element("child2");
322         root.appendChild(child1);
323         root.appendChild(child2);
324         Document in = new Document(root);
325         try {
326             XIncluder.resolve(in);
327             fail("Resolved relative URI in baseless document");
328         }
329         catch (BadHrefAttributeException success) {
330             assertEquals(
331               "Could not resolve relative URI test.xml because the "
332               + "xi:include element does not have a base URI.",
333               success.getMessage());
334         }
335 
336     }
337 
338 
testIncludeTextWithCustomNodeFactory()339     public void testIncludeTextWithCustomNodeFactory()
340       throws ParsingException, IOException, XIncludeException {
341 
342         File input = new File(inputDir, "c2.xml");
343         Builder builder = new Builder(new TextNodeFactory());
344         Document doc = builder.build(input);
345         Document result = XIncluder.resolve(doc, builder);
346         Document expectedResult = builder.build(
347           new File(outputDir, "c2.xml")
348         );
349         assertEquals(expectedResult, result);
350         Element root = result.getRootElement();
351         for (int i = 0; i < root.getChildCount(); i++) {
352             Node node = root.getChild(i);
353             if (node instanceof Text) {
354                 assertTrue(node instanceof TextSubclass);
355             }
356         }
357 
358     }
359 
360 
testParseEqualsTextWithNodeFactoryThatRemovesAllTextNodes()361     public void testParseEqualsTextWithNodeFactoryThatRemovesAllTextNodes()
362       throws ParsingException, IOException, XIncludeException {
363 
364         File input = new File(inputDir, "c2.xml");
365         Document doc = builder.build(input);
366         Document result = XIncluder.resolve(doc, new Builder(new TextFilter()));
367         Document expectedResult = builder.build(
368           new File(outputDir, "c2a.xml")
369         );
370         assertEquals(expectedResult, result);
371 
372     }
373 
374 
375     private static class TextFilter extends NodeFactory {
376 
makeText(String data)377         public Nodes makeText(String data) {
378             return new Nodes();
379         }
380 
381     }
382 
383 
testParseEqualsTextWithNodeFactoryThatReplacesTextNodesWithComments()384     public void testParseEqualsTextWithNodeFactoryThatReplacesTextNodesWithComments()
385       throws ParsingException, IOException, XIncludeException {
386 
387         File input = new File(inputDir, "c2.xml");
388         Document doc = builder.build(input);
389         Document result = XIncluder.resolve(doc, new Builder(new TextToComment()));
390         Document expectedResult = builder.build(
391           new File(outputDir, "c2b.xml")
392         );
393         assertEquals(expectedResult, result);
394 
395     }
396 
397 
398     private static class TextToComment extends NodeFactory {
399 
makeText(String data)400         public Nodes makeText(String data) {
401             return new Nodes(new Comment(data));
402         }
403 
404     }
405 
406 
testParseEqualsTextWithNodeFactoryThatReplacesTextNodesWithAttributes()407     public void testParseEqualsTextWithNodeFactoryThatReplacesTextNodesWithAttributes()
408       throws ParsingException, IOException, XIncludeException {
409 
410         File input = new File(inputDir, "c2.xml");
411         Document doc = builder.build(input);
412         Document result = XIncluder.resolve(doc, new Builder(new TextToAttribute()));
413         Document expectedResult = builder.build(
414           new File(outputDir, "c2c.xml")
415         );
416         assertEquals(expectedResult, result);
417 
418     }
419 
420 
testParseEqualsTextWithNodeFactoryThatReplacesTextNodesWithTwoElements()421     public void testParseEqualsTextWithNodeFactoryThatReplacesTextNodesWithTwoElements()
422       throws ParsingException, IOException, XIncludeException {
423 
424         File input = new File(inputDir, "c2.xml");
425         Document doc = builder.build(input);
426         Document result = XIncluder.resolve(doc, new Builder(new TextToElements()));
427         Document expectedResult = builder.build(
428           new File(outputDir, "c2d.xml")
429         );
430         assertEquals(expectedResult, result);
431 
432     }
433 
434 
435     private static class TextToElements extends NodeFactory {
436 
makeText(String data)437         public Nodes makeText(String data) {
438             Nodes result = new Nodes();
439             result.append(new Element("empty1"));
440             result.append(new Element("empty2"));
441             return result;
442         }
443 
444     }
445 
446 
447     private static class TextToAttribute extends NodeFactory {
448 
makeText(String data)449         public Nodes makeText(String data) {
450             return new Nodes(new Attribute("name", data));
451         }
452 
453     }
454 
455 
testUnrecognizedXPointerScheme()456     public void testUnrecognizedXPointerScheme()
457       throws ParsingException, IOException {
458 
459         File input = new File(inputDir, "unrecognizedscheme.xml");
460         Document doc = builder.build(input);
461         try {
462             XIncluder.resolve(doc);
463             fail("Allowed unrecognized scheme");
464         }
465         catch (XIncludeException success) {
466             assertNotNull(success.getMessage());
467         }
468 
469     }
470 
471 
testUnrecognizedXPointerSchemeWithFallback()472     public void testUnrecognizedXPointerSchemeWithFallback()
473       throws IOException, ParsingException, XIncludeException {
474 
475         File input = new File(inputDir, "unrecognizedschemewithfallback.xml");
476         File output = new File(outputDir, "unrecognizedschemewithfallback.xml");
477         Document doc = builder.build(input);
478         Document actual = XIncluder.resolve(doc);
479         Document expected = builder.build(output);
480         assertEquals(expected, actual);
481 
482     }
483 
484 
testIncludeTextWithCustomNodeFactoryThatChangesElementNames()485     public void testIncludeTextWithCustomNodeFactoryThatChangesElementNames()
486       throws ParsingException, IOException, XIncludeException {
487 
488         File input = new File(inputDir, "c1.xml");
489         Document doc = builder.build(input);
490         Document result = XIncluder.resolve(doc, new Builder(new NodeFactoryTest.CFactory()));
491         Document expectedResult = builder.build(
492           new File(outputDir, "c1a.xml")
493         );
494         assertEquals(expectedResult, result);
495 
496     }
497 
498 
testIncludeTextWithCustomNodeFactoryThatOnlyReturnsRoot()499     public void testIncludeTextWithCustomNodeFactoryThatOnlyReturnsRoot()
500       throws ParsingException, IOException, XIncludeException {
501 
502         File input = new File(inputDir, "c1.xml");
503         Document doc = builder.build(input);
504         Document result = XIncluder.resolve(doc, new Builder(new NodeFactoryTest.MinimizingFactory()));
505         Document expectedResult = builder.build(
506           new File(outputDir, "c1b.xml")
507         );
508         assertEquals(expectedResult, result);
509 
510     }
511 
512 
testIncludeTextWithCustomNodeFactoryThatFiltersElementsNamedB()513     public void testIncludeTextWithCustomNodeFactoryThatFiltersElementsNamedB()
514       throws ParsingException, IOException, XIncludeException {
515 
516         File input = new File(inputDir, "d1.xml");
517         Document doc = builder.build(input);
518         Document result = XIncluder.resolve(doc, new Builder(new NodeFactoryTest.BFilter()));
519         Document expectedResult = builder.build(
520           new File(outputDir, "d1.xml")
521         );
522         assertEquals(expectedResult, result);
523 
524     }
525 
526 
testIncludeTextWithCustomNodeFactoryThatReturnsEachNonRootElementThreeTimes()527     public void testIncludeTextWithCustomNodeFactoryThatReturnsEachNonRootElementThreeTimes()
528       throws ParsingException, IOException, XIncludeException {
529 
530         File input = new File(inputDir, "c1.xml");
531         Document doc = builder.build(input);
532         Document result = XIncluder.resolve(doc,
533           new Builder(new NodeFactoryTest.TripleElementFilter()));
534         Document expectedResult = builder.build(
535           new File(outputDir, "triple.xml")
536         );
537         assertEquals(expectedResult, result);
538 
539     }
540 
541 
test1()542     public void test1()
543       throws ParsingException, IOException, XIncludeException {
544 
545         File input = new File(inputDir, "test.xml");
546         Document doc = builder.build(input);
547         Document result = XIncluder.resolve(doc);
548         Document expectedResult = builder.build(
549           new File(outputDir, "test.xml")
550         );
551         assertEquals(expectedResult, result);
552 
553     }
554 
555 
testBaseURIsPreservedInSameDocumentInclusion()556     public void testBaseURIsPreservedInSameDocumentInclusion()
557       throws ParsingException, IOException, XIncludeException {
558 
559         File input = new File(inputDir, "includefromsamedocumentwithbase.xml");
560         Document doc = builder.build(input);
561         Document result = XIncluder.resolve(doc);
562         Document expectedResult = builder.build(
563           new File(outputDir, "includefromsamedocumentwithbase.xml")
564         );
565         assertEquals(expectedResult, result);
566 
567     }
568 
569 
testBaseURIsPreservedInResultDocument()570     public void testBaseURIsPreservedInResultDocument()
571       throws ParsingException, IOException, XIncludeException {
572 
573         Document doc = new Document(new Element("root"));
574         doc.setBaseURI("http://www.example.org/");
575         Document result = XIncluder.resolve(doc);
576         assertEquals("http://www.example.org/", result.getBaseURI());
577 
578     }
579 
580 
581     /* public void testResolveNodes()
582       throws IOException, ParsingException, XIncludeException {
583         File dir = new File(inputDir, "");
584         Element include = new Element("xi:include", XIncluder.XINCLUDE_NS);
585         include.setBaseURI(dir.toURL().toExternalForm());
586         include.addAttribute(new Attribute("href", "disclaimer.xml"));
587         Nodes in = new Nodes(include);
588         Nodes out = XIncluder.resolve(in);
589         assertEquals(1, out.size());
590         Element result = (Element) out.get(0);
591         assertEquals("disclaimer",result.getQualifiedName());
592     } */
593 
594 
testNullBaseURI()595     public void testNullBaseURI()
596       throws ParsingException, IOException, XIncludeException {
597 
598         File input = new File(inputDir, "disclaimer.xml");
599         String data = "<document xmlns:xi='http://www.w3.org/2001/XInclude'>"
600           + "\n  <p>120 Mz is adequate for an average home user.</p>"
601           + "\n  <xi:include href='" + input.toURI() + "'/>\n</document>";
602         Reader reader = new StringReader(data);
603         Document doc = builder.build(reader);
604         Document result = XIncluder.resolve(doc);
605         Document expectedResult = builder.build(
606           new File(outputDir, "c1.xml")
607         );
608         assertEquals(expectedResult, result);
609 
610     }
611 
612 
testBadIRIIsAFatalError()613     public void testBadIRIIsAFatalError()
614       throws IOException, ParsingException, XIncludeException {
615 
616         String data = "<document xmlns:xi='http://www.w3.org/2001/XInclude'>"
617           + "<xi:include href='http://www.example.com/a%5.html'>"
618           + "<xi:fallback>Ooops!</xi:fallback></xi:include></document>";
619         Reader reader = new StringReader(data);
620         Document doc = builder.build(reader);
621         try {
622             XIncluder.resolve(doc);
623             fail("Resolved fallback when encountering a syntactically incorrect URI");
624         }
625         catch (BadHrefAttributeException success) {
626             assertNotNull(success.getMessage());
627         }
628 
629     }
630 
631 
testBadIRIWithUnrecognizedSchemeIsAFatalError()632     public void testBadIRIWithUnrecognizedSchemeIsAFatalError()
633       throws IOException, ParsingException, XIncludeException {
634 
635         String data = "<doc xmlns:xi='http://www.w3.org/2001/XInclude'>"
636           + "<xi:include href='scheme://www.example.com/a%5.html'>"
637           + "<xi:fallback>Ooops!</xi:fallback></xi:include></doc>";
638         Reader reader = new StringReader(data);
639         Document doc = builder.build(reader);
640         try {
641             XIncluder.resolve(doc);
642             fail("Resolved fallback when encountering a syntactically incorrect URI");
643         }
644         catch (BadHrefAttributeException success) {
645             assertNotNull(success.getMessage());
646         }
647 
648     }
649 
650 
testGoodIRIWithUnrecognizedSchemeIsAResourceError()651     public void testGoodIRIWithUnrecognizedSchemeIsAResourceError()
652       throws IOException, ParsingException, XIncludeException {
653 
654         String data = "<document xmlns:xi='http://www.w3.org/2001/XInclude'>"
655           + "<xi:include href='scheme://www.example.com/a.html'>"
656           + "<xi:fallback>Correct!</xi:fallback></xi:include></document>";
657         Reader reader = new StringReader(data);
658         Document doc = builder.build(reader);
659         Document result = XIncluder.resolve(doc);
660         assertEquals("<?xml version=\"1.0\"?>\n"
661           + "<document xmlns:xi=\"http://www.w3.org/2001/XInclude\">Correct!</document>\n",
662           result.toXML());
663 
664     }
665 
666 
testBadAcceptAttribute()667     public void testBadAcceptAttribute()
668       throws ParsingException, IOException, XIncludeException {
669 
670         String data = "<document xmlns:xi='http://www.w3.org/2001/XInclude'>"
671           + "\n  <p>120 MHz is adequate for an average home user.</p>"
672           + "\n  <xi:include href='http://www.example.com' "
673           + "accept='text/html&#x0D;&#x0A;Something: bad'/>\n</document>";
674         Reader reader = new StringReader(data);
675         Document doc = builder.build(reader);
676         try {
677             XIncluder.resolve(doc);
678             fail("Allowed accept header containing carriage return linefeed");
679         }
680         catch (BadHTTPHeaderException success) {
681             assertNotNull(success.getMessage());
682         }
683 
684     }
685 
686 
testBadAcceptAttributeWithLatin1Character()687     public void testBadAcceptAttributeWithLatin1Character()
688       throws ParsingException, IOException, XIncludeException {
689 
690         String data = "<document xmlns:xi='http://www.w3.org/2001/XInclude'>"
691           + "\n  <p>120 MHz is adequate for an average home user.</p>"
692           + "\n  <xi:include href='http://www.example.com' "
693           + "accept='text/html&#xA0;Something: bad'/>\n</document>";
694         Reader reader = new StringReader(data);
695         Document doc = builder.build(reader);
696         try {
697             XIncluder.resolve(doc);
698             fail("Allowed accept header containing non-ASCII character");
699         }
700         catch (BadHTTPHeaderException success) {
701             assertNotNull(success.getMessage());
702         }
703 
704     }
705 
706 
testUnrecognizedAttributesAreIgnored()707     public void testUnrecognizedAttributesAreIgnored()
708       throws ParsingException, IOException, XIncludeException {
709 
710         File input = new File(inputDir, "extraattributes.xml");
711         Document doc = builder.build(input);
712         Document result = XIncluder.resolve(doc);
713         Document expectedResult = builder.build(
714           new File(outputDir, "c1.xml")
715         );
716         assertEquals(expectedResult, result);
717 
718     }
719 
720 
testEmptyFallback()721     public void testEmptyFallback()
722       throws ParsingException, IOException, XIncludeException {
723 
724         File input = new File(inputDir, "emptyfallback.xml");
725         Document doc = builder.build(input);
726         Document result = XIncluder.resolve(doc);
727         Document expectedResult = builder.build(
728           new File(outputDir, "emptyfallback.xml")
729         );
730         assertEquals(expectedResult, result);
731 
732     }
733 
734 
testFallbackInIncludedDocument()735     public void testFallbackInIncludedDocument()
736       throws ParsingException, IOException, XIncludeException {
737 
738         File input = new File(inputDir, "metafallbacktest.xml");
739         Document doc = builder.build(input);
740         Document result = XIncluder.resolve(doc);
741         Document expectedResult = builder.build(
742           new File(outputDir, "metafallbacktest.xml")
743         );
744         assertEquals(expectedResult, result);
745 
746     }
747 
748 
testFallbackInIncludedDocumentUsesAnIntradocumentXPointer()749     public void testFallbackInIncludedDocumentUsesAnIntradocumentXPointer()
750       throws ParsingException, IOException, XIncludeException {
751 
752         File input = new File(inputDir, "metafallbacktest6.xml");
753         Document doc = builder.build(input);
754         Document result = XIncluder.resolve(doc);
755         Document expectedResult = builder.build(
756           new File(outputDir, "metafallbacktest6.xml")
757         );
758         assertEquals(expectedResult, result);
759 
760     }
761 
762 
763     // changed for b5
testFallbackInIncludedDocumentIncludesADocumentWithParseEqualsText()764     public void testFallbackInIncludedDocumentIncludesADocumentWithParseEqualsText()
765       throws ParsingException, IOException, XIncludeException {
766 
767         File input = new File(inputDir, "metafallbacktest2.xml");
768         Document doc = builder.build(input);
769         Document result = XIncluder.resolve(doc);
770         Document expectedResult = builder.build(
771           new File(outputDir, "metafallbacktest2.xml")
772         );
773         assertEquals(expectedResult, result);
774 
775     }
776 
777 
testFallbackInIncludedDocumentWithBadParseAttribute()778     public void testFallbackInIncludedDocumentWithBadParseAttribute()
779       throws ParsingException, IOException, XIncludeException {
780 
781         File input = new File(inputDir, "metafallbacktest3.xml");
782         Document doc = builder.build(input);
783         try {
784             XIncluder.resolve(doc);
785             fail("Allowed bad parse attribute");
786         }
787         catch (BadParseAttributeException success) {
788             assertNotNull(success.getMessage());
789         }
790 
791     }
792 
793 
testFallbackInIncludedDocumentWithMissingHrefAndParseAttributes()794     public void testFallbackInIncludedDocumentWithMissingHrefAndParseAttributes()
795       throws ParsingException, IOException, XIncludeException {
796 
797         File input = new File(inputDir, "metafallbacktest4.xml");
798         Document doc = builder.build(input);
799         try {
800             XIncluder.resolve(doc);
801             fail("Allowed bad parse attribute");
802         }
803         catch (NoIncludeLocationException success) {
804             assertNotNull(success.getMessage());
805         }
806 
807     }
808 
809 
testFallbackInIncludedDocumentWithFragmentID()810     public void testFallbackInIncludedDocumentWithFragmentID()
811       throws ParsingException, IOException, XIncludeException {
812 
813         File input = new File(inputDir, "metafallbacktestwithfragmentid.xml");
814         Document doc = builder.build(input);
815         try {
816             XIncluder.resolve(doc);
817             fail("Allowed document with fragment ID in href attribute");
818         }
819         catch (BadHrefAttributeException success) {
820             assertNotNull(success.getMessage());
821         }
822 
823     }
824 
825 
826     // changed in b5
testXPointerIsNotResolvedAgainstTheSourceInfoset()827     public void testXPointerIsNotResolvedAgainstTheSourceInfoset()
828       throws ParsingException, IOException, XIncludeException {
829 
830         File input = new File(inputDir, "metafallbacktest5.xml");
831         Document doc = builder.build(input);
832         try {
833             XIncluder.resolve(doc);
834             fail("Allowed XPointer that doesn't resolve against the acquired infoset but does resolve against the source infoset");
835         }
836         catch (XIncludeException ex) {
837             assertNotNull(ex.getMessage());
838         }
839 
840     }
841 
842 
testFallbackInIncludedDocumentThatResolvesToNonElement()843     public void testFallbackInIncludedDocumentThatResolvesToNonElement()
844       throws ParsingException, IOException, XIncludeException {
845 
846         File input = new File(inputDir, "metafallbacktotexttest.xml");
847         Document doc = builder.build(input);
848         Document result = XIncluder.resolve(doc);
849         Document expectedResult = builder.build(
850           new File(outputDir, "metafallbacktotexttest.xml")
851         );
852         assertEquals(expectedResult, result);
853 
854     }
855 
856 
testFallbackInIncludedDocumentWithXPointer()857     public void testFallbackInIncludedDocumentWithXPointer()
858       throws ParsingException, IOException, XIncludeException {
859         // This test case activates processFallbackSilently
860         File input = new File(inputDir, "metafallbacktestwithxpointer.xml");
861         Document doc = builder.build(input);
862         Document result = XIncluder.resolve(doc);
863         Document expectedResult = builder.build(
864           new File(outputDir, "metafallbacktestwithxpointer.xml")
865         );
866         assertEquals(expectedResult, result);
867 
868     }
869 
870 
871     // changed in b5
872     // test case where fallback falls back to text and comments rather than
873     // an element
testFallbackInIncludedDocumentWithXPointer2()874     public void testFallbackInIncludedDocumentWithXPointer2()
875       throws ParsingException, IOException, XIncludeException {
876 
877         // This test case activates processFallbackSilently
878         File input = new File(inputDir, "metafallbacktestwithxpointer2.xml");
879         Document doc = builder.build(input);
880         Document result = XIncluder.resolve(doc);
881         Document expectedResult = builder.build(
882           new File(outputDir, "metafallbacktestwithxpointer2.xml")
883         );
884         assertEquals(expectedResult, result);
885 
886     }
887 
888 
testNoFallbackInIncludedDocumentWithXPointer()889     public void testNoFallbackInIncludedDocumentWithXPointer()
890       throws ParsingException, IOException, XIncludeException {
891 
892         // This test case activates processFallbackSilently
893         File input = new File(inputDir, "metamissingfallbacktestwithxpointer.xml");
894         Document doc = builder.build(input);
895         try {
896             XIncluder.resolve(doc);
897             fail("Should have thrown IOException");
898         }
899         catch (IOException success) {
900             assertNotNull(success.getMessage());
901         }
902 
903     }
904 
905 
testFallbackInIncludedDocumentHasBadXPointer()906     public void testFallbackInIncludedDocumentHasBadXPointer()
907       throws ParsingException, IOException, XIncludeException {
908         // This test case activates processFallbackSilently
909         File input = new File(inputDir, "metafallbackwithbadxpointertest.xml");
910         Document doc = builder.build(input);
911         try {
912             XIncluder.resolve(doc);
913             fail("Should have thrown XIncludeException");
914         }
915         catch (XIncludeException success) {
916             assertNotNull(success.getMessage());
917             assertNotNull(success.getCause());
918         }
919 
920     }
921 
922 
923     // from the XInclude CR
testC1()924     public void testC1()
925       throws ParsingException, IOException, XIncludeException {
926 
927         File input = new File(inputDir, "c1.xml");
928         Document doc = builder.build(input);
929         Document result = XIncluder.resolve(doc);
930         Document expectedResult = builder.build(
931           new File(outputDir, "c1.xml")
932         );
933         assertEquals(expectedResult, result);
934 
935     }
936 
937 
testRelativeURLBaseURIFixup()938     public void testRelativeURLBaseURIFixup()
939       throws ParsingException, IOException, XIncludeException {
940 
941         File input = new File(inputDir, "relative.xml");
942         Document doc = builder.build(input);
943         Document result = XIncluder.resolve(doc);
944         assertEquals(doc.getBaseURI(), result.getBaseURI());
945         Document expectedResult = builder.build(
946           new File(outputDir, "relative.xml")
947         );
948         assertEquals(expectedResult, result);
949         Element root = result.getRootElement();
950         Element red = root.getFirstChildElement("red");
951         String base = red.getAttributeValue("base", Namespace.XML_NAMESPACE);
952         assertEquals("basedata/red.xml", base);
953 
954     }
955 
956 
957     // same test with explicit parse="xml"
testParseEqualsXML()958     public void testParseEqualsXML()
959       throws ParsingException, IOException, XIncludeException {
960 
961         File input = new File(inputDir, "parseequalxml.xml");
962         Document doc = builder.build(input);
963         Document result = XIncluder.resolve(doc);
964         Document expectedResult = builder.build(
965           new File(outputDir, "c1.xml")
966         );
967         assertEquals(expectedResult, result);
968 
969     }
970 
971 
972     // changed in b5
testAcceptableCirclePointer()973     public void testAcceptableCirclePointer()
974       throws ParsingException, IOException, XIncludeException {
975 
976         File input = new File(inputDir, "legalcircle.xml");
977         Document doc = builder.build(input);
978         try {
979             XIncluder.resolve(doc);
980             fail("Allowed circular reference");
981         }
982         catch (InclusionLoopException success) {
983             assertNotNull(success.getMessage());
984         }
985 
986     }
987 
988 
989     // from the XInclude CR
testC2()990     public void testC2()
991       throws ParsingException, IOException, XIncludeException {
992 
993         File input = new File(inputDir, "c2.xml");
994         Document doc = builder.build(input);
995         Document result = XIncluder.resolve(doc);
996         Document expectedResult = builder.build(
997           new File(outputDir, "c2.xml")
998         );
999         assertEquals(expectedResult, result);
1000 
1001     }
1002 
1003 
1004     // from the XInclude CR
testC3()1005     public void testC3()
1006       throws ParsingException, IOException, XIncludeException {
1007 
1008         File input = new File(inputDir, "c3.xml");
1009         Document doc = builder.build(input);
1010         Document result = XIncluder.resolve(doc);
1011         Document expectedResult = builder.build(
1012           new File(outputDir, "c3.xml")
1013         );
1014         assertEquals(expectedResult, result);
1015 
1016     }
1017 
1018 
1019     // C4 skipped for the moment because it uses XPointers
1020     // that XOM doesn't yet support
1021 
1022     // from the XInclude CR
1023     // Don't use this one yet, because there appear to be
1024     // mistakes in the spec examples
1025     /*public void testC5() throws ParsingException, IOException, XIncludeException {
1026 
1027         File input = new File(inputDir, "c5.xml");
1028         Document doc = builder.build(input);
1029         Document result = XIncluder.resolve(doc);
1030         Document expectedResult = builder.build(new File(outputDir, "c5.xml"));
1031         XMLAssert.assertEquals(expectedResult, result);
1032 
1033     } */
1034 
1035 
1036     private static class TextNodeFactory extends NodeFactory {
1037 
makeText(String data)1038         public Nodes makeText(String data) {
1039             return new Nodes(new TextSubclass(data));
1040         }
1041 
1042     }
1043 
1044     private static class TextSubclass extends Text {
1045 
TextSubclass(String data)1046         TextSubclass(String data) {
1047             super(data);
1048         }
1049 
copy()1050         public Node copy() {
1051             return new TextSubclass(this.getValue());
1052         }
1053 
1054     }
1055 
1056 
testRecurseWithinSameDocument()1057     public void testRecurseWithinSameDocument()
1058       throws ParsingException, IOException, XIncludeException {
1059 
1060         File input = new File(inputDir, "recursewithinsamedocument.xml");
1061         Document doc = builder.build(input);
1062         Document result = XIncluder.resolve(doc);
1063         Document expectedResult = builder.build(
1064           new File(outputDir, "recursewithinsamedocument.xml")
1065         );
1066         assertEquals(expectedResult, result);
1067 
1068     }
1069 
1070 
testSiblingIncludes()1071     public void testSiblingIncludes()
1072       throws ParsingException, IOException, XIncludeException {
1073 
1074         File input = new File(inputDir, "paralleltest.xml");
1075         Document doc = builder.build(input);
1076         Document result = XIncluder.resolve(doc);
1077         Document expectedResult = builder.build(
1078           new File(outputDir, "paralleltest.xml")
1079         );
1080         assertEquals(expectedResult, result);
1081 
1082     }
1083 
1084 
testNamespaces()1085     public void testNamespaces()
1086       throws ParsingException, IOException, XIncludeException {
1087 
1088         File input = new File(inputDir, "namespacetest.xml");
1089         Document doc = builder.build(input);
1090         Document result = XIncluder.resolve(doc);
1091         Document expectedResult = builder.build(
1092           new File(outputDir, "namespacetest.xml")
1093         );
1094         assertEquals(expectedResult, result);
1095 
1096     }
1097 
1098 
testIncludeReferencesItItself()1099     public void testIncludeReferencesItItself()
1100       throws ParsingException, IOException, XIncludeException {
1101 
1102         File input = new File(inputDir, "internalcircular.xml");
1103         Document doc = builder.build(input);
1104         try {
1105             XIncluder.resolve(doc);
1106             fail("Allowed include element to reference itself");
1107         }
1108         catch (InclusionLoopException success) {
1109             assertNotNull(success.getMessage());
1110         }
1111 
1112     }
1113 
1114 
testIncludeReferencesItsAncestor()1115     public void testIncludeReferencesItsAncestor()
1116       throws ParsingException, IOException, XIncludeException {
1117 
1118         File input = new File(inputDir, "internalcircularviaancestor.xml");
1119         Document doc = builder.build(input);
1120         try {
1121             XIncluder.resolve(doc);
1122             fail("Allowed include element to reference its own ancestor");
1123         }
1124         catch (InclusionLoopException success) {
1125             assertNotNull(success.getMessage());
1126         }
1127 
1128     }
1129 
1130 
testNoInclusions()1131     public void testNoInclusions()
1132       throws ParsingException, IOException, XIncludeException {
1133 
1134         File input = new File(inputDir, "latin1.xml");
1135         Document doc = builder.build(input);
1136         Document result = XIncluder.resolve(doc);
1137         Document expectedResult = builder.build(
1138           new File(outputDir, "latin1.xml")
1139         );
1140         assertEquals(expectedResult, result);
1141 
1142     }
1143 
1144 
test2()1145     public void test2()
1146       throws ParsingException, IOException, XIncludeException {
1147 
1148         File input = new File(inputDir, "simple.xml");
1149         Document doc = builder.build(input);
1150         Document result = XIncluder.resolve(doc);
1151         Document expectedResult = builder.build(
1152           new File(outputDir, "simple.xml")
1153         );
1154         assertEquals(expectedResult, result);
1155 
1156     }
1157 
1158 
testReplaceRoot()1159     public void testReplaceRoot()
1160       throws ParsingException, IOException, XIncludeException {
1161 
1162         File input = new File(inputDir, "roottest.xml");
1163         Document doc = builder.build(input);
1164         Document result = XIncluder.resolve(doc);
1165         Document expectedResult = builder.build(
1166           new File(outputDir, "roottest.xml")
1167         );
1168         assertEquals(expectedResult, result);
1169 
1170     }
1171 
1172 
1173     // In this test the included document has a prolog and an epilog
testReplaceRoot2()1174     public void testReplaceRoot2()
1175       throws ParsingException, IOException, XIncludeException {
1176 
1177         File input = new File(inputDir, "roottest2.xml");
1178         Document doc = builder.build(input);
1179         Document result = XIncluder.resolve(doc);
1180         Document expectedResult = builder.build(
1181           new File(outputDir, "roottest2.xml")
1182         );
1183         assertEquals(expectedResult, result);
1184 
1185     }
1186 
1187 
testIncludeElementsCannotHaveIncludeChildren()1188     public void testIncludeElementsCannotHaveIncludeChildren()
1189       throws ParsingException, IOException, XIncludeException {
1190         File input = new File(inputDir, "nestedxinclude.xml");
1191         Document doc = builder.build(input);
1192         try {
1193             XIncluder.resolve(doc);
1194             fail("allowed include element to contain another include element");
1195         }
1196         catch (XIncludeException success) {
1197             assertNotNull(success.getMessage());
1198         }
1199     }
1200 
1201 
testIncludeElementsCannotHaveChildrenFromXIncludeNamespace()1202     public void testIncludeElementsCannotHaveChildrenFromXIncludeNamespace()
1203       throws ParsingException, IOException, XIncludeException {
1204         File input = new File(inputDir, "nestedxincludenamespace.xml");
1205         Document doc = builder.build(input);
1206         try {
1207             XIncluder.resolve(doc);
1208             fail("allowed include element to contain another include element");
1209         }
1210         catch (XIncludeException success) {
1211             assertNotNull(success.getMessage());
1212         }
1213     }
1214 
1215 
testFallbackIsNotChildOfIncludeElement()1216     public void testFallbackIsNotChildOfIncludeElement()
1217       throws ParsingException, IOException, XIncludeException {
1218         File input = new File(inputDir, "nakedfallback.xml");
1219         Document doc = builder.build(input);
1220         try {
1221             XIncluder.resolve(doc);
1222             fail("allowed fallback that was not child of an include element");
1223         }
1224         catch (XIncludeException success) {
1225             assertNotNull(success.getMessage());
1226         }
1227     }
1228 
1229 
testFallbackCantContainFallbackElement()1230     public void testFallbackCantContainFallbackElement()
1231       throws ParsingException, IOException, XIncludeException {
1232         File input = new File(inputDir, "fallbackcontainsfallback.xml");
1233         Document doc = builder.build(input);
1234         try {
1235             XIncluder.resolve(doc);
1236             fail("allowed fallback inside another fallback element");
1237         }
1238         catch (XIncludeException success) {
1239             assertNotNull(success.getMessage());
1240         }
1241     }
1242 
1243 
1244     // In this test the fallback is activated.
testMultipleFallbacks()1245     public void testMultipleFallbacks()
1246       throws ParsingException, IOException, XIncludeException {
1247         File input = new File(inputDir, "multiplefallbacks.xml");
1248         Document doc = builder.build(input);
1249         try {
1250             XIncluder.resolve(doc);
1251             fail("allowed multiple fallback elements");
1252         }
1253         catch (XIncludeException success) {
1254             assertNotNull(success.getMessage());
1255         }
1256     }
1257 
1258 
1259     // In this test the fallback is not needed.
testMultipleFallbacks2()1260     public void testMultipleFallbacks2()
1261       throws ParsingException, IOException, XIncludeException {
1262         File input = new File(inputDir, "multiplefallbacks2.xml");
1263         Document doc = builder.build(input);
1264         try {
1265             XIncluder.resolve(doc);
1266             fail("allowed multiple fallback elements");
1267         }
1268         catch (XIncludeException success) {
1269             assertNotNull(success.getMessage());
1270         }
1271     }
1272 
1273 
testDocumentIncludesItself()1274     public void testDocumentIncludesItself()
1275       throws ParsingException, IOException, XIncludeException {
1276         File input = new File(inputDir, "circle1.xml");
1277         Document doc = builder.build(input);
1278         try {
1279             XIncluder.resolve(doc);
1280             fail("allowed parsed include of self");
1281         }
1282         catch (InclusionLoopException success) {
1283             assertNotNull(success.getMessage());
1284             assertEquals(input.toURI().toString(), success.getURI());
1285         }
1286     }
1287 
1288 
testInclusionLoopWithLength2Cycle()1289     public void testInclusionLoopWithLength2Cycle()
1290       throws ParsingException, IOException, XIncludeException {
1291 
1292         File input = new File(inputDir, "circle2a.xml");
1293         File errorFile = new File(inputDir, "circle2b.xml");
1294         Document doc = builder.build(input);
1295         try {
1296             XIncluder.resolve(doc);
1297             fail("allowed circular include, cycle length 1");
1298         }
1299         catch (InclusionLoopException success) {
1300             assertTrue(success.getMessage().indexOf(errorFile.toURI().toString()) > 1);
1301             assertTrue(success.getMessage().indexOf(input.toURI().toString()) > 1);
1302             assertEquals(errorFile.toURI().toString(), success.getURI());
1303         }
1304 
1305     }
1306 
1307 
testMissingHref()1308     public void testMissingHref()
1309       throws ParsingException, IOException, XIncludeException {
1310 
1311         File input = new File(inputDir, "missinghref.xml");
1312         Document doc = builder.build(input);
1313         try {
1314             XIncluder.resolve(doc);
1315             fail("allowed missing href");
1316         }
1317         catch (NoIncludeLocationException success) {
1318             assertNotNull(success.getMessage());
1319             assertEquals(doc.getBaseURI(), success.getURI());
1320         }
1321 
1322     }
1323 
1324 
testBadParseAttribute()1325     public void testBadParseAttribute()
1326       throws ParsingException, IOException, XIncludeException, URISyntaxException {
1327 
1328         File input = new File(inputDir, "badparseattribute.xml");
1329         Document doc = builder.build(input);
1330         try {
1331             XIncluder.resolve(doc);
1332             fail("allowed bad parse attribute");
1333         }
1334         catch (BadParseAttributeException success) {
1335             assertNotNull(success.getMessage());
1336             URI u1 = input.toURI();
1337             URI u2 = new URI(success.getURI());
1338             assertEquals(u1, u2);
1339         }
1340 
1341     }
1342 
1343 
testUnavailableResource()1344     public void testUnavailableResource()
1345       throws ParsingException, IOException, XIncludeException {
1346         File input = new File(inputDir, "missingfile.xml");
1347         Document doc = builder.build(input);
1348         try {
1349             XIncluder.resolve(doc);
1350             fail("allowed unresolvable resource");
1351         }
1352         catch (IOException success) {
1353             assertNotNull(success.getMessage());
1354         }
1355 
1356     }
1357 
1358 
testFallback()1359     public void testFallback()
1360       throws ParsingException, IOException, XIncludeException {
1361 
1362         File input = new File(inputDir, "fallbacktest.xml");
1363         Document doc = builder.build(input);
1364         Document result = XIncluder.resolve(doc);
1365         Document expectedResult = builder.build(
1366           new File(outputDir, "fallbacktest.xml")
1367         );
1368         assertEquals(expectedResult, result);
1369 
1370     }
1371 
1372 
testFallbackWithRecursiveInclude()1373     public void testFallbackWithRecursiveInclude()
1374       throws ParsingException, IOException, XIncludeException {
1375 
1376         File input = new File(inputDir, "fallbacktest2.xml");
1377         Document doc = builder.build(input);
1378         Document result = XIncluder.resolve(doc);
1379         Document expectedResult = builder.build(
1380           new File(outputDir, "fallbacktest2.xml")
1381         );
1382         assertEquals(expectedResult, result);
1383 
1384     }
1385 
1386 
testEncodingAttribute()1387     public void testEncodingAttribute()
1388       throws ParsingException, IOException, XIncludeException {
1389 
1390         File input = new File(inputDir, "utf16.xml");
1391         Document doc = builder.build(input);
1392         Document result = XIncluder.resolve(doc);
1393         Document expectedResult = builder.build(
1394           new File(outputDir, "utf16.xml")
1395         );
1396         assertEquals(expectedResult, result);
1397 
1398     }
1399 
1400 
testXPointerBareNameID()1401     public void testXPointerBareNameID()
1402       throws ParsingException, IOException, XIncludeException {
1403 
1404         File input = new File(inputDir, "xptridtest.xml");
1405         Document doc = builder.build(input);
1406         Document result = XIncluder.resolve(doc);
1407         Document expectedResult = builder.build(
1408           new File(outputDir, "xptridtest.xml")
1409         );
1410         assertEquals(expectedResult, result);
1411 
1412     }
1413 
1414 
testXPointerXMLID()1415     public void testXPointerXMLID()
1416       throws ParsingException, IOException, XIncludeException {
1417 
1418         File input = new File(inputDir, "xmlidtest.xml");
1419         Document doc = builder.build(input);
1420         Document result = XIncluder.resolve(doc);
1421         Document expectedResult = builder.build(
1422           new File(outputDir, "xmlidtest.xml")
1423         );
1424         assertEquals(expectedResult, result);
1425 
1426     }
1427 
1428 
testShorthandXPointerMatchesNothing()1429     public void testShorthandXPointerMatchesNothing()
1430       throws ParsingException, IOException, URISyntaxException {
1431 
1432         File input = new File(inputDir, "xptridtest2.xml");
1433         Document doc = builder.build(input);
1434         try {
1435             XIncluder.resolve(doc);
1436             fail("Resolved a document with an XPointer " +
1437               "that selects no subresource");
1438         }
1439         catch (XIncludeException success) {
1440             assertNotNull(success.getMessage());
1441             // Must compare URLs instead of strings here to avoid
1442             // issues of whether a file URL begins file:/ or file:///
1443             URI u1 = input.toURI();
1444             URI u2 = new URI(success.getURI());
1445             assertEquals(u1, u2);
1446         }
1447 
1448 
1449         /* I used to think this case included nothing.
1450            Now I think an XPointer that matches no
1451            subresource, and does not have a fallback is in error.
1452         Document expectedResult = builder.build(
1453           new File(outputDir, "xptridtest2.xml")
1454         );
1455         assertEquals(expectedResult, result);
1456         */
1457 
1458     }
1459 
1460 
testXPointerPureTumbler()1461     public void testXPointerPureTumbler()
1462       throws ParsingException, IOException, XIncludeException {
1463 
1464         File input = new File(inputDir, "xptrtumblertest.xml");
1465         Document doc = builder.build(input);
1466         Document result = XIncluder.resolve(doc);
1467         Document expectedResult = builder.build(
1468           new File(outputDir, "xptrtumblertest.xml")
1469         );
1470         assertEquals(expectedResult, result);
1471 
1472     }
1473 
1474 
testUnrecognizedColonizedSchemeNameBackedUpByTumbler()1475     public void testUnrecognizedColonizedSchemeNameBackedUpByTumbler()
1476       throws ParsingException, IOException, XIncludeException {
1477 
1478         File input = new File(inputDir, "colonizedschemename.xml");
1479         Document doc = builder.build(input);
1480         Document result = XIncluder.resolve(doc);
1481         Document expectedResult = builder.build(
1482           new File(outputDir, "xptrtumblertest.xml")
1483         );
1484         assertEquals(expectedResult, result);
1485 
1486     }
1487 
1488 
testXPointerSyntaxErrorInSecondPart()1489     public void testXPointerSyntaxErrorInSecondPart()
1490       throws ParsingException, IOException {
1491 
1492         File input = new File(inputDir, "laterfailure.xml");
1493         Document doc = builder.build(input);
1494         try {
1495             XIncluder.resolve(doc);
1496             fail("Didn't find syntax error in 2nd XPointer part" +
1497                 " when the first part resolved successfully");
1498         }
1499         catch (XIncludeException success) {
1500             assertNotNull(success.getMessage());
1501         }
1502 
1503     }
1504 
1505 
testBadElementSchemeDataIsNotAnError()1506     public void testBadElementSchemeDataIsNotAnError()
1507       throws ParsingException, IOException, XIncludeException {
1508 
1509         File input = new File(inputDir, "badelementschemedata.xml");
1510         Document doc = builder.build(input);
1511         Document result = XIncluder.resolve(doc);
1512         Document expectedResult = builder.build(
1513           new File(outputDir, "badelementschemedata.xml")
1514         );
1515         // dumpResult(input, result);
1516 
1517         assertEquals(expectedResult, result);
1518 
1519     }
1520 
1521 
testXPointerSyntaxErrorMissingFinalParenthesis()1522     public void testXPointerSyntaxErrorMissingFinalParenthesis()
1523       throws ParsingException, IOException {
1524 
1525         File input = new File(inputDir, "laterfailure2.xml");
1526         Document doc = builder.build(input);
1527         try {
1528             XIncluder.resolve(doc);
1529             fail("Didn't find syntax error in 2nd XPointer part" +
1530                 " when the first part resolved successfully");
1531         }
1532         catch (XIncludeException success) {
1533             assertNotNull(success.getMessage());
1534         }
1535 
1536     }
1537 
1538 
1539     // Test we can include from same document using only
1540     // an xpointer attribute
testOnlyXPointer()1541     public void testOnlyXPointer()
1542       throws ParsingException, IOException, XIncludeException {
1543 
1544         File input = new File(inputDir, "onlyxpointer.xml");
1545         Document doc = builder.build(input);
1546         Document result = XIncluder.resolve(doc);
1547         Document expectedResult = builder.build(
1548           new File(outputDir, "onlyxpointer.xml")
1549         );
1550 
1551         assertEquals(expectedResult, result);
1552 
1553     }
1554 
1555 
1556     // Test with 3 element schemes in the XPointer.
1557     // The first and second one point to nothing. The third one
1558     // selects something.
testXPointerTripleTumbler()1559     public void testXPointerTripleTumbler()
1560       throws ParsingException, IOException, XIncludeException {
1561 
1562         File input = new File(inputDir, "xptr2tumblertest.xml");
1563         Document doc = builder.build(input);
1564         Document result = XIncluder.resolve(doc);
1565         Document expectedResult = builder.build(
1566           new File(outputDir, "xptrtumblertest.xml")
1567         );
1568         assertEquals(expectedResult, result);
1569 
1570     }
1571 
1572 
1573     // Test with 2 element schemes in the XPointer.
1574     // The first one uses an ID that doesn't exist
1575     // and points to nothing. The second one
1576     // selects something.
testXPointerDoubleTumbler()1577     public void testXPointerDoubleTumbler()
1578       throws ParsingException, IOException, XIncludeException {
1579 
1580         File input = new File(inputDir, "xptrdoubletumblertest.xml");
1581         Document doc = builder.build(input);
1582         Document result = XIncluder.resolve(doc);
1583         Document expectedResult = builder.build(
1584           new File(outputDir, "xptrtumblertest.xml")
1585         );
1586         assertEquals(expectedResult, result);
1587 
1588     }
1589 
1590 
1591     // Test with 2 element schemes in the XPointer.
1592     // The first one uses an ID that points to something.
1593     // The second one points to something too. Both element schemes
1594     // use IDs exclusively, no child sequences.
testXPointerDoubleElementByID()1595     public void testXPointerDoubleElementByID()
1596       throws ParsingException, IOException, XIncludeException {
1597 
1598         File input = new File(inputDir, "xptrdoubleelementtest.xml");
1599         Document doc = builder.build(input);
1600         Document result = XIncluder.resolve(doc);
1601         Document expectedResult = builder.build(
1602           new File(outputDir, "xptrdoubleelementtest.xml")
1603         );
1604         assertEquals(expectedResult, result);
1605 
1606     }
1607 
1608 
1609     // Test with 2 element schemes in the XPointer.
1610     // The first one uses a child sequence that points to something.
1611     // The second one points to something too. Both element schemes
1612     // use child sequences exclusively, no IDs.
testXPointerDoubleElementByChildSequence()1613     public void testXPointerDoubleElementByChildSequence()
1614       throws ParsingException, IOException, XIncludeException {
1615 
1616         File input = new File(inputDir, "xptrdoublechildsequence.xml");
1617         Document doc = builder.build(input);
1618         Document result = XIncluder.resolve(doc);
1619         Document expectedResult = builder.build(
1620           new File(outputDir, "xptrdoubleelementtest.xml")
1621         );
1622         assertEquals(expectedResult, result);
1623 
1624     }
1625 
1626 
1627     // Make sure XPointer failures are treated as a resource error,
1628     // not a fatal error.
testXPointerFailureIsAResourceError()1629     public void testXPointerFailureIsAResourceError()
1630       throws ParsingException, IOException, XIncludeException {
1631 
1632         File input = new File(
1633           "data/xinclude/input/xptrtumblerfailsbutfallback.xml"
1634         );
1635         Document doc = builder.build(input);
1636         Document result = XIncluder.resolve(doc);
1637         // For debugging
1638         // dumpResult(input, result);
1639         Document expectedResult = builder.build(
1640           new File(outputDir, "xptrtumblertest.xml")
1641         );
1642         assertEquals(expectedResult, result);
1643 
1644     }
1645 
1646 
1647     // Make sure XPointer syntax errors are treated as a resource
1648     // error, not a fatal error per section 4.2 of XInclude CR
1649     /* Resources that are unavailable for any reason
1650       (for example the resource doesn't exist, connection
1651       difficulties or security restrictions prevent it from being
1652       fetched, the URI scheme isn't a fetchable one, the resource
1653       is in an unsuppored encoding, the resource is determined
1654       through implementation-specific mechanisms not to be XML, or a
1655       syntax error in an [XPointer Framework]) result in a resource
1656       error.  */
testXPointerSyntaxErrorIsAResourceError()1657     public void testXPointerSyntaxErrorIsAResourceError()
1658       throws ParsingException, IOException, XIncludeException {
1659 
1660         File input = new File(
1661           "data/xinclude/input/xptrsyntaxerrorbutfallback.xml"
1662         );
1663         Document doc = builder.build(input);
1664         Document result = XIncluder.resolve(doc);
1665         Document expectedResult = builder.build(
1666           new File(outputDir, "xptrtumblertest.xml")
1667         );
1668         assertEquals(expectedResult, result);
1669 
1670     }
1671 
1672 
1673     // Test with 3 element schemes in the XPointer,
1674     // separated by white space.
1675     // The first one points to nothing. The third one
1676     // selects something.
testXPointerTumblerWithWhiteSpace()1677     public void testXPointerTumblerWithWhiteSpace()
1678       throws ParsingException, IOException, XIncludeException {
1679 
1680         File input
1681           = new File(inputDir, "xptrtumblertest3.xml");
1682         Document doc = builder.build(input);
1683         Document result = XIncluder.resolve(doc);
1684         Document expectedResult = builder.build(
1685           new File(outputDir, "xptrtumblertest.xml")
1686         );
1687         assertEquals(expectedResult, result);
1688 
1689     }
1690 
1691 
testXPointerTumblerMatchesNothing()1692     public void testXPointerTumblerMatchesNothing()
1693       throws ParsingException, IOException, URISyntaxException {
1694 
1695         File input = new File(
1696           "data/xinclude/input/xptrtumblertest2.xml"
1697         );
1698         Document doc = builder.build(input);
1699         try {
1700             XIncluder.resolve(doc);
1701             fail("Did not error on XPointer matching nothing");
1702         }
1703         catch (XIncludeException success) {
1704             assertNotNull(success.getMessage());
1705             URI u1 = input.toURI();
1706             URI u2 = new URI(success.getURI());
1707             assertEquals(u1, u2);
1708         }
1709 
1710     }
1711 
1712 
testMalformedXPointer()1713     public void testMalformedXPointer()
1714       throws ParsingException, IOException, URISyntaxException {
1715 
1716         File input = new File(inputDir, "badxptr.xml");
1717         Document doc = builder.build(input);
1718         try {
1719             XIncluder.resolve(doc);
1720             fail("Allowed malformed XPointer");
1721         }
1722         catch (XIncludeException success) {
1723             assertNotNull(success.getMessage());
1724             URI u1 = input.toURI();
1725             URI u2 = new URI(success.getURI());
1726             assertEquals(u1, u2);
1727         }
1728 
1729     }
1730 
1731 
testXPointerExceptionSelfCausation()1732     public void testXPointerExceptionSelfCausation()
1733       throws ParsingException, IOException {
1734 
1735         File input = new File(inputDir, "badxptr.xml");
1736         Document doc = builder.build(input);
1737         try {
1738             XIncluder.resolve(doc);
1739             fail("Allowed malformed XPointer");
1740         }
1741         catch (XIncludeException success) {
1742             Exception cause = (Exception) success.getCause();
1743             assertNotNull(cause.getMessage());
1744             try {
1745                 cause.initCause(cause);
1746                 fail("Self causation");
1747             }
1748             catch (IllegalArgumentException ex) {
1749                 assertNotNull(ex.getMessage());
1750             }
1751         }
1752 
1753     }
1754 
1755 
testXPointerExceptionGetCause()1756     public void testXPointerExceptionGetCause()
1757       throws ParsingException, IOException {
1758 
1759         File input = new File(inputDir, "badxptr.xml");
1760         Document doc = builder.build(input);
1761         try {
1762             XIncluder.resolve(doc);
1763             fail("Allowed malformed XPointer");
1764         }
1765         catch (XIncludeException success) {
1766             Exception cause = (Exception) success.getCause();
1767             Exception ex = new Exception();
1768             cause.initCause(ex);
1769             assertEquals(ex, cause.getCause());
1770         }
1771 
1772     }
1773 
1774 
testAnotherMalformedXPointer()1775     public void testAnotherMalformedXPointer()
1776       throws ParsingException, IOException, URISyntaxException {
1777 
1778         // testing use of non NCNAME as ID
1779         File input = new File(inputDir, "badxptr2.xml");
1780         Document doc = builder.build(input);
1781         try {
1782             XIncluder.resolve(doc);
1783             fail("Allowed another malformed XPointer");
1784         }
1785         catch (XIncludeException success) {
1786             assertNotNull(success.getMessage());
1787             URI u1 = input.toURI();
1788             URI u2 = new URI(success.getURI());
1789             assertEquals(u1, u2);
1790         }
1791 
1792     }
1793 
1794 
testMalformedXPointerWithFallback()1795     public void testMalformedXPointerWithFallback()
1796       throws ParsingException, IOException, XIncludeException {
1797 
1798         File input = new File(inputDir, "xptrfallback.xml");
1799         Document doc = builder.build(input);
1800         Document result = XIncluder.resolve(doc);
1801         Document expectedResult = builder.build(new File(
1802           "data/xinclude/output/xptrfallback.xml")
1803         );
1804         assertEquals(expectedResult, result);
1805 
1806     }
1807 
1808 
testIDAndTumbler()1809     public void testIDAndTumbler()
1810       throws ParsingException, IOException, XIncludeException {
1811 
1812         File input = new File(
1813           "data/xinclude/input/xptridandtumblertest.xml"
1814         );
1815         Document doc = builder.build(input);
1816         Document result = XIncluder.resolve(doc);
1817         Document expectedResult = builder.build(new File(
1818           "data/xinclude/output/xptridandtumblertest.xml")
1819         );
1820         assertEquals(expectedResult, result);
1821 
1822     }
1823 
1824 
testAutoDetectUTF16BigEndianWithByteOrderMark()1825     public void testAutoDetectUTF16BigEndianWithByteOrderMark()
1826       throws ParsingException, IOException, XIncludeException {
1827 
1828         File input = new File(
1829           "data/xinclude/input/UTF16BigEndianWithByteOrderMark.xml"
1830         );
1831         Document doc = builder.build(input);
1832         Document result = XIncluder.resolve(doc);
1833         Document expectedResult = builder.build(new File(
1834           "data/xinclude/output/UTF16BigEndianWithByteOrderMark.xml")
1835         );
1836         assertEquals(expectedResult, result);
1837 
1838     }
1839 
1840 
testAutoDetectUTF16LittleEndianWithByteOrderMark()1841     public void testAutoDetectUTF16LittleEndianWithByteOrderMark()
1842       throws ParsingException, IOException, XIncludeException {
1843 
1844         File input = new File(
1845           "data/xinclude/input/UTF16LittleEndianWithByteOrderMark.xml"
1846         );
1847         Document doc = builder.build(input);
1848         Document result = XIncluder.resolve(doc);
1849         Document expectedResult = builder.build(new File(
1850           "data/xinclude/output/UTF16LittleEndianWithByteOrderMark.xml"
1851         ));
1852         assertEquals(expectedResult, result);
1853 
1854     }
1855 
1856 
testAutoDetectUTF8WithByteOrderMark()1857     public void testAutoDetectUTF8WithByteOrderMark()
1858       throws ParsingException, IOException, XIncludeException {
1859 
1860         File input = new File(
1861           "data/xinclude/input/UTF8WithByteOrderMark.xml"
1862         );
1863         Document doc = builder.build(input);
1864         Document result = XIncluder.resolve(doc);
1865         Document expectedResult = builder.build(
1866           new File(outputDir, "UTF8WithByteOrderMark.xml")
1867         );
1868         assertEquals(expectedResult, result);
1869 
1870     }
1871 
1872 
testAutoDetectUnicodeBigUnmarked()1873     public void testAutoDetectUnicodeBigUnmarked()
1874       throws ParsingException, IOException, XIncludeException {
1875 
1876         File input = new File(
1877           "data/xinclude/input/UnicodeBigUnmarked.xml"
1878         );
1879         Document doc = builder.build(input);
1880         Document result = XIncluder.resolve(doc);
1881         Document expectedResult = builder.build(
1882           new File(outputDir, "UnicodeBigUnmarked.xml")
1883         );
1884         assertEquals(expectedResult, result);
1885 
1886     }
1887 
1888 
testUnicodeLittleUnmarked()1889     public void testUnicodeLittleUnmarked()
1890       throws ParsingException, IOException, XIncludeException {
1891 
1892         File input = new File(
1893           "data/xinclude/input/UnicodeLittleUnmarked.xml"
1894         );
1895         Document doc = builder.build(input);
1896         Document result = XIncluder.resolve(doc);
1897         Document expectedResult = builder.build(
1898           new File(outputDir, "UnicodeLittleUnmarked.xml")
1899         );
1900         assertEquals(expectedResult, result);
1901 
1902     }
1903 
1904 
1905 /*// Java doesn't yet support the UTF-32BE and UTF32LE encodings
1906     public void testUTF32BE()
1907       throws ParsingException, IOException, XIncludeException {
1908 
1909         File input = new File(
1910           "data/xinclude/input/UTF32BE.xml"
1911         );
1912         Document doc = builder.build(input);
1913         Document result = XIncluder.resolve(doc);
1914         Document expectedResult = builder.build(
1915           new File(outputDir, "UTF32BE.xml")
1916         );
1917         assertEquals(expectedResult, result);
1918 
1919     }
1920 
1921     public void testUTF32LE()
1922       throws ParsingException, IOException, XIncludeException {
1923 
1924         File input = new File(
1925           "data/xinclude/input/UTF32LE.xml"
1926         );
1927         Document doc = builder.build(input);
1928         Document result = XIncluder.resolve(doc);
1929         Document expectedResult = builder.build(
1930           new File(outputDir, "UTF32LE.xml")
1931         );
1932         assertEquals(expectedResult, result);
1933 
1934     }
1935 */
1936 
1937 
testEBCDIC()1938     public void testEBCDIC()
1939       throws ParsingException, IOException, XIncludeException {
1940 
1941         File input = new File(inputDir, "EBCDIC.xml");
1942         Document doc = builder.build(input);
1943         Document result = XIncluder.resolve(doc);
1944         Document expected = builder.build(new File(outputDir, "EBCDIC.xml"));
1945         assertEquals(expected, result);
1946 
1947     }
1948 
1949 
1950   // Turn off these tests because Java doesn't support UCS4 yet
1951  /*   public void testAutoDetectUCS4BE()
1952       throws ParsingException, IOException, XIncludeException {
1953 
1954         File input = new File(inputDir, "UCS4BE.xml");
1955         Document doc = builder.build(input);
1956         Document result = XIncluder.resolve(doc);
1957         Document expectedResult = builder.build(
1958           new File(outputDir, "UTF8WithByteOrderMark.xml")
1959         );
1960         assertEquals(expectedResult, result);
1961 
1962     }
1963 
1964     public void testAutoDetectUCS4LE()
1965       throws ParsingException, IOException, XIncludeException {
1966 
1967         File input = new File(inputDir, "UCS4LE.xml");
1968         Document doc = builder.build(input);
1969         Document result = XIncluder.resolve(doc);
1970         Document expectedResult = builder.build(
1971           new File(outputDir, "UTF8WithByteOrderMark.xml")
1972         );
1973         assertEquals(expectedResult, result);
1974 
1975     } */
1976 
1977 
1978     // Need a test case where A includes B, B includes C
1979     // and B encounters the error (e.g. a missing href)
1980     // to make sure B's URL is in the error message, not A's
testChildDocumentSetsErrorURI()1981     public void testChildDocumentSetsErrorURI()
1982       throws ParsingException, IOException, XIncludeException, URISyntaxException {
1983 
1984         File input = new File(inputDir, "toplevel.xml");
1985         File error = new File(inputDir, "onedown.xml");
1986         Document doc = builder.build(input);
1987         try {
1988             XIncluder.resolve(doc);
1989             fail("Missing HREF not detected");
1990         }
1991         catch (NoIncludeLocationException success) {
1992             assertNotNull(success.getMessage());
1993             URI u1 = error.toURI();
1994             URI u2 = new URI(success.getURI());
1995             assertEquals(u1, u2);
1996         }
1997 
1998     }
1999 
2000 
testColonizedNameForIdValueInElementScheme()2001     public void testColonizedNameForIdValueInElementScheme()
2002       throws ParsingException, IOException {
2003 
2004         File input = new File(inputDir, "badxptr3.xml");
2005         Document doc = builder.build(input);
2006         try {
2007             XIncluder.resolve(doc);
2008             fail("Bad ID in element not detected");
2009         }
2010         catch (XIncludeException success) {
2011             assertNotNull(success.getMessage());
2012         }
2013 
2014     }
2015 
2016 
testBadIdValueInElementScheme()2017     public void testBadIdValueInElementScheme()
2018       throws ParsingException, IOException {
2019 
2020         File input = new File(inputDir, "badxptr4.xml");
2021         Document doc = builder.build(input);
2022         try {
2023             XIncluder.resolve(doc);
2024             fail("Bad ID in element not detected");
2025         }
2026         catch (XIncludeException success) {
2027             assertNotNull(success.getMessage());
2028         }
2029 
2030     }
2031 
2032 
testCirclePointer()2033     public void testCirclePointer()
2034       throws ParsingException, IOException, XIncludeException {
2035 
2036         File input = new File(inputDir, "circlepointer1.xml");
2037         Document doc = builder.build(input);
2038         try {
2039             XIncluder.resolve(doc);
2040             fail("Allowed circular reference via XPointer");
2041         }
2042         catch (InclusionLoopException success) {
2043             assertNotNull(success.getMessage());
2044         }
2045 
2046     }
2047 
2048 
testXPointerOverridesFragmentID()2049     public void testXPointerOverridesFragmentID()
2050       throws ParsingException, IOException, XIncludeException {
2051 
2052         File input = new File(inputDir, "xpointeroverridesfragmentid.xml"
2053         );
2054         Document doc = builder.build(input);
2055         try {
2056             XIncluder.resolve(doc);
2057             fail("Allowed href attribute with fragment ID");
2058         }
2059         catch (XIncludeException success) {
2060             assertNotNull(success.getMessage());
2061         }
2062 
2063     }
2064 
2065 
testFailsOnFragmentID()2066     public void testFailsOnFragmentID()
2067       throws ParsingException, IOException, XIncludeException {
2068 
2069         File input = new File(inputDir, "ignoresfragmentid.xml");
2070         Document doc = builder.build(input);
2071         try {
2072             XIncluder.resolve(doc);
2073             fail("Allowed href attribute with fragment ID");
2074         }
2075         catch (XIncludeException success) {
2076             assertNotNull(success.getMessage());
2077         }
2078 
2079     }
2080 
2081 
2082     // This also tests that the base URI applied to an element is as set by the xml:base
2083     // attribute, not the document.
testFragmentIDsAreRemovedFromElementBaseURIsAfterInclusion()2084     public void testFragmentIDsAreRemovedFromElementBaseURIsAfterInclusion()
2085       throws ParsingException, IOException, XIncludeException {
2086 
2087         File input = new File(inputDir, "basewithfragmentid.xml");
2088         Document doc = builder.build(input);
2089         Document result = XIncluder.resolve(doc);
2090         Document expectedResult = builder.build(
2091           new File(outputDir, "basewithfragmentid.xml")
2092         );
2093         assertEquals(expectedResult, result);
2094 
2095     }
2096 
2097 
testIncludeLowerCaseFileNames()2098     public void testIncludeLowerCaseFileNames()
2099       throws ParsingException, IOException, XIncludeException {
2100 
2101         File input = new File(inputDir, "lowercasealphabet.xml");
2102         Document doc = builder.build(input);
2103         Document result = XIncluder.resolve(doc);
2104         Document expectedResult = builder.build(
2105           new File(outputDir, "lowercasealphabet.xml")
2106         );
2107         assertEquals(expectedResult, result);
2108 
2109     }
2110 
2111 
testIncludeUpperCaseFileNames()2112     public void testIncludeUpperCaseFileNames()
2113       throws ParsingException, IOException, XIncludeException {
2114 
2115         File input = new File(inputDir, "uppercasealphabet.xml");
2116         Document doc = builder.build(input);
2117         Document result = XIncluder.resolve(doc);
2118         Document expectedResult = builder.build(
2119           new File(outputDir, "uppercasealphabet.xml")
2120         );
2121         assertEquals(expectedResult, result);
2122 
2123     }
2124 
2125 
testIncludeDigitFileNames()2126     public void testIncludeDigitFileNames()
2127       throws ParsingException, IOException, XIncludeException {
2128 
2129         File input = new File(inputDir, "numeric.xml");
2130         Document doc = builder.build(input);
2131         Document result = XIncluder.resolve(doc);
2132         Document expectedResult = builder.build(
2133           new File(outputDir, "numeric.xml")
2134         );
2135         assertEquals(expectedResult, result);
2136 
2137     }
2138 
2139 
testIncludeHighPunctuationFileNames()2140     public void testIncludeHighPunctuationFileNames()
2141       throws ParsingException, IOException, XIncludeException {
2142 
2143         // Windows has a problem with some of these file names so
2144         // first we have to generate the file, just to avoid storing
2145         // it in the zip archive
2146         try {
2147             File f = new File(inputDir, "{|}.txt");
2148             Writer out = new OutputStreamWriter(
2149               new FileOutputStream(f), "UTF8");
2150             out.write("{|}");
2151             out.flush();
2152             out.close();
2153 
2154             File input = new File(inputDir, "punctuation.xml");
2155             Document doc = builder.build(input);
2156             Document result = XIncluder.resolve(doc);
2157             Document expectedResult = builder.build(
2158               new File(outputDir, "punctuation.xml")
2159             );
2160             f.delete();
2161             assertEquals(expectedResult, result);
2162         }
2163         catch (FileNotFoundException ex) {
2164             // This file can't even exist on Windows.
2165             // We can only test this on Unix.
2166             if (!windows) throw ex;
2167         }
2168 
2169     }
2170 
2171 
testMiddlePunctuationError()2172     public void testMiddlePunctuationError()
2173       throws ParsingException, IOException, XIncludeException {
2174 
2175         File input = new File(inputDir, "middlepunctuationerror.xml");
2176         Document doc = builder.build(input);
2177         try {
2178             XIncluder.resolve(doc);
2179             fail("Allowed illegal IRI with right square bracket ]");
2180         }
2181         catch (BadHrefAttributeException success) {
2182             assertNotNull(success.getMessage());
2183         }
2184 
2185     }
2186 
2187 
testIncludeLowerPunctuationFileNames()2188     public void testIncludeLowerPunctuationFileNames()
2189       throws ParsingException, IOException, XIncludeException {
2190 
2191         try {
2192             File f = new File(inputDir, "!\"$&'+,.txt");
2193             Writer out = new OutputStreamWriter(
2194               new FileOutputStream(f), "UTF8");
2195             out.write("!\"$&'+,");
2196             out.flush();
2197             out.close();
2198 
2199             File input = new File(inputDir, "lowerpunctuation.xml");
2200             Document doc = builder.build(input);
2201             Document result = XIncluder.resolve(doc);
2202             Document expectedResult = builder.build(
2203               new File(outputDir, "lowerpunctuation.xml")
2204             );
2205             f.delete();
2206             assertEquals(expectedResult, result);
2207         }
2208         catch (FileNotFoundException ex) {
2209             // This file can't even exist on Windows.
2210             // We can only test this on Unix.
2211             if (!windows) throw ex;
2212         }
2213 
2214     }
2215 
2216 
testLineEnds()2217     public void testLineEnds()
2218       throws ParsingException, IOException, XIncludeException {
2219 
2220         File input = new File(inputDir, "lineends.xml");
2221         Document doc = builder.build(input);
2222         Document result = XIncluder.resolve(doc);
2223         Document expected = builder.build(
2224           new File(outputDir, "lineends.xml")
2225         );
2226         assertEquals(expected, result);
2227 
2228     }
2229 
2230 
2231     // This is semantically bad; but still meets the
2232     // syntax of fragment IDs from RFC 2396
testBadXPointerInFragmentIDIsFatalError()2233     public void testBadXPointerInFragmentIDIsFatalError()
2234       throws ParsingException, IOException, XIncludeException {
2235 
2236         File input = new File(
2237           "data/xinclude/input/meaninglessfragmentid.xml");
2238         Document doc = builder.build(input);
2239         try {
2240             XIncluder.resolve(doc);
2241             fail("Allowed href attribute with fragment ID");
2242         }
2243         catch (XIncludeException success) {
2244             assertNotNull(success.getMessage());
2245         }
2246 
2247     }
2248 
2249 
2250     // These tests actually connect to IBiblio to load the included
2251     // data. This is necessary because file URLs don't support
2252     // content negotiation
testAcceptLanguageFrench()2253     public void testAcceptLanguageFrench()
2254       throws ParsingException, IOException, XIncludeException {
2255 
2256         File input = new File(inputDir, "acceptfrench.xml");
2257         Document doc = builder.build(input);
2258         Document result = XIncluder.resolve(doc);
2259         Document expectedResult = builder.build(
2260           new File(outputDir, "acceptfrench.xml")
2261         );
2262         assertEquals(expectedResult, result);
2263 
2264     }
2265 
2266 
testAcceptLanguageEnglish()2267     public void testAcceptLanguageEnglish()
2268       throws ParsingException, IOException, XIncludeException {
2269 
2270         File input = new File(inputDir, "acceptenglish.xml");
2271         Document doc = builder.build(input);
2272         Document result = XIncluder.resolve(doc);
2273         Document expectedResult = builder.build(
2274           new File(outputDir, "acceptenglish.xml")
2275         );
2276         assertEquals(expectedResult, result);
2277 
2278     }
2279 
2280 
testAcceptPlainText()2281     public void testAcceptPlainText()
2282       throws ParsingException, IOException, XIncludeException {
2283 
2284         File input = new File(inputDir, "acceptplaintext.xml");
2285         Document doc = builder.build(input);
2286         Document result = XIncluder.resolve(doc);
2287         Document expectedResult = builder.build(
2288           new File(outputDir, "acceptplaintext.xml")
2289         );
2290         assertEquals(expectedResult, result);
2291 
2292     }
2293 
2294 
testAcceptHTML()2295     public void testAcceptHTML()
2296       throws ParsingException, IOException, XIncludeException {
2297 
2298         File input = new File(inputDir, "accepthtml.xml");
2299         Document doc = builder.build(input);
2300         Document result = XIncluder.resolve(doc);
2301         Document expectedResult = builder.build(
2302           new File(outputDir, "accepthtml.xml")
2303         );
2304         assertEquals(expectedResult, result);
2305 
2306     }
2307 
2308 
testBadHTTPHeaderExceptionConstructor()2309     public void testBadHTTPHeaderExceptionConstructor() {
2310 
2311         String message = "test";
2312         XIncludeException ex = new BadHTTPHeaderException(
2313            message, "http://www.example.com/");
2314         assertEquals(message, ex.getMessage());
2315         assertEquals("http://www.example.com/", ex.getURI());
2316 
2317     }
2318 
2319 
testBadHrefAttributerExceptionConstructor()2320     public void testBadHrefAttributerExceptionConstructor() {
2321 
2322         String message = "test";
2323         Exception ex = new BadHrefAttributeException(message);
2324         assertEquals(message, ex.getMessage());
2325 
2326     }
2327 
2328 
testPercentEscapesAreNotAllowedInXPointerAttributes()2329     public void testPercentEscapesAreNotAllowedInXPointerAttributes()
2330       throws ParsingException, IOException, XIncludeException {
2331 
2332         File input = new File(inputDir, "xpointerwithpercentescape.xml");
2333         Document doc = builder.build(input);
2334         try {
2335             XIncluder.resolve(doc);
2336             fail("Allowed xpointer attribute with percent escape");
2337         }
2338         catch (XIncludeException success) {
2339             assertNotNull(success.getMessage());
2340             Exception cause = (Exception) success.getCause();
2341             assertNotNull(cause);
2342         }
2343 
2344     }
2345 
testXPointerExceptionReinitializeCause()2346     public void testXPointerExceptionReinitializeCause()
2347       throws ParsingException, IOException, XIncludeException {
2348 
2349         File input = new File(inputDir, "xpointerwithpercentescape.xml");
2350         Document doc = builder.build(input);
2351         try {
2352             XIncluder.resolve(doc);
2353             fail("Allowed xpointer attribute with percent escape");
2354         }
2355         catch (XIncludeException success) {
2356             Exception cause = (Exception) success.getCause();
2357             try {
2358                 cause.initCause(new Exception());
2359                 fail("Reinitialized cause");
2360             }
2361             catch (IllegalStateException ex) {
2362                 assertNotNull(ex.getMessage());
2363             }
2364         }
2365 
2366     }
2367 
2368 
2369 
2370     // WARNING: this test is one interpretation of the XInclude
2371     // proposed recommendation. It asserts that encoding attributes
2372     // that do not contain legal encoding names are fatal errors.
2373     // This is far from certain. It is also possible the working group
2374     // will choose to interpret these as resource errors.
testMalformedEncodingAttribute()2375     public void testMalformedEncodingAttribute()
2376       throws IOException, ParsingException, XIncludeException {
2377 
2378         File input = new File(inputDir, "badencoding.xml");
2379         Document doc = builder.build(input);
2380         try {
2381             XIncluder.resolve(doc);
2382             fail("Allowed encoding attribute with white space");
2383         }
2384         catch (BadEncodingAttributeException success) {
2385             assertNotNull(success.getMessage());
2386             assertTrue(success.getURI().endsWith(input.getName()));
2387         }
2388 
2389     }
2390 
2391 
testEmptyEncodingAttribute()2392     public void testEmptyEncodingAttribute()
2393       throws IOException, ParsingException, XIncludeException {
2394 
2395         File input = new File(inputDir, "emptyencoding.xml");
2396         Document doc = builder.build(input);
2397         try {
2398             XIncluder.resolve(doc);
2399             fail("Allowed encoding attribute with no value");
2400         }
2401         catch (BadEncodingAttributeException success) {
2402             assertNotNull(success.getMessage());
2403             assertTrue(success.getURI().endsWith(input.getName()));
2404         }
2405 
2406     }
2407 
2408 
testEncodingAttributeStartsWithDigit()2409     public void testEncodingAttributeStartsWithDigit()
2410       throws IOException, ParsingException, XIncludeException {
2411 
2412         File input = new File(inputDir, "digitencoding.xml");
2413         Document doc = builder.build(input);
2414         try {
2415             XIncluder.resolve(doc);
2416             fail("Allowed encoding attribute starting with digit");
2417         }
2418         catch (BadEncodingAttributeException success) {
2419             assertNotNull(success.getMessage());
2420             assertTrue(success.getURI().endsWith(input.getName()));
2421         }
2422 
2423     }
2424 
2425 
2426     // Test that a malformed parse attribute is not thrown when the
2427     // fallback element containing it is not activated.
testHiddenError()2428     public void testHiddenError()
2429       throws ParsingException, IOException, XIncludeException {
2430 
2431         File input = new File(inputDir, "hiddenerror.xml");
2432         Document doc = builder.build(input);
2433         XIncluder.resolve(doc);
2434 
2435     }
2436 
2437 
2438     // Test that an href attribute that has a fragment identifier
2439     // is not a fatal error when the fallback element containing
2440     // it is not activated.
testHiddenError2()2441     public void testHiddenError2()
2442       throws ParsingException, IOException, XIncludeException {
2443 
2444         File input = new File(inputDir, "hiddenerror2.xml");
2445         Document doc = builder.build(input);
2446         XIncluder.resolve(doc);
2447 
2448     }
2449 
2450 
2451     // Test that a fallback element with a non-include parent is not a
2452     // fatal error when the ancestor fallback element containing it is
2453     // not activated.
testHiddenError3()2454     public void testHiddenError3()
2455       throws ParsingException, IOException, XIncludeException {
2456 
2457         File input = new File(inputDir, "hiddenerror3.xml");
2458         Document doc = builder.build(input);
2459         XIncluder.resolve(doc);
2460 
2461     }
2462 
2463 
2464     // Test that an xpointer attribute that uses percent escapes
2465     // is a not a fatal error when the
2466     // fallback element containing it is not activated. See
2467     // http://lists.w3.org/Archives/Public/www-xml-xinclude-comments/2004Oct/0008.html
testXpointerAttributeContainsPercentEscapeInUnactivatedFallback()2468     public void testXpointerAttributeContainsPercentEscapeInUnactivatedFallback()
2469       throws ParsingException, IOException, XIncludeException {
2470 
2471         File input = new File(inputDir, "hiddenerror3.xml");
2472         Document doc = builder.build(input);
2473         XIncluder.resolve(doc);
2474 
2475     }
2476 
2477 
2478 }