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:
parent
bcd76541ab
commit
6ea41dc619
|
@ -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). -->
|
||||
|
|
11
etc/web.xml
11
etc/web.xml
|
@ -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
1
lib/.gitignore
vendored
|
@ -1,5 +1,6 @@
|
|||
bsf.jar
|
||||
jacl.jar
|
||||
jakarta-regexp*.jar
|
||||
js.jar
|
||||
log4j.jar
|
||||
mysql.jar
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
164
src/com/silverwrist/venice/ui/NullSession.java
Normal file
164
src/com/silverwrist/venice/ui/NullSession.java
Normal 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
|
|
@ -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);
|
||||
|
|
51
src/com/silverwrist/venice/ui/VeniceUISession.java
Normal file
51
src/com/silverwrist/venice/ui/VeniceUISession.java
Normal 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
|
31
src/com/silverwrist/venice/ui/VeniceUISessionFactory.java
Normal file
31
src/com/silverwrist/venice/ui/VeniceUISessionFactory.java
Normal 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
|
|
@ -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
|
||||
*--------------------------------------------------------------------------------
|
||||
|
|
28
src/com/silverwrist/venice/ui/rpc/XmlRpcDispatch.java
Normal file
28
src/com/silverwrist/venice/ui/rpc/XmlRpcDispatch.java
Normal 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
|
123
src/com/silverwrist/venice/ui/rpc/XmlRpcFault.java
Normal file
123
src/com/silverwrist/venice/ui/rpc/XmlRpcFault.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.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
|
172
src/com/silverwrist/venice/ui/rpc/XmlRpcMethod.java
Normal file
172
src/com/silverwrist/venice/ui/rpc/XmlRpcMethod.java
Normal 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
|
392
src/com/silverwrist/venice/ui/rpc/XmlRpcRequest.java
Normal file
392
src/com/silverwrist/venice/ui/rpc/XmlRpcRequest.java
Normal 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
|
24
src/com/silverwrist/venice/ui/rpc/XmlRpcSelfSerializer.java
Normal file
24
src/com/silverwrist/venice/ui/rpc/XmlRpcSelfSerializer.java
Normal 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
|
471
src/com/silverwrist/venice/ui/rpc/XmlRpcSerializer.java
Normal file
471
src/com/silverwrist/venice/ui/rpc/XmlRpcSerializer.java
Normal 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
|
198
src/com/silverwrist/venice/ui/rpc/XmlRpcServlet.java
Normal file
198
src/com/silverwrist/venice/ui/rpc/XmlRpcServlet.java
Normal 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
|
70
src/com/silverwrist/venice/ui/rpc/XmlRpcTestHandler.java
Normal file
70
src/com/silverwrist/venice/ui/rpc/XmlRpcTestHandler.java
Normal 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
|
|
@ -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
|
||||
|
|
206
src/com/silverwrist/venice/ui/servlet/HttpVeniceUISession.java
Normal file
206
src/com/silverwrist/venice/ui/servlet/HttpVeniceUISession.java
Normal 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
|
|
@ -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,94 +590,88 @@ 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
|
||||
{ // load the document
|
||||
request_doc = loader.loadPostData(request.getInputStream()); // may throw ValidationException
|
||||
|
||||
} // end try
|
||||
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
|
||||
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
|
||||
mphandler = new ServletMultipartHandler(request);
|
||||
|
||||
} // end try
|
||||
catch (ServletMultipartException smpe)
|
||||
{ // unable to parse POST data for some reason
|
||||
logger.error("Multipart data acquisition failed: " + smpe.getMessage(),smpe);
|
||||
throw new ValidationException("invalid multipart request: " + smpe.getMessage(),smpe);
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end else if
|
||||
|
||||
} // end if
|
||||
|
||||
// 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
|
||||
{ // 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);
|
||||
{ // get the user default locale
|
||||
my_locale = session.getUser().getLocale();
|
||||
|
||||
} // 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 (DataException de)
|
||||
{ // locale problems...
|
||||
my_locale = Locale.getDefault();
|
||||
|
||||
} // end catch
|
||||
|
||||
// read the user's preferred time zone
|
||||
try
|
||||
{ // get the user default timezone
|
||||
my_timezone = session.getUser().getTimeZone();
|
||||
|
||||
} // end try
|
||||
catch (DataException de)
|
||||
{ // time zone problems...
|
||||
my_timezone = TimeZone.getDefault();
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end if
|
||||
|
||||
if (request.getMethod().equals("POST") && ServletMultipartHandler.canHandle(request))
|
||||
{ // if this is a multipart/form-data POST, create the handler object
|
||||
try
|
||||
{ // use the multipart handler and get something
|
||||
mphandler = new ServletMultipartHandler(request);
|
||||
|
||||
} // end try
|
||||
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);
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end if
|
||||
|
||||
// read the user's preferred locale
|
||||
try
|
||||
{ // get the user default locale
|
||||
my_locale = user.getLocale();
|
||||
|
||||
} // end try
|
||||
catch (DataException de)
|
||||
{ // locale problems...
|
||||
else
|
||||
{ // just default locale/timezone
|
||||
my_locale = Locale.getDefault();
|
||||
|
||||
} // end catch
|
||||
|
||||
// read the user's preferred time zone
|
||||
try
|
||||
{ // get the user default timezone
|
||||
my_timezone = user.getTimeZone();
|
||||
|
||||
} // end try
|
||||
catch (DataException de)
|
||||
{ // time zone problems...
|
||||
my_timezone = TimeZone.getDefault();
|
||||
|
||||
} // end catch
|
||||
} // end else
|
||||
|
||||
// Come up with a "first guess" at the location.
|
||||
StringBuffer loc_buf = new StringBuffer(request.getServletPath());
|
||||
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue
Block a user