the first implementation of an XML-RPC server endpoint within Venice...

also tweaked the session code to allow session types other than standard HTTP
cookie-based sessions.  The XML-RPC code doesn't do anything interesting yet.
This commit is contained in:
Eric J. Bowersox 2002-01-13 09:12:51 +00:00
parent bcd76541ab
commit 6ea41dc619
22 changed files with 2238 additions and 131 deletions

View File

@ -271,6 +271,17 @@
</remap>
</remapper>
<!-- Configuration for the RPC interfaces. -->
<rpc>
<xmlrpc-methods>
<method name="venice:test\.sumDifference">
<object class="com.silverwrist.venice.ui.rpc.XmlRpcTestHandler"/>
<env name="e1" value="foo"/>
<env name="p1" value="${param.0}"/>
</method>
</xmlrpc-methods>
</rpc>
<!-- Contains standard messages displayed by front end -->
<messages>
<!-- The message displayed at the top of "top" when you're not logged in (HTML). -->

View File

@ -119,6 +119,12 @@
<servlet-class>com.silverwrist.venice.ui.servlet.RemapperServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>XmlRpc</servlet-name>
<description>Handles XML-RPC calls for the application.</description>
<servlet-class>com.silverwrist.venice.ui.rpc.XmlRpcServlet</servlet-class>
</servlet>
<!-- Servlet mappings -->
<servlet-mapping>
@ -182,6 +188,11 @@
<url-pattern>/verifyemail</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>XmlRpc</servlet-name>
<url-pattern>/RPC2</url-pattern>
</servlet-mapping>
<!-- Global parameters for the HTTP session -->
<session-config>
<session-timeout>60</session-timeout> <!-- 1 hour -->

1
lib/.gitignore vendored
View File

@ -1,5 +1,6 @@
bsf.jar
jacl.jar
jakarta-regexp*.jar
js.jar
log4j.jar
mysql.jar

View File

@ -6,6 +6,7 @@ compatible with the versions specified here.
Library Version File Name(s) Install To
-------------------------------------------------------------------------------------------------
Apache Jakarta Regexp 1.2 jakarta-regexp-1.2.jar Venice "lib" subdirectory
Apache LOG4J 1.1.3 log4j.jar Venice "lib" subdirectory
Bean Scripting Framework 2.2 bsf.jar Venice "lib" subdirectory
Jacl (Tcl interpreter) 1.3(CVS) jacl.jar, tcljava.jar Venice "lib" subdirectory

View File

@ -31,8 +31,7 @@ if (user.isLoggedIn())
{ // user is logged in - we want to log out
// TODO: only remove the login cookie if it was actually set!
rinput.deleteCookie(RequestInput.LOGIN_COOKIE); // remove the login cookie
rinput.replaceUser(null); // no more user context
rinput.setSessionAttribute(RequestInput.LEFT_MENU_SESSION_ATTR,null); // and clear menus too
rinput.endSession();
target = "top.js.vs"; // take 'em back to the top

View File

@ -0,0 +1,164 @@
/*
* 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;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.ui.config.RootConfig;
public class NullSession implements VeniceUISession, VeniceUISessionFactory
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static NullSession self = null;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
private NullSession()
{ // do nothing
} // end constructor
/*--------------------------------------------------------------------------------
* Internal operations
*--------------------------------------------------------------------------------
*/
private final void bogus()
{
throw new IllegalStateException("null session is not valid");
} // end bogus
/*--------------------------------------------------------------------------------
* Implementations from interface VeniceUISession
*--------------------------------------------------------------------------------
*/
public long getCreationTime()
{
bogus();
return 0;
} // end getCreationTime
public String getID()
{
return null;
} // end getID
public long getLastAccessedTime()
{
return 0;
} // end getLastAccessedTime
public void setMaxInactiveInterval(int interval)
{ // do nothing
} // end setMaxInactiveInterval
public int getMaxInactiveInterval()
{
return -1;
} // end getMaxInactiveInterval
public Object getAttribute(String name)
{
bogus();
return null;
} // end getAttribute
public Enumeration getAttributeNames()
{
bogus();
return null;
} // end getAttributeNames
public void setAttribute(String name, Object o)
{
bogus();
} // end setAttribute
public void removeAttribute(String name)
{
bogus();
} // end removeAttribute
public void invalidate()
{
bogus();
} // end invalidate
public UserContext getUser()
{
bogus();
return null;
} // end getUser
public void setUser(UserContext user)
{
bogus();
} // end setUser
public void preprocess(RequestInput ri)
{ // do nothing
} // end preprocess
/*--------------------------------------------------------------------------------
* Implementations from interface VeniceUISessionFactory
*--------------------------------------------------------------------------------
*/
public VeniceUISession createSession(ServletContext ctxt, HttpServletRequest request,
HttpServletResponse response, VeniceEngine engine,
RootConfig config)
{
return this;
} // end createSession
/*--------------------------------------------------------------------------------
* External static operations
*--------------------------------------------------------------------------------
*/
public static final synchronized NullSession get()
{
if (self==null)
self = new NullSession();
return self;
} // end get
} // end class NullSession

View File

@ -11,7 +11,7 @@
*
* 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) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* Copyright (C) 2001-02 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
@ -23,6 +23,7 @@ import java.io.IOException;
import java.util.Date;
import java.util.Enumeration;
import java.util.Map;
import org.w3c.dom.Document;
import com.silverwrist.util.ServletMultipartException;
import com.silverwrist.venice.core.CommunityContext;
import com.silverwrist.venice.core.UserContext;
@ -53,6 +54,8 @@ public interface RequestInput extends LinkTypes
public abstract String getSourceAddress();
public abstract void endSession();
public abstract boolean hasParameter(String name);
public abstract String getParameter(String name);
@ -75,6 +78,10 @@ public interface RequestInput extends LinkTypes
public abstract InputStream getParameterDataStream(String name) throws ServletMultipartException;
public abstract Document getRequestDocument();
public abstract boolean sessionBound();
public abstract boolean isImageButtonClicked(String name);
public abstract Object getAppAttribute(String name);

View File

