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
1e09409604
commit
d3e7a0bcd0
@ -195,3 +195,11 @@ can be obtained at:
|
||||
* HOMEPAGE:
|
||||
* 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>4.1.0.Beta4-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
@ -500,6 +500,7 @@
|
||||
<module>codec-mqtt</module>
|
||||
<module>codec-socks</module>
|
||||
<module>codec-stomp</module>
|
||||
<module>codec-xml</module>
|
||||
<module>resolver</module>
|
||||
<module>resolver-dns</module>
|
||||
<module>transport</module>
|
||||
@ -593,6 +594,12 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml</groupId>
|
||||
<artifactId>aalto-xml</artifactId>
|
||||
<version>0.9.9</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.jcraft</groupId>
|
||||
<artifactId>jzlib</artifactId>
|
||||
|
Loading…
Reference in New Issue
Block a user