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]);
+    }
+}


Reply via email to