@ -0,0 +1,51 @@
/*
* 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;
import java.util.*;
import com.silverwrist.venice.core.*;
public interface VeniceUISession
{
public abstract long getCreationTime();
public abstract String getID();
public abstract long getLastAccessedTime();
public abstract void setMaxInactiveInterval(int interval);
public abstract int getMaxInactiveInterval();
public abstract Object getAttribute(String name);
public abstract Enumeration getAttributeNames();
public abstract void setAttribute(String name, Object o);
public abstract void removeAttribute(String name);
public abstract void invalidate();
public abstract UserContext getUser();
public abstract void setUser(UserContext user);
public abstract void preprocess(RequestInput ri);
} // end class VeniceUISession

View File

@ -0,0 +1,31 @@
/*
* 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;
import javax.servlet.*;
import javax.servlet.http.*;
import com.silverwrist.venice.core.VeniceEngine;
import com.silverwrist.venice.ui.config.RootConfig;
public interface VeniceUISessionFactory
{
public abstract VeniceUISession createSession(ServletContext ctxt, HttpServletRequest request,
HttpServletResponse response, VeniceEngine engine,
RootConfig config) throws ServletException;
} // end interface VeniceUISessionFactory

View File

@ -11,7 +11,7 @@
*
* 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) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* Copyright (C) 2001-02 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
@ -30,6 +30,7 @@ import com.silverwrist.venice.ui.menus.CommunityMenu;
import com.silverwrist.venice.ui.menus.CommunityMenuFactory;
import com.silverwrist.venice.ui.menus.Menu;
import com.silverwrist.venice.ui.menus.MenuComponent;
import com.silverwrist.venice.ui.rpc.XmlRpcMethod;
import com.silverwrist.venice.util.*;
public class RootConfig implements LinkTypes, ColorSelectors
@ -79,6 +80,7 @@ public class RootConfig implements LinkTypes, ColorSelectors
private ButtonHolder buttons; // the button definitions
private String[] content_hdr; // the content header parts
private Remapper remapper; // the URL remapper
private List xmlrpc_methods; // the list of XML-RPC methods
private StockMessages stock_messages; // the stock messages
private Map menus; // the menus
private DialogManager dialogs; // the dialog manager
@ -324,7 +326,7 @@ public class RootConfig implements LinkTypes, ColorSelectors
for (i=0; i<nl.getLength(); i++)
{ // loop through the subelements
Node n = nl.item(i);
if ((n.getNodeType()==Node.ELEMENT_NODE))
if (n.getNodeType()==Node.ELEMENT_NODE)
{ // retrieve the font size and add it to our map
DOMElementHelper h = new DOMElementHelper((Element)n);
tmap.put(n.getNodeName(),h.getElementText());
@ -367,6 +369,35 @@ public class RootConfig implements LinkTypes, ColorSelectors
// Initialize the remapper object.
remapper = new Remapper(sect,this);
// Get the <rpc/> section.
sect = loader.configGetSubSection(root_h,"rpc");
sect_h = new DOMElementHelper(sect);
// Get the <xmlrpc-methods/> section.
sect1 = loader.configGetSubSection(sect_h,"xmlrpc-methods");
nl = sect1.getChildNodes();
ArrayList tmp_alist = new ArrayList();
for (i=0; i<nl.getLength(); i++)
{ // look for methods
Node n = nl.item(i);
if (n.getNodeType()==Node.ELEMENT_NODE)
{ // look for a <method/> element and use it to initialize a method
if (n.getNodeName().equals("method"))
tmp_alist.add(new XmlRpcMethod((Element)n));
} // end if
} // end for
if (tmp_alist.isEmpty())
xmlrpc_methods = Collections.EMPTY_LIST;
else
{ // save off the methods list
tmp_alist.trimToSize();
xmlrpc_methods = Collections.unmodifiableList(tmp_alist);
} // end else
// Get the <messages/> section.
sect = loader.configGetSubSection(root_h,"messages");
@ -718,6 +749,12 @@ public class RootConfig implements LinkTypes, ColorSelectors
} // end getDefaultServletAddress
public final List getXmlRpcMethods()
{
return xmlrpc_methods;
} // end getXmlRpcMethods
/*--------------------------------------------------------------------------------
* Static initializer
*--------------------------------------------------------------------------------

View File

@ -0,0 +1,28 @@
/*
* 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.Map;
import com.silverwrist.venice.ui.RequestInput;
public interface XmlRpcDispatch
{
public abstract Object dispatch(RequestInput req, XmlRpcRequest xreq, Map environment)
throws Exception, XmlRpcFault;
} // end interface XmlRpcDispatch

View 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.io.IOException;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.ui.*;
import com.silverwrist.venice.ui.helpers.ThrowableContent;
public class XmlRpcFault extends ThrowableContent implements ContentExecute
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
// Some "standard" XML-RPC error codes.
public static final int INVALID_REQUEST = -32600;
public static final int METHOD_NOT_FOUND = -32601;
public static final int INVALID_PARAMS = -32602;
public static final int INTERNAL_ERROR = -32603;
public static final int APPLICATION_ERROR = -32500;
public static final int SERVER_ERROR = -32400;
public static final int TRANSPORT_ERROR = -32300;
public static final int DEFAULT_ERROR = 0;
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private int fault_code = DEFAULT_ERROR;
/*--------------------------------------------------------------------------------
* Constructors
*--------------------------------------------------------------------------------
*/
public XmlRpcFault(String msg)
{
super(msg);
} // end constructor
public XmlRpcFault(int code, String msg)
{
super(msg);
fault_code = code;
} // end constructor
public XmlRpcFault(Throwable t)
{
super(t);
} // end constructor
public XmlRpcFault(int code, Throwable t)
{
super(t);
fault_code = code;
} // end constructor
public XmlRpcFault(String msg, Throwable t)
{
super(msg,t);
} // end constructor
public XmlRpcFault(int code, String msg, Throwable t)
{
super(msg,t);
fault_code = code;
} // end constructor
/*--------------------------------------------------------------------------------
* Implementations from interface ContentExecute
*--------------------------------------------------------------------------------
*/
public void execute(RequestExec req) throws IOException
{
StringBuffer b =
new StringBuffer("<?xml version=\"1.0\"?>\r\n<methodResponse><fault><value><struct>\r\n<member>\r\n"
+ "<name>faultCode</name>\r\n<value><int>");
b.append(fault_code);
b.append("</int></value>\r\n</member>\r\n<member>\r\n<name>faultString</name>\r\n<value><string>");
b.append(StringUtil.encodeHTML(getMessage()));
b.append("</string></value>\r\n</member>\r\n</struct></value></fault></methodResponse>\r\n");
byte[] raw = b.toString().getBytes("UTF-8");
req.sendBinary("text/xml",raw);
} // end execute
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public final int getFaultCode()
{
return fault_code;
} // end getFaultCode
} // end class XmlRpcFault

View File

