/* * Created on Jun 21, 2005 * * Licensed 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. * * Copyright @2005 the original author or authors. */ package org.springmodules.remoting.xmlrpc; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import junit.framework.TestCase; import org.apache.commons.codec.binary.Base64; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springmodules.remoting.xmlrpc.support.XmlRpcArray; import org.springmodules.remoting.xmlrpc.support.XmlRpcBase64; import org.springmodules.remoting.xmlrpc.support.XmlRpcBoolean; import org.springmodules.remoting.xmlrpc.support.XmlRpcDateTime; import org.springmodules.remoting.xmlrpc.support.XmlRpcDouble; import org.springmodules.remoting.xmlrpc.support.XmlRpcElement; import org.springmodules.remoting.xmlrpc.support.XmlRpcInteger; import org.springmodules.remoting.xmlrpc.support.XmlRpcRequest; import org.springmodules.remoting.xmlrpc.support.XmlRpcString; import org.springmodules.remoting.xmlrpc.support.XmlRpcStruct; import org.springmodules.remoting.xmlrpc.support.XmlRpcStruct.XmlRpcMember; /** * <p> * Template for testing implementations of * <code>{@link XmlRpcRequestParser}</code>. * </p> * * @author Alex Ruiz * * @version $Revision$ $Date$ */ public abstract class AbstractXmlRpcRequestParserTests extends TestCase { /** * Message logger. */ protected final Log logger = LogFactory.getLog(this.getClass()); /** * Name of the method specified in the XML-RPC request. */ private String methodName; /** * Primary object that is under test. */ private XmlRpcRequestParser parser; /** * Contains the names of the service and method separated by a dot. */ private String serviceAndMethodNames; /** * Name of the service specified in the XML-RPC request. */ private String serviceName; /** * Constructor. */ public AbstractXmlRpcRequestParserTests() { super(); } /** * Constructor. * * @param name * the name of the test case to construct. */ public AbstractXmlRpcRequestParserTests(String name) { super(name); } /** * Returns the implementation of <code>{@link XmlRpcRequestParser}</code> to * test. * * @return the primary object that is under test. */ protected abstract XmlRpcRequestParser getXmlRpcRequestParserImplementation(); /** * Give subclasses the opportunity to set up their own test fixture. */ protected void onSetUp() throws Exception { // subclasses may override this method. } /** * Sets up the test fixture. */ protected final void setUp() throws Exception { super.setUp(); this.onSetUp(); this.parser = this.getXmlRpcRequestParserImplementation(); this.serviceName = "myService"; this.methodName = "myMethod"; this.serviceAndMethodNames = this.serviceName + "." + this.methodName; } /** * Verifies that the method * <code>{@link XmlRpcRequestParser#parseRequest(InputStream)}</code> parses * correctly a XML-RPC request containing array parameters. */ public final void testParseRequestWithArrayParameters() { XmlRpcArray xmlRpcArray = new XmlRpcArray(); xmlRpcArray.add(new XmlRpcString("Luke")); xmlRpcArray.add(new XmlRpcString("Leia")); XmlRpcElement[] parameters = { xmlRpcArray }; XmlRpcRequest expected = new XmlRpcRequest(this.serviceName, this.methodName, parameters); StringBuffer builder = new StringBuffer(); builder.append("<?xml version=\"1.0\"?>"); builder.append("<methodCall><methodName>"); builder.append(this.serviceAndMethodNames); builder.append("</methodName><params><param><value><array><data>"); XmlRpcElement[] elements = xmlRpcArray.getElements(); int memberCount = elements.length; for (int i = 0; i < memberCount; i++) { XmlRpcString element = (XmlRpcString) elements[i]; builder.append("<value>"); builder.append(element.getValue()); builder.append("</value>"); } builder.append("</data></array></value></param></params></methodCall>"); String request = builder.toString(); InputStream inputStream = new ByteArrayInputStream(request.getBytes()); XmlRpcRequest actual = this.parser.parseRequest(inputStream); this.logger.info("XML-RPC request: " + request); this.logger.info(actual); assertEquals("<XML-RPC request>", expected, actual); } /** * Verifies that the method * <code>{@link XmlRpcRequestParser#parseRequest(InputStream)}</code> parses * correctly a XML-RPC request containing base64 parameters. */ public final void testParseRequestWithBase64Parameters() { byte[] value = new byte[] { 8, 94, 6 }; byte[] encodedValue = Base64.encodeBase64(value); XmlRpcBase64 xmlRpcBase64 = new XmlRpcBase64(value); XmlRpcElement[] parameters = { xmlRpcBase64 }; XmlRpcRequest expected = new XmlRpcRequest(this.serviceName, this.methodName, parameters); StringBuffer builder = new StringBuffer(); builder.append("<?xml version=\"1.0\"?>"); builder.append("<methodCall><methodName>"); builder.append(this.serviceAndMethodNames); builder.append("</methodName><params><param><value><base64>"); builder.append(new String(encodedValue, 0, encodedValue.length)); builder.append("</base64></value></param></params></methodCall>"); String request = builder.toString(); InputStream inputStream = new ByteArrayInputStream(request.getBytes()); XmlRpcRequest actual = this.parser.parseRequest(inputStream); this.logger.info("XML-RPC request: " + request); this.logger.info(actual); assertEquals("<XML-RPC request>", expected, actual); } /** * Verifies that the method * <code>{@link XmlRpcRequestParser#parseRequest(InputStream)}</code> parses * correctly a XML-RPC request containing boolean parameters. */ public final void testParseRequestWithBooleanParameters() { XmlRpcBoolean[] parameters = { new XmlRpcBoolean(Boolean.TRUE), new XmlRpcBoolean(Boolean.FALSE) }; XmlRpcRequest expected = new XmlRpcRequest(this.serviceName, this.methodName, parameters); StringBuffer builder = new StringBuffer(); builder.append("<?xml version=\"1.0\"?>"); builder.append("<methodCall><methodName>"); builder.append(this.serviceAndMethodNames); builder.append("</methodName><params>"); int parameterCount = parameters.length; for (int i = 0; i < parameterCount; i++) { XmlRpcBoolean xmlRpcBoolean = parameters[i]; Boolean value = (Boolean) xmlRpcBoolean.getValue(); builder.append("<param><value><boolean>"); builder.append(value.booleanValue() ? "1" : "0"); builder.append("</boolean></value></param>"); } builder.append("</params></methodCall>"); String request = builder.toString(); InputStream inputStream = new ByteArrayInputStream(request.getBytes()); XmlRpcRequest actual = this.parser.parseRequest(inputStream); this.logger.info("XML-RPC request: " + request); this.logger.info(actual); assertEquals("<XML-RPC request>", expected, actual); } /** * Verifies that the method * <code>{@link XmlRpcRequestParser#parseRequest(InputStream)}</code> parses * correctly a XML-RPC request containing date/time parameters. */ public final void testParseRequestWithDateTimeParameters() { DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss"); Calendar calendar = new GregorianCalendar(); calendar.set(Calendar.MILLISECOND, 0); Date value = calendar.getTime(); XmlRpcDateTime xmlRpcDateTime = new XmlRpcDateTime(value); XmlRpcElement[] parameters = { xmlRpcDateTime }; XmlRpcRequest expected = new XmlRpcRequest(this.serviceName, this.methodName, parameters); StringBuffer builder = new StringBuffer(); builder.append("<?xml version=\"1.0\"?>"); builder.append("<methodCall><methodName>"); builder.append(this.serviceAndMethodNames); builder.append("</methodName><params><param><value><dateTime.iso8601>"); builder.append(dateFormat.format(value)); builder.append("</dateTime.iso8601></value></param></params></methodCall>"); String request = builder.toString(); InputStream inputStream = new ByteArrayInputStream(request.getBytes()); XmlRpcRequest actual = this.parser.parseRequest(inputStream); this.logger.info("XML-RPC request: " + request); this.logger.info(actual); assertEquals("<XML-RPC request>", expected, actual); } /** * Verifies that the method * <code>{@link XmlRpcRequestParser#parseRequest(InputStream)}</code> parses * correctly a XML-RPC request containing double-precision signed floating * point numbers as parameters. */ public final void testParseRequestWithDoubleParameters() { Double value = new Double(782.99); XmlRpcDouble xmlRpcDouble = new XmlRpcDouble(value); XmlRpcElement[] parameters = { xmlRpcDouble }; XmlRpcRequest expected = new XmlRpcRequest(this.serviceName, this.methodName, parameters); StringBuffer builder = new StringBuffer(); builder.append("<?xml version=\"1.0\"?>"); builder.append("<methodCall><methodName>"); builder.append(this.serviceAndMethodNames); builder.append("</methodName><params><param><value><double>"); builder.append(value.toString()); builder.append("</double></value></param></params></methodCall>"); String request = builder.toString(); InputStream inputStream = new ByteArrayInputStream(request.getBytes()); XmlRpcRequest actual = this.parser.parseRequest(inputStream); this.logger.info("XML-RPC request: " + request); this.logger.info(actual); assertEquals("<XML-RPC request>", expected, actual); } /** * Verifies that the method * <code>{@link XmlRpcRequestParser#parseRequest(InputStream)}</code> parses * correctly a XML-RPC request containing four-byte signed integer parameters. */ public final void testParseRequestWithIntegerParameters() { XmlRpcInteger[] parameters = { new XmlRpcInteger(new Integer(54)), new XmlRpcInteger(new Integer(438)) }; XmlRpcRequest expected = new XmlRpcRequest(this.serviceName, this.methodName, parameters); StringBuffer builder = new StringBuffer(); builder.append("<?xml version=\"1.0\"?>"); builder.append("<methodCall><methodName>"); builder.append(this.serviceAndMethodNames); builder.append("</methodName><params>"); int parameterCount = parameters.length; for (int i = 0; i < parameterCount; i++) { XmlRpcInteger xmlRpcInteger = parameters[i]; Integer value = (Integer) xmlRpcInteger.getValue(); // even parameters will have "i4" as name, odd parameters will have "int" // as name. String elementName = (i % 2 == 0) ? "i4" : "int"; builder.append("<param><value><"); builder.append(elementName); builder.append(">"); builder.append(value.toString()); builder.append("</"); builder.append(elementName); builder.append("></value></param>"); } builder.append("</params></methodCall>"); String request = builder.toString(); InputStream inputStream = new ByteArrayInputStream(request.getBytes()); XmlRpcRequest actual = this.parser.parseRequest(inputStream); this.logger.info("XML-RPC request: " + request); this.logger.info(actual); assertEquals("<XML-RPC request>", expected, actual); } /** * Verifies that the method * <code>{@link XmlRpcRequestParser#parseRequest(InputStream)}</code> parses * correctly a XML-RPC request containing string parameters. */ public final void testParseRequestWithStringParameters() { XmlRpcString[] parameters = { new XmlRpcString("Hoth"), new XmlRpcString("Endor") }; XmlRpcRequest expected = new XmlRpcRequest(this.serviceName, this.methodName, parameters); StringBuffer builder = new StringBuffer(); builder.append("<?xml version=\"1.0\"?>"); builder.append("<methodCall><methodName>"); builder.append(this.serviceAndMethodNames); builder.append("</methodName><params>"); int parameterCount = parameters.length; for (int i = 0; i < parameterCount; i++) { XmlRpcString xmlRpcString = parameters[i]; String value = (String) xmlRpcString.getValue(); // even parameters will have an extra "string" element. boolean addStringElement = (i % 2 == 0); builder.append("<param><value>"); if (addStringElement) { builder.append("<string>"); } builder.append(value); if (addStringElement) { builder.append("</string>"); } builder.append("</value></param>"); } builder.append("</params></methodCall>"); String request = builder.toString(); InputStream inputStream = new ByteArrayInputStream(request.getBytes()); XmlRpcRequest actual = this.parser.parseRequest(inputStream); this.logger.info("XML-RPC request: " + request); this.logger.info(actual); assertEquals("<XML-RPC request>", expected, actual); } /** * Verifies that the method * <code>{@link XmlRpcRequestParser#parseRequest(InputStream)}</code> parses * correctly a XML-RPC request containing struct parameters. */ public final void testParseRequestWithStructParameters() { XmlRpcStruct xmlRpcStruct = new XmlRpcStruct(); xmlRpcStruct.add("name", new XmlRpcString("Darth Vader")); xmlRpcStruct.add("role", new XmlRpcString("Sith lord")); XmlRpcElement[] parameters = { xmlRpcStruct }; XmlRpcRequest expected = new XmlRpcRequest(this.serviceName, this.methodName, parameters); StringBuffer builder = new StringBuffer(); builder.append("<?xml version=\"1.0\"?>"); builder.append("<methodCall><methodName>"); builder.append(this.serviceAndMethodNames); builder.append("</methodName><params><param><value><struct>"); XmlRpcMember[] members = xmlRpcStruct.getMembers(); int memberCount = members.length; for (int i = 0; i < memberCount; i++) { XmlRpcMember member = members[i]; XmlRpcString value = (XmlRpcString) member.value; builder.append("<member><name>"); builder.append(member.name); builder.append("</name><value>"); builder.append(value.getValue()); builder.append("</value></member>"); } builder.append("</struct></value></param></params></methodCall>"); String request = builder.toString(); InputStream inputStream = new ByteArrayInputStream(request.getBytes()); XmlRpcRequest actual = this.parser.parseRequest(inputStream); this.logger.info("XML-RPC request: " + request); this.logger.info(actual); assertEquals("<XML-RPC request>", expected, actual); } }