1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.xml;
17
18 import com.fasterxml.aalto.AsyncByteArrayFeeder;
19 import com.fasterxml.aalto.AsyncXMLInputFactory;
20 import com.fasterxml.aalto.AsyncXMLStreamReader;
21 import com.fasterxml.aalto.stax.InputFactoryImpl;
22 import io.netty.buffer.ByteBuf;
23 import io.netty.channel.ChannelHandlerContext;
24 import io.netty.handler.codec.ByteToMessageDecoder;
25
26 import javax.xml.stream.XMLInputFactory;
27 import javax.xml.stream.XMLStreamConstants;
28 import javax.xml.stream.XMLStreamException;
29 import java.util.List;
30
31
32
33
34
35
36
37 public class XmlDecoder extends ByteToMessageDecoder {
38
39 private static final AsyncXMLInputFactory XML_INPUT_FACTORY;
40
41 static {
42
43 InputFactoryImpl factory = new InputFactoryImpl();
44 factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
45 factory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
46 factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.FALSE);
47 XML_INPUT_FACTORY = factory;
48 }
49
50 private static final XmlDocumentEnd XML_DOCUMENT_END = XmlDocumentEnd.INSTANCE;
51
52 private final AsyncXMLStreamReader<AsyncByteArrayFeeder> streamReader = XML_INPUT_FACTORY.createAsyncForByteArray();
53 private final AsyncByteArrayFeeder streamFeeder = streamReader.getInputFeeder();
54
55 @Override
56 protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
57 byte[] buffer = new byte[in.readableBytes()];
58 in.readBytes(buffer);
59 try {
60 streamFeeder.feedInput(buffer, 0, buffer.length);
61 } catch (XMLStreamException exception) {
62 in.skipBytes(in.readableBytes());
63 throw exception;
64 }
65
66 while (!streamFeeder.needMoreInput()) {
67 int type = streamReader.next();
68 switch (type) {
69 case XMLStreamConstants.START_DOCUMENT:
70 out.add(new XmlDocumentStart(streamReader.getEncoding(), streamReader.getVersion(),
71 streamReader.isStandalone(), streamReader.getCharacterEncodingScheme()));
72 break;
73 case XMLStreamConstants.END_DOCUMENT:
74 out.add(XML_DOCUMENT_END);
75 break;
76 case XMLStreamConstants.START_ELEMENT:
77 XmlElementStart elementStart = new XmlElementStart(streamReader.getLocalName(),
78 streamReader.getName().getNamespaceURI(), streamReader.getPrefix());
79 for (int x = 0; x < streamReader.getAttributeCount(); x++) {
80 XmlAttribute attribute = new XmlAttribute(streamReader.getAttributeType(x),
81 streamReader.getAttributeLocalName(x), streamReader.getAttributePrefix(x),
82 streamReader.getAttributeNamespace(x), streamReader.getAttributeValue(x));
83 elementStart.attributes().add(attribute);
84 }
85 for (int x = 0; x < streamReader.getNamespaceCount(); x++) {
86 XmlNamespace namespace = new XmlNamespace(streamReader.getNamespacePrefix(x),
87 streamReader.getNamespaceURI(x));
88 elementStart.namespaces().add(namespace);
89 }
90 out.add(elementStart);
91 break;
92 case XMLStreamConstants.END_ELEMENT:
93 XmlElementEnd elementEnd = new XmlElementEnd(streamReader.getLocalName(),
94 streamReader.getName().getNamespaceURI(), streamReader.getPrefix());
95 for (int x = 0; x < streamReader.getNamespaceCount(); x++) {
96 XmlNamespace namespace = new XmlNamespace(streamReader.getNamespacePrefix(x),
97 streamReader.getNamespaceURI(x));
98 elementEnd.namespaces().add(namespace);
99 }
100 out.add(elementEnd);
101 break;
102 case XMLStreamConstants.PROCESSING_INSTRUCTION:
103 out.add(new XmlProcessingInstruction(streamReader.getPIData(), streamReader.getPITarget()));
104 break;
105 case XMLStreamConstants.CHARACTERS:
106 out.add(new XmlCharacters(streamReader.getText()));
107 break;
108 case XMLStreamConstants.COMMENT:
109 out.add(new XmlComment(streamReader.getText()));
110 break;
111 case XMLStreamConstants.SPACE:
112 out.add(new XmlSpace(streamReader.getText()));
113 break;
114 case XMLStreamConstants.ENTITY_REFERENCE:
115 out.add(new XmlEntityReference(streamReader.getLocalName(), streamReader.getText()));
116 break;
117 case XMLStreamConstants.DTD:
118 out.add(new XmlDTD(streamReader.getText()));
119 break;
120 case XMLStreamConstants.CDATA:
121 out.add(new XmlCdata(streamReader.getText()));
122 break;
123 }
124 }
125 }
126
127 }