@ -0,0 +1,172 @@
/*
* 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 org.apache.log4j.*;
import org.apache.regexp.*;
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 XmlRpcMethod
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Category logger = Category.getInstance(XmlRpcMethod.class);
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private REProgram method_pgm; // regular expression program to match method name
private String remap_value = null; // remap value
private Class obj_class = null; // "class" handler for object
private Map raw_env; // "raw" environment
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public XmlRpcMethod(Element cfg) throws ConfigException
{
XMLLoader loader = XMLLoader.get();
String method_name = loader.configGetAttribute(cfg,"name");
try
{ // compile the method name into a regular expression program
RECompiler comp = new RECompiler();
method_pgm = comp.compile("^" + method_name + "$");
} // end try
catch (RESyntaxException rese)
{ // not a valid regular expression program
logger.error("not a valid RE expression: " + method_name,rese);
throw new ConfigException("method name \"" + method_name + "\" not valid regular expression",cfg);
} // end catch
DOMElementHelper cfg_h = new DOMElementHelper(cfg);
Element sub;
if ((sub = cfg_h.getSubElement("object"))!=null)
{ // object handler element is present
DOMElementHelper sub_h = new DOMElementHelper(sub);
if (sub_h.hasAttribute("class"))
{ // the class is valid - try and load it
try
{ // load the class referenced by the handler
obj_class = Class.forName(sub.getAttribute("class"));
if (!(XmlRpcDispatch.class.isAssignableFrom(obj_class)))
throw new ConfigException("object handler class \"" + sub.getAttribute("class")
+ "\" is not an XmlRpcDispatch class",sub);
} // end try
catch (ClassNotFoundException cnfe)
{ // class not found - bail out
throw new ConfigException("object handler class \"" + sub.getAttribute("class")
+ "\" not found",sub);
} // end catch
} // end if
else // no referent for object handler - bail out now
throw new ConfigException("object handler for method \"" + "\" not valid",sub);
} // end if
else // no handler - this is an error
throw new ConfigException("method \"" + method_name + "\" does not have a valid handler",cfg);
NodeList nl = sub.getChildNodes();
HashMap tmp_env = new HashMap();
for (int i=0; i<nl.getLength(); i++)
{ // look for specific nodes
Node n = nl.item(i);
if (n.getNodeType()==Node.ELEMENT_NODE)
{ // process various elements
if (n.getNodeName().equals("env"))
tmp_env.put(loader.configGetAttribute((Element)n,"name"),
loader.configGetAttribute((Element)n,"value"));
} // end if
} // end for
if (tmp_env.isEmpty())
raw_env = Collections.EMPTY_MAP;
else
raw_env = Collections.unmodifiableMap(tmp_env);
} // end constructor
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public final void configureMatcher(RE re)
{
re.setProgram(method_pgm);
} // end configureMatcher
public final String getRemap()
{
return remap_value;
} // end getRemap
public final Object dispatch(RequestInput req, XmlRpcRequest xreq, Map sub_map) throws Exception, XmlRpcFault
{
// prepare the environment
HashMap env = new HashMap();
Iterator it = raw_env.entrySet().iterator();
while (it.hasNext())
{ // do replacements to make the environment
Map.Entry ntry = (Map.Entry)(it.next());
env.put(ntry.getKey().toString(),StringUtil.replaceAllVariables(ntry.getValue().toString(),sub_map));
} // end while
if (obj_class!=null)
{ // object class method call - look for a cached object first
Map cache = (Map)(req.getAppAttribute(XmlRpcServlet.OBJECT_CLASS_CACHE_ATTR));
XmlRpcDispatch disp = (XmlRpcDispatch)(cache.get(obj_class.getName()));
if (disp==null)
{ // create new instance and cache it
disp = (XmlRpcDispatch)(obj_class.newInstance());
cache.put(obj_class.getName(),disp);
} // end if
return disp.dispatch(req,xreq,env); // dispatch the call
} // end if
// unable to dispatch things
return new XmlRpcFault(XmlRpcFault.APPLICATION_ERROR,"dispatch failure");
} // end dispatch
} // end class XmlRpcMethod

View File

@ -0,0 +1,392 @@
/*
* 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.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
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 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 <param/> children of the <params/> node
NodeList nl = params.getChildNodes();
for (int i=0; i<nl.getLength(); i++)
{ // look at the child node...
Node n = nl.item(i);
if (n.getNodeType()==Node.ELEMENT_NODE)
{ // make sure it's a <param/> 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<nl.getLength(); i++)
{ // look for any sub-element within a value
Node n = nl.item(i);
if (n.getNodeType()==Node.ELEMENT_NODE)
{ // save off the type-specific element
if (type!=null)
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,
"more than one type-specific element within a \"value\" element");
type = (Element)n;
} // end if
} // end for
if (type!=null)
{ // look at the contents of the "type" element
DOMElementHelper h = new DOMElementHelper(type);
final String name = type.getTagName();
if (name.equals("i4") || name.equals("int"))
{ // parse an integer value
String s = h.getElementText();
if (s==null)
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,"invalid null inside \"" + name + "\" value");
Integer rc = null;
try
{ // create the return value
rc = new Integer(s.trim());
} // end try
catch (NumberFormatException nfe)
{ // bogus number!
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,"invalid integer value inside \"" + name
+ "\" value");
} // end catch
return rc;
} // end if
else if (name.equals("boolean"))
{ // parse a boolean value
String s = h.getElementText();
if (s==null)
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,"invalid null inside \"boolean\" value");
s = s.trim();
if (s.equals("1"))
return Boolean.TRUE;
else if (s.equals("0"))
return Boolean.FALSE;
else
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,"invalid value inside \"boolean\" value");
} // end else if
else if (name.equals("string"))
{ // parse a string value
String s = h.getElementText();
if (s==null)
s = "";
return s;
} // end else if
else if (name.equals("double"))
{ // parse a double-precision floating-point value
String s = h.getElementText();
if (s==null)
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,"invalid null inside \"double\" value");
Double rc = null;
try
{ // create the return value
rc = new Double(s.trim());
} // end try
catch (NumberFormatException nfe)
{ // bogus number!
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,
"invalid floating-point value inside \"double\" value");
} // end catch
return rc;
} // end else if
else if (name.equals("dateTime.iso8601"))
{ // parse a date/time value
String dstr = h.getElementText();
if (dstr==null)
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,"invalid null inside \"dateTime.iso8601\" value");
dstr = dstr.trim();
// run some validation checks on the string
if ((dstr.charAt(8)!='T') || (dstr.charAt(11)!=':') || (dstr.charAt(14)!=':'))
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,
"invalid ISO8601 date/time value inside \"dateTime.iso8601\" value");
try
{ // use a GregorianCalendar to convert the fields into the appropriate format
GregorianCalendar cal = new GregorianCalendar(utc);
cal.set(Calendar.YEAR,Integer.parseInt(dstr.substring(0,4)));
cal.set(Calendar.MONTH,Integer.parseInt(dstr.substring(4,6)) - 1 + Calendar.JANUARY);
cal.set(Calendar.DAY_OF_MONTH,Integer.parseInt(dstr.substring(6,8)));
cal.set(Calendar.HOUR_OF_DAY,Integer.parseInt(dstr.substring(9,11)));
cal.set(Calendar.MINUTE,Integer.parseInt(dstr.substring(12,14)));
cal.set(Calendar.SECOND,Integer.parseInt(dstr.substring(15,17)));
return cal.getTime();
} // end try
catch (NumberFormatException nfe)
{ // numeric conversion error!
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,
"invalid ISO8601 date/time value inside \"dateTime.iso8601\" value");
} // end catch
} // end else if
else if (name.equals("base64"))
{ // parse a binary value
String s = h.getElementText();
if (s==null)
return new byte[0];
byte[] encoded_data = null;
try
{ // get the encoded data
encoded_data = s.getBytes("US-ASCII");
} // end try
catch (UnsupportedEncodingException uee)
{ // this is bogus
throw new InternalStateError("US-ASCII reports as 'unsupported'...shouldn't happen");
} // end catch
byte[] rc = null;
try
{ // wrap the byte array in a stream and decode it
// note: we use JavaMail's MIME decoder here
ByteArrayInputStream encoded_stm = new ByteArrayInputStream(encoded_data);
InputStream decoded_stm = MimeUtility.decode(encoded_stm,"base64");
// copy the decoded information to a new stream
ByteArrayOutputStream out_stm = new ByteArrayOutputStream();
IOUtil.copy(decoded_stm,out_stm);
IOUtil.shutdown(decoded_stm);
IOUtil.shutdown(encoded_stm);
// save the byte array backing the new stream
rc = out_stm.toByteArray();
IOUtil.shutdown(out_stm);
} // end try
catch (IOException ioe)
{ // error schlepping all those bits around
throw new XmlRpcFault(XmlRpcFault.INTERNAL_ERROR,
"unable to load binary data from \"base64\" value");
} // end catch
catch (MessagingException me)
{ // invalid format
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,"invalid encoded data inside \"base64\" value");
} // end catch
return rc;
} // end else if
else if (name.equals("struct"))
return parseStruct(type);
else if (name.equals("array"))
return parseArray(type);
else // no dice here
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,
"invalid type element \"" + name + "\" specified inside a \"value\"");
} // 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 = val.getChildNodes();
ArrayList rc = new ArrayList();
for (int i=0; i<nl.getLength(); i++)
{ // look for <value/> elements within the <data/> 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")))
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,
"non-value element found inside array \"data\" element");
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<nl.getLength(); i++)
{ // seek out all the <member/> elements within a <struct/> 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")))
throw new XmlRpcFault(XmlRpcFault.INVALID_REQUEST,
"non-member element found inside \"struct\" element");
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
} // end class XmlRpcRequest

View File

@ -0,0 +1,24 @@
/*
* 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;
public interface XmlRpcSelfSerializer
{
public abstract String serializeXmlRpc() throws XmlRpcFault;
} // end interface XmlRpcSelfSerializer

View File

@ -0,0 +1,471 @@
/*
* 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.beans.*;
import java.io.*;
import java.lang.ref.*;
import java.lang.reflect.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import org.apache.log4j.*;
import com.silverwrist.util.*;
public class XmlRpcSerializer
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Category logger = Category.getInstance(XmlRpcSerializer.class);
private static XmlRpcSerializer self = null;
private static SimpleTimeZone utc = new SimpleTimeZone(0,"UTC");
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
private XmlRpcSerializer()
{ // do nothing
} // end constructor
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public final String serialize(boolean b)
{
return "<boolean>" + (b ? "1" : "0") + "</boolean>";
} // end serialize
public final String serialize(byte b)
{
return this.serialize((int)b);
} // end serialize
public final String serialize(char c)
{
return "<string>" + c + "</string>";
} // end serialize
public final String serialize(double d)
{
return "<double>" + d + "</double>";
} // end serialize
public final String serialize(float f)
{
return this.serialize((double)f);
} // end serialize
public final String serialize(int i)
{
return "<int>" + i + "</int>";
} // end serialize
public final String serialize(long l)
{
return this.serialize((double)l);
} // end serialize
public final String serialize(short s)
{
return this.serialize((int)s);
} // end serialize
public final String serialize(Object obj) throws XmlRpcFault
{
if (obj==null)
return serializeString(null);
// self-serializing objects
if (obj instanceof XmlRpcSelfSerializer)
return ((XmlRpcSelfSerializer)obj).serializeXmlRpc();
// types from java.io.*
if (obj instanceof InputStream)
return serializeInputStream((InputStream)obj);
// types from java.sql.*
if (obj instanceof java.sql.Blob)
{ // serialize the blob as a binary stream
try
{ // just get its input stream
return serializeInputStream(((java.sql.Blob)obj).getBinaryStream());
} // end try
catch (java.sql.SQLException e)
{ // fault on error here
throw new XmlRpcFault(XmlRpcFault.INTERNAL_ERROR,"unable to save binary data");
} // end catch
} // end if
// types from java.util.*
if (obj instanceof Calendar)
return serializeCalendar((Calendar)obj);
if (obj instanceof Collection)
return serializeCollection((Collection)obj);
if (obj instanceof java.util.Date)
return serializeDate((java.util.Date)obj);
if (obj instanceof Enumeration)
return serializeEnumeration((Enumeration)obj);
if (obj instanceof Iterator)
return serializeIterator((Iterator)obj);
if (obj instanceof Map)
return serializeMap((Map)obj);
// types from java.lang.ref.*
if (obj instanceof Reference) // for a reference, encode its referent
return this.serialize(((Reference)obj).get());
// types from java.lang.*
if (obj instanceof Boolean)
return this.serialize(((Boolean)obj).booleanValue());
if (obj instanceof Character)
return this.serialize(((Character)obj).charValue());
if ((obj instanceof Byte) || (obj instanceof Short) || (obj instanceof Integer))
return this.serialize(((Number)obj).intValue());
if ((obj instanceof Long) || (obj instanceof Float) || (obj instanceof Double))
return this.serialize(((Number)obj).doubleValue());
// String and StringBuffer are handled properly by the fallback mechanism below
// last-ditch fallback method - use toString, get the string, and encode it
return serializeString(obj.toString());
} // end serialize
public final String serialize(boolean[] ba)
{
StringBuffer b = new StringBuffer("<array>\r\n<data>\r\n");
for (int i=0; i<ba.length; i++)
b.append("<value>").append(this.serialize(ba[i])).append("</value>\r\n");
b.append("</data>\r\n</array>");
return b.toString();
} // end serialize
public final String serialize(byte[] ba) throws XmlRpcFault
{
return this.serializeInputStream(new ByteArrayInputStream(ba));
} // end serialize
public final String serialize(char[] ca)
{
StringBuffer b = new StringBuffer("<array>\r\n<data>\r\n");
for (int i=0; i<ca.length; i++)
b.append("<value>").append(this.serialize(ca[i])).append("</value>\r\n");
b.append("</data>\r\n</array>");
return b.toString();
} // end serialize
public final String serialize(double[] da)
{
StringBuffer b = new StringBuffer("<array>\r\n<data>\r\n");
for (int i=0; i<da.length; i++)
b.append("<value>").append(this.serialize(da[i])).append("</value>\r\n");
b.append("</data>\r\n</array>");
return b.toString();
} // end serialize
public final String serialize(float[] fa)
{
StringBuffer b = new StringBuffer("<array>\r\n<data>\r\n");
for (int i=0; i<fa.length; i++)
b.append("<value>").append(this.serialize((double)(fa[i]))).append("</value>\r\n");
b.append("</data>\r\n</array>");
return b.toString();
} // end serialize
public final String serialize(int[] ia)
{
StringBuffer b = new StringBuffer("<array>\r\n<data>\r\n");
for (int i=0; i<ia.length; i++)
b.append("<value>").append(this.serialize(ia[i])).append("</value>\r\n");
b.append("</data>\r\n</array>");
return b.toString();
} // end serialize
public final String serialize(long[] la)
{
StringBuffer b = new StringBuffer("<array>\r\n<data>\r\n");
for (int i=0; i<la.length; i++)
b.append("<value>").append(this.serialize((double)(la[i]))).append("</value>\r\n");
b.append("</data>\r\n</array>");
return b.toString();
} // end serialize
public final String serialize(short[] sa)
{
StringBuffer b = new StringBuffer("<array>\r\n<data>\r\n");
for (int i=0; i<sa.length; i++)
b.append("<value>").append(this.serialize((int)(sa[i]))).append("</value>\r\n");
b.append("</data>\r\n</array>");
return b.toString();
} // end serialize
public final String serialize(Object[] arr) throws XmlRpcFault
{
StringBuffer b = new StringBuffer("<array>\r\n<data>\r\n");
for (int i=0; i<arr.length; i++)
b.append("<value>").append(this.serialize(arr[i])).append("</value>\r\n");
b.append("</data>\r\n</array>");
return b.toString();
} // end serialize
public final String serializeBean(Object obj, BeanInfo binf) throws XmlRpcFault
{
PropertyDescriptor[] props = binf.getPropertyDescriptors();
StringBuffer b = new StringBuffer("<struct>\r\n");
final Object[] no_params = new Object[0];
for (int i=0; i<props.length; i++)
{ // get property names and values
Method mread = props[i].getReadMethod();
if (mread!=null)
{ // use the method to get the value associated with the name
try
{ // append the member data
b.append("<member>\r\n<name>").append(StringUtil.encodeHTML(props[i].getName()));
b.append("</name>\r\n<value>").append(this.serialize(mread.invoke(obj,no_params)));
b.append("</value>\r\n</member>\r\n");
} // end try
catch (IllegalAccessException iae)
{ // unable to access that method
throw new XmlRpcFault(XmlRpcFault.INTERNAL_ERROR,iae);
} // end catch
catch (InvocationTargetException ite)
{ // the method we invoked threw an exception
throw new XmlRpcFault(XmlRpcFault.INTERNAL_ERROR,ite.getTargetException());
} // end catch
} // end if
} // end for
b.append("</struct>\r\n");
return b.toString();
} // end serializeBean
public final String serializeBean(Object obj) throws XmlRpcFault
{
try
{ // get the BeanInfo via introspection
return serializeBean(obj,Introspector.getBeanInfo(obj.getClass()));
} // end try
catch (IntrospectionException e)
{ // introspection failed
throw new XmlRpcFault(XmlRpcFault.INTERNAL_ERROR,e);
} // end catch
} // end serializeBean
public final String serializeCalendar(Calendar cal)
{
// Create the two string buffers converting the date.
StringBuffer rc = new StringBuffer("<dateTime.iso8601>");
StringBuffer conv = new StringBuffer();
String c;
// Encode the year first.
conv.append("0000").append(cal.get(Calendar.YEAR));
c = conv.toString();
rc.append(c.substring(c.length()-4));
// Now the month...
conv.setLength(0);
conv.append("00").append(cal.get(Calendar.MONTH) - Calendar.JANUARY + 1);
c = conv.toString();
rc.append(c.substring(c.length()-2));
// And the day...
conv.setLength(0);
conv.append("00").append(cal.get(Calendar.DAY_OF_MONTH));
c = conv.toString();
rc.append(c.substring(c.length()-2)).append('T');
// And the hour...
conv.setLength(0);
conv.append("00").append(cal.get(Calendar.HOUR_OF_DAY));
c = conv.toString();
rc.append(c.substring(c.length()-2)).append(':');
// And the minute...
conv.setLength(0);
conv.append("00").append(cal.get(Calendar.MINUTE));
c = conv.toString();
rc.append(c.substring(c.length()-2)).append(':');
// And the second...
conv.setLength(0);
conv.append("00").append(cal.get(Calendar.SECOND));
c = conv.toString();
rc.append(c.substring(c.length()-2)).append("</dateTime.iso8601>");
// This is the resulting date/time value.
return rc.toString();
} // end serializeCalendar
public final String serializeCollection(Collection coll) throws XmlRpcFault
{
return serializeIterator(coll.iterator());
} // end serializeCollection
public final String serializeDate(java.util.Date date) throws XmlRpcFault
{
GregorianCalendar cal = new GregorianCalendar(utc);
cal.setTime(date);
return serializeCalendar(cal);
} // end serializeDate
public final String serializeEnumeration(Enumeration enum) throws XmlRpcFault
{
StringBuffer b = new StringBuffer("<array>\r\n<data>\r\n");
while (enum.hasMoreElements())
b.append("<value>").append(this.serialize(enum.nextElement())).append("</value>");
b.append("</data>\r\n</array>");
return b.toString();
} // end serializeIterator
public final String serializeInputStream(InputStream stm) throws XmlRpcFault
{
String rc = null;
try
{ // convert the data bytes to encoded bytes first
ByteArrayOutputStream internal_stm = new ByteArrayOutputStream();
OutputStream encode_stm = MimeUtility.encode(internal_stm,"base64");
IOUtil.copy(stm,encode_stm);
encode_stm.flush();
// turn our encoded output into an InputStream
ByteArrayInputStream internal2_stm = new ByteArrayInputStream(internal_stm.toByteArray());
IOUtil.shutdown(encode_stm);
IOUtil.shutdown(internal_stm);
// build a StringWriter containing the converted contents
StringWriter wr = new StringWriter();
wr.write("<base64>");
InputStreamReader rd = new InputStreamReader(internal2_stm,"US-ASCII");
IOUtil.copy(rd,wr);
IOUtil.shutdown(rd);
IOUtil.shutdown(internal2_stm);
wr.write("</base64>");
// send out the complete string
rc = wr.toString();
IOUtil.shutdown(wr);
} // end try
catch (IOException ioe)
{ // this is an internal error
throw new XmlRpcFault(XmlRpcFault.INTERNAL_ERROR,"unable to save binary data");
} // end catch
catch (MessagingException me)
{ // and so is this
throw new XmlRpcFault(XmlRpcFault.INTERNAL_ERROR,"unable to encode binary data");
} // end catch
return rc;
} // end serializeInputStream
public final String serializeIterator(Iterator it) throws XmlRpcFault
{
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("</data>\r\n</array>");
return b.toString();
} // end serializeIterator
public final String serializeMap(Map m) throws XmlRpcFault
{
StringBuffer b = new StringBuffer("<struct>\r\n");
Iterator it = m.entrySet().iterator();
while (it.hasNext())
{ // serialize each entry in turn
Map.Entry ntry = (Map.Entry)(it.next());
b.append("<member>\r\n<name>").append(StringUtil.encodeHTML(ntry.getKey().toString()));
b.append("</name>\r\n<value>").append(this.serialize(ntry.getValue()));
b.append("</value>\r\n</member>\r\n");
} // end while
b.append("</struct>\r\n");
return b.toString();
} // end serializeMap
public final String serializeString(String s)
{
if (s==null)
return "<string></string>";
return "<string>" + StringUtil.encodeHTML(s) + "</string>";
} // end serializeString
/*--------------------------------------------------------------------------------
* External static operations
*--------------------------------------------------------------------------------
*/
public static final synchronized XmlRpcSerializer get()
{
if (self==null)
self = new XmlRpcSerializer();
return self;
} // end get
} // end class XmlRpcSerializer

