/*
* 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 .
*
* 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 ,
* 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.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import org.apache.log4j.*;
import org.w3c.dom.*;
import com.silverwrist.util.*;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.util.XMLLoader;
public class XmlRpcRequest
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Category logger = Category.getInstance(XmlRpcRequest.class);
private static SimpleTimeZone utc = new SimpleTimeZone(0,"UTC");
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
String method_name; // the method name
List method_params; // the method parameters
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
XmlRpcRequest(Document req_doc) throws XmlRpcFault
{
if (req_doc==null)
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,"no XML call structure found");
try
{
// load the initial structure and method name
XMLLoader loader = XMLLoader.get();
Element root = loader.postGetRootElement(req_doc,"methodCall");
DOMElementHelper root_h = new DOMElementHelper(root);
method_name = loader.postGetSubElementText(root_h,"methodName");
// parse the parameters
Element params = root_h.getSubElement("params");
ArrayList tmp_method_params = new ArrayList();
if (params!=null)
{ // look for children of the node
NodeList nl = params.getChildNodes();
for (int i=0; i node
if (!(n.getNodeName().equals("param")))
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,
"non-param element found inside \"params\" element");
tmp_method_params.add(parseValue(loader.postGetSubSection((Element)n,"value")));
} // end if
// else ignore this node
} // end for
} // end if
// save the method parameters
if (tmp_method_params.isEmpty())
method_params = Collections.EMPTY_LIST;
else
{ // make it read-only before
tmp_method_params.trimToSize();
method_params = Collections.unmodifiableList(tmp_method_params);
} // end else
} // end try
catch (ValidationException ve)
{ // validation exceptions get translated to XML-RPC faults
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,ve);
} // end catch
} // end constructor
/*--------------------------------------------------------------------------------
* Internal static operations
*--------------------------------------------------------------------------------
*/
private static final Object parseValue(Element val) throws ValidationException, XmlRpcFault
{
XMLLoader loader = XMLLoader.get();
// see if the value has an embedded type...
NodeList nl = val.getChildNodes();
Element type = null;
for (int i=0; i element: expected a valid type but got a <" + name + "/>");
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,
"invalid type element \"" + name + "\" specified inside a \"value\"");
} // end else
} // end if
else
{ // if there's no type-specific element, treat it as a string
DOMElementHelper h = new DOMElementHelper(val);
String s = h.getElementText();
if (s==null)
s = "";
return s;
} // end else
} // end parseValue
private static final List parseArray(Element val) throws XmlRpcFault, ValidationException
{
XMLLoader loader = XMLLoader.get();
Element data = loader.postGetSubSection(val,"data");
NodeList nl = data.getChildNodes();
ArrayList rc = new ArrayList();
for (int i=0; i elements within the element
Node n = nl.item(i);
if (n.getNodeType()==Node.ELEMENT_NODE)
{ // make sure we've got a value element here!
if (!(n.getNodeName().equals("value")))
{ // this is a bogus value!
logger.error("inside array : expected a but found a <" + n.getNodeName() + "/>");
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,
"non-value element found inside array \"data\" element");
} // end if
rc.add(parseValue((Element)n));
} // end if
} // end for
if (rc.isEmpty())
return Collections.EMPTY_LIST;
else
{ // trim the result array and return the list
rc.trimToSize();
return Collections.unmodifiableList(rc);
} // end else
} // end parseArray
private static final Map parseStruct(Element val) throws XmlRpcFault, ValidationException
{
XMLLoader loader = XMLLoader.get();
NodeList nl = val.getChildNodes();
HashMap rc = new HashMap();
for (int i=0; i elements within a element
Node n = nl.item(i);
if (n.getNodeType()==Node.ELEMENT_NODE)
{ // make sure we've got a value element here!
if (!(n.getNodeName().equals("member")))
{ // this is a bogus value
logger.error("inside : expected a but found a <" + n.getNodeName() + "/>");
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,
"non-member element found inside \"struct\" element");
} // end if
DOMElementHelper h = new DOMElementHelper((Element)n);
String my_name = loader.postGetSubElementText(h,"name").trim();
Element my_val = loader.postGetSubSection(h,"value");
rc.put(my_name,parseValue(my_val));
} // end if
} // end for
if (rc.isEmpty())
return Collections.EMPTY_MAP;
else
return Collections.unmodifiableMap(rc);
} // end parseStruct
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public final String getMethod()
{
return method_name;
} // end getMethod
public final int getParamCount()
{
return method_params.size();
} // end getParamCount
public final List getParams()
{
return method_params;
} // end getParams
public final Object getParam(int ndx)
{
return method_params.get(ndx);
} // end getParam
public final String getParamType(int ndx)
{
Object foo = method_params.get(ndx);
if (foo instanceof Integer)
return "int";
if (foo instanceof Boolean)
return "boolean";
if (foo instanceof String)
return "string";
if (foo instanceof Double)
return "double";
if (foo instanceof Date)
return "dateTime";
if (foo instanceof byte[])
return "base64";
if (foo instanceof Map)
return "struct";
if (foo instanceof List)
return "array";
return "(unknown)";
} // end getParamType
public final int getParamInt(int ndx) throws XmlRpcFault
{
Object foo = method_params.get(ndx);
if (foo instanceof Integer)
return ((Integer)foo).intValue();
else if (foo instanceof Boolean)
return ((Boolean)foo).booleanValue() ? 1 : 0;
else
throw new XmlRpcFault(XmlRpcFault.INVALID_PARAMS,"parameter type mismatch");
} // end getParamInt
public final double getParamDouble(int ndx) throws XmlRpcFault
{
Object foo = method_params.get(ndx);
if ((foo instanceof Integer) || (foo instanceof Double))
return ((Number)foo).doubleValue();
else if (foo instanceof Boolean)
return ((Boolean)foo).booleanValue() ? 1 : 0;
else
throw new XmlRpcFault(XmlRpcFault.INVALID_PARAMS,"parameter type mismatch");
} // end getParamDouble
public final String getParamString(int ndx) throws XmlRpcFault
{
Object foo = method_params.get(ndx);
if ((foo instanceof byte[]) || (foo instanceof List) || (foo instanceof Map))
throw new XmlRpcFault(XmlRpcFault.INVALID_PARAMS,"parameter type mismatch");
return foo.toString();
} // end getParamString
} // end class XmlRpcRequest