Eric J. Bowersox 25c5817a67 implemented the initial XML-RPC APIs in Venice - for creating and destroying
"sessions," logging in, posting messages to topics, attaching files to
messages, and a couple of minor things that aren't as important right now
2002-02-01 22:40:55 +00:00

204 lines
6.6 KiB
Java

/*
* 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 javax.servlet.*;
import org.apache.log4j.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.ui.*;
import com.silverwrist.venice.ui.config.RootConfig;
import com.silverwrist.venice.ui.servlet.RequestImpl;
class RpcSessionBroker
{
/*--------------------------------------------------------------------------------
* Internal class for sweeping the sessions
*--------------------------------------------------------------------------------
*/
class SessionSweeper extends TimerTask
{
private LinkedList workspace = new LinkedList();
SessionSweeper()
{
super();
} // end constructor
public void run()
{
synchronized (RpcSessionBroker.this)
{ // seek and destroy all expired sessions
Iterator it = sessions.values().iterator();
while (it.hasNext())
{ // find all the tasks that are due to be invalidated
RpcVeniceUISession s = (RpcVeniceUISession)(it.next());
if (s.canUnloadNow())
workspace.addLast(s);
} // end while
while (workspace.size()>0)
{ // invalidate all sessions that have not been accessed recently
RpcVeniceUISession s = (RpcVeniceUISession)(workspace.removeFirst());
if (logger.isDebugEnabled())
logger.debug("session sweeper removing session with ID " + s.getID());
s.invalidate();
} // end while
} // end synchronized block
} // end run
} // end class SessionSweeper
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Category logger = Category.getInstance(RpcSessionBroker.class);
private static final String ATTRIBUTE = "ui.rpc.SessionBroker";
private static final long INTERVAL = 1000;
private static final String PREFIX = "rpcsess:";
private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
private static final int ID_LENGTH = 40;
private static Random rng = new Random(); // random number generator
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private HashMap sessions = new HashMap(); // the actual sessions
private VeniceEngine engine; // the Venice engine
private int timeout_value; // the timeout value
private Timer timer = new Timer(true); // the interval timer used to schedule sweeps
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
private RpcSessionBroker(VeniceEngine engine, RootConfig root)
{
this.engine = engine;
this.timeout_value = root.getRpcSessionTimeout();
timer.scheduleAtFixedRate(new SessionSweeper(),INTERVAL,INTERVAL);
} // end constructor
/*--------------------------------------------------------------------------------
* Internal operations
*--------------------------------------------------------------------------------
*/
private static final String generateID()
{
StringBuffer buf = new StringBuffer(PREFIX);
for (int i=0; i<ID_LENGTH; i++)
buf.append(ALPHABET.charAt(rng.nextInt(ALPHABET.length())));
return buf.toString();
} // end generateID
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
final int getTimeout()
{
return timeout_value;
} // end getTimeout
final VeniceEngine getEngine()
{
return engine;
} // end getEngine
final synchronized VeniceUISession getSession(String id)
{
if (logger.isDebugEnabled())
logger.debug("looking up session with ID " + id + " - current session count is " + sessions.size());
RpcVeniceUISession rc = (RpcVeniceUISession)(sessions.get(id));
if (rc!=null)
rc.touch();
return rc;
} // end getSession
final synchronized VeniceUISession createSession(String remote_address) throws DataException
{
String new_id = generateID();
while (sessions.containsKey(new_id))
new_id = generateID();
RpcVeniceUISession rc = new RpcVeniceUISession(new_id,remote_address,this);
sessions.put(new_id,rc);
if (logger.isDebugEnabled())
logger.debug("created new session with ID " + new_id + " - session count now " + sessions.size());
return rc;
} // end createSession
final synchronized void detachSession(String id)
{
if (logger.isDebugEnabled())
logger.debug("removing session with ID " + id + " - current session count is " + sessions.size());
sessions.remove(id);
if (logger.isDebugEnabled())
logger.debug("session count now " + sessions.size());
} // end detachSession
/*--------------------------------------------------------------------------------
* External static operations
*--------------------------------------------------------------------------------
*/
public static RpcSessionBroker get(ServletContext ctxt)
{
return (RpcSessionBroker)(RequestImpl.getAppAttribute(ctxt,ATTRIBUTE));
} // end get
public static RpcSessionBroker get(RequestInput ri)
{
return (RpcSessionBroker)(ri.getAppAttribute(ATTRIBUTE));
} // end get
public static synchronized void init(ServletContext ctxt, VeniceEngine engine, RootConfig root)
{
if (RequestImpl.getAppAttribute(ctxt,ATTRIBUTE)==null)
RequestImpl.setAppAttribute(ctxt,ATTRIBUTE,new RpcSessionBroker(engine,root));
} // end init
} // end class RpcSessionBroker