View File

@ -0,0 +1,198 @@
/*
* 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.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.regexp.*;
import com.silverwrist.util.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.ui.*;
import com.silverwrist.venice.ui.config.RootConfig;
import com.silverwrist.venice.ui.servlet.BaseServlet;
import com.silverwrist.venice.ui.servlet.RequestImpl;
public class XmlRpcServlet extends BaseServlet
{
/*--------------------------------------------------------------------------------
* Inner class that implements the actual "normal" return value
*--------------------------------------------------------------------------------
*/
static class XmlRpcReturnValue implements ContentExecute
{
private Object obj;
XmlRpcReturnValue(Object obj)
{
this.obj = obj;
} // end constructor
public void execute(RequestExec req) throws IOException
{
StringBuffer b =
new StringBuffer("<?xml version=\"1.0\"?>\r\n<methodResponse><params><param>\r\n<value>");
try
{ // serialize the returned object
XmlRpcSerializer serializer = XmlRpcSerializer.get();
b.append(serializer.serialize(obj));
} // end try
catch (XmlRpcFault f)
{ // if we get a fault here, just execute THAT instead
f.execute(req);
return;
} // end catch
b.append("</value>\r\n</param></params></methodResponse>\r\n");
byte[] raw = b.toString().getBytes("UTF-8");
req.sendBinary("text/xml",raw);
} // end execute
} // end class XmlRpcReturnValue
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static final String METHOD_LIST_ATTR = "ui.xmlrpc.MethodList";
public static final String OBJECT_CLASS_CACHE_ATTR = "ui.xmlrpc.class.ObjectCache";
/*--------------------------------------------------------------------------------
* Overrides from class BaseServlet
*--------------------------------------------------------------------------------
*/
protected void init(ServletConfig config, ServletContext ctxt, VeniceEngine engine, RootConfig root,
String root_file_path)
{
List methods = root.getXmlRpcMethods();
RequestImpl.setAppAttribute(ctxt,METHOD_LIST_ATTR,methods);
RequestImpl.setAppAttribute(ctxt,OBJECT_CLASS_CACHE_ATTR,Collections.synchronizedMap(new HashMap()));
} // end init
protected VeniceUISessionFactory getSessionFactory()
{
return NullSession.get(); // null session by default
} // end getSessionFactory
protected Object translateServletException(RequestInput ri, Exception e)
{
return null;
} // end translateServletException
public Object process(RequestInput req)
{
XmlRpcRequest xreq;
try
{ // get the XML-RPC request structure
xreq = new XmlRpcRequest(req.getRequestDocument());
} // end try
catch (XmlRpcFault f)
{ // return the fault structure
return f;
} // end catch
// Prepare the parameters map
int i;
HashMap param_repl_map = new HashMap();
for (i=0; i<xreq.getParamCount(); i++)
{ // fill in the parameters...
Object obj = xreq.getParam(i);
if ((obj instanceof String) || (obj instanceof Integer) || (obj instanceof Double))
param_repl_map.put("param." + i,obj.toString());
} // end for
// Find an appropriate method to handle this call.
List methods = (List)(req.getAppAttribute(METHOD_LIST_ATTR));
boolean rescan = false;
RE matcher = new RE();
String the_name = xreq.getMethod();
XmlRpcMethod meth = null;
HashMap sub_map;
do
{ // search for a method
rescan = false;
Iterator it = methods.iterator();
boolean found = false;
while (!found && it.hasNext())
{ // look for a match on the method name
meth = (XmlRpcMethod)(it.next());
meth.configureMatcher(matcher);
found = matcher.match(the_name);
} // end while
if (!found) // method not found
return new XmlRpcFault(XmlRpcFault.METHOD_NOT_FOUND,"Method not found: " + the_name);
// prepare the substitution map
sub_map = (HashMap)(param_repl_map.clone());
int ct = matcher.getParenCount();
for (i=0; i<=ct; i++)
sub_map.put("match." + i,matcher.getParen(i));
String remap = meth.getRemap();
if (remap!=null)
{ // substitute in variables and rescan
the_name = StringUtil.replaceAllVariables(remap,sub_map);
rescan = true;
} // end if
} while (rescan);
try
{ // dispatch the method call
Object 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);
} // end catch
catch (XmlRpcFault f)
{ // pass faults right on up
return f;
} // end catch
} // end process
} // end class XmlRpcServlet

