KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > nu > xom > tests > CanonicalizerTest


1 /* Copyright 2002-2004 Elliotte Rusty Harold
2    
3    This library is free software; you can redistribute it and/or modify
4    it under the terms of version 2.1 of the GNU Lesser General Public
5    License as published by the Free Software Foundation.
6    
7    This library is distributed in the hope that it will be useful,
8    but WITHOUT ANY WARRANTY; without even the implied warranty of
9    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10    GNU Lesser General Public License for more details.
11    
12    You should have received a copy of the GNU Lesser General Public
13    License along with this library; if not, write to the
14    Free Software Foundation, Inc., 59 Temple Place, Suite 330,
15    Boston, MA 02111-1307 USA
16    
17    You can contact Elliotte Rusty Harold by sending e-mail to
18    elharo@metalab.unc.edu. Please include the word "XOM" in the
19    subject line. The XOM home page is located at http://www.xom.nu/
20 */

21
22 package nu.xom.tests;
23
24 import java.io.BufferedInputStream JavaDoc;
25 import java.io.ByteArrayInputStream JavaDoc;
26 import java.io.ByteArrayOutputStream JavaDoc;
27 import java.io.DataInputStream JavaDoc;
28 import java.io.File JavaDoc;
29 import java.io.FileInputStream JavaDoc;
30 import java.io.FilenameFilter JavaDoc;
31 import java.io.IOException JavaDoc;
32 import java.io.InputStream JavaDoc;
33
34 import com.ibm.icu.text.Normalizer;
35
36 import nu.xom.Attribute;
37 import nu.xom.Builder;
38 import nu.xom.Document;
39 import nu.xom.Element;
40 import nu.xom.Elements;
41 import nu.xom.ParsingException;
42 import nu.xom.canonical.Canonicalizer;
43
44 /**
45  * <p>
46  * Tests canonicalization.
47  * </p>
48  *
49  * @author Elliotte Rusty Harold
50  * @version 1.0
51  *
52  */

