Author: jochen
Date: Tue Nov 21 14:25:28 2006
New Revision: 477931
URL: http://svn.apache.org/viewvc?view=rev&rev=477931
Log:
Added documentation for XML-RPC introspection.
Added:
webservices/xmlrpc/trunk/src/site/apt/introspection.apt
webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/MetadataTest.java
Modified:
webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/Util.java
webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/XmlRpcSystemImpl.java
webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/webserver/WebServer.java
webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/AuthenticationTest.java
webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/BaseTest.java
Modified:
webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/Util.java
URL:
http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/Util.java?view=diff&rev=477931&r1=477930&r2=477931
==============================================================================
---
webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/Util.java
(original)
+++
webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/Util.java
Tue Nov 21 14:25:28 2006
@@ -171,9 +171,9 @@
public static String getMethodHelp(Class pClass, Method pMethod) {
StringBuffer sb = new StringBuffer();
sb.append("Invokes the method ");
- sb.append(pMethod.getReturnType().getClass().getName());
- sb.append(".");
sb.append(pClass.getName());
+ sb.append(".");
+ sb.append(pMethod.getName());
sb.append("(");
Class[] paramClasses = pMethod.getParameterTypes();
for (int i = 0; i < paramClasses.length; i++) {
Modified:
webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/XmlRpcSystemImpl.java
URL:
http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/XmlRpcSystemImpl.java?view=diff&rev=477931&r1=477930&r2=477931
==============================================================================
---
webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/XmlRpcSystemImpl.java
(original)
+++
webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/XmlRpcSystemImpl.java
Tue Nov 21 14:25:28 2006
@@ -16,6 +16,12 @@
package org.apache.xmlrpc.metadata;
import org.apache.xmlrpc.XmlRpcException;
+import org.apache.xmlrpc.XmlRpcHandler;
+import org.apache.xmlrpc.XmlRpcRequest;
+import org.apache.xmlrpc.server.PropertyHandlerMapping;
+import org.apache.xmlrpc.server.RequestProcessorFactoryFactory;
+import org.apache.xmlrpc.server.XmlRpcNoSuchHandlerException;
+import
org.apache.xmlrpc.server.RequestProcessorFactoryFactory.RequestProcessorFactory;
/** This class implements the various "system" calls,
@@ -53,4 +59,30 @@
public String[] listMethods() throws XmlRpcException {
return mapping.getListMethods();
}
+
+ /**
+ * Adds an instance of this class to the given handler
+ * mapping.
+ */
+ public static void addSystemHandler(final PropertyHandlerMapping
pMapping)
+ throws XmlRpcException {
+ final RequestProcessorFactoryFactory factory =
pMapping.getRequestProcessorFactoryFactory();
+ final XmlRpcSystemImpl systemHandler = new XmlRpcSystemImpl(pMapping);
+ pMapping.setRequestProcessorFactoryFactory(new
RequestProcessorFactoryFactory(){
+ public RequestProcessorFactory getRequestProcessorFactory(Class
pClass)
+ throws XmlRpcException {
+ if (XmlRpcSystemImpl.class.equals(pClass)) {
+ return new RequestProcessorFactory(){
+ public Object getRequestProcessor(XmlRpcRequest
request)
+ throws XmlRpcException {
+ return systemHandler;
+ }
+ };
+ } else {
+ return factory.getRequestProcessorFactory(pClass);
+ }
+ }
+ });
+ pMapping.addHandler("system", XmlRpcSystemImpl.class);
+ }
}
Modified:
webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/webserver/WebServer.java
URL:
http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/webserver/WebServer.java?view=diff&rev=477931&r1=477930&r2=477931
==============================================================================
---
webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/webserver/WebServer.java
(original)
+++
webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/webserver/WebServer.java
Tue Nov 21 14:25:28 2006
@@ -369,7 +369,9 @@
Thread l = listener;
listener = null;
l.interrupt();
- pool.shutdown();
+ if (pool != null) {
+ pool.shutdown();
+ }
}
}
Added: webservices/xmlrpc/trunk/src/site/apt/introspection.apt
URL:
http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/src/site/apt/introspection.apt?view=auto&rev=477931
==============================================================================
--- webservices/xmlrpc/trunk/src/site/apt/introspection.apt (added)
+++ webservices/xmlrpc/trunk/src/site/apt/introspection.apt Tue Nov 21 14:25:28
2006
@@ -0,0 +1,60 @@
+ ---------------------------
+ Advanced Programming Topics
+ ---------------------------
+
+ Apache XML-RPC supports XML-RPC introspection, as specified by
+ {{{http://scripts.incutio.com/xmlrpc/introspection.html}
+ http://scripts.incutio.com/xmlrpc/introspection.html}}. This
+ page describes how to configure the XML-RPC server for
+ introspection.
+
+What is introspection?
+
+ Introspection is the servers ability to provide metadata
+ to the client. The client may ask "What method names does
+ the server offer?", "How do I invoke method 'foo'?", or
+ "Can you give me help on method 'foo'?".
+
+ The client does so by invoking the special methods
+ "system.listMethods", "system.methodSignature" and
+ "system.methodHelp". These are described in detail in the
+ non-official specification for XML-RPC introspection, which
+ you'll find at
+ {{{http://scripts.incutio.com/xmlrpc/introspection.html}
+ http://scripts.incutio.com/xmlrpc/introspection.html}}.
+
+How do I configure the server for introspection?
+
+ The server requires a special mapping. Basically, you simply add
+ a "system" handler, which is implemented by the class
+ <<<XmlRpcSystemImpl>>>. Here's how you would do that in the
+ <<<XmlRpcServlet>>>:
+
+---------------------------------------------------------
+ public class MyXmlRpcServlet extends XmlRpcServlet {
+ protected XmlRpcHandlerMapping newXmlRpcHandlerMapping()
+ throws XmlRpcException {
+ PropertyHandlerMapping mapping =
+ (PropertyHandlerMapping) newXmlRpcHandlerMapping();
+ XmlRpcSystemImpl.addSystemHandler(mapping);
+ }
+ }
+---------------------------------------------------------
+
+ Quite similar, you would override a protected method, if you
+ prefer using the <<<WebServer>>> class:
+
+---------------------------------------------------------
+ public class MyWebServer extends WebServer {
+ public MyWebServer(int pPort) {
+ super(pPort);
+ }
+
+ protected XmlRpcStreamServer newXmlRpcStreamServer(){
+ XmlRpcStreamServer xmlRpcStreamServer = new
ConnectionServer();
+ PropertyHandlerMapping mapping =
(PropertyHandlerMapping) xmlRpcStreamServer.getHandlerMapping();
+ XmlRpcSystemImpl.addSystemHandler(mapping);
+ return xmlRpcStreamServer;
+ }
+ }
+---------------------------------------------------------
Modified:
webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/AuthenticationTest.java
URL:
http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/AuthenticationTest.java?view=diff&rev=477931&r1=477930&r2=477931
==============================================================================
---
webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/AuthenticationTest.java
(original)
+++
webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/AuthenticationTest.java
Tue Nov 21 14:25:28 2006
@@ -17,9 +17,6 @@
import java.io.IOException;
-import javax.servlet.ServletException;
-
-import org.apache.log4j.BasicConfigurator;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.XmlRpcRequest;
import org.apache.xmlrpc.XmlRpcRequestConfig;
Modified:
webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/BaseTest.java
URL:
http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/BaseTest.java?view=diff&rev=477931&r1=477930&r2=477931
==============================================================================
---
webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/BaseTest.java
(original)
+++
webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/BaseTest.java
Tue Nov 21 14:25:28 2006
@@ -26,7 +26,6 @@
import java.util.Map;
import java.util.TimeZone;
-import javax.servlet.ServletException;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
Added:
webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/MetadataTest.java
URL:
http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/MetadataTest.java?view=auto&rev=477931
==============================================================================
---
webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/MetadataTest.java
(added)
+++
webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/MetadataTest.java
Tue Nov 21 14:25:28 2006
@@ -0,0 +1,106 @@
+package org.apache.xmlrpc.test;
+
+import java.io.IOException;
+import java.text.Collator;
+import java.util.Arrays;
+import java.util.Locale;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.apache.xmlrpc.client.XmlRpcClient;
+import org.apache.xmlrpc.client.XmlRpcClientConfig;
+import org.apache.xmlrpc.metadata.XmlRpcSystemImpl;
+import org.apache.xmlrpc.server.PropertyHandlerMapping;
+import org.apache.xmlrpc.server.XmlRpcHandlerMapping;
+
+
+/**
+ * Test class for the introspection stuff.
+ */
+public class MetadataTest extends XmlRpcTestCase {
+ protected XmlRpcHandlerMapping getHandlerMapping() throws IOException,
+ XmlRpcException {
+ PropertyHandlerMapping mapping = new PropertyHandlerMapping();
+ mapping.addHandler("Adder", AuthenticationTest.AdderImpl.class);
+ XmlRpcSystemImpl.addSystemHandler(mapping);
+ return mapping;
+ }
+
+ /**
+ * Test, whether the actual handlers are working.
+ */
+ public void testAdder() throws Exception {
+ for (int i = 0; i < providers.length; i++) {
+ testAdder(providers[i]);
+ }
+ }
+
+ private void testAdder(ClientProvider pProvider) throws Exception {
+ XmlRpcClient client = pProvider.getClient();
+ XmlRpcClientConfig config = getConfig(pProvider);
+ client.setConfig(config);
+ Object o = client.execute("Adder.add", new Object[]{new Integer(3),
new Integer(5)});
+ assertEquals(new Integer(8), o);
+ }
+
+ /**
+ * Test for system.listMethods.
+ */
+ public void testListMethods() throws Exception {
+ for (int i = 0; i < providers.length; i++) {
+ testListMethods(providers[i]);
+ }
+ }
+
+ private void testListMethods(ClientProvider pProvider) throws Exception {
+ XmlRpcClient client = pProvider.getClient();
+ XmlRpcClientConfig config = getConfig(pProvider);
+ client.setConfig(config);
+ Object o = client.execute("system.listMethods", new Object[0]);
+ Object[] methodList = (Object[]) o;
+ Arrays.sort(methodList, Collator.getInstance(Locale.US));
+ assertEquals(4, methodList.length);
+ assertEquals("Adder.add", methodList[0]);
+ assertEquals("system.listMethods", methodList[1]);
+ assertEquals("system.methodHelp", methodList[2]);
+ assertEquals("system.methodSignature", methodList[3]);
+ }
+
+ /**
+ * Test for system.methodHelp.
+ */
+ public void testMethodHelp() throws Exception {
+ for (int i = 0; i < providers.length; i++) {
+ testMethodHelp(providers[i]);
+ }
+ }
+
+ private void testMethodHelp(ClientProvider pProvider) throws Exception {
+ XmlRpcClient client = pProvider.getClient();
+ XmlRpcClientConfig config = getConfig(pProvider);
+ client.setConfig(config);
+ String help = (String) client.execute("system.methodHelp", new
Object[]{"Adder.add"});
+ assertEquals("Invokes the method
org.apache.xmlrpc.test.AuthenticationTest$AdderImpl.add(int, int).", help);
+ }
+
+ /**
+ * Test for system.methodSignature.
+ */
+ public void testMethodSignature() throws Exception {
+ for (int i = 0; i < providers.length; i++) {
+ testMethodSignature(providers[i]);
+ }
+ }
+
+ private void testMethodSignature(ClientProvider pProvider) throws
Exception {
+ XmlRpcClient client = pProvider.getClient();
+ XmlRpcClientConfig config = getConfig(pProvider);
+ client.setConfig(config);
+ Object[] signatures = (Object[])
client.execute("system.methodSignature", new Object[]{"Adder.add"});
+ assertEquals(signatures.length, 1);
+ Object[] signature = (Object[]) signatures[0];
+ assertEquals(3, signature.length);
+ assertEquals("int", signature[0]);
+ assertEquals("int", signature[1]);
+ assertEquals("int", signature[2]);
+ }
+}