View File

@ -0,0 +1,70 @@
/*
* 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 XmlRpcTestHandler implements XmlRpcDispatch
{
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public XmlRpcTestHandler()
{ // do nothing
} // end constructor
/*--------------------------------------------------------------------------------
* Implementations from interface XmlRpcDispatch
*--------------------------------------------------------------------------------
*/
public Object dispatch(RequestInput req, XmlRpcRequest xreq, Map environment) throws Exception, XmlRpcFault
{
if (xreq.getMethod().equals("venice:test.sumDifference"))
{ // do the sumdifference API
if (xreq.getParamCount()!=2)
throw new XmlRpcFault(XmlRpcFault.INVALID_PARAMS,"parameter count mismatch");
Integer n1, n2;
try
{ // cast parameters to Integer
n1 = (Integer)(xreq.getParam(0));
n2 = (Integer)(xreq.getParam(1));
} // end try
catch (ClassCastException e)
{ // class cast exception!
throw new XmlRpcFault(XmlRpcFault.INVALID_PARAMS,"parameter type mismatch");
} // end catch
HashMap rc = new HashMap();
rc.put("sum",new Integer(n1.intValue() + n2.intValue()));
rc.put("difference",new Integer(n1.intValue() - n2.intValue()));
return rc;
} // end if
return null;
} // end dispatch
} // end class XmlRpcTestHandler

