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.XMLStreamConstants;
27 import javax.xml.stream.XMLStreamException;
28 import java.util.List;
29
30
31
32
33
34
35
36 public class XmlDecoder extends ByteToMessageDecoder {
37
38 private static final AsyncXMLInputFactory XML_INPUT_FACTORY = new InputFactoryImpl();
39 private static final XmlDocumentEnd XML_DOCUMENT_END = XmlDocumentEnd.INSTANCE;
40
41 private final AsyncXMLStreamReader<AsyncByteArrayFeeder> streamReader = XML_INPUT_FACTORY.createAsyncForByteArray();
42 private final AsyncByteArrayFeeder streamFeeder = streamReader.getInputFeeder();
43
44 @Override
45 protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
46 byte[] buffer = new byte[in.readableBytes()];
47 in.readBytes(buffer);
48 try {
49 streamFeeder.feedInput(buffer, 0, buffer.length);
50 } catch (XMLStreamException exception) {
51 in.skipBytes(in.readableBytes());
52 throw exception;
53 }
54
55 while (!streamFeeder.needMoreInput()) {
56 int type = streamReader.next();
57 switch (type) {
58 case XMLStreamConstants.START_DOCUMENT:
59 out.add(new XmlDocumentStart(streamReader.getEncoding(), streamReader.getVersion(),
60 streamReader.isStandalone(), streamReader.getCharacterEncodingScheme()));
61 break;
62 case XMLStreamConstants.END_DOCUMENT:
63 out.add(XML_DOCUMENT_END);
64 break;
65 case XMLStreamConstants.START_ELEMENT:
66 XmlElementStart elementStart = new XmlElementStart(streamReader.getLocalName(),
67 streamReader.getName().getNamespaceURI(), streamReader.getPrefix());
68 for (int x = 0; x < streamReader.getAttributeCount(); x++) {
69 XmlAttribute attribute = new XmlAttribute(streamReader.getAttributeType(x),
70 streamReader.getAttributeLocalName(x), streamReader.getAttributePrefix(x),
71 streamReader.getAttributeNamespace(x), streamReader.getAttributeValue(x));
72 elementStart.attributes().add(attribute);
73 }
74 for (int x = 0; x < streamReader.getNamespaceCount(); x++) {
75 XmlNamespace namespace = new XmlNamespace(streamReader.getNamespacePrefix(x),
76 streamReader.getNamespaceURI(x));
77 elementStart.namespaces().add(namespace);
78 }
79 out.add(elementStart);
80 break;
81 case XMLStreamConstants.END_ELEMENT:
82 XmlElementEnd elementEnd = new XmlElementEnd(streamReader.getLocalName(),
83 streamReader.getName().getNamespaceURI(), streamReader.getPrefix());
84 for (int x = 0; x < streamReader.getNamespaceCount(); x++) {
85 XmlNamespace namespace = new XmlNamespace(streamReader.getNamespacePrefix(x),
86 streamReader.getNamespaceURI(x));
87 elementEnd.namespaces().add(namespace);
88 }
89 out.add(elementEnd);
90 break;
91 case XMLStreamConstants.PROCESSING_INSTRUCTION:
92 out.add(new XmlProcessingInstruction(streamReader.getPIData(), streamReader.getPITarget()));
93 break;
94 case XMLStreamConstants.CHARACTERS:
95 out.add(new XmlCharacters(streamReader.getText()));
96 break;
97 case XMLStreamConstants.COMMENT:
98 out.add(new XmlComment(streamReader.getText()));
99 break;
100 case XMLStreamConstants.SPACE:
101 out.add(new XmlSpace(streamReader.getText()));
102 break;
103 case XMLStreamConstants.ENTITY_REFERENCE:
104 out.add(new XmlEntityReference(streamReader.getLocalName(), streamReader.getText()));
105 break;
106 case XMLStreamConstants.DTD:
107 out.add(new XmlDTD(streamReader.getText()));
108 break;
109 case XMLStreamConstants.CDATA:
110 out.add(new XmlCdata(streamReader.getText()));
111 break;
112 }
113 }
114 }
115
116 }