1 package parse;
   2 
   3 import java.io.IOException;
   4 import java.io.StringReader;
   5 import java.nio.charset.Charset;
   6 import java.util.ArrayList;
   7 import java.util.List;
   8 import static org.testng.Assert.assertEquals;
   9 import org.testng.annotations.Test;
  10 import org.xml.sax.Attributes;
  11 import org.xml.sax.InputSource;
  12 import org.xml.sax.SAXException;
  13 import org.xml.sax.XMLReader;
  14 import org.xml.sax.ext.DefaultHandler2;
  15 import org.xml.sax.helpers.XMLReaderFactory;
  16 
  17 /**
  18  * JDK-6770436: Entity callback order differs between Java1.5 and Java1.6
  19  * https://bugs.openjdk.java.net/browse/JDK-6770436
  20  *
  21  */
  22 
  23 public class EntityCharacterEventOrder {
  24 
  25     protected final static String xmlEncoding = "ISO-8859-15";
  26     protected static Charset xmlEncodingCharset = null;
  27 
  28     String _xml;
  29     static {
  30         xmlEncodingCharset = Charset.forName(xmlEncoding);
  31     }
  32     /**
  33     public static void main(String[] args) {
  34         TestRunner.run(JDK6770436Test.class);
  35     }
  36 */
  37     @Test
  38     public void entityCallbackOrderJava() throws SAXException, IOException {
  39         final String input = "<element> &amp; some more text</element>";
  40 
  41         final MockContentHandler handler = new MockContentHandler();
  42         final XMLReader xmlReader = XMLReaderFactory.createXMLReader();
  43 
  44         xmlReader.setContentHandler(handler);
  45         xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", handler);
  46 
  47         xmlReader.parse(new InputSource(new StringReader(input)));
  48 
  49         final List<String> events = handler.getEvents();
  50         printEvents(events);
  51         assertCallbackOrder(events); //regression from JDK5
  52     }
  53 
  54     private void assertCallbackOrder(final List<String> events) {
  55         assertEquals("startDocument", events.get(0));
  56         assertEquals("startElement 'element'", events.get(1));
  57         assertEquals("characters ' '", events.get(2));
  58         assertEquals("startEntity 'amp'", events.get(3));
  59         assertEquals("characters '&'", events.get(4));
  60         assertEquals("endEntity 'amp'", events.get(5));
  61         assertEquals("characters ' some more text'", events.get(6));
  62         assertEquals("endElement 'element'", events.get(7));
  63         assertEquals("endDocument", events.get(8));
  64     }
  65 
  66     private void printEvents(final List<String> events) {
  67         events.stream().forEach((e) -> {
  68             System.out.println(e);
  69         });
  70     }
  71     
  72     private class MockContentHandler extends DefaultHandler2 {
  73 
  74         private List<String> events;
  75 
  76         public List<String> getEvents() {
  77             return events;
  78         }
  79 
  80         @Override
  81         public void startDocument() throws SAXException {
  82             events = new ArrayList<String>();
  83             events.add("startDocument");
  84         }
  85 
  86         @Override
  87         public void characters(char[] ch, int start, int length) throws SAXException {
  88             events.add("characters '" + new String(ch, start, length) + "'");
  89         }
  90 
  91         @Override
  92         public void startElement(String uri, String localName, String name, Attributes atts) throws SAXException {
  93             events.add("startElement '" + name + "'");
  94         }
  95 
  96         @Override
  97         public void endElement(String uri, String localName, String name) throws SAXException {
  98             events.add("endElement '" + name + "'");
  99         }
 100 
 101         @Override
 102         public void endDocument() throws SAXException {
 103             events.add("endDocument");
 104         }
 105 
 106         @Override
 107         public void startEntity(String name) throws SAXException {
 108             events.add("startEntity '" + name + "'");
 109         }
 110 
 111         @Override
 112         public void endEntity(String name) throws SAXException {
 113             events.add("endEntity '" + name + "'");
 114         }
 115     }
 116 }