View File

@ -11,7 +11,7 @@
*
* 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) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* Copyright (C) 2001-02 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
@ -34,6 +34,38 @@ import com.silverwrist.venice.ui.script.ScriptManagerContainer;
public abstract class BaseServlet extends HttpServlet
{
/*--------------------------------------------------------------------------------
* Internal session factory object
*--------------------------------------------------------------------------------
*/
static class HttpSessionFactory implements VeniceUISessionFactory
{
private static final String ATTR_NAME = VeniceUISession.class.getName();
HttpSessionFactory()
{ // do nothing
} // end constructor
public VeniceUISession createSession(ServletContext ctxt, HttpServletRequest request,
HttpServletResponse response, VeniceEngine engine,
RootConfig config) throws ServletException
{
HttpSession session = request.getSession(true);
VeniceUISession rc = (VeniceUISession)(session.getAttribute(ATTR_NAME));
if (rc==null)
{ // return a new session
rc = new HttpVeniceUISession(request,session,engine);
session.setAttribute(ATTR_NAME,rc);
} // end if
return rc;
} // end createSession
} // end class HttpSessionFactory
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
@ -49,6 +81,8 @@ public abstract class BaseServlet extends HttpServlet
private static Category logger = Category.getInstance(BaseServlet.class);
private static VeniceUISessionFactory factory = new HttpSessionFactory();
/*--------------------------------------------------------------------------------
* Internal operations
*--------------------------------------------------------------------------------
@ -56,14 +90,16 @@ public abstract class BaseServlet extends HttpServlet
private Object translateException(RequestInput req, Exception e)
{
// try the servlet first
Object rc = translateServletException(req,e);
if (rc!=null)
return rc;
// otherwise, go it alone
logger.info("BaseServlet.translateException translating exception",e);
if (e instanceof ScriptingException)
return new ErrorBox("Scripting Error",e,null);
// Last-ditch effort: get the specific servlet to translate the exception.
Object rc = translateServletException(req,e);
if (rc!=null)
return rc;
return new ErrorBox("Unhandled Exception Detected!",e.toString(),e,null);
} // end translateException
@ -77,13 +113,41 @@ public abstract class BaseServlet extends HttpServlet
try
{ // create the actual request implementation
ServletContext ctxt = getServletContext();
RequestImpl the_request =
new RequestImpl(ctxt,request,response,(VeniceEngine)(ctxt.getAttribute(ENGINE_ATTRIBUTE)),
(RootConfig)(ctxt.getAttribute(UICONFIG_ATTRIBUTE)));
RequestImpl the_request = null;
try
{ // create the request object
the_request = new RequestImpl(ctxt,request,response,
(VeniceEngine)(ctxt.getAttribute(ENGINE_ATTRIBUTE)),
(RootConfig)(ctxt.getAttribute(UICONFIG_ATTRIBUTE)),
getSessionFactory());
} // end try
catch (ValidationException ve)
{ // error in formatting of the request - bug out
response.sendError(HttpServletResponse.SC_BAD_REQUEST,ve.toString());
return;
} // end catch
String default_location = the_request.getLocation();
// log the username with all log messages, if the user is logged in
boolean record_user = the_request.getUser().isLoggedIn();
boolean record_user = false;
if (the_request.sessionBound())
{ // has the session been bound?
try
{ // find out whether they're logged in
record_user = the_request.getUser().isLoggedIn();
} // end try
catch (IllegalStateException e)
{ // if not, just forget about it
record_user = false;
} // end catch
} // end if
if (record_user)
NDC.push(the_request.getUser().getUserName());
@ -176,6 +240,12 @@ public abstract class BaseServlet extends HttpServlet
{ // default does nothing
} // end init
protected VeniceUISessionFactory getSessionFactory()
{
return factory;
} // end getSessionFactory
protected Object translateServletException(RequestInput ri, Exception e)
{
return null; // does nothing by default

View File

@ -0,0 +1,206 @@
/*
* 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.servlet;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.log4j.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.ui.*;
class HttpVeniceUISession implements VeniceUISession
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static final String SESSION_ATTRIBUTE_STEM = "venice.vars.";
private static Category logger = Category.getInstance(HttpVeniceUISession.class);
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private HttpSession session;
private UserContext user;
private Cookie venice_cookie = null;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
HttpVeniceUISession(HttpServletRequest request, HttpSession session, VeniceEngine engine)
throws ServletException
{
this.session = session; // save off the session variable
try
{ // tell the engine to create us a user context
user = engine.createUserContext(request.getRemoteAddr());
// Did the user send a Venice authentication cookie? If so, try to use it.
Cookie[] cookies = request.getCookies();
Cookie venice_cookie = null;
for (int i=0; (venice_cookie==null) && (i<cookies.length); i++)
{ // look for a Venice authentication cookie
if (RequestInput.LOGIN_COOKIE.equals(cookies[i].getName()))
venice_cookie = cookies[i];
} // end for
} // end try
catch (DataException e)
{ // context creation failed - remap the exception
logger.error("Session creation failed: " + e.getMessage(),e);
throw new ServletException("Session creation failed: " + e.getMessage(),e);
} // end catch
} // end constructor
/*--------------------------------------------------------------------------------
* Implementations from interface VeniceUISession
*--------------------------------------------------------------------------------
*/
public long getCreationTime()
{
return session.getCreationTime();
} // end getCreationTime
public String getID()
{
return session.getId();
} // end getID
public long getLastAccessedTime()
{
return session.getLastAccessedTime();
} // end getLastAccessedTime
public void setMaxInactiveInterval(int interval)
{
session.setMaxInactiveInterval(interval);
} // end setMaxInactiveInterval
public int getMaxInactiveInterval()
{
return session.getMaxInactiveInterval();
} // end getMaxInactiveInterval
public Object getAttribute(String name)
{
return session.getAttribute(SESSION_ATTRIBUTE_STEM + name);
} // end getAttribute
public Enumeration getAttributeNames()
{
Enumeration raw = session.getAttributeNames();
ArrayList rc = new ArrayList();
while (raw.hasMoreElements())
{ // look for attributes we've added
String tmp = (String)(raw.nextElement());
if (tmp.startsWith(SESSION_ATTRIBUTE_STEM))
rc.add(tmp.substring(SESSION_ATTRIBUTE_STEM.length()));
} // end while
return Collections.enumeration(rc);
} // end getAttributeNames
public void setAttribute(String name, Object o)
{
session.setAttribute(SESSION_ATTRIBUTE_STEM + name,o);
} // end setAttribute
public void removeAttribute(String name)
{
session.removeAttribute(SESSION_ATTRIBUTE_STEM + name);
} // end removeAttribute
public void invalidate()
{
session.invalidate();
} // end invalidate
public UserContext getUser()
{
return user;
} // end getUser
public void setUser(UserContext user)
{
this.user = user;
} // end setUser
public void preprocess(RequestInput ri)
{
if (venice_cookie!=null)
{ // try to log in with the cookie
try
{ // attempt authentication
if (!(user.authenticateWithToken(venice_cookie.getValue())))
ri.deleteCookie(RequestInput.LOGIN_COOKIE); // delete bogus cookie if it didn't work
} // end try
catch (DataException de)
{ // it didn't work...
ri.deleteCookie(RequestInput.LOGIN_COOKIE);
} // end catch
venice_cookie = null;
} // end if
} // end preprocess
/*--------------------------------------------------------------------------------
* Implementations from interface HttpSessionBindingListener
*--------------------------------------------------------------------------------
*/
public void valueBound(HttpSessionBindingEvent event)
{ // do nothing
} // end valueBound
public void valueUnbound(HttpSessionBindingEvent event)
{
this.session = null;
this.user = null;
} // end valueUnbound
} // end class HttpVeniceUISession

