1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package org.apache.harmony.tests.javax.xml.parsers;
18 
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.util.HashMap;
24 
25 import org.xml.sax.Attributes;
26 import org.xml.sax.HandlerBase;
27 import org.xml.sax.InputSource;
28 import org.xml.sax.Locator;
29 import org.xml.sax.SAXParseException;
30 import org.xml.sax.helpers.DefaultHandler;
31 
32 /**
33  * Support for SAXParserTest. Shares the element keys used in the golden files.
34  * Compares the result of the parser with golden data.
35  * Contains the handler classes used to track the output of the parser.
36  */
37 class SAXParserTestSupport {
38 
39     public static final char SEPARATOR_ELEMENT = '^';
40     public static final char SEPARATOR_STRING = '$';
41     public static final char SEPARATOR_DATA = '#';
42 
43     public static final String XML_WF = "/wf/";
44     public static final String XML_NWF = "/nwf/";
45 
46     public static final String XML_WF_OUT_DH = "/out_dh/";
47     public static final String XML_WF_OUT_HB = "/out_hb/";
48 
49     public static final String XML_SYSTEM_ID = "." + "/systemid/";
50 
51     public static final String KEY_IS_START_DOC = "isEndDocument";
52     public static final String KEY_IS_END_DOC = "isStartDocument";
53     public static final String KEY_TEXT = "text";
54     public static final String KEY_ERROR = "error";
55     public static final String KEY_FATAL_ERROR = "fatalError";
56     public static final String KEY_WARNING = "warning";
57     public static final String KEY_END_ELEMENT = "endElement";
58     public static final String KEY_END_PREFIX_MAPPING = "endPrefixMapping";
59     public static final String KEY_IGNORABLE_WHITE_SPACE =
60         "ignorableWhitespace";
61     public static final String KEY_NOTATION_DECL = "notationDecl";
62     public static final String KEY_PROCESSING_INSTRUCTION =
63         "processingInstruction";
64     public static final String KEY_RESOLVE_ENTITY = "resolveEntity";
65     public static final String KEY_DOCUMENT_LOCATORS = "documentLocators";
66     public static final String KEY_SKIPPED_ENTITY = "skippedEntity";
67     public static final String KEY_START_ELEMENT = "startElement";
68     public static final String KEY_START_PREFIX_MAPPING = "startPrefixMapping";
69     public static final String KEY_UNPARSED_ENTITY_DECL = "unparsedEntityDecl";
70 
71     static String [] KEYS = {KEY_IS_START_DOC, KEY_IS_END_DOC, KEY_TEXT,
72             KEY_ERROR, KEY_FATAL_ERROR, KEY_WARNING, KEY_END_ELEMENT,
73             KEY_END_PREFIX_MAPPING, KEY_PROCESSING_INSTRUCTION,
74             KEY_SKIPPED_ENTITY, KEY_START_ELEMENT,
75             KEY_START_PREFIX_MAPPING};
76 
77     static {
createTempDirectories()78         createTempDirectories();
79     }
80 
createTempDirectories()81     static void createTempDirectories() {
82         String tmp = System.getProperty("java.io.tmpdir", ".");
83 
84         new File(tmp).mkdirs();
85         new File(tmp, XML_WF).mkdirs();
86         new File(tmp, XML_NWF).mkdirs();
87         new File(tmp, XML_WF_OUT_DH).mkdirs();
88         new File(tmp, XML_WF_OUT_HB).mkdirs();
89     }
90 
91     /**
92      * Initialize the SAXParserTest reference by filling in the data from the
93      * file passed to the method. This will be the reference to compare
94      * against with the output of the parser.
95      */
readFile(String fileName)96     public HashMap<String, String> readFile(String fileName) {
97         HashMap<String, String> storage = new HashMap<String, String>();
98         try {
99 
100             InputStream is = new FileInputStream(fileName);
101 
102             int c = is.read();
103 
104             StringBuffer str = new StringBuffer();
105             int i = 0;
106             while(c != -1) {
107                 if((char)c == SEPARATOR_DATA) {
108                   //  if(str.length() > 0) {
109                         if(i < KEYS.length) {
110                             storage.put(KEYS[i], str.toString());
111                         //    System.out.println(str.toString());
112                             str.setLength(0);
113                             i++;
114                         }
115                   //  }
116                 } else {
117                     str.append((char)c);
118                 }
119                 try {
120                     c = is.read();
121                 } catch (Exception e) {
122                     c = -1;
123                 }
124             }
125             try {
126                 is.close();
127             } catch (IOException e) {
128             }
129 
130         } catch(IOException ioe) {
131             System.out.println("IOException during processing the file: "
132                     + fileName);
133         }
134         return storage;
135     }
136 
137     /**
138      * Compares the content of two HashMaps. One map should be the reference
139      * containing the correct string for each xml document element and the other
140      * should contain the elements filled with output from the parser.
141      *
142      * @param original the reference
143      * @param result the result of the parser
144      * @return true if they're equal.
145      */
equalsMaps(HashMap<String, String> original, HashMap<String, String> result)146     public static boolean equalsMaps(HashMap<String, String> original,
147             HashMap<String, String> result) {
148 
149         if(original == null && result == null) {
150             return true;
151         } else {
152             if(original.size() != result.size()) return false;
153 
154             for(int i = 0; i < KEYS.length; i++) {
155                 if(!original.get(KEYS[i]).equals(result.get(KEYS[i]))) {
156                     System.out.println("for "+KEYS[i]+": original:" +
157                             original.get(KEYS[i]));
158                     System.out.println();
159                     System.out.println("  result:" + result.get(KEYS[i]));
160                     System.out.println();
161                     return false;
162                 }
163             }
164             return true;
165         }
166     }
167 
168     static class MyDefaultHandler extends DefaultHandler {
169 
170         public StringBuffer data_isEndDocument = new StringBuffer();
171         public StringBuffer data_isStartDocument = new StringBuffer();
172         public StringBuffer data_text = new StringBuffer();
173         public StringBuffer data_error = new StringBuffer();
174         public StringBuffer data_fatalError = new StringBuffer();
175         public StringBuffer data_warning = new StringBuffer();
176         public StringBuffer data_endElement = new StringBuffer();
177         public StringBuffer data_endPrefixMapping = new StringBuffer();
178         public StringBuffer data_processingInstruction = new StringBuffer();
179         public StringBuffer data_skippedEntity = new StringBuffer();
180         public StringBuffer data_startElement = new StringBuffer();
181         public StringBuffer data_startPrefixMapping = new StringBuffer();
182 
createData()183         public HashMap<String, String> createData() {
184             HashMap<String, String> hm = new HashMap<String, String>();
185             hm.put(KEY_IS_END_DOC, data_isEndDocument.toString());
186             hm.put(KEY_IS_START_DOC, data_isStartDocument.toString());
187             hm.put(KEY_TEXT, data_text.toString());
188             hm.put(KEY_ERROR, data_error.toString());
189             hm.put(KEY_FATAL_ERROR, data_fatalError.toString());
190             hm.put(KEY_WARNING, data_warning.toString());
191             hm.put(KEY_END_ELEMENT, data_endElement.toString());
192             hm.put(KEY_END_PREFIX_MAPPING, data_endPrefixMapping.toString());
193 
194             hm.put(KEY_PROCESSING_INSTRUCTION,
195                     data_processingInstruction.toString());
196             hm.put(KEY_SKIPPED_ENTITY, data_skippedEntity.toString());
197             hm.put(KEY_START_ELEMENT, data_startElement.toString());
198             hm.put(KEY_START_PREFIX_MAPPING,
199                     data_startPrefixMapping.toString());
200             return hm;
201         }
202 
printMap()203         public void printMap() {
204             System.out.print(data_isStartDocument.toString() + SEPARATOR_DATA +
205                     data_isEndDocument.toString() + SEPARATOR_DATA +
206                     data_text.toString() + SEPARATOR_DATA +
207                     data_error.toString()+ SEPARATOR_DATA +
208                     data_fatalError.toString()+ SEPARATOR_DATA +
209                     data_warning.toString()+ SEPARATOR_DATA +
210                     data_endElement.toString() + SEPARATOR_DATA+
211                     data_endPrefixMapping.toString()+ SEPARATOR_DATA +
212                     data_processingInstruction.toString() + SEPARATOR_DATA +
213                     data_skippedEntity.toString() +  SEPARATOR_DATA +
214                     data_startElement.toString() + SEPARATOR_DATA +
215                     data_startPrefixMapping.toString()+ SEPARATOR_DATA);
216         }
217 
218         @Override
characters(char[] ch, int start, int length)219         public void characters(char[] ch, int start, int length) {
220             String str = new String(ch, start, length);
221             data_text.append(str);
222             // different sax parsers are allowed to handle chunking differently,
223             // therefore we cannot rely on identical chunks being delivered.
224             //data_text.append(ParsingSupport.SEPARATOR_ELEMENT);
225         }
226 
227         @Override
endDocument()228         public void endDocument() {
229             data_isEndDocument.append(true);
230             data_isEndDocument.append(SEPARATOR_ELEMENT);
231         }
232 
233         @Override
endElement(String uri, String localName, String qName)234         public void endElement(String uri, String localName, String qName) {
235             StringBuffer sb = new StringBuffer();
236             sb.append(uri);
237             sb.append(SEPARATOR_STRING);
238             sb.append(localName);
239             sb.append(SEPARATOR_STRING);
240             sb.append(qName);
241             data_endElement.append(sb);
242             data_endElement.append(SEPARATOR_ELEMENT);
243         }
244 
245         @Override
endPrefixMapping(String prefix)246         public void endPrefixMapping(String prefix) {
247             data_endPrefixMapping.append(prefix);
248             data_endPrefixMapping.append(SEPARATOR_ELEMENT);
249         }
250 
251         @Override
error(SAXParseException e)252         public void error(SAXParseException e) {
253             data_error.append(e);
254             data_error.append(SEPARATOR_ELEMENT);
255         }
256 
257         @Override
fatalError(SAXParseException e)258         public void fatalError(SAXParseException e) {
259             data_fatalError.append(e);
260             data_fatalError.append(SEPARATOR_ELEMENT);
261         }
262 
263         @Override
ignorableWhitespace(char[] ch, int start, int length)264         public void ignorableWhitespace(char[] ch, int start, int length) {
265             /*    String s = new String(ch, start, length);
266             ignorableWhitespace.append(s);
267             ignorableWhitespace.append(ParsingSupport.SEPARATOR_ELEMENT);*/
268         }
269 
270         @Override
notationDecl(String name, String publicId, String systemId)271         public void notationDecl(String name, String publicId,
272                 String systemId) {
273             /* data_notationDecl.append(name + ParsingSupport.SEPARATOR_STRING +
274                               publicId + ParsingSupport.SEPARATOR_STRING +
275                               systemId + ParsingSupport.SEPARATOR_STRING);
276             data_notationDecl.append(ParsingSupport.SEPARATOR_ELEMENT);*/
277         }
278 
279         @Override
processingInstruction(String target, String data)280         public void processingInstruction(String target, String data) {
281             data_processingInstruction.append(target + SEPARATOR_STRING + data);
282             data_processingInstruction.append(SEPARATOR_ELEMENT);
283         }
284 
285         @Override
resolveEntity(String publicId, String systemId)286         public InputSource    resolveEntity(String publicId, String systemId) {
287             // data_resolveEntity.append(publicId +
288             //            ParsingSupport.SEPARATOR_STRING + systemId);
289             // data_resolveEntity.append(ParsingSupport.SEPARATOR_ELEMENT);
290             return null;
291         }
292 
293         @Override
setDocumentLocator(Locator locator)294         public void setDocumentLocator(Locator locator) {
295             //       data_documentLocators.append(locator);
296             // data_documentLocators.append(ParsingSupport.SEPARATOR_ELEMENT);
297         }
298 
299         @Override
skippedEntity(String name)300         public void skippedEntity(String name) {
301             data_skippedEntity.append(name);
302             data_skippedEntity.append(SEPARATOR_ELEMENT);
303         }
304 
305         @Override
startDocument()306         public void startDocument() {
307             data_isStartDocument.append(true);
308             data_isStartDocument.append(SEPARATOR_ELEMENT);
309         }
310 
311         @Override
startElement(String uri, String localName, String qName, Attributes attributes)312         public void startElement(String uri, String localName, String qName,
313                 Attributes attributes) {
314             data_startElement.append(uri);
315             data_startElement.append(SEPARATOR_STRING);
316             data_startElement.append(localName);
317             data_startElement.append(SEPARATOR_STRING);
318             data_startElement.append(qName);
319 
320             for(int i = 0; i < attributes.getLength(); i ++)
321                 data_startElement.append(
322                         SEPARATOR_STRING +attributes.getQName(i) +
323                         SEPARATOR_STRING + attributes.getValue(i));
324 
325             data_isStartDocument.append(SEPARATOR_ELEMENT);
326         }
327 
328         @Override
startPrefixMapping(String prefix, String uri)329         public void startPrefixMapping(String prefix, String uri) {
330             data_startPrefixMapping.append(prefix + SEPARATOR_STRING + uri);
331         }
332 
333         @Override
unparsedEntityDecl(String name, String publicId, String systemId, String notationName)334         public void unparsedEntityDecl(String name, String publicId,
335                 String systemId, String notationName) {
336             // data_unparsedEntityDecl.append(name
337             //     + ParsingSupport.SEPARATOR_STRING + publicId
338             //     + ParsingSupport.SEPARATOR_STRING
339             //     + systemId + ParsingSupport.SEPARATOR_STRING + notationName);
340         }
341 
342         @Override
warning(SAXParseException e)343         public void warning(SAXParseException e) {
344             data_warning.append(e);
345         }
346     }
347 
348     @SuppressWarnings("deprecation")
349     static class MyHandler extends HandlerBase {
350 
351         public StringBuffer data_isEndDocument = new StringBuffer();
352         public StringBuffer data_isStartDocument = new StringBuffer();
353         public StringBuffer data_text = new StringBuffer();
354         public StringBuffer data_error = new StringBuffer();
355         public StringBuffer data_fatalError = new StringBuffer();
356         public StringBuffer data_warning = new StringBuffer();
357         public StringBuffer data_endElement = new StringBuffer();
358         public StringBuffer data_endPrefixMapping = new StringBuffer();
359         public StringBuffer data_processingInstruction = new StringBuffer();
360         public StringBuffer data_skippedEntity = new StringBuffer();
361         public StringBuffer data_startElement = new StringBuffer();
362         public StringBuffer data_startPrefixMapping = new StringBuffer();
363 
printMap()364         public void printMap() {
365             System.out.print(data_isStartDocument.toString() + SEPARATOR_DATA +
366                     data_isEndDocument.toString() + SEPARATOR_DATA +
367                     data_text.toString() + SEPARATOR_DATA +
368                     data_error.toString()+ SEPARATOR_DATA +
369                     data_fatalError.toString()+ SEPARATOR_DATA +
370                     data_warning.toString()+ SEPARATOR_DATA +
371                     data_endElement.toString() + SEPARATOR_DATA+
372                     data_endPrefixMapping.toString()+ SEPARATOR_DATA +
373                     data_processingInstruction.toString() + SEPARATOR_DATA +
374                     data_skippedEntity.toString() +  SEPARATOR_DATA +
375                     data_startElement.toString() + SEPARATOR_DATA +
376                     data_startPrefixMapping.toString()+ SEPARATOR_DATA);
377         }
378 
createData()379         public HashMap<String, String> createData() {
380             HashMap<String, String> hm = new HashMap<String, String>();
381             hm.put(KEY_IS_END_DOC, data_isEndDocument.toString());
382             hm.put(KEY_IS_START_DOC, data_isStartDocument.toString());
383             hm.put(KEY_TEXT, data_text.toString());
384             hm.put(KEY_ERROR, data_error.toString());
385             hm.put(KEY_FATAL_ERROR, data_fatalError.toString());
386             hm.put(KEY_WARNING, data_warning.toString());
387             hm.put(KEY_END_ELEMENT, data_endElement.toString());
388             hm.put(KEY_END_PREFIX_MAPPING, data_endPrefixMapping.toString());
389             hm.put(KEY_PROCESSING_INSTRUCTION,
390                     data_processingInstruction.toString());
391             hm.put(KEY_SKIPPED_ENTITY, data_skippedEntity.toString());
392             hm.put(KEY_START_ELEMENT, data_startElement.toString());
393             hm.put(KEY_START_PREFIX_MAPPING,
394                     data_startPrefixMapping.toString());
395             return hm;
396         }
397 
398         @Override
characters(char[] ch, int start, int length)399         public void characters(char[] ch, int start, int length) {
400             String str = new String(ch, start, length);
401             data_text.append(str);
402             // different sax parsers are allowed to handle chunking differently,
403             // therefore we cannot rely on identical chunks being delivered.
404             //data_text.append(ParsingSupport.SEPARATOR_ELEMENT);
405         }
406 
407         @Override
endDocument()408         public void    endDocument() {
409             data_isEndDocument.append(true);
410             data_isEndDocument.append(SEPARATOR_ELEMENT);
411         }
412 
endElement(String uri, String localName, String qName)413         public void endElement(String uri, String localName, String qName) {
414             StringBuffer sb = new StringBuffer();
415             sb.append(uri);
416             sb.append(SEPARATOR_STRING);
417             sb.append(localName);
418             sb.append(SEPARATOR_STRING);
419             sb.append(qName);
420             data_endElement.append(sb);
421             data_endElement.append(SEPARATOR_ELEMENT);
422         }
423 
424         @Override
error(SAXParseException e)425         public void error(SAXParseException e) {
426             data_error.append(e);
427             data_error.append(SEPARATOR_ELEMENT);
428         }
429 
430         @Override
fatalError(SAXParseException e)431         public void fatalError(SAXParseException e) {
432             data_fatalError.append(e);
433             data_fatalError.append(SEPARATOR_ELEMENT);
434         }
435 
436         @Override
ignorableWhitespace(char[] ch, int start, int length)437         public void ignorableWhitespace(char[] ch, int start, int length) {
438 
439         }
440 
441         @Override
notationDecl(String name, String publicId, String systemId)442         public void notationDecl(String name, String publicId,
443                 String systemId) {
444 
445         }
446 
447         @Override
processingInstruction(String target, String data)448         public void processingInstruction(String target, String data) {
449             data_processingInstruction.append(target + SEPARATOR_STRING + data);
450             data_processingInstruction.append(SEPARATOR_ELEMENT);
451         }
452 
453         @Override
resolveEntity(String publicId, String systemId)454         public InputSource    resolveEntity(String publicId, String systemId) {
455             return null;
456         }
457 
458         @Override
setDocumentLocator(Locator locator)459         public void setDocumentLocator(Locator locator) {
460 
461         }
462 
463         @Override
startDocument()464         public void startDocument() {
465             data_isStartDocument.append(true);
466             data_isStartDocument.append(SEPARATOR_ELEMENT);
467         }
468 
startElement(String uri, String localName, String qName, Attributes attributes)469         public void startElement(String uri, String localName, String qName,
470                 Attributes attributes) {
471             data_startElement.append(uri);
472             data_startElement.append(SEPARATOR_STRING);
473             data_startElement.append(localName);
474             data_startElement.append(SEPARATOR_STRING);
475             data_startElement.append(qName);
476 
477             for(int i = 0; i < attributes.getLength(); i ++)
478                 data_startElement.append(SEPARATOR_STRING
479                         + attributes.getQName(i) +
480                         SEPARATOR_STRING + attributes.getValue(i));
481 
482             data_isStartDocument.append(SEPARATOR_ELEMENT);
483         }
484 
485         @Override
unparsedEntityDecl(String name, String publicId, String systemId, String notationName)486         public void unparsedEntityDecl(String name, String publicId,
487                 String systemId, String notationName) {
488 
489         }
490 
491         @Override
warning(SAXParseException e)492         public void warning(SAXParseException e) {
493             data_warning.append(e);
494         }
495     }
496 }
497