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 [EMAIL PROTECTED] #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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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 - * [EMAIL PROTECTED] #registerPublicMethods(java.util.Map, String, Class, Object)}. + * [EMAIL PROTECTED] #registerPublicMethods(java.util.Map, String, Class)}. * @param pKey The class key, which is passed - * to [EMAIL PROTECTED] #registerPublicMethods(java.util.Map, String, Class, Object)}. - * @param pHandler The object, which is handling requests. + * to [EMAIL PROTECTED] #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 [EMAIL PROTECTED] 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 @@ * [EMAIL PROTECTED] #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 [EMAIL PROTECTED] 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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]