View File

@ -11,7 +11,7 @@
*
* 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) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* Copyright (C) 2001-02 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
@ -39,6 +39,7 @@ import com.silverwrist.venice.ui.menus.CommunityMenu;
import com.silverwrist.venice.ui.menus.Menu;
import com.silverwrist.venice.ui.menus.MenuComponent;
import com.silverwrist.venice.ui.script.*;
import com.silverwrist.venice.util.XMLLoader;
public class RequestImpl implements RequestInput
{
@ -553,9 +554,6 @@ public class RequestImpl implements RequestInput
private static final String STYLESHEET_ATTRIBUTE = "com.silverwrist.venice.rendering.StyleSheet";
private static final String APP_ATTRIBUTE_STEM = "com.silverwrist.venice.ui.variables.";
private static final String USERCTXT_ATTRIBUTE = "user.context";
private static final String SESSION_ATTRIBUTE_STEM = "venice.vars.";
public static final String REQUEST_CONTENT = "com.silverwrist.venice.ui.Content";
public static final String REQUEST_INPUT = "com.silverwrist.venice.ui.RequestInput";
public static final String REQUEST_OUTPUT = "com.silverwrist.venice.ui.RequestOutput";
@ -569,10 +567,9 @@ public class RequestImpl implements RequestInput
private ServletContext ctxt; // the servlet context
private HttpServletRequest request; // the servlet request data
private HttpServletResponse response; // the servlet response data
private HttpSession session; // the current HTTP session
private VeniceUISession session; // the current HTTP session
private VeniceEngine engine; // the Venice engine context
private RootConfig config; // the UI configuration data
private UserContext user; // the current user context
private ServletMultipartHandler mphandler = null; // if this is a multipart/form-data POST
private ArrayList new_cookies = null; // cookies to be added to the response
private boolean end_response = true; // do we need to properly end the response?
@ -585,6 +582,7 @@ public class RequestImpl implements RequestInput
private DateFormat activity_time = null; // format to use for activity string times
private CommunityContext community = null; // the current community
private LinkedList auto_cleanup = null; // auto-cleanup callbacks
private Document request_doc = null; // request parsed as an XML document
/*--------------------------------------------------------------------------------
* Constructor
@ -592,56 +590,35 @@ public class RequestImpl implements RequestInput
*/
RequestImpl(ServletContext ctxt, HttpServletRequest request, HttpServletResponse response,
VeniceEngine engine, RootConfig config) throws ServletException
VeniceEngine engine, RootConfig config, VeniceUISessionFactory factory)
throws ServletException, ValidationException
{
// Set up the basic variables.
this.ctxt = ctxt;
this.request = request;
this.response = response;
this.session = request.getSession(true);
this.engine = engine;
this.config = config;
// Create or retrieve the user context.
user = (UserContext)(session.getAttribute(USERCTXT_ATTRIBUTE));
if (user==null)
{ // the user context isn't present yet
if (request.getMethod().equals("POST"))
{ // POSTs can have special handling for the request data
if (request.getContentType().startsWith("text/xml"))
{ // this is some sort of XML-based request - parse it into a DOM tree
XMLLoader loader = XMLLoader.get();
try
{ // tell the engine to create us a user context
user = engine.createUserContext(request.getRemoteAddr());
// Did the user send a Venice authentication cookie? If so, try to use it.
Cookie[] cookies = request.getCookies();
Cookie venice_cookie = null;
for (int i=0; (venice_cookie==null) && (i<cookies.length); i++)
{ // look for a Venice authentication cookie
if (LOGIN_COOKIE.equals(cookies[i].getName()))
venice_cookie = cookies[i];
} // end for
if (venice_cookie!=null)
{ // attempt to authenticate with this cookie
if (!(user.authenticateWithToken(venice_cookie.getValue())))
deleteCookie(LOGIN_COOKIE); // delete bogus cookie if it didn't work
} // end if
// else don't authenticate, stay in the "anonymous" state
// Save the user context.
session.setAttribute(USERCTXT_ATTRIBUTE,user);
{ // load the document
request_doc = loader.loadPostData(request.getInputStream()); // may throw ValidationException
} // end try
catch (DataException e)
{ // context creation failed - remap the exception
logger.error("Session creation failed: " + e.getMessage(),e);
throw new ServletException("Session creation failed: " + e.getMessage(),e);
catch (IOException ioe)
{ // IO exception...sigh
logger.error("IO error loading request document",ioe);
throw new ServletException("IO error loading request document: " + ioe.toString(),ioe);
} // end catch
} // end if
if (request.getMethod().equals("POST") && ServletMultipartHandler.canHandle(request))
else if (ServletMultipartHandler.canHandle(request))
{ // if this is a multipart/form-data POST, create the handler object
try
{ // use the multipart handler and get something
@ -651,16 +628,23 @@ public class RequestImpl implements RequestInput
catch (ServletMultipartException smpe)
{ // unable to parse POST data for some reason
logger.error("Multipart data acquisition failed: " + smpe.getMessage(),smpe);
throw new ServletException("Unable to retrieve parameters: " + smpe.getMessage(),smpe);
throw new ValidationException("invalid multipart request: " + smpe.getMessage(),smpe);
} // end catch
} // end else if
} // end if
// read the user's preferred locale
// Create the UI session.
session = factory.createSession(ctxt,request,response,engine,config);
session.preprocess(this);
if (!(session instanceof NullSession))
{ // read the user's preferred locale
try
{ // get the user default locale
my_locale = user.getLocale();
my_locale = session.getUser().getLocale();
} // end try
catch (DataException de)
@ -672,7 +656,7 @@ public class RequestImpl implements RequestInput
// read the user's preferred time zone
try
{ // get the user default timezone
my_timezone = user.getTimeZone();
my_timezone = session.getUser().getTimeZone();
} // end try
catch (DataException de)
@ -681,6 +665,14 @@ public class RequestImpl implements RequestInput
} // end catch
} // end if
else
{ // just default locale/timezone
my_locale = Locale.getDefault();
my_timezone = TimeZone.getDefault();
} // end else
// Come up with a "first guess" at the location.
StringBuffer loc_buf = new StringBuffer(request.getServletPath());
if (loc_buf.charAt(0)=='/')
@ -865,8 +857,17 @@ public class RequestImpl implements RequestInput
} // end getSourceAddress
public void endSession()
{
session.invalidate();
session = null;
} // end endSession
public boolean hasParameter(String name)
{
if (request_doc!=null)
return false;
if (mphandler!=null)
return mphandler.hasParameter(name);
else
@ -876,6 +877,8 @@ public class RequestImpl implements RequestInput
public String getParameter(String name)
{
if (request_doc!=null)
return null;
if (mphandler!=null)
return mphandler.getValue(name);
else
@ -942,6 +945,8 @@ public class RequestImpl implements RequestInput
public Enumeration getParameterNames()
{
if (request_doc!=null)
return Collections.enumeration(Collections.EMPTY_LIST);
if (mphandler!=null)
return mphandler.getNames();
else
@ -951,6 +956,8 @@ public class RequestImpl implements RequestInput
public String[] getParameterValues(String name)
{
if (request_doc!=null)
return new String[0];
if (mphandler!=null)
return mphandler.getParamValues(name);
else
@ -960,6 +967,8 @@ public class RequestImpl implements RequestInput
public boolean isFileParam(String name)
{
if (request_doc!=null)
return false;
if (mphandler!=null)
return mphandler.isFileParam(name);
else
@ -969,6 +978,8 @@ public class RequestImpl implements RequestInput
public String getParameterType(String name)
{
if (request_doc!=null)
return null;
if (mphandler!=null)
return mphandler.getContentType(name);
else
@ -978,6 +989,8 @@ public class RequestImpl implements RequestInput
public int getParameterSize(String name)
{
if (request_doc!=null)
return -1;
if (mphandler!=null)
return mphandler.getContentSize(name);
else
@ -998,6 +1011,18 @@ public class RequestImpl implements RequestInput
} // end getParameterDataStream
public Document getRequestDocument()
{
return request_doc;
} // end getRequestDocument
public boolean sessionBound()
{
return ((session!=null) && !(session instanceof NullSession));
} // end sessionBound
public boolean isImageButtonClicked(String name)
{
return this.hasParameter(name + ".x");
@ -1018,13 +1043,16 @@ public class RequestImpl implements RequestInput
public Object getSessionAttribute(String name)
{
return getSessionAttribute(session,name);
return session.getAttribute(name);
} // end getSessionAttribute
public void setSessionAttribute(String name, Object o)
{
setSessionAttribute(session,name,o);
if (o==null)
session.removeAttribute(name);
else
session.setAttribute(name,o);
} // end setSessionAttribute
@ -1075,17 +1103,13 @@ public class RequestImpl implements RequestInput
public UserContext getUser()
{
return user;
return session.getUser();
} // end getUser
public void replaceUser(UserContext new_user)
{
if (new_user==null)
session.removeAttribute(USERCTXT_ATTRIBUTE);
else
session.setAttribute(USERCTXT_ATTRIBUTE,new_user);
user = new_user;
session.setUser(new_user);
} // end replaceUser
@ -1332,6 +1356,7 @@ public class RequestImpl implements RequestInput
public Content[] getSideBoxes() throws AccessError, DataException
{
UserContext user = session.getUser();
SideBoxManager sbmgr = config.getSideBoxManager();
List descrs = user.getSideBoxList();
Content[] rc = new Content[descrs.size()];
@ -1399,7 +1424,7 @@ public class RequestImpl implements RequestInput
try
{ // turn the string into a community ID, and thence to a CommunityContext
int tmp_id = Integer.parseInt(parm);
community = user.getCommunityContext(tmp_id);
community = session.getUser().getCommunityContext(tmp_id);
if (community==null)
{ // trap any null results (may not be possible with communities, but you never know)
logger.error("Community #" + tmp_id + " was not found!");
@ -1532,36 +1557,6 @@ public class RequestImpl implements RequestInput
} // end setAppAttribute
public final static Object getSessionAttribute(HttpSession session, String name)
{
return session.getAttribute(SESSION_ATTRIBUTE_STEM + name);
} // end getSessionAttribute
public final static void setSessionAttribute(HttpSession session, String name, Object o)
{
if (o==null)
session.removeAttribute(SESSION_ATTRIBUTE_STEM + name);
else
session.setAttribute(SESSION_ATTRIBUTE_STEM + name,o);
} // end setSessionAttribute
public final static Object getSessionAttribute(HttpServletRequest request, String name)
{
HttpSession session = request.getSession(true);
return ((session!=null) ? getSessionAttribute(session,name) : null);
} // end getSessionAttribute
public final static void setSessionAttribute(HttpServletRequest request, String name, Object o)
{
HttpSession session = request.getSession(true);
if (session!=null)
setSessionAttribute(session,name,o);
} // end setSessionAttribute
public final static Object getRequestAttribute(ServletRequest request, String name)
{
return request.getAttribute(REQUEST_ATTRIBUTE_STEM + name);

View File

@ -181,6 +181,17 @@ public class XMLLoader
} // end configGetRootElement
public final Element postGetRootElement(Document doc, String expected_name) throws ValidationException
{
Element rc = doc.getDocumentElement();
if (rc.getTagName().equals(expected_name))
return rc; // we're OK
logger.fatal("posted document is not a <" + expected_name + "/> document (actual root tag: <"
+ rc.getTagName() + "/>)");
throw new ValidationException("root element is not \"" + expected_name + "\"");
} // end postGetRootElement
public final String configGetText(DOMElementHelper h) throws ConfigException
{
String rc = h.getElementText();
@ -189,7 +200,7 @@ public class XMLLoader
logger.fatal("<" + h.getElement().getTagName() + "/> has no value");
throw new ConfigException("no data value found in <" + h.getElement().getTagName() + "/>",h.getElement());
} // end configGetSubElementText
} // end configGetText
public final String configGetText(Element elt) throws ConfigException
{
@ -208,12 +219,29 @@ public class XMLLoader
} // end configGetSubElementText
public final String postGetSubElementText(DOMElementHelper h, String elt_name) throws ValidationException
{
String rc = h.getSubElementText(elt_name);
if (rc!=null)
return rc; // we're OK
logger.fatal("<" + h.getElement().getTagName() + "/> has no <" + elt_name + "/> element");
throw new ValidationException("no \"" + elt_name + "\" element found in \""
+ h.getElement().getTagName() + "\"");
} // end postGetSubElementText
public final String configGetSubElementText(Element elt, String subelt_name) throws ConfigException
{
return configGetSubElementText(new DOMElementHelper(elt),subelt_name);
} // end configGetSubElementText
public final String postGetSubElementText(Element elt, String subelt_name) throws ValidationException
{
return postGetSubElementText(new DOMElementHelper(elt),subelt_name);
} // end postGetSubElementText
public final Element configGetSubSection(DOMElementHelper h, String sect_name) throws ConfigException
{
Element rc = h.getSubElement(sect_name);
@ -225,12 +253,29 @@ public class XMLLoader
} // end configGetSubElementText
public final Element postGetSubSection(DOMElementHelper h, String sect_name) throws ValidationException
{
Element rc = h.getSubElement(sect_name);
if (rc!=null)
return rc; // we're OK
logger.fatal("<" + h.getElement().getTagName() + "/> has no <" + sect_name + "/> element");
throw new ValidationException("no \"" + sect_name + "\" element found in \""
+ h.getElement().getTagName() + "\"");
} // end postGetSubSection
public final Element configGetSubSection(Element sect, String subsect_name) throws ConfigException
{
return configGetSubSection(new DOMElementHelper(sect),subsect_name);
} // end configGetSubSection
public final Element postGetSubSection(Element sect, String subsect_name) throws ValidationException
{
return postGetSubSection(new DOMElementHelper(sect),subsect_name);
} // end postGetSubSection
public final void configVerifyNodeName(Node n, String name, Element enclosing_sect) throws ConfigException
{
if (n.getNodeName().equals(name))