You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xmlrpc-dev@ws.apache.org by jo...@apache.org on 2006/06/10 23:25:12 UTC

svn commit: r413365 - in /webservices/xmlrpc/trunk: server/src/main/java/org/apache/xmlrpc/metadata/ server/src/main/java/org/apache/xmlrpc/server/ server/src/main/java/org/apache/xmlrpc/webserver/ src/changes/ src/site/fml/ tests/src/test/java/org/apa...

Author: jochen
Date: Sat Jun 10 14:25:12 2006
New Revision: 413365

URL: http://svn.apache.org/viewvc?rev=413365&view=rev
Log:
It is now possible to create and initialize handler objects per request.

Modified:
    webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/ReflectiveXmlRpcMetaDataHandler.java
    webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/AbstractReflectiveHandlerMapping.java
    webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/DynamicHandlerMapping.java
    webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/PropertyHandlerMapping.java
    webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/ReflectiveXmlRpcHandler.java
    webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/webserver/XmlRpcServlet.java
    webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/webserver/XmlRpcServletServer.java
    webservices/xmlrpc/trunk/src/changes/changes.xml
    webservices/xmlrpc/trunk/src/site/fml/faq.fml
    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/ReflectiveXmlRpcMetaDataHandler.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/ReflectiveXmlRpcMetaDataHandler.java?rev=413365&r1=413364&r2=413365&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/ReflectiveXmlRpcMetaDataHandler.java (original)
+++ webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/metadata/ReflectiveXmlRpcMetaDataHandler.java Sat Jun 10 14:25:12 2006
@@ -35,8 +35,21 @@
 	 * this handler. Typically, this will be the same as
 	 * <pre>pInstance.getClass()</pre>. It is used for diagnostic
 	 * messages only.
-	 * @param pInstance The instance, which will be invoked for
-	 * executing the handler.
+     * @param pInstanceIsStateless The handler
+     * can operate in either of two operation modes:
+     * <ol>
+     *   <li>The object, which is actually performing the requests,
+     *     is initialized at startup. In other words, there is only
+     *     one object, which is performing all the requests.
+     *     Obviously, this is the faster operation mode. On the
+     *     other hand, it has the disadvantage, that the object
+     *     must be stateless.</li>
+     *   <li>A new object is created for any request. This is slower,
+     *     because the object needs to be initialized. On the other
+     *     hand, it allows for stateful objects, which may take
+     *     request specific configuration like the clients IP address,
+     *     and the like.</li>
+     * </ol>
 	 * @param pMethods The method, which will be invoked for
 	 * executing the handler. 
 	 * @param pSignatures The signature, which will be returned by
@@ -45,9 +58,10 @@
 	 * by {@link #getMethodHelp()}.
 	 */
 	public ReflectiveXmlRpcMetaDataHandler(AbstractReflectiveHandlerMapping pMapping,
-			Class pClass, Object pInstance, Method[] pMethods,
-			String[][] pSignatures, String pMethodHelp) {
-		super(pMapping, pClass, pInstance, pMethods);
+			    Class pClass, boolean pInstanceIsStateless, Method[] pMethods,
+			    String[][] pSignatures, String pMethodHelp)
+            throws XmlRpcException {
+		super(pMapping, pClass, pInstanceIsStateless, pMethods);
 		signatures = pSignatures;
 		methodHelp = pMethodHelp;
 	}

Modified: webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/AbstractReflectiveHandlerMapping.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/AbstractReflectiveHandlerMapping.java?rev=413365&r1=413364&r2=413365&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/AbstractReflectiveHandlerMapping.java (original)
+++ webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/AbstractReflectiveHandlerMapping.java Sat Jun 10 14:25:12 2006
@@ -48,9 +48,43 @@
             throws XmlRpcException;
     }
 
+    /** An object, which is called for initializing the
+     * actual handler object.
+     */
+    public interface InitializationHandler {
+        /** Called for initializing the object, which
+         * is was returned by {@link ReflectiveXmlRpcHandler#newInstance()}.
+         */
+        public void init(XmlRpcRequest pRequest, Object pObject)
+            throws XmlRpcException;
+    }
+
     protected Map handlerMap = new HashMap();
     private AuthenticationHandler authenticationHandler;
+    private InitializationHandler initializationHandler;
+    private final boolean instanceIsStateless;
 
