Integrate non-blocking XML parser as Netty codec (#2806)
Motivation: Provide non-blocking XML parser as Netty codec. Modifications: New codec implemented/extracted. io.netty.handler.codec.xml.XmlDecoder decodes XML fed by Netty without blocking. Result: Non-blocking XML stream parsing.
This commit is contained in:
parent
ed416e0189
commit
d5207bc35c
@ -195,3 +195,11 @@ can be obtained at:
|
|||||||
* HOMEPAGE:
|
* HOMEPAGE:
|
||||||
* http://logging.apache.org/log4j/
|
* http://logging.apache.org/log4j/
|
||||||
|
|
||||||
|
This product optionally depends on 'Aalto XML', an ultra-high performance
|
||||||
|
non-blocking XML processor, which can be obtained at:
|
||||||
|
|
||||||
|
* LICENSE:
|
||||||
|
* license/LICENSE.aalto-xml.txt (Apache License 2.0)
|
||||||
|
* HOMEPAGE:
|
||||||
|
* http://wiki.fasterxml.com/AaltoHome
|
||||||
|
|
||||||
|
48
codec-xml/pom.xml
Normal file
48
codec-xml/pom.xml
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright 2014 The Netty Project
|
||||||
|
~
|
||||||
|
~ The Netty Project licenses this file to you under the Apache License,
|
||||||
|
~ version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
~ with the License. You may obtain a copy of the License at:
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
~ License for the specific language governing permissions and limitations
|
||||||
|
~ under the License.
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-parent</artifactId>
|
||||||
|
<version>5.0.0.Alpha2-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>netty-codec-xml</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Netty/Codec/XML</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>netty-codec</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>netty-handler</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml</groupId>
|
||||||
|
<artifactId>aalto-xml</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.xml;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML attributes, it is part of {@link XmlElement}
|
||||||
|
*/
|
||||||
|
public class XmlAttribute {
|
||||||
|
|
||||||
|
private final String type;
|
||||||
|
private final String name;
|
||||||
|
private final String prefix;
|
||||||
|
private final String namespace;
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
public XmlAttribute(String type, String name, String prefix, String namespace, String value) {
|
||||||
|
this.type = type;
|
||||||
|
this.name = name;
|
||||||
|
this.prefix = prefix;
|
||||||
|
this.namespace = namespace;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String type() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String name() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String prefix() {
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String namespace() {
|
||||||
|
return namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String value() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) { return true; }
|
||||||
|
if (o == null || getClass() != o.getClass()) { return false; }
|
||||||
|
|
||||||
|
XmlAttribute that = (XmlAttribute) o;
|
||||||
|
|
||||||
|
if (!name.equals(that.name)) { return false; }
|
||||||
|
if (namespace != null ? !namespace.equals(that.namespace) : that.namespace != null) { return false; }
|
||||||
|
if (prefix != null ? !prefix.equals(that.prefix) : that.prefix != null) { return false; }
|
||||||
|
if (type != null ? !type.equals(that.type) : that.type != null) { return false; }
|
||||||
|
if (value != null ? !value.equals(that.value) : that.value != null) { return false; }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = type != null ? type.hashCode() : 0;
|
||||||
|
result = 31 * result + name.hashCode();
|
||||||
|
result = 31 * result + (prefix != null ? prefix.hashCode() : 0);
|
||||||
|
result = 31 * result + (namespace != null ? namespace.hashCode() : 0);
|
||||||
|
result = 31 * result + (value != null ? value.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "XmlAttribute{" +
|
||||||
|
"type='" + type + '\'' +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
", prefix='" + prefix + '\'' +
|
||||||
|
", namespace='" + namespace + '\'' +
|
||||||
|
", value='" + value + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.xml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML CDATA ... <![CDATA[<sender>John Smith</sender>]]>
|
||||||
|
*/
|
||||||
|
public class XmlCdata extends XmlContent {
|
||||||
|
|
||||||
|
public XmlCdata(String data) {
|
||||||
|
super(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.xml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML characters, e.g. <test>characters</test>, but not CDATA.
|
||||||
|
*/
|
||||||
|
public class XmlCharacters extends XmlContent {
|
||||||
|
|
||||||
|
public XmlCharacters(String data) {
|
||||||
|
super(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.xml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML Comment
|
||||||
|
*/
|
||||||
|
public class XmlComment extends XmlContent {
|
||||||
|
|
||||||
|
public XmlComment(String data) {
|
||||||
|
super(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.xml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML Content is base class for XML CDATA, Comments, Characters and Space
|
||||||
|
*/
|
||||||
|
public abstract class XmlContent {
|
||||||
|
|
||||||
|
private final String data;
|
||||||
|
|
||||||
|
protected XmlContent(String data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String data() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) { return true; }
|
||||||
|
if (o == null || getClass() != o.getClass()) { return false; }
|
||||||
|
|
||||||
|
XmlContent that = (XmlContent) o;
|
||||||
|
|
||||||
|
if (data != null ? !data.equals(that.data) : that.data != null) { return false; }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return data != null ? data.hashCode() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "XmlContent{" +
|
||||||
|
"data='" + data + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.xml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DTD (Document Type Definition)
|
||||||
|
*/
|
||||||
|
public class XmlDTD {
|
||||||
|
|
||||||
|
private final String text;
|
||||||
|
|
||||||
|
public XmlDTD(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String text() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) { return true; }
|
||||||
|
if (o == null || getClass() != o.getClass()) { return false; }
|
||||||
|
|
||||||
|
XmlDTD xmlDTD = (XmlDTD) o;
|
||||||
|
|
||||||
|
if (text != null ? !text.equals(xmlDTD.text) : xmlDTD.text != null) { return false; }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return text != null ? text.hashCode() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "XmlDTD{" +
|
||||||
|
"text='" + text + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.xml;
|
||||||
|
|
||||||
|
import com.fasterxml.aalto.AsyncInputFeeder;
|
||||||
|
import com.fasterxml.aalto.AsyncXMLInputFactory;
|
||||||
|
import com.fasterxml.aalto.AsyncXMLStreamReader;
|
||||||
|
import com.fasterxml.aalto.stax.InputFactoryImpl;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||||
|
|
||||||
|
import javax.xml.stream.XMLStreamConstants;
|
||||||
|
import javax.xml.stream.XMLStreamException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Async XML decoder based on <a href="https://github.com/FasterXML/aalto-xml">Aalto XML parser</a>.
|
||||||
|
*
|
||||||
|
* Parses the incoming data into one of XML messages defined in this package.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class XmlDecoder extends ByteToMessageDecoder {
|
||||||
|
|
||||||
|
private static final AsyncXMLInputFactory XML_INPUT_FACTORY = new InputFactoryImpl();
|
||||||
|
private static final XmlDocumentEnd XML_DOCUMENT_END = XmlDocumentEnd.INSTANCE;
|
||||||
|
|
||||||
|
private final AsyncXMLStreamReader streamReader = XML_INPUT_FACTORY.createAsyncXMLStreamReader();
|
||||||
|
private final AsyncInputFeeder streamFeeder = streamReader.getInputFeeder();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
||||||
|
byte[] buffer = new byte[in.readableBytes()];
|
||||||
|
in.readBytes(buffer);
|
||||||
|
try {
|
||||||
|
streamFeeder.feedInput(buffer, 0, buffer.length);
|
||||||
|
} catch (XMLStreamException exception) {
|
||||||
|
in.skipBytes(in.readableBytes());
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!streamFeeder.needMoreInput()) {
|
||||||
|
int type = streamReader.next();
|
||||||
|
switch (type) {
|
||||||
|
case XMLStreamConstants.START_DOCUMENT:
|
||||||
|
out.add(new XmlDocumentStart(streamReader.getEncoding(), streamReader.getVersion(),
|
||||||
|
streamReader.isStandalone(), streamReader.getCharacterEncodingScheme()));
|
||||||
|
break;
|
||||||
|
case XMLStreamConstants.END_DOCUMENT:
|
||||||
|
out.add(XML_DOCUMENT_END);
|
||||||
|
break;
|
||||||
|
case XMLStreamConstants.START_ELEMENT:
|
||||||
|
XmlElementStart elementStart = new XmlElementStart(streamReader.getLocalName(),
|
||||||
|
streamReader.getName().getNamespaceURI(), streamReader.getPrefix());
|
||||||
|
for (int x = 0; x < streamReader.getAttributeCount(); x++) {
|
||||||
|
XmlAttribute attribute = new XmlAttribute(streamReader.getAttributeType(x),
|
||||||
|
streamReader.getAttributeLocalName(x), streamReader.getAttributePrefix(x),
|
||||||
|
streamReader.getAttributeNamespace(x), streamReader.getAttributeValue(x));
|
||||||
|
elementStart.attributes().add(attribute);
|
||||||
|
}
|
||||||
|
for (int x = 0; x < streamReader.getNamespaceCount(); x++) {
|
||||||
|
XmlNamespace namespace = new XmlNamespace(streamReader.getNamespacePrefix(x),
|
||||||
|
streamReader.getNamespaceURI(x));
|
||||||
|
elementStart.namespaces().add(namespace);
|
||||||
|
}
|
||||||
|
out.add(elementStart);
|
||||||
|
break;
|
||||||
|
case XMLStreamConstants.END_ELEMENT:
|
||||||
|
XmlElementEnd elementEnd = new XmlElementEnd(streamReader.getLocalName(),
|
||||||
|
streamReader.getName().getNamespaceURI(), streamReader.getPrefix());
|
||||||
|
for (int x = 0; x < streamReader.getNamespaceCount(); x++) {
|
||||||
|
XmlNamespace namespace = new XmlNamespace(streamReader.getNamespacePrefix(x),
|
||||||
|
streamReader.getNamespaceURI(x));
|
||||||
|
elementEnd.namespaces().add(namespace);
|
||||||
|
}
|
||||||
|
out.add(elementEnd);
|
||||||
|
break;
|
||||||
|
case XMLStreamConstants.PROCESSING_INSTRUCTION:
|
||||||
|
out.add(new XmlProcessingInstruction(streamReader.getPIData(), streamReader.getPITarget()));
|
||||||
|
break;
|
||||||
|
case XMLStreamConstants.CHARACTERS:
|
||||||
|
out.add(new XmlCharacters(streamReader.getText()));
|
||||||
|
break;
|
||||||
|
case XMLStreamConstants.COMMENT:
|
||||||
|
out.add(new XmlComment(streamReader.getText()));
|
||||||
|
break;
|
||||||
|
case XMLStreamConstants.SPACE:
|
||||||
|
out.add(new XmlSpace(streamReader.getText()));
|
||||||
|
break;
|
||||||
|
case XMLStreamConstants.ENTITY_REFERENCE:
|
||||||
|
out.add(new XmlEntityReference(streamReader.getLocalName(), streamReader.getText()));
|
||||||
|
break;
|
||||||
|
case XMLStreamConstants.DTD:
|
||||||
|
out.add(new XmlDTD(streamReader.getText()));
|
||||||
|
break;
|
||||||
|
case XMLStreamConstants.CDATA:
|
||||||
|
out.add(new XmlCdata(streamReader.getText()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.xml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End of XML document
|
||||||
|
*/
|
||||||
|
public final class XmlDocumentEnd {
|
||||||
|
|
||||||
|
public static final XmlDocumentEnd INSTANCE = new XmlDocumentEnd();
|
||||||
|
|
||||||
|
private XmlDocumentEnd() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.xml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Beginning of the XML document ... i.e. XML header
|
||||||
|
*/
|
||||||
|
public class XmlDocumentStart {
|
||||||
|
|
||||||
|
private final String encoding;
|
||||||
|
private final String version;
|
||||||
|
private final boolean standalone;
|
||||||
|
private final String encodingScheme;
|
||||||
|
|
||||||
|
public XmlDocumentStart(String encoding, String version, boolean standalone, String encodingScheme) {
|
||||||
|
this.encoding = encoding;
|
||||||
|
this.version = version;
|
||||||
|
this.standalone = standalone;
|
||||||
|
this.encodingScheme = encodingScheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return defined or guessed XML encoding **/
|
||||||
|
public String encoding() {
|
||||||
|
return encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return defined XML version or null **/
|
||||||
|
public String version() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return standalonity of the document **/
|
||||||
|
public boolean standalone() {
|
||||||
|
return standalone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return defined encoding or null **/
|
||||||
|
public String encodingScheme() {
|
||||||
|
return encodingScheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) { return true; }
|
||||||
|
if (o == null || getClass() != o.getClass()) { return false; }
|
||||||
|
|
||||||
|
XmlDocumentStart that = (XmlDocumentStart) o;
|
||||||
|
|
||||||
|
if (standalone != that.standalone) { return false; }
|
||||||
|
if (encoding != null ? !encoding.equals(that.encoding) : that.encoding != null) { return false; }
|
||||||
|
if (encodingScheme != null ? !encodingScheme.equals(that.encodingScheme) : that.encodingScheme != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (version != null ? !version.equals(that.version) : that.version != null) { return false; }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = encoding != null ? encoding.hashCode() : 0;
|
||||||
|
result = 31 * result + (version != null ? version.hashCode() : 0);
|
||||||
|
result = 31 * result + (standalone ? 1 : 0);
|
||||||
|
result = 31 * result + (encodingScheme != null ? encodingScheme.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "XmlDocumentStart{" +
|
||||||
|
"encoding='" + encoding + '\'' +
|
||||||
|
", version='" + version + '\'' +
|
||||||
|
", standalone=" + standalone +
|
||||||
|
", encodingScheme='" + encodingScheme + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.xml;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic XML element in document, {@link XmlElementStart} represents open element and provides access to attributes,
|
||||||
|
* {@link XmlElementEnd} represents closing element.
|
||||||
|
*/
|
||||||
|
public abstract class XmlElement {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final String namespace;
|
||||||
|
private final String prefix;
|
||||||
|
|
||||||
|
private final List<XmlNamespace> namespaces = new LinkedList<XmlNamespace>();
|
||||||
|
|
||||||
|
protected XmlElement(String name, String namespace, String prefix) {
|
||||||
|
this.name = name;
|
||||||
|
this.namespace = namespace;
|
||||||
|
this.prefix = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String name() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String namespace() {
|
||||||
|
return namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String prefix() {
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<XmlNamespace> namespaces() {
|
||||||
|
return namespaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) { return true; }
|
||||||
|
if (o == null || getClass() != o.getClass()) { return false; }
|
||||||
|
|
||||||
|
XmlElement that = (XmlElement) o;
|
||||||
|
|
||||||
|
if (!name.equals(that.name)) { return false; }
|
||||||
|
if (namespace != null ? !namespace.equals(that.namespace) : that.namespace != null) { return false; }
|
||||||
|
if (namespaces != null ? !namespaces.equals(that.namespaces) : that.namespaces != null) { return false; }
|
||||||
|
if (prefix != null ? !prefix.equals(that.prefix) : that.prefix != null) { return false; }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = name.hashCode();
|
||||||
|
result = 31 * result + (namespace != null ? namespace.hashCode() : 0);
|
||||||
|
result = 31 * result + (prefix != null ? prefix.hashCode() : 0);
|
||||||
|
result = 31 * result + (namespaces != null ? namespaces.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return ", name='" + name + '\'' +
|
||||||
|
", namespace='" + namespace + '\'' +
|
||||||
|
", prefix='" + prefix + '\'' +
|
||||||
|
", namespaces=" + namespaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.xml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specific {@link XmlElement} representing end of element.
|
||||||
|
*/
|
||||||
|
public class XmlElementEnd extends XmlElement {
|
||||||
|
|
||||||
|
public XmlElementEnd(String name, String namespace, String prefix) {
|
||||||
|
super(name, namespace, prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "XmlElementStart{" +
|
||||||
|
super.toString() +
|
||||||
|
"} ";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.xml;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specific {@link XmlElement} representing beginning of element.
|
||||||
|
*/
|
||||||
|
public class XmlElementStart extends XmlElement {
|
||||||
|
|
||||||
|
private final List<XmlAttribute> attributes = new LinkedList<XmlAttribute>();
|
||||||
|
|
||||||
|
public XmlElementStart(String name, String namespace, String prefix) {
|
||||||
|
super(name, namespace, prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<XmlAttribute> attributes() {
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) { return true; }
|
||||||
|
if (o == null || getClass() != o.getClass()) { return false; }
|
||||||
|
if (!super.equals(o)) { return false; }
|
||||||
|
|
||||||
|
XmlElementStart that = (XmlElementStart) o;
|
||||||
|
|
||||||
|
if (attributes != null ? !attributes.equals(that.attributes) : that.attributes != null) { return false; }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = 31 * result + (attributes != null ? attributes.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "XmlElementStart{" +
|
||||||
|
"attributes=" + attributes +
|
||||||
|
super.toString() +
|
||||||
|
"} ";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.xml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML entity reference ... {@code &#nnnn;}
|
||||||
|
*/
|
||||||
|
public class XmlEntityReference {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final String text;
|
||||||
|
|
||||||
|
public XmlEntityReference(String name, String text) {
|
||||||
|
this.name = name;
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String name() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String text() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) { return true; }
|
||||||
|
if (o == null || getClass() != o.getClass()) { return false; }
|
||||||
|
|
||||||
|
XmlEntityReference that = (XmlEntityReference) o;
|
||||||
|
|
||||||
|
if (name != null ? !name.equals(that.name) : that.name != null) { return false; }
|
||||||
|
if (text != null ? !text.equals(that.text) : that.text != null) { return false; }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = name != null ? name.hashCode() : 0;
|
||||||
|
result = 31 * result + (text != null ? text.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "XmlEntityReference{" +
|
||||||
|
"name='" + name + '\'' +
|
||||||
|
", text='" + text + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.xml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML namespace is part of XML element.
|
||||||
|
*/
|
||||||
|
public class XmlNamespace {
|
||||||
|
|
||||||
|
private final String prefix;
|
||||||
|
private final String uri;
|
||||||
|
|
||||||
|
public XmlNamespace(String prefix, String uri) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
this.uri = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String prefix() {
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String uri() {
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) { return true; }
|
||||||
|
if (o == null || getClass() != o.getClass()) { return false; }
|
||||||
|
|
||||||
|
XmlNamespace that = (XmlNamespace) o;
|
||||||
|
|
||||||
|
if (prefix != null ? !prefix.equals(that.prefix) : that.prefix != null) { return false; }
|
||||||
|
if (uri != null ? !uri.equals(that.uri) : that.uri != null) { return false; }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = prefix != null ? prefix.hashCode() : 0;
|
||||||
|
result = 31 * result + (uri != null ? uri.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "XmlNamespace{" +
|
||||||
|
"prefix='" + prefix + '\'' +
|
||||||
|
", uri='" + uri + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.xml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML processing instruction
|
||||||
|
*/
|
||||||
|
public class XmlProcessingInstruction {
|
||||||
|
|
||||||
|
private final String data;
|
||||||
|
private final String target;
|
||||||
|
|
||||||
|
public XmlProcessingInstruction(String data, String target) {
|
||||||
|
this.data = data;
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String data() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String target() {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) { return true; }
|
||||||
|
if (o == null || getClass() != o.getClass()) { return false; }
|
||||||
|
|
||||||
|
XmlProcessingInstruction that = (XmlProcessingInstruction) o;
|
||||||
|
|
||||||
|
if (data != null ? !data.equals(that.data) : that.data != null) { return false; }
|
||||||
|
if (target != null ? !target.equals(that.target) : that.target != null) { return false; }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = data != null ? data.hashCode() : 0;
|
||||||
|
result = 31 * result + (target != null ? target.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "XmlProcessingInstruction{" +
|
||||||
|
"data='" + data + '\'' +
|
||||||
|
", target='" + target + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.xml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* White space characters
|
||||||
|
*/
|
||||||
|
public class XmlSpace extends XmlContent {
|
||||||
|
|
||||||
|
public XmlSpace(String data) {
|
||||||
|
super(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML codec provides asynchronous and non-blocking XML parser based on the
|
||||||
|
* <a href="https://github.com/FasterXML/aalto-xml">Aalto XML parser</a>.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.xml;
|
@ -0,0 +1,299 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.xml;
|
||||||
|
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.channel.embedded.EmbeddedChannel;
|
||||||
|
import io.netty.util.CharsetUtil;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.*;
|
||||||
|
import static org.hamcrest.core.IsNull.nullValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies the basic functionality of the {@link XmlDecoder}.
|
||||||
|
* XML borrowed from <a href="http://www.studytrails.com/java/xml/woodstox/java-xml-woodstox-validation-xml-schema.jsp">
|
||||||
|
* Woodstox : Validate against XML Schema</a>
|
||||||
|
*/
|
||||||
|
public class XmlDecoderTest {
|
||||||
|
|
||||||
|
private static final String XML1 = "<?xml version=\"1.0\"?>" +
|
||||||
|
"<!DOCTYPE employee SYSTEM \"employee.dtd\">" +
|
||||||
|
"<?xml-stylesheet type=\"text/css\" href=\"netty.css\"?>" +
|
||||||
|
"<?xml-test ?>" +
|
||||||
|
"<employee xmlns:nettya=\"http://netty.io/netty/a\">" +
|
||||||
|
"<nettya:id>±1</nettya:id>\n" +
|
||||||
|
"<name ";
|
||||||
|
|
||||||
|
private static final String XML2 = "type=\"given\">Alba</name><![CDATA[ <some data >/> ]]>" +
|
||||||
|
" <!-- namespaced --><nettyb:salary xmlns:nettyb=\"http://netty.io/netty/b\" nettyb:period=\"weekly\">" +
|
||||||
|
"100</nettyb:salary><last/></employee>";
|
||||||
|
|
||||||
|
private static final String XML3 = "<?xml version=\"1.1\" encoding=\"UTf-8\" standalone=\"yes\"?><netty></netty>";
|
||||||
|
|
||||||
|
private static final String XML4 = "<netty></netty>";
|
||||||
|
|
||||||
|
private EmbeddedChannel channel;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws Exception {
|
||||||
|
channel = new EmbeddedChannel(new XmlDecoder());
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void teardown() throws Exception {
|
||||||
|
channel.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test feeds basic XML and verifies the resulting messages
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void shouldDecodeRequestWithSimpleXml() {
|
||||||
|
Object temp;
|
||||||
|
|
||||||
|
write(XML1);
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlDocumentStart.class));
|
||||||
|
assertThat(((XmlDocumentStart) temp).version(), is("1.0"));
|
||||||
|
assertThat(((XmlDocumentStart) temp).encoding(), is("UTF-8"));
|
||||||
|
assertThat(((XmlDocumentStart) temp).standalone(), is(false));
|
||||||
|
assertThat(((XmlDocumentStart) temp).encodingScheme(), is(nullValue()));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlDTD.class));
|
||||||
|
assertThat(((XmlDTD) temp).text(), is("employee.dtd"));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlProcessingInstruction.class));
|
||||||
|
assertThat(((XmlProcessingInstruction) temp).target(), is("xml-stylesheet"));
|
||||||
|
assertThat(((XmlProcessingInstruction) temp).data(), is("type=\"text/css\" href=\"netty.css\""));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlProcessingInstruction.class));
|
||||||
|
assertThat(((XmlProcessingInstruction) temp).target(), is("xml-test"));
|
||||||
|
assertThat(((XmlProcessingInstruction) temp).data(), is(""));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlElementStart.class));
|
||||||
|
assertThat(((XmlElementStart) temp).name(), is("employee"));
|
||||||
|
assertThat(((XmlElementStart) temp).prefix(), is(""));
|
||||||
|
assertThat(((XmlElementStart) temp).namespace(), is(""));
|
||||||
|
assertThat(((XmlElementStart) temp).attributes().size(), is(0));
|
||||||
|
assertThat(((XmlElementStart) temp).namespaces().size(), is(1));
|
||||||
|
assertThat(((XmlElementStart) temp).namespaces().get(0).prefix(), is("nettya"));
|
||||||
|
assertThat(((XmlElementStart) temp).namespaces().get(0).uri(), is("http://netty.io/netty/a"));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlElementStart.class));
|
||||||
|
assertThat(((XmlElementStart) temp).name(), is("id"));
|
||||||
|
assertThat(((XmlElementStart) temp).prefix(), is("nettya"));
|
||||||
|
assertThat(((XmlElementStart) temp).namespace(), is("http://netty.io/netty/a"));
|
||||||
|
assertThat(((XmlElementStart) temp).attributes().size(), is(0));
|
||||||
|
assertThat(((XmlElementStart) temp).namespaces().size(), is(0));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlEntityReference.class));
|
||||||
|
assertThat(((XmlEntityReference) temp).name(), is("plusmn"));
|
||||||
|
assertThat(((XmlEntityReference) temp).text(), is(""));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlCharacters.class));
|
||||||
|
assertThat(((XmlCharacters) temp).data(), is("1"));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlElementEnd.class));
|
||||||
|
assertThat(((XmlElementEnd) temp).name(), is("id"));
|
||||||
|
assertThat(((XmlElementEnd) temp).prefix(), is("nettya"));
|
||||||
|
assertThat(((XmlElementEnd) temp).namespace(), is("http://netty.io/netty/a"));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlCharacters.class));
|
||||||
|
assertThat(((XmlCharacters) temp).data(), is("\n"));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, nullValue());
|
||||||
|
|
||||||
|
write(XML2);
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlElementStart.class));
|
||||||
|
assertThat(((XmlElementStart) temp).name(), is("name"));
|
||||||
|
assertThat(((XmlElementStart) temp).prefix(), is(""));
|
||||||
|
assertThat(((XmlElementStart) temp).namespace(), is(""));
|
||||||
|
assertThat(((XmlElementStart) temp).attributes().size(), is(1));
|
||||||
|
assertThat(((XmlElementStart) temp).attributes().get(0).name(), is("type"));
|
||||||
|
assertThat(((XmlElementStart) temp).attributes().get(0).value(), is("given"));
|
||||||
|
assertThat(((XmlElementStart) temp).attributes().get(0).prefix(), is(""));
|
||||||
|
assertThat(((XmlElementStart) temp).attributes().get(0).namespace(), is(""));
|
||||||
|
assertThat(((XmlElementStart) temp).namespaces().size(), is(0));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlCharacters.class));
|
||||||
|
assertThat(((XmlCharacters) temp).data(), is("Alba"));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlElementEnd.class));
|
||||||
|
assertThat(((XmlElementEnd) temp).name(), is("name"));
|
||||||
|
assertThat(((XmlElementEnd) temp).prefix(), is(""));
|
||||||
|
assertThat(((XmlElementEnd) temp).namespace(), is(""));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlCdata.class));
|
||||||
|
assertThat(((XmlCdata) temp).data(), is(" <some data >/> "));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlCharacters.class));
|
||||||
|
assertThat(((XmlCharacters) temp).data(), is(" "));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlComment.class));
|
||||||
|
assertThat(((XmlComment) temp).data(), is(" namespaced "));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlElementStart.class));
|
||||||
|
assertThat(((XmlElementStart) temp).name(), is("salary"));
|
||||||
|
assertThat(((XmlElementStart) temp).prefix(), is("nettyb"));
|
||||||
|
assertThat(((XmlElementStart) temp).namespace(), is("http://netty.io/netty/b"));
|
||||||
|
assertThat(((XmlElementStart) temp).attributes().size(), is(1));
|
||||||
|
assertThat(((XmlElementStart) temp).attributes().get(0).name(), is("period"));
|
||||||
|
assertThat(((XmlElementStart) temp).attributes().get(0).value(), is("weekly"));
|
||||||
|
assertThat(((XmlElementStart) temp).attributes().get(0).prefix(), is("nettyb"));
|
||||||
|
assertThat(((XmlElementStart) temp).attributes().get(0).namespace(), is("http://netty.io/netty/b"));
|
||||||
|
assertThat(((XmlElementStart) temp).namespaces().size(), is(1));
|
||||||
|
assertThat(((XmlElementStart) temp).namespaces().get(0).prefix(), is("nettyb"));
|
||||||
|
assertThat(((XmlElementStart) temp).namespaces().get(0).uri(), is("http://netty.io/netty/b"));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlCharacters.class));
|
||||||
|
assertThat(((XmlCharacters) temp).data(), is("100"));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlElementEnd.class));
|
||||||
|
assertThat(((XmlElementEnd) temp).name(), is("salary"));
|
||||||
|
assertThat(((XmlElementEnd) temp).prefix(), is("nettyb"));
|
||||||
|
assertThat(((XmlElementEnd) temp).namespace(), is("http://netty.io/netty/b"));
|
||||||
|
assertThat(((XmlElementEnd) temp).namespaces().size(), is(1));
|
||||||
|
assertThat(((XmlElementEnd) temp).namespaces().get(0).prefix(), is("nettyb"));
|
||||||
|
assertThat(((XmlElementEnd) temp).namespaces().get(0).uri(), is("http://netty.io/netty/b"));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlElementStart.class));
|
||||||
|
assertThat(((XmlElementStart) temp).name(), is("last"));
|
||||||
|
assertThat(((XmlElementStart) temp).prefix(), is(""));
|
||||||
|
assertThat(((XmlElementStart) temp).namespace(), is(""));
|
||||||
|
assertThat(((XmlElementStart) temp).attributes().size(), is(0));
|
||||||
|
assertThat(((XmlElementStart) temp).namespaces().size(), is(0));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlElementEnd.class));
|
||||||
|
assertThat(((XmlElementEnd) temp).name(), is("last"));
|
||||||
|
assertThat(((XmlElementEnd) temp).prefix(), is(""));
|
||||||
|
assertThat(((XmlElementEnd) temp).namespace(), is(""));
|
||||||
|
assertThat(((XmlElementEnd) temp).namespaces().size(), is(0));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlElementEnd.class));
|
||||||
|
assertThat(((XmlElementEnd) temp).name(), is("employee"));
|
||||||
|
assertThat(((XmlElementEnd) temp).prefix(), is(""));
|
||||||
|
assertThat(((XmlElementEnd) temp).namespace(), is(""));
|
||||||
|
assertThat(((XmlElementEnd) temp).namespaces().size(), is(1));
|
||||||
|
assertThat(((XmlElementEnd) temp).namespaces().get(0).prefix(), is("nettya"));
|
||||||
|
assertThat(((XmlElementEnd) temp).namespaces().get(0).uri(), is("http://netty.io/netty/a"));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, nullValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test checks for different attributes in XML header
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void shouldDecodeXmlHeader() {
|
||||||
|
Object temp;
|
||||||
|
|
||||||
|
write(XML3);
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlDocumentStart.class));
|
||||||
|
assertThat(((XmlDocumentStart) temp).version(), is("1.1"));
|
||||||
|
assertThat(((XmlDocumentStart) temp).encoding(), is("UTF-8"));
|
||||||
|
assertThat(((XmlDocumentStart) temp).standalone(), is(true));
|
||||||
|
assertThat(((XmlDocumentStart) temp).encodingScheme(), is("UTF-8"));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlElementStart.class));
|
||||||
|
assertThat(((XmlElementStart) temp).name(), is("netty"));
|
||||||
|
assertThat(((XmlElementStart) temp).prefix(), is(""));
|
||||||
|
assertThat(((XmlElementStart) temp).namespace(), is(""));
|
||||||
|
assertThat(((XmlElementStart) temp).attributes().size(), is(0));
|
||||||
|
assertThat(((XmlElementStart) temp).namespaces().size(), is(0));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlElementEnd.class));
|
||||||
|
assertThat(((XmlElementEnd) temp).name(), is("netty"));
|
||||||
|
assertThat(((XmlElementEnd) temp).prefix(), is(""));
|
||||||
|
assertThat(((XmlElementEnd) temp).namespace(), is(""));
|
||||||
|
assertThat(((XmlElementEnd) temp).namespaces().size(), is(0));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, nullValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test checks for no XML header
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void shouldDecodeWithoutHeader() {
|
||||||
|
Object temp;
|
||||||
|
|
||||||
|
write(XML4);
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlDocumentStart.class));
|
||||||
|
assertThat(((XmlDocumentStart) temp).version(), is(nullValue()));
|
||||||
|
assertThat(((XmlDocumentStart) temp).encoding(), is("UTF-8"));
|
||||||
|
assertThat(((XmlDocumentStart) temp).standalone(), is(false));
|
||||||
|
assertThat(((XmlDocumentStart) temp).encodingScheme(), is(nullValue()));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlElementStart.class));
|
||||||
|
assertThat(((XmlElementStart) temp).name(), is("netty"));
|
||||||
|
assertThat(((XmlElementStart) temp).prefix(), is(""));
|
||||||
|
assertThat(((XmlElementStart) temp).namespace(), is(""));
|
||||||
|
assertThat(((XmlElementStart) temp).attributes().size(), is(0));
|
||||||
|
assertThat(((XmlElementStart) temp).namespaces().size(), is(0));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, instanceOf(XmlElementEnd.class));
|
||||||
|
assertThat(((XmlElementEnd) temp).name(), is("netty"));
|
||||||
|
assertThat(((XmlElementEnd) temp).prefix(), is(""));
|
||||||
|
assertThat(((XmlElementEnd) temp).namespace(), is(""));
|
||||||
|
assertThat(((XmlElementEnd) temp).namespaces().size(), is(0));
|
||||||
|
|
||||||
|
temp = channel.readInbound();
|
||||||
|
assertThat(temp, nullValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void write(String content) {
|
||||||
|
assertThat(channel.writeInbound(Unpooled.copiedBuffer(content, CharsetUtil.UTF_8)), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
13
license/LICENSE.aalto-xml.txt
Normal file
13
license/LICENSE.aalto-xml.txt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
This copy of Aalto XML processor is licensed under the
|
||||||
|
Apache (Software) License, version 2.0 ("the License").
|
||||||
|
See the License for details about distribution rights, and the
|
||||||
|
specific rights regarding derivate works.
|
||||||
|
|
||||||
|
You may obtain a copy of the License at:
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
A copy is also included with both the the downloadable source code package
|
||||||
|
and jar that contains class bytecodes, as file "ASL 2.0". In both cases,
|
||||||
|
that file should be located next to this file: in source distribution
|
||||||
|
the location should be "release-notes/asl"; and in jar "META-INF/"
|
7
pom.xml
7
pom.xml
@ -502,6 +502,7 @@
|
|||||||
<module>codec-mqtt</module>
|
<module>codec-mqtt</module>
|
||||||
<module>codec-socks</module>
|
<module>codec-socks</module>
|
||||||
<module>codec-stomp</module>
|
<module>codec-stomp</module>
|
||||||
|
<module>codec-xml</module>
|
||||||
<module>resolver</module>
|
<module>resolver</module>
|
||||||
<module>resolver-dns</module>
|
<module>resolver-dns</module>
|
||||||
<module>transport</module>
|
<module>transport</module>
|
||||||
@ -595,6 +596,12 @@
|
|||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml</groupId>
|
||||||
|
<artifactId>aalto-xml</artifactId>
|
||||||
|
<version>0.9.9</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.jcraft</groupId>
|
<groupId>com.jcraft</groupId>
|
||||||
<artifactId>jzlib</artifactId>
|
<artifactId>jzlib</artifactId>
|
||||||
|
Loading…
Reference in New Issue
Block a user