300 lines
13 KiB
Java
300 lines
13 KiB
Java
/*
|
|
* 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=\"https://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=\"https://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("https://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("https://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("https://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("https://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("https://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("https://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("https://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("https://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("https://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));
|
|
}
|
|
|
|
}
|