+    /** Creates a new instance.
+     * @param pInstanceIsStateless The handler
+     * can operate in either of two operation modes:
+     * <ol>
+     *   <li>The object, which is actually performing the requests,
+     *     is initialized at startup. In other words, there is only
+     *     one object, which is performing all the requests.
+     *     Obviously, this is the faster operation mode. On the
+     *     other hand, it has the disadvantage, that the object
+     *     must be stateless.</li>
+     *   <li>A new object is created for any request. This is slower,
+     *     because the object needs to be initialized. On the other
+     *     hand, it allows for stateful objects, which may take
+     *     request specific configuration like the clients IP address,
+     *     and the like.</li>
+     * </ol>
+     */
+    protected AbstractReflectiveHandlerMapping(boolean pInstanceIsStateless) {
+        instanceIsStateless = pInstanceIsStateless;
+    }
+    
     /** Returns the authentication handler, if any, or null.
      */
     public AuthenticationHandler getAuthenticationHandler() {
@@ -59,11 +93,22 @@
 
     /** Sets the authentication handler, if any, or null.
      */
-    public void setAuthenticationHandler(
-            AuthenticationHandler pAuthenticationHandler) {
+    public void setAuthenticationHandler(AuthenticationHandler pAuthenticationHandler) {
         authenticationHandler = pAuthenticationHandler;
     }
 
+    /** Returns the initialization handler, if any, or null.
+     */
+    public InitializationHandler getInitializationHandler() {
+        return initializationHandler;
+    }
+
+    /** Sets the initialization handler, if any, or null.
+     */
+    public void setInitializationHandler(InitializationHandler pInitializationHandler) {
+        initializationHandler = pInitializationHandler;
+    }
+
     /** Searches for methods in the given class. For any valid
      * method, it creates an instance of {@link XmlRpcHandler}.
      * Valid methods are defined as follows:
@@ -82,15 +127,9 @@
      * @param pKey Suffix for building handler names. A dot and
      * the method name are being added.
      * @param pType The class being inspected.
-     * @param pInstance The object being invoked. Note, that this
-     * object must be stateless: Multiple threads can run on it
-     * at the same time.
      */
     protected void registerPublicMethods(Map pMap, String pKey,
-    		Class pType, Object pInstance) {
-    	if (pInstance == null) {
-    		throw new NullPointerException("The object instance must not be null.");
-    	}
+    		Class pType) throws XmlRpcException {
     	Map map = new HashMap();
         Method[] methods = pType.getMethods();
         for (int i = 0;  i < methods.length;  i++) {
@@ -124,7 +163,7 @@
             Map.Entry entry = (Map.Entry) iter.next();
             String name = (String) entry.getKey();
             Method[] mArray = (Method[]) entry.getValue();
-            pMap.put(name, newXmlRpcHandler(pType, pInstance, mArray));
+            pMap.put(name, newXmlRpcHandler(pType, mArray));
         }
     }
 
@@ -132,22 +171,16 @@
      * @param pClass The class, which was inspected for handler
      * methods. This is used for error messages only. Typically,
      * it is the same than <pre>pInstance.getClass()</pre>.
-     * @param pInstance The object, which is being invoked by
-     * the created handler. Typically an instance of
-     * <code>pClass</code>.
      * @param pMethods The method being invoked.
      */
     protected XmlRpcHandler newXmlRpcHandler(final Class pClass,
-    		final Object pInstance, final Method[] pMethods) {
-    	if (pInstance == null) {
-    		throw new NullPointerException("The object instance must not be null.");
-    	}
+            final Method[] pMethods) throws XmlRpcException {
     	String[][] sig = getSignature(pMethods);
     	String help = getMethodHelp(pClass, pMethods);
     	if (sig == null  ||  help == null) {
-    		return new ReflectiveXmlRpcHandler(this, pClass, pInstance, pMethods);
+    		return new ReflectiveXmlRpcHandler(this, pClass, instanceIsStateless, pMethods);
     	}
-    	return new ReflectiveXmlRpcMetaDataHandler(this, pClass, pInstance,
+    	return new ReflectiveXmlRpcMetaDataHandler(this, pClass, instanceIsStateless,
     			pMethods, sig, help);
     }
 

Modified: webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/DynamicHandlerMapping.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/DynamicHandlerMapping.java?rev=413365&r1=413364&r2=413365&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/DynamicHandlerMapping.java (original)
+++ webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/DynamicHandlerMapping.java Sat Jun 10 14:25:12 2006
@@ -2,20 +2,43 @@
 
 import java.util.Iterator;
 
+import org.apache.xmlrpc.XmlRpcException;
+
 
 /** A handler mapping, which requires explicit registration
  * of handlers.
  */
 public class DynamicHandlerMapping extends AbstractReflectiveHandlerMapping {
+    /** Creates a new instance.
+     * @param pInstanceIsStateless The handler
+     * can operate in either of two operation modes:
+     * <ol>
+     *   <li>The object, which is actually performing the requests,
+     *     is initialized at startup. In other words, there is only
+     *     one object, which is performing all the requests.
+     *     Obviously, this is the faster operation mode. On the
+     *     other hand, it has the disadvantage, that the object
+     *     must be stateless.</li>
+     *   <li>A new object is created for any request. This is slower,
+     *     because the object needs to be initialized. On the other
+     *     hand, it allows for stateful objects, which may take
+     *     request specific configuration like the clients IP address,
+     *     and the like.</li>
+     * </ol>
+     */
+    public DynamicHandlerMapping(boolean pInstanceIsStateless) {
+        super(pInstanceIsStateless);
+    }
+
 	/** Adds handlers for the given object to the mapping.
 	 * The handlers are build by invoking
-	 * {@link #registerPublicMethods(java.util.Map, String, Class, Object)}.
+	 * {@link #registerPublicMethods(java.util.Map, String, Class)}.
 	 * @param pKey The class key, which is passed
-	 * to {@link #registerPublicMethods(java.util.Map, String, Class, Object)}.
-	 * @param pHandler The object, which is handling requests.
+	 * to {@link #registerPublicMethods(java.util.Map, String, Class)}.
+	 * @param pClass Class, which is responsible for handling the request.
 	 */
-    public void addHandler(String pKey, Object pHandler) {
-        registerPublicMethods(handlerMap, pKey, pHandler.getClass(), pHandler);
+    public void addHandler(String pKey, Class pClass) throws XmlRpcException {
+        registerPublicMethods(handlerMap, pKey, pClass);
     }
 
     /** Removes all handlers with the given class key.

Modified: webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/PropertyHandlerMapping.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/PropertyHandlerMapping.java?rev=413365&r1=413364&r2=413365&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/PropertyHandlerMapping.java (original)
+++ webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/PropertyHandlerMapping.java Sat Jun 10 14:25:12 2006
@@ -45,11 +45,28 @@
      * @param pClassLoader Classloader being used to load the classes.
      * @param pURL The URL, from which the property file is being
      * loaded.
+     * @param pInstanceIsStateless The handler
+     * can operate in either of two operation modes:
+     * <ol>
+     *   <li>The object, which is actually performing the requests,
+     *     is initialized at startup. In other words, there is only
+     *     one object, which is performing all the requests.
+     *     Obviously, this is the faster operation mode. On the
+     *     other hand, it has the disadvantage, that the object
+     *     must be stateless.</li>
+     *   <li>A new object is created for any request. This is slower,
+     *     because the object needs to be initialized. On the other
+     *     hand, it allows for stateful objects, which may take
+     *     request specific configuration like the clients IP address,
+     *     and the like.</li>
+     * </ol>
      * @throws IOException Loading the property file failed.
      * @throws XmlRpcException Initializing the handlers failed.
      */
-    public PropertyHandlerMapping(ClassLoader pClassLoader, URL pURL)
+    public PropertyHandlerMapping(ClassLoader pClassLoader, URL pURL,
+                boolean pInstanceIsStateless)
             throws IOException, XmlRpcException {
+        super(pInstanceIsStateless);
         handlerMap = load(pClassLoader, pURL);
     }
 
@@ -58,18 +75,38 @@
      * @param pClassLoader Classloader being used to locate
      * the resource.
      * @param pResource Resource being loaded.
+     * @param pInstanceIsStateless The handler
+     * can operate in either of two operation modes:
+     * <ol>
+     *   <li>The object, which is actually performing the requests,
+     *     is initialized at startup. In other words, there is only
+     *     one object, which is performing all the requests.
+     *     Obviously, this is the faster operation mode. On the
+     *     other hand, it has the disadvantage, that the object
+     *     must be stateless.</li>
+     *   <li>A new object is created for any request. This is slower,
+     *     because the object needs to be initialized. On the other
+     *     hand, it allows for stateful objects, which may take
+     *     request specific configuration like the clients IP address,
+     *     and the like.</li>
+     * </ol>
      * @throws IOException Loading the property file failed.
      * @throws XmlRpcException Initializing the handlers failed.
      */
-    public PropertyHandlerMapping(ClassLoader pClassLoader, String pResource)
+    public PropertyHandlerMapping(ClassLoader pClassLoader, String pResource,
+                boolean pInstanceIsStateless)
             throws IOException, XmlRpcException {
+        this(pClassLoader, asURL(pClassLoader, pResource), pInstanceIsStateless);
+    }
+
+    private static URL asURL(ClassLoader pClassLoader, String pResource) throws IOException {
         URL url = pClassLoader.getResource(pResource);
         if (url == null) {
             throw new IOException("Unable to locate resource " + pResource);
         }
-        handlerMap = load(pClassLoader, url);
+        return url;
     }
-
+    
     private Map load(ClassLoader pClassLoader, URL pURL) throws IOException, XmlRpcException {
         Map map = new HashMap();
         Properties props = new Properties();
@@ -78,13 +115,13 @@
             Map.Entry entry = (Map.Entry) iter.next();
             String key = (String) entry.getKey();
             String value = (String) entry.getValue();
-            Object o = newHandlerObject(pClassLoader, value);
-            registerPublicMethods(map, key, o.getClass(), o);
+            Class c = newHandlerClass(pClassLoader, value);
+            registerPublicMethods(map, key, c);
         }
         return map;
     }
 
-    protected Object newHandlerObject(ClassLoader pClassLoader, String pClassName)
+    protected Class newHandlerClass(ClassLoader pClassLoader, String pClassName)
             throws XmlRpcException {
         final Class c;
         try {
@@ -95,12 +132,6 @@
         if (c == null) {
             throw new XmlRpcException(0, "Loading class " + pClassName + " returned null.");
         }
-        try {
-            return c.newInstance();
-        } catch (InstantiationException e) {
-            throw new XmlRpcException("Failed to instantiate class " + c.getName(), e);
-        } catch (IllegalAccessException e) {
-            throw new XmlRpcException("Illegal access when instantiating class " + c.getName(), e);
-        }
+        return c;
     }
 }

Modified: webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/ReflectiveXmlRpcHandler.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/ReflectiveXmlRpcHandler.java?rev=413365&r1=413364&r2=413365&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/ReflectiveXmlRpcHandler.java (original)
+++ webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/server/ReflectiveXmlRpcHandler.java Sat Jun 10 14:25:12 2006
@@ -24,6 +24,7 @@
 import org.apache.xmlrpc.common.XmlRpcNotAuthorizedException;
 import org.apache.xmlrpc.metadata.Util;
 import org.apache.xmlrpc.server.AbstractReflectiveHandlerMapping.AuthenticationHandler;
+import org.apache.xmlrpc.server.AbstractReflectiveHandlerMapping.InitializationHandler;
 
 
 /** Default implementation of {@link XmlRpcHandler}.
@@ -31,8 +32,8 @@
 public class ReflectiveXmlRpcHandler implements XmlRpcHandler {
 	private final AbstractReflectiveHandlerMapping mapping;
 	private final Class clazz;
-	private final Object instance;
 	private final Method[] methods;
+    private final Object theInstance;
 
 	/** Creates a new instance.
 	 * @param pMapping The mapping, which creates this handler.
@@ -40,19 +41,44 @@
 	 * this handler. Typically, this will be the same as
 	 * <pre>pInstance.getClass()</pre>. It is used for diagnostic
 	 * messages only.
-	 * @param pInstance The instance, which will be invoked for
-	 * executing the handler.
+	 * @param pInstanceIsStateless The handler
+	 * can operate in either of two operation modes:
+	 * <ol>
+	 *   <li>The object, which is actually performing the requests,
+	 *     is initialized at startup. In other words, there is only
+	 *     one object, which is performing all the requests.
+	 *     Obviously, this is the faster operation mode. On the
+	 *     other hand, it has the disadvantage, that the object
+	 *     must be stateless.</li>
+	 *   <li>A new object is created for any request. This is slower,
+	 *     because the object needs to be initialized. On the other
+	 *     hand, it allows for stateful objects, which may take
+	 *     request specific configuration like the clients IP address,
+	 *     and the like.</li>
+	 * </ol>
 	 * @param pMethods The method, which will be invoked for
 	 * executing the handler. 
 	 */
 	public ReflectiveXmlRpcHandler(AbstractReflectiveHandlerMapping pMapping,
-				Class pClass, Object pInstance, Method[] pMethods) {
+				Class pClass, boolean pInstanceIsStateless, Method[] pMethods)
+            throws XmlRpcException {
 		mapping = pMapping;
 		clazz = pClass;
-		instance = pInstance;
 		methods = pMethods;
+        theInstance = pInstanceIsStateless ? newInstance() : null;
 	}
 
+    private Object getInstance(XmlRpcRequest pRequest) throws XmlRpcException {
+        final InitializationHandler ih = mapping.getInitializationHandler();
+        if (ih == null) {
+            return theInstance == null ? newInstance() : theInstance;
+        } else {
+            final Object instance = newInstance();
+            ih.init(pRequest, instance);
+            return instance;
+        }
+    }
+
 	public Object execute(XmlRpcRequest pRequest) throws XmlRpcException {
 	    AuthenticationHandler authHandler = mapping.getAuthenticationHandler();
 	    if (authHandler != null  &&  !authHandler.isAuthorized(pRequest)) {
@@ -62,21 +88,22 @@
 	    for (int j = 0;  j < args.length;  j++) {
 	        args[j] = pRequest.getParameter(j);
 	    }
-	    if (methods.length == 1) {
-            return invoke(methods[0], args);
+	    Object instance = getInstance(pRequest);
+        if (methods.length == 1) {
+            return invoke(instance, methods[0], args);
         } else {
             for (int i = 0;  i < methods.length;  i++) {
                 if (Util.isMatching(methods[i], args)) {
-                    return invoke(methods[i], args);
+                    return invoke(instance, methods[i], args);
                 }
             }
             throw new XmlRpcException("No method matching arguments: " + Util.getSignature(args));
         }
     }
 
-    private Object invoke(Method pMethod, Object[] pArgs) throws XmlRpcException {
+    private Object invoke(Object pInstance, Method pMethod, Object[] pArgs) throws XmlRpcException {
         try {
-	        return pMethod.invoke(instance, pArgs);
+	        return pMethod.invoke(pInstance, pArgs);
 	    } catch (IllegalAccessException e) {
 	        throw new XmlRpcException("Illegal access to method "
 	                                  + pMethod.getName() + " in class "
@@ -93,4 +120,14 @@
 	                                  + t.getMessage(), t);
 	    }
 	}
+
+    protected Object newInstance() throws XmlRpcException {
+        try {
+            return clazz.newInstance();
+        } catch (InstantiationException e) {
+            throw new XmlRpcException("Failed to instantiate class " + clazz.getName(), e);
+        } catch (IllegalAccessException e) {
+            throw new XmlRpcException("Illegal access when instantiating class " + clazz.getName(), e);
+        }
+    }
 }

Modified: webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/webserver/XmlRpcServlet.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/webserver/XmlRpcServlet.java?rev=413365&r1=413364&r2=413365&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/webserver/XmlRpcServlet.java (original)
+++ webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/webserver/XmlRpcServlet.java Sat Jun 10 14:25:12 2006
@@ -104,7 +104,7 @@
 	 * {@link #newXmlRpcHandlerMapping()}.
 	 */
 	protected PropertyHandlerMapping newPropertyHandlerMapping(URL url) throws IOException, XmlRpcException {
-		return new PropertyHandlerMapping(getClass().getClassLoader(), url);
+		return new PropertyHandlerMapping(getClass().getClassLoader(), url, false);
 	}
 
 	/** Creates a new instance of {@link org.apache.xmlrpc.webserver.RequestData}

Modified: webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/webserver/XmlRpcServletServer.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/webserver/XmlRpcServletServer.java?rev=413365&r1=413364&r2=413365&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/webserver/XmlRpcServletServer.java (original)
+++ webservices/xmlrpc/trunk/server/src/main/java/org/apache/xmlrpc/webserver/XmlRpcServletServer.java Sat Jun 10 14:25:12 2006
@@ -67,12 +67,12 @@
         }
     }
 
-	protected XmlRpcHttpRequestConfigImpl newConfig() {
+	protected XmlRpcHttpRequestConfigImpl newConfig(HttpServletRequest pRequest) {
 		return new XmlRpcHttpRequestConfigImpl();
 	}
 
 	protected XmlRpcHttpRequestConfigImpl getConfig(HttpServletRequest pRequest) {
-		XmlRpcHttpRequestConfigImpl result = newConfig();
+		XmlRpcHttpRequestConfigImpl result = newConfig(pRequest);
 		XmlRpcHttpServerConfig serverConfig = (XmlRpcHttpServerConfig) getConfig();
 		result.setBasicEncoding(serverConfig.getBasicEncoding());
 		result.setContentLengthOptional(serverConfig.isContentLengthOptional());

Modified: webservices/xmlrpc/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/src/changes/changes.xml?rev=413365&r1=413364&r2=413365&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/src/changes/changes.xml (original)
+++ webservices/xmlrpc/trunk/src/changes/changes.xml Sat Jun 10 14:25:12 2006
@@ -66,6 +66,10 @@
         The XmlRpcServlet allows to configure its "enabledForExtensions"
         value as an init parameter.
       </action>
+      <action dev="jochen" type="enhancement">
+        It is now possible to create and initialize handler objects per
+        request.
+      </action>
     </release>
     <release version="3.0a1" date="17-Feb-2005">
       <action dev="jochen" type="enhancement">

Modified: webservices/xmlrpc/trunk/src/site/fml/faq.fml
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/src/site/fml/faq.fml?rev=413365&r1=413364&r2=413365&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/src/site/fml/faq.fml (original)
+++ webservices/xmlrpc/trunk/src/site/fml/faq.fml Sat Jun 10 14:25:12 2006
@@ -131,7 +131,7 @@
       <answer>
         <p>The PropertyHandlerMapping assumes, that handlers are POJO's
           (plain old java objects). However, this is not always desirable.
-          For example, sometimes it is assumes that handlers need to
+          For example, sometimes it is assumed that handlers need to
           be initialized by the servlet, which is configured through
           parameters.</p>
         <p>The recommended solution is to create a subclass of the
@@ -154,6 +154,57 @@
 		};
 	}
     
+}
+        ]]></source>
+      </answer>
+    </faq>
+
+    <faq id="client_ip">
+      <question>How to I get the clients IP address in a handler?</question>
+      <answer>
+        <p>That's a similar question than the question on initializing handlers.
+          The main difference is, that in this case you want to initialize the
+          handler with any request. So, here's how to do it: First of all,
+          we assume that all handlers will implement an interface
+          RequestInitializableHandler. This interface has an init method,
+          which is being called to receive an object with the clients
+          IP address:</p>
+        <source><![CDATA[
+public class MyConfig extends XmlRpcHttpRequestConfigImpl {
+	private String clientIpAddress;
+	public String getClientIpAddress() {
+	    return clientIpAddress;
+	}
+	public void setClientIpAddress(String pClientIpAddress) {
+	    clientIpAddress = pClientIpAddress;
+	}
+}
+
+public interface RequestInitializableHandler {
+    public void init(MyConfig pConfig);
+}
+
+public class MyXmlRpcServlet extends XmlRpcServlet {
+	protected XmlRpcServletServer newXmlRpcServer(ServletConfig pConfig)
+			throws XmlRpcException {
+		return new XmlRpcServletServer(){
+	        protected XmlRpcHttpRequestConfigImpl newConfig(HttpServletRequest pRequest) {
+	            MyConfig config = new MyConfig();
+	            config.setClientIpAddress(pRequest.getRemoteAddr());
+	            return config;
+	        }
+		};
+	}
+	protected PropertyHandlerMapping newPropertyHandlerMapping(URL url) throws IOException, XmlRpcException {
+		PropertyHandlerMapping result = super.newPropertyHandlerMapping(url);
+		result.setInitializableHandler(new InitializableHandler(){
+            public void init(XmlRpcRequest pRequest, Object pObject)
+                    throws XmlRpcException {
+                ((RequestInitializableHandler) pObject).init((MyConfig) pRequest.getConfig());
+            }
+		});
+		return result;
+	}
 }
         ]]></source>
       </answer>

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?rev=413365&r1=413364&r2=413365&view=diff
==============================================================================
--- 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 Sat Jun 10 14:25:12 2006
@@ -303,7 +303,8 @@
 
 	protected XmlRpcHandlerMapping getHandlerMapping() throws IOException, XmlRpcException {
 		return new PropertyHandlerMapping(getClass().getClassLoader(),
-										  getClass().getResource("BaseTest.properties"));
+										  getClass().getResource("BaseTest.properties"),
+                                          true);
 	}
 
 	protected XmlRpcClientConfigImpl getConfig(ClientProvider pProvider) throws Exception {



---------------------------------------------------------------------
To unsubscribe, e-mail: xmlrpc-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: xmlrpc-dev-help@ws.apache.org