53 public class CanonicalizerTest extends XOMTestCase {
54
55     private final static double version = Double.parseDouble(
56       System.getProperty("java.version").substring(0,3)
57     );
58     
59     private File JavaDoc canonical;
60     private File JavaDoc input;
61     private File JavaDoc output;
62     
63     public CanonicalizerTest(String JavaDoc name) {
64         super(name);
65     }
66
67     
68     private Builder builder = new Builder();
69     
70     
71     protected void setUp() {
72         File JavaDoc data = new File JavaDoc("data");
73         canonical = new File JavaDoc(data, "canonical");
74         input = new File JavaDoc(canonical, "input");
75         output = new File JavaDoc(canonical, "output");
76     }
77
78     
79     public void testWithComments() throws ParsingException, IOException JavaDoc {
80       
81         File JavaDoc tests = input;
82         String JavaDoc[] inputs = tests.list(new XMLFilter());
83         for (int i = 0; i < inputs.length; i++) {
84             File JavaDoc input = new File JavaDoc(tests, inputs[i]);
85             Document doc = builder.build(input);
86             ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc();
87             try {
88                 Canonicalizer serializer = new Canonicalizer(out);
89                 serializer.write(doc);
90             }
91             finally {
92                 out.close();
93             }
94             byte[] actual = out.toByteArray();
95             
96             File JavaDoc expected = new File JavaDoc(output, input.getName() + ".out");
97             assertEquals(
98               input.getName(), expected.length(), actual.length);
99             byte[] expectedBytes = new byte[actual.length];
100             InputStream JavaDoc fin = new FileInputStream JavaDoc(expected);
101             DataInputStream JavaDoc in = new DataInputStream JavaDoc(fin);
102             try {
103                 in.readFully(expectedBytes);
104             }
105             finally {
106                 in.close();
107             }
108             for (int j = 0; j < expectedBytes.length; j++) {
109                 assertEquals(expectedBytes[i], actual[i]);
110             }
111             
112         }
113         
114     }
115     
116     
117     public void testWithoutComments()
118       throws ParsingException, IOException JavaDoc {
119       
120         File JavaDoc tests = input;
121         String JavaDoc[] inputs = tests.list(new XMLFilter());
122         for (int i = 0; i < inputs.length; i++) {
123             File JavaDoc input = new File JavaDoc(tests, inputs[i]);
124             Document doc = builder.build(input);
125            
126             ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc();
127             try {
128                 Canonicalizer serializer
129                   = new Canonicalizer(out, false);
130                 serializer.write(doc);
131             }
132             finally {
133                 out.close();
134             }
135             
136             byte[] actual = out.toByteArray();
137             
138             // for debugging
139
/* File debug = new File(canonical, "debug/"
140              + input.getName() + ".dbg");
141             OutputStream fout = new FileOutputStream(debug);
142             fout.write(actual);
143             fout.close(); */

144             
145             File JavaDoc expected = new File JavaDoc(canonical, "wocommentsoutput/");
146             expected = new File JavaDoc(expected, input.getName() + ".out");
147             byte[] expectedBytes = new byte[actual.length];
148             InputStream JavaDoc fin = new FileInputStream JavaDoc(expected);
149             DataInputStream JavaDoc in = new DataInputStream JavaDoc(fin);
150             try {
151                 in.readFully(expectedBytes);
152             }
153             finally {
154                 in.close();
155             }
156             for (int j = 0; j < expectedBytes.length; j++) {
157                 assertEquals(expectedBytes[i], actual[i]);
158             }
159             out.close();
160
161         }
162         
163     }
164     
165     
166     public void testRelativeNamespaceURIsForbidden()
167       throws ParsingException, IOException JavaDoc {
168         
169         try {
170             String JavaDoc data = "<test xmlns=\"relative\">data</test>";
171             Document doc = builder.build(data, "http://www.ex.org/");
172             ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc();
173             Canonicalizer serializer
174               = new Canonicalizer(out, false);
175             serializer.write(doc);
176             fail("Canonicalized document with relative namespace URI");
177         }
178         catch (ParsingException success) {
179             assertNotNull(success.getMessage());
180         }
181         
182     }
183     
184     
185 /* public void testNodeList()
186       throws ParsingException, IOException {
187         
188         Element element = new Element("test");
189         Nodes nodes = new Nodes();
190         nodes.append(element);
191         ByteArrayOutputStream out = new ByteArrayOutputStream();
192         Canonicalizer serializer
193           = new Canonicalizer(out, false);
194         serializer.write(nodes);
195         serializer.flush();
196         byte[] data = out.toByteArray();
197         String result = new String(data, "UTF-8");
198         assertEquals("<test></test>", result);
199         
200     }
201     
202     public void testNodeListNamespace()
203       throws ParsingException, IOException {
204         
205         Element parent = new Element("parent");
206         parent.addNamespaceDeclaration(
207           "pre", "http://www.example.com/");
208         Element element = new Element("test");
209         parent.appendChild(element);
210         Nodes nodes = new Nodes();
211         nodes.append(element);
212         ByteArrayOutputStream out = new ByteArrayOutputStream();
213         Canonicalizer serializer
214           = new Canonicalizer(out, false);
215         serializer.write(nodes);
216         serializer.flush();
217         byte[] data = out.toByteArray();
218         String result = new String(data, "UTF-8");
219         assertEquals(
220           "<test xmlns:pre=\"http://www.example.com/\"></test>",
221           result
222         );
223         
224     }
225     
226     public void testNodeListXMLAttributes()
227       throws ParsingException, IOException {
228         
229         Element grandparent = new Element("grandparent");
230         grandparent.addAttribute(new Attribute("xml:base",
231           "http://www.w3.org/XML/1998/namespace",
232           "http://www.example.com/"));
233         grandparent.addAttribute(new Attribute("testing",
234           "This should not appear in the output"));
235         Element parent = new Element("parent");
236         grandparent.appendChild(parent);
237         Document doc = new Document(grandparent);
238         parent.addAttribute(new Attribute("xml:space",
239           "http://www.w3.org/XML/1998/namespace", "preserve"));
240         Element element = new Element("test");
241         parent.appendChild(element);
242         Nodes nodes = new Nodes();
243         nodes.append(element);
244         ByteArrayOutputStream out = new ByteArrayOutputStream();
245         Canonicalizer serializer
246           = new Canonicalizer(out, false);
247         serializer.write(nodes);
248         serializer.flush();
249         byte[] data = out.toByteArray();
250         String result = new String(data, "UTF-8");
251         assertEquals(
252           "<test xml:base=\"http://www.example.com/\" xml:space=\"preserve\"></test>",
253           result);
254         
255     } */

256     
257     private static class XMLFilter implements FilenameFilter JavaDoc {
258                 
259         public boolean accept(File JavaDoc directory, String JavaDoc name) {
260             if (name.endsWith(".xml")) return true;
261             return false;
262         }
263         
264     }
265     
266     
267     public void testNFCFromISO88591()
268       throws ParsingException, IOException JavaDoc {
269         isoNormalizationTest("ISO-8859-1");
270     }
271     
272     
273     public void testNFCFromISO88592()
274       throws ParsingException, IOException JavaDoc {
275         isoNormalizationTest("ISO-8859-2");
276     }
277     
278     
279     public void testNFCFromISO88593()
280       throws ParsingException, IOException JavaDoc {
281         isoNormalizationTest("ISO-8859-3");
282     }
283     
284     
285     public void testNFCFromISO88594()
286       throws ParsingException, IOException JavaDoc {
287         isoNormalizationTest("ISO-8859-4");
288     }
289     
290     
291     public void testNFCFromISO88595()
292       throws ParsingException, IOException JavaDoc {
293         isoNormalizationTest("ISO-8859-5");
294     }
295     
296     
297     public void testNFCFromISO88596()
298       throws ParsingException, IOException JavaDoc {
299         
300         // This test fails in 1.2.2 due to an apparent bug in the
301
// conversion of the characters '1' and '0' to bytes in
302
// ISO-8859-6
303
isoNormalizationTest("ISO-8859-6");
304         
305     }
306     
307     
308     public void testNFCFromISO88597()
309       throws ParsingException, IOException JavaDoc {
310         isoNormalizationTest("ISO-8859-7");
311     }
312     
313     
314     public void testNFCFromISO88598()
315       throws ParsingException, IOException JavaDoc {
316         isoNormalizationTest("ISO-8859-8");
317     }
318     
319     
320     public void testNFCFromISO88599()
321       throws ParsingException, IOException JavaDoc {
322         isoNormalizationTest("ISO-8859-9");
323     }
324     
325     
326     public void testNFCFromISO885913()
327       throws ParsingException, IOException JavaDoc {
328         
329         if (version >= 1.3) {
330             // iSO-8859-6 not supported in Java 1.2
331
isoNormalizationTest("ISO-8859-13");
332         }
333         
334     }
335
336     
337     public void testNFCFromISO885915()
338       throws ParsingException, IOException JavaDoc {
339         isoNormalizationTest("ISO-8859-15");
340     }
341     
342     
343     // 14 and 16 aren't tested because Java doesn't support them yet
344
private void isoNormalizationTest(String JavaDoc encoding)
345       throws ParsingException, IOException JavaDoc {
346         
347         String JavaDoc prolog = "<?xml version='1.0' encoding='"
348           + encoding + "'?>\r\n<root>";
349         
350         byte[] prologData = prolog.getBytes(encoding);
351         
352         String JavaDoc epilog = "</root>";
353         byte[] epilogData = epilog.getBytes(encoding);
354         byte[] data = new byte[prologData.length + epilogData.length + 255 - 160 + 1];
355         System.arraycopy(prologData, 0, data, 0, prologData.length);
356         System.arraycopy(epilogData, 0, data,
357           data.length - epilogData.length, epilogData.length);
358         for (int i = 160; i <= 255; i++) {
359             data[prologData.length + (i-160)] = (byte) i;
360         }
361         InputStream JavaDoc in = new ByteArrayInputStream JavaDoc(data);
362         Document doc = builder.build(in);
363         String JavaDoc rawResult = doc.getValue();
364         String JavaDoc normalizedResult = Normalizer.normalize(rawResult, Normalizer.NFC);
365         assertEquals("Parser doesn't use NFC when converting from " + encoding,
366           normalizedResult, rawResult);
367         
368     }
369
370     
371     public void testEBCDIC()
372       throws ParsingException, IOException JavaDoc {
373           
374         String JavaDoc encoding = "IBM037";
375         String JavaDoc prolog = "<?xml version='1.0' encoding='"
376           + encoding + "'?>\r\n<root>";
377         byte[] prologData = prolog.getBytes(encoding);
378         String JavaDoc epilog = "</root>";
379         byte[] epilogData = epilog.getBytes(encoding);
380         byte[] data = new byte[prologData.length + epilogData.length + 255 - 160 + 1];
381         System.arraycopy(prologData, 0, data, 0, prologData.length);
382         System.arraycopy(epilogData, 0, data,
383           data.length - epilogData.length, epilogData.length);
384         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(255 - 160 + 1);
385         for (int i = 160; i <= 255; i++) {
386             buffer.append((char) i);
387         }
388         byte[] temp = buffer.toString().getBytes(encoding);
389         System.arraycopy(temp, 0, data, prologData.length, temp.length);
390         InputStream JavaDoc in = new ByteArrayInputStream JavaDoc(data);
391         Document doc = builder.build(in);
392         String JavaDoc rawResult = doc.getValue();
393         String JavaDoc normalizedResult = Normalizer.normalize(rawResult, Normalizer.NFC);
394         assertEquals("Parser doesn't use NFC when converting from " + encoding,
395           normalizedResult, rawResult);
396         
397     }
398
399     
400     // make sure null pointer exception doesn't cause any output
401
public void testNullDocument()
402       throws IOException JavaDoc {
403         
404         ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc();
405         Canonicalizer canonicalizer = new Canonicalizer(out);
406         try {
407             canonicalizer.write(null);
408             fail("Wrote null document");
409         }
410         catch (NullPointerException JavaDoc success) {
411             // success
412
}
413         byte[] result = out.toByteArray();
414         assertEquals(0, result.length);
415         
416     }
417     
418     
419     public void testWhiteSpaceTrimmingInNonCDATAAttribute()
420       throws IOException JavaDoc {
421         Attribute attribute = new Attribute("name", " value1 value2 ");
422         attribute.setType(Attribute.Type.NMTOKENS);
423         Element root = new Element("root");
424         root.addAttribute(attribute);
425         Document doc = new Document(root);
426         ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc();
427         Canonicalizer canonicalizer = new Canonicalizer(out);
428         canonicalizer.write(doc);
429         out.close();
430         String JavaDoc result = new String JavaDoc(out.toByteArray(), "UTF8");
431         assertEquals("<root name=\"value1 value2\"></root>", result);
432     }
433     
434     
435     // compare to output generated by Apache XML Security code
436
public void testXMLConformanceTestSuiteDocuments()
437       throws ParsingException, IOException JavaDoc {
438       
439         File JavaDoc masterList = new File JavaDoc(canonical, "xmlconf");
440         masterList = new File JavaDoc(masterList, "xmlconf.xml");
441         if (masterList.exists()) {
442             Document xmlconf = builder.build(masterList);
443             Elements testcases = xmlconf.getRootElement().getChildElements("TESTCASES");
444             processTestCases(testcases);
445         }
446
447     }
448
449     
450     // xmlconf/xmltest/valid/sa/097.xml appears to be screwed up by a lot
451
// of parsers
452
private void processTestCases(Elements testcases)
453       throws ParsingException, IOException JavaDoc {
454         
455         for (int i = 0; i < testcases.size(); i++) {
456               Element testcase = testcases.get(i);
457               Elements tests = testcase.getChildElements("TEST");
458               processTests(tests);
459               Elements level2 = testcase.getChildElements("TESTCASES");
460               // need to be recursive to handle recursive IBM test cases
461
processTestCases(level2);
462         }
463         
464     }
465
466
467     private void processTests(Elements tests)
468       throws ParsingException, IOException JavaDoc {
469         
470         for (int i = 0; i < tests.size(); i++) {
471             Element test = tests.get(i);
472             String JavaDoc namespace = test.getAttributeValue("NAMESPACE");
473             if ("no".equals(namespace)) continue;
474             String JavaDoc type = test.getAttributeValue("TYPE");
475             if ("not-wf".equals(type)) continue;
476             String JavaDoc uri = test.getAttributeValue("URI");
477             String JavaDoc base = test.getBaseURI();
478             // Hack because URIUtil isn't public; and I don't want to
479
// depend on 1.4 only java.net.URI
480
Element parent = new Element("e");
481             parent.setBaseURI(base);
482             Element child = new Element("a");
483             child.addAttribute(new Attribute("xml:base",
484               "http://www.w3.org/XML/1998/namespace", uri));
485             parent.appendChild(child);
486             String JavaDoc resolvedURI = child.getBaseURI();
487             
488             Document doc = builder.build(resolvedURI);
489             ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc();
490             try {
491                 Canonicalizer serializer = new Canonicalizer(out);
492                 serializer.write(doc);
493             }
494             finally {
495                 out.close();
496             }
497             byte[] actual = out.toByteArray();
498             
499             File JavaDoc input = new File JavaDoc(resolvedURI.substring(5) + ".can");
500             assertEquals(resolvedURI, input.length(), actual.length);
501             byte[] expected = new byte[actual.length];
502             DataInputStream JavaDoc in = new DataInputStream JavaDoc(
503               new BufferedInputStream JavaDoc(new FileInputStream JavaDoc(input)));
504             try {
505                 in.readFully(expected);
506             }
507             finally {
508                 in.close();
509             }
510             for (int j = 0; j < expected.length; j++) {
511                 assertEquals(resolvedURI + " at byte " + j,
512                   expected[j], actual[j]);
513             }
514             
515         }
516         
517     }
518
519
520 }
521
Popular Tags