You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xmlrpc-auto@ws.apache.org by jo...@apache.org on 2006/11/23 23:21:42 UTC
svn commit: r478685 - in /webservices/xmlrpc/trunk: ./
common/src/main/java/org/apache/xmlrpc/parser/
common/src/main/java/org/apache/xmlrpc/serializer/ src/changes/
tests/src/test/java/org/apache/xmlrpc/test/
Author: jochen
Date: Thu Nov 23 14:21:42 2006
New Revision: 478685
URL: http://svn.apache.org/viewvc?view=rev&rev=478685
Log:
It is now possible, to have other objects than strings as
map keys, if extensions are enabled.
Modified:
webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/parser/MapParser.java
webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/serializer/MapSerializer.java
webservices/xmlrpc/trunk/pom.xml
webservices/xmlrpc/trunk/src/changes/changes.xml
webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/SerializerTest.java
Modified: webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/parser/MapParser.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/parser/MapParser.java?view=diff&rev=478685&r1=478684&r2=478685
==============================================================================
--- webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/parser/MapParser.java (original)
+++ webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/parser/MapParser.java Thu Nov 23 14:21:42 2006
@@ -35,7 +35,8 @@
*/
public class MapParser extends RecursiveTypeParserImpl {
private int level = 0;
- private String name;
+ private StringBuffer nameBuffer = new StringBuffer();
+ private Object nameObject;
private Map map;
private boolean inName, inValue, doneValue;
@@ -51,17 +52,21 @@
}
protected void addResult(Object pResult) throws SAXException {
- if (name == null) {
- throw new SAXParseException("Invalid state: Expected name",
- getDocumentLocator());
- } else {
- if (map.containsKey(name)) {
- throw new SAXParseException("Duplicate name: " + name,
- getDocumentLocator());
- } else {
- map.put(name, pResult);
- }
- }
+ if (inName) {
+ nameObject = pResult;
+ } else {
+ if (nameObject == null) {
+ throw new SAXParseException("Invalid state: Expected name",
+ getDocumentLocator());
+ } else {
+ if (map.containsKey(nameObject)) {
+ throw new SAXParseException("Duplicate name: " + nameObject,
+ getDocumentLocator());
+ } else {
+ map.put(nameObject, pResult);
+ }
+ }
+ }
}
public void startDocument() throws SAXException {
@@ -72,9 +77,8 @@
}
public void characters(char[] pChars, int pOffset, int pLength) throws SAXException {
- if (inName) {
- String s = new String(pChars, pOffset, pLength);
- name = name == null ? s : name + s;
+ if (inName && !inValue) {
+ nameBuffer.append(pChars, pOffset, pLength);
} else {
super.characters(pChars, pOffset, pLength);
}
@@ -105,7 +109,8 @@
getDocumentLocator());
}
doneValue = inName = inValue = false;
- name = null;
+ nameObject = null;
+ nameBuffer.setLength(0);
break;
case 2:
if (doneValue) {
@@ -114,7 +119,7 @@
getDocumentLocator());
}
if ("".equals(pURI) && MapSerializer.NAME_TAG.equals(pLocalName)) {
- if (name == null) {
+ if (nameObject == null) {
inName = true;
} else {
throw new SAXParseException("Expected " + TypeSerializerImpl.VALUE_TAG
@@ -122,7 +127,7 @@
getDocumentLocator());
}
} else if ("".equals(pURI) && TypeSerializerImpl.VALUE_TAG.equals(pLocalName)) {
- if (name == null) {
+ if (nameObject == null) {
throw new SAXParseException("Expected " + MapSerializer.NAME_TAG
+ ", got " + new QName(pURI, pLocalName),
getDocumentLocator());
@@ -133,6 +138,20 @@
}
break;
+ case 3:
+ if (inName && "".equals(pURI) && TypeSerializerImpl.VALUE_TAG.equals(pLocalName)) {
+ if (cfg.isEnabledForExtensions()) {
+ inValue = true;
+ startValueTag();
+ } else {
+ throw new SAXParseException("Expected /" + MapSerializer.NAME_TAG
+ + ", got " + new QName(pURI, pLocalName),
+ getDocumentLocator());
+ }
+ } else {
+ super.startElement(pURI, pLocalName, pQName, pAttrs);
+ }
+ break;
default:
super.startElement(pURI, pLocalName, pQName, pAttrs);
break;
@@ -149,11 +168,28 @@
case 2:
if (inName) {
inName = false;
- } else if (inValue) {
+ if (nameObject == null) {
+ nameObject = nameBuffer.toString();
+ } else {
+ for (int i = 0; i < nameBuffer.length(); i++) {
+ if (!Character.isWhitespace(nameBuffer.charAt(i))) {
+ throw new SAXParseException("Unexpected non-whitespace character in member name",
+ getDocumentLocator());
+ }
+ }
+ }
+ } else if (inValue) {
endValueTag();
doneValue = true;
}
break;
+ case 3:
+ if (inName && inValue && "".equals(pURI) && TypeSerializerImpl.VALUE_TAG.equals(pLocalName)) {
+ endValueTag();
+ } else {
+ super.endElement(pURI, pLocalName, pQName);
+ }
+ break;
default:
super.endElement(pURI, pLocalName, pQName);
}
Modified: webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/serializer/MapSerializer.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/serializer/MapSerializer.java?view=diff&rev=478685&r1=478684&r2=478685
==============================================================================
--- webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/serializer/MapSerializer.java (original)
+++ webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/serializer/MapSerializer.java Thu Nov 23 14:21:42 2006
@@ -27,18 +27,22 @@
/** A {@link TypeSerializer} for maps.
*/
public class MapSerializer extends TypeSerializerImpl {
- private final XmlRpcStreamConfig config;
+ /** Tag name of a maps struct tag.
+ */
+ public static final String STRUCT_TAG = "struct";
+
+ /** Tag name of a maps member tag.
+ */
+ public static final String MEMBER_TAG = "member";
+
+ /** Tag name of a maps members name tag.
+ */
+ public static final String NAME_TAG = "name";
+
+ private final XmlRpcStreamConfig config;
private final TypeFactory typeFactory;
- /** Tag name of a maps struct tag.
- */
- public static final String STRUCT_TAG = "struct";
- /** Tag name of a maps member tag.
- */
- public static final String MEMBER_TAG = "member";
- /** Tag name of a maps members name tag.
- */
- public static final String NAME_TAG = "name";
- /** Creates a new instance.
+
+ /** Creates a new instance.
* @param pTypeFactory The factory being used for creating serializers.
* @param pConfig The configuration being used for creating serializers.
*/
@@ -46,30 +50,43 @@
typeFactory = pTypeFactory;
config = pConfig;
}
- protected void writeEntry(ContentHandler pHandler, String pKey, Object pValue) throws SAXException {
+
+ protected void writeEntry(ContentHandler pHandler, Object pKey, Object pValue) throws SAXException {
pHandler.startElement("", MEMBER_TAG, MEMBER_TAG, ZERO_ATTRIBUTES);
pHandler.startElement("", NAME_TAG, NAME_TAG, ZERO_ATTRIBUTES);
- pHandler.characters(pKey.toCharArray(), 0, pKey.length());
+ if (config.isEnabledForExtensions() && !(pKey instanceof String)) {
+ writeValue(pHandler, pKey);
+ } else {
+ String key = pKey.toString();
+ pHandler.characters(key.toCharArray(), 0, key.length());
+ }
pHandler.endElement("", NAME_TAG, NAME_TAG);
- TypeSerializer ts = typeFactory.getSerializer(config, pValue);
+ writeValue(pHandler, pValue);
+ pHandler.endElement("", MEMBER_TAG, MEMBER_TAG);
+ }
+
+ private void writeValue(ContentHandler pHandler, Object pValue)
+ throws SAXException {
+ TypeSerializer ts = typeFactory.getSerializer(config, pValue);
if (ts == null) {
throw new SAXException("Unsupported Java type: " + pValue.getClass().getName());
}
ts.write(pHandler, pValue);
- pHandler.endElement("", MEMBER_TAG, MEMBER_TAG);
- }
- protected void writeData(ContentHandler pHandler, Object pData) throws SAXException {
+ }
+
+ protected void writeData(ContentHandler pHandler, Object pData) throws SAXException {
Map map = (Map) pData;
for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) {
Map.Entry entry = (Map.Entry) iter.next();
- writeEntry(pHandler, entry.getKey().toString(), entry.getValue());
+ writeEntry(pHandler, entry.getKey(), entry.getValue());
}
}
- public void write(final ContentHandler pHandler, Object pObject) throws SAXException {
+
+ public void write(final ContentHandler pHandler, Object pObject) throws SAXException {
pHandler.startElement("", VALUE_TAG, VALUE_TAG, ZERO_ATTRIBUTES);
pHandler.startElement("", STRUCT_TAG, STRUCT_TAG, ZERO_ATTRIBUTES);
writeData(pHandler, pObject);
pHandler.endElement("", STRUCT_TAG, STRUCT_TAG);
pHandler.endElement("", VALUE_TAG, VALUE_TAG);
}
-}
\ No newline at end of file
+}
Modified: webservices/xmlrpc/trunk/pom.xml
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/pom.xml?view=diff&rev=478685&r1=478684&r2=478685
==============================================================================
--- webservices/xmlrpc/trunk/pom.xml (original)
+++ webservices/xmlrpc/trunk/pom.xml Thu Nov 23 14:21:42 2006
@@ -314,12 +314,12 @@
<repository>
<id>apache.releases</id>
<name>Apache Release Distribution Repository</name>
- <url>scpexe://people.apache.org/www/people.apache.org/repo/m2-ibiblio-rsync-repository</url>
+ <url>scp://people.apache.org/www/people.apache.org/repo/m2-ibiblio-rsync-repository</url>
</repository>
<snapshotRepository>
<id>apache.snapshots</id>
<name>Apache Development Snapshot Repository</name>
- <url>scpexe://people.apache.org/www/people.apache.org/repo/m2-snapshot-repository</url>
+ <url>scp://people.apache.org/www/people.apache.org/repo/m2-snapshot-repository</url>
</snapshotRepository>
<site>
Modified: webservices/xmlrpc/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/src/changes/changes.xml?view=diff&rev=478685&r1=478684&r2=478685
==============================================================================
--- webservices/xmlrpc/trunk/src/changes/changes.xml (original)
+++ webservices/xmlrpc/trunk/src/changes/changes.xml Thu Nov 23 14:21:42 2006
@@ -44,6 +44,10 @@
The ClientFactory is now able to use a custom name for the remote
handler. So far, it was always using the interface name.
</action>
+ <action dev="jochen" type="add" issue="XMLRPC-127">
+ It is now possible to have other objects than strings as
+ map keys.
+ </action>
</release>
<release version="3.0.1-SNAPSHOT" date="Not yet released">
<action dev="jochen" type="fix">
Modified: webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/SerializerTest.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/SerializerTest.java?view=diff&rev=478685&r1=478684&r2=478685
==============================================================================
--- webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/SerializerTest.java (original)
+++ webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/SerializerTest.java Thu Nov 23 14:21:42 2006
@@ -15,11 +15,15 @@
*/
package org.apache.xmlrpc.test;
+import java.io.StringReader;
import java.util.Calendar;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.TimeZone;
+import javax.xml.parsers.SAXParserFactory;
+
import junit.framework.TestCase;
import org.apache.xmlrpc.XmlRpcRequest;
@@ -28,8 +32,14 @@
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
import org.apache.xmlrpc.client.XmlRpcClientRequestImpl;
import org.apache.xmlrpc.client.XmlRpcSunHttpTransportFactory;
+import org.apache.xmlrpc.common.TypeFactoryImpl;
import org.apache.xmlrpc.common.XmlRpcStreamRequestConfig;
+import org.apache.xmlrpc.parser.XmlRpcRequestParser;
+import org.apache.xmlrpc.server.XmlRpcServer;
+import org.apache.xmlrpc.server.XmlRpcServerConfigImpl;
+import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
/** A test case for the various serializers.
@@ -146,5 +156,45 @@
+ "<param><value><dateTime.iso8601>19330612T11:07:21</dateTime.iso8601></value></param>"
+ "</params></methodCall>";
assertEquals(expect, got);
+ }
+
+ /**
+ * Test for XMLRPC-127: Is it possible to transmit a
+ * map with integers as the keys?
+ */
+ public void testIntegerKeyMap() throws Exception {
+ Map map = new HashMap();
+ map.put(new Integer(1), "one");
+ XmlRpcStreamRequestConfig config = getExConfig();
+ XmlRpcRequest request = new XmlRpcClientRequestImpl(config, "integerKeyMap", new Object[]{map});
+ String got = writeRequest(config, request);
+ String expect =
+ "<?xml version=\"1.0\" encoding=\"US-ASCII\"?>"
+ + "<methodCall xmlns:ex=\"http://ws.apache.org/xmlrpc/namespaces/extensions\">"
+ + "<methodName>integerKeyMap</methodName><params>"
+ + "<param><value><struct><member>"
+ + "<name><value><i4>1</i4></value></name>"
+ + "<value>one</value></member>"
+ + "</struct></value></param>"
+ + "</params></methodCall>";
+ assertEquals(expect, got);
+
+ XmlRpcServer server = new XmlRpcServer();
+ XmlRpcServerConfigImpl serverConfig = new XmlRpcServerConfigImpl();
+ serverConfig.setEnabledForExtensions(true);
+ server.setConfig(serverConfig);
+ XmlRpcRequestParser parser = new XmlRpcRequestParser(serverConfig, new TypeFactoryImpl(server));
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ spf.setValidating(false);
+ spf.setNamespaceAware(true);
+ XMLReader xr = spf.newSAXParser().getXMLReader();
+ xr.setContentHandler(parser);
+ xr.parse(new InputSource(new StringReader(expect)));
+ assertEquals("integerKeyMap", parser.getMethodName());
+ List params = parser.getParams();
+ assertEquals(1, params.size());
+ Map paramMap = (Map) params.get(0);
+ assertEquals(1, paramMap.size());
+ assertEquals("one", paramMap.get(new Integer(1)));
}
}