the XML-RPC code passed its first validation - OK, next: add the "boxcarring"
call system.multicall, and tweak the implementation a bit after seeing the output "live"
This commit is contained in:
		
							parent
							
								
									394a1863e0
								
							
						
					
					
						commit
						4ee98731e6
					
				@ -280,6 +280,9 @@
 | 
			
		||||
      <!-- XML-RPC validation suite -->
 | 
			
		||||
      <method name="validator1\.[a-zA-Z]*"><script name="test/validation.js"/></method>
 | 
			
		||||
 | 
			
		||||
      <!-- Multicall "boxcar" marshaller (see http://www.xmlrpc.com/discuss/msgReader$1208) -->
 | 
			
		||||
      <method name="system.multicall"><object class="com.silverwrist.venice.ui.rpc.XmlRpcMulticall"/></method>
 | 
			
		||||
 | 
			
		||||
      <method name="venice:test\.sumDifference">
 | 
			
		||||
        <!-- <object class="com.silverwrist.venice.ui.rpc.XmlRpcTestHandler"/> -->
 | 
			
		||||
        <script name="test/test1.js"/>
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,8 @@
 | 
			
		||||
// Implements the XML-RPC Validation Suite functions as documented by UserLand Software,
 | 
			
		||||
// see http://www.xmlrpc.com/validator1Docs
 | 
			
		||||
 | 
			
		||||
// -- PASSES VALIDATION as of 1/16/2002; 11:31:28 PM
 | 
			
		||||
 | 
			
		||||
importPackage(java.util);
 | 
			
		||||
importPackage(Packages.com.silverwrist.venice.ui.rpc);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										123
									
								
								src/com/silverwrist/venice/ui/rpc/XmlRpcMulticall.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								src/com/silverwrist/venice/ui/rpc/XmlRpcMulticall.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,123 @@
 | 
			
		||||
/*
 | 
			
		||||
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 | 
			
		||||
 * (the "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
 | 
			
		||||
 * 
 | 
			
		||||
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 | 
			
		||||
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 | 
			
		||||
 * language governing rights and limitations under the License.
 | 
			
		||||
 * 
 | 
			
		||||
 * The Original Code is the Venice Web Communities System.
 | 
			
		||||
 * 
 | 
			
		||||
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 | 
			
		||||
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 | 
			
		||||
 * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Contributor(s): 
 | 
			
		||||
 */
 | 
			
		||||
package com.silverwrist.venice.ui.rpc;
 | 
			
		||||
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import com.silverwrist.venice.ui.*;
 | 
			
		||||
 | 
			
		||||
public class XmlRpcMulticall implements XmlRpcDispatch
 | 
			
		||||
{
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Constructor
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public XmlRpcMulticall()
 | 
			
		||||
  { // do nothing
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Internal operations
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private static final XmlRpcRequest parseRequest(RequestInput req, Object obj) throws XmlRpcFault
 | 
			
		||||
  {
 | 
			
		||||
    try
 | 
			
		||||
    { // this object should be a struct with two elements, methodName (string) and params (array).
 | 
			
		||||
      // Parse those out.
 | 
			
		||||
      Map map = (Map)obj;
 | 
			
		||||
      String method_name = (String)(map.get("methodName"));
 | 
			
		||||
      List params = (List)(map.get("params"));
 | 
			
		||||
      if ((method_name==null) || (params==null))
 | 
			
		||||
	throw new XmlRpcFault(XmlRpcFault.INVALID_PARAMS,"missing multicall struct elements");
 | 
			
		||||
      return new XmlRpcRequest(req,method_name,params);
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (ClassCastException cce)
 | 
			
		||||
    { // parameter is not right
 | 
			
		||||
      throw new XmlRpcFault(XmlRpcFault.INVALID_PARAMS,"array parameter type mismatch");
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
 | 
			
		||||
  } // end parseRequest
 | 
			
		||||
 | 
			
		||||
  private static final Map faultToStruct(XmlRpcFault f)
 | 
			
		||||
  {
 | 
			
		||||
    Map rc = new TreeMap();
 | 
			
		||||
    rc.put("faultCode",new Integer(f.getFaultCode()));
 | 
			
		||||
    rc.put("faultString",f.getMessage());
 | 
			
		||||
    return rc;
 | 
			
		||||
 | 
			
		||||
  } // end faultToStruct
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Implementations from interface XmlRpcDispatch
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public Object dispatch(RequestInput req, XmlRpcRequest xreq, Map environment) throws Exception, XmlRpcFault
 | 
			
		||||
  {
 | 
			
		||||
    if (!(xreq.getMethod().equals("system.multicall")))
 | 
			
		||||
      throw new XmlRpcFault(XmlRpcFault.METHOD_NOT_FOUND,"invalid method name: " + xreq.getMethod());
 | 
			
		||||
    if (xreq.getParamCount()!=1)
 | 
			
		||||
      throw new XmlRpcFault(XmlRpcFault.INVALID_PARAMS,"parameter count mismatch");
 | 
			
		||||
 | 
			
		||||
    List raw_calls;
 | 
			
		||||
    try
 | 
			
		||||
    { // array output
 | 
			
		||||
      raw_calls = (List)(xreq.getParam(0));
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (ClassCastException cce)
 | 
			
		||||
    { // type mismatch
 | 
			
		||||
      throw new XmlRpcFault(XmlRpcFault.INVALID_PARAMS,"parameter type mismatch");
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
 | 
			
		||||
    if (raw_calls.isEmpty())
 | 
			
		||||
      return Collections.EMPTY_LIST;  // no calls here - this is good as a presence check
 | 
			
		||||
 | 
			
		||||
    // parse out subrequests, call them, and return them
 | 
			
		||||
    ArrayList rc = new ArrayList(raw_calls.size());
 | 
			
		||||
    Iterator it = raw_calls.iterator();
 | 
			
		||||
    while (it.hasNext())
 | 
			
		||||
    { // parse out a request and dispatch it
 | 
			
		||||
      try
 | 
			
		||||
      { // parse the request
 | 
			
		||||
	XmlRpcRequest sub_xreq = parseRequest(req,it.next());
 | 
			
		||||
	Object sub_rc = XmlRpcServlet.dispatchMethodCall(req,sub_xreq);
 | 
			
		||||
	if (sub_rc instanceof XmlRpcFault)
 | 
			
		||||
	  sub_rc = faultToStruct((XmlRpcFault)sub_rc);
 | 
			
		||||
	rc.add(sub_rc);
 | 
			
		||||
 | 
			
		||||
      } // end try
 | 
			
		||||
      catch (XmlRpcFault f)
 | 
			
		||||
      { // save the fault code for the operation
 | 
			
		||||
	rc.add(faultToStruct(f));
 | 
			
		||||
 | 
			
		||||
      } // end catch
 | 
			
		||||
 | 
			
		||||
    } // end while
 | 
			
		||||
 | 
			
		||||
    return rc;  // return all the results at once to be serialized
 | 
			
		||||
 | 
			
		||||
  } // end dispatch
 | 
			
		||||
 | 
			
		||||
} // end class XmlRpcMulticall
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,7 @@ import org.apache.log4j.*;
 | 
			
		||||
import org.w3c.dom.*;
 | 
			
		||||
import com.silverwrist.util.*;
 | 
			
		||||
import com.silverwrist.venice.except.*;
 | 
			
		||||
import com.silverwrist.venice.ui.*;
 | 
			
		||||
import com.silverwrist.venice.util.XMLLoader;
 | 
			
		||||
 | 
			
		||||
public class XmlRpcRequest
 | 
			
		||||
@ -43,15 +44,16 @@ public class XmlRpcRequest
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  RequestInput req;            // request input system
 | 
			
		||||
  String method_name;          // the method name
 | 
			
		||||
  List method_params;          // the method parameters
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Constructor
 | 
			
		||||
   * Constructors
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  XmlRpcRequest(Document req_doc) throws XmlRpcFault
 | 
			
		||||
  XmlRpcRequest(RequestInput req, Document req_doc) throws XmlRpcFault
 | 
			
		||||
  {
 | 
			
		||||
    if (req_doc==null)
 | 
			
		||||
      throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,"no XML call structure found");
 | 
			
		||||
@ -104,6 +106,16 @@ public class XmlRpcRequest
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
 | 
			
		||||
    this.req = req;  // save reference off
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
  XmlRpcRequest(RequestInput req, String method_name, List method_params)
 | 
			
		||||
  {
 | 
			
		||||
    this.req = req;
 | 
			
		||||
    this.method_name = method_name;
 | 
			
		||||
    this.method_params = method_params;
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
@ -447,7 +447,7 @@ public class XmlRpcSerializer
 | 
			
		||||
  {
 | 
			
		||||
    StringBuffer b = new StringBuffer("<array>\r\n<data>\r\n");
 | 
			
		||||
    while (it.hasNext())
 | 
			
		||||
      b.append("<value>").append(this.serialize(it.next())).append("</value>");
 | 
			
		||||
      b.append("<value>").append(this.serialize(it.next())).append("</value>\r\n");
 | 
			
		||||
    b.append("</data>\r\n</array>");
 | 
			
		||||
    return b.toString();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -111,7 +111,7 @@ public class XmlRpcServlet extends BaseServlet
 | 
			
		||||
    XmlRpcRequest xreq;
 | 
			
		||||
    try
 | 
			
		||||
    { // get the XML-RPC request structure
 | 
			
		||||
      xreq = new XmlRpcRequest(req.getRequestDocument());
 | 
			
		||||
      xreq = new XmlRpcRequest(req,req.getRequestDocument());
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (XmlRpcFault f)
 | 
			
		||||
@ -120,6 +120,21 @@ public class XmlRpcServlet extends BaseServlet
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
 | 
			
		||||
    // dispatch the call and wrap non-fault returns for proper XML formatting
 | 
			
		||||
    Object rc = dispatchMethodCall(req,xreq);
 | 
			
		||||
    if (!(rc instanceof XmlRpcFault))
 | 
			
		||||
      rc = new XmlRpcReturnValue(rc);
 | 
			
		||||
    return rc;
 | 
			
		||||
 | 
			
		||||
  } // end process
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * External static operations
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  static Object dispatchMethodCall(RequestInput req, XmlRpcRequest xreq)
 | 
			
		||||
  {
 | 
			
		||||
    // Prepare the parameters map
 | 
			
		||||
    int i;
 | 
			
		||||
    HashMap param_repl_map = new HashMap();
 | 
			
		||||
@ -168,31 +183,31 @@ public class XmlRpcServlet extends BaseServlet
 | 
			
		||||
 | 
			
		||||
      } // end if
 | 
			
		||||
 | 
			
		||||
    } while (rescan);
 | 
			
		||||
    } while (rescan); // end do
 | 
			
		||||
 | 
			
		||||
    Object rc;
 | 
			
		||||
    try
 | 
			
		||||
    { // dispatch the method call
 | 
			
		||||
      Object rc = meth.dispatch(req,xreq,sub_map);
 | 
			
		||||
    { // call the method and translate anything "out of the ordinary" into an XmlRpcFault
 | 
			
		||||
      rc = meth.dispatch(req,xreq,sub_map);
 | 
			
		||||
      if (rc==null)
 | 
			
		||||
	rc = new XmlRpcFault(XmlRpcFault.APPLICATION_ERROR,"no return value");
 | 
			
		||||
      else if (rc instanceof Exception)
 | 
			
		||||
	rc = new XmlRpcFault((Exception)rc);
 | 
			
		||||
      else if (!(rc instanceof XmlRpcFault))
 | 
			
		||||
	rc = new XmlRpcReturnValue(rc);
 | 
			
		||||
      return rc;
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (Exception e)
 | 
			
		||||
    { // if there's an exception, turn it into a "Fault" message
 | 
			
		||||
      return new XmlRpcFault(e);
 | 
			
		||||
      rc = new XmlRpcFault(e);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
    catch (XmlRpcFault f)
 | 
			
		||||
    { // pass faults right on up
 | 
			
		||||
      return f;
 | 
			
		||||
      rc = f;
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
 | 
			
		||||
  } // end process
 | 
			
		||||
    return rc;
 | 
			
		||||
 | 
			
		||||
  } // end dispatchMethodCall
 | 
			
		||||
 | 
			
		||||
} // end class XmlRpcServlet
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user