001// Copyright (c) 2001 Hursh Jain (http://www.mollypages.org) 002// The Molly framework is freely distributable under the terms of an 003// MIT-style license. For details, see the molly pages web site at: 004// http://www.mollypages.org/. Use, modify, have fun ! 005 006package fc.web.servlet; 007 008import java.io.*; 009import java.util.logging.*; 010import java.util.*; 011import javax.servlet.*; 012import javax.servlet.http.*; 013 014import fc.io.*; 015import fc.web.*; 016import fc.util.*; 017 018//In the future, java.security should allow us to use logon credentials for 019//security. Right now, as of jdk 1.4 it seems to be non-trivial to create 020//and install new security policies based on the current login info. java.security 021//is really targetted towards code principals i.e, granting *code* various permissions 022//based on where the code was *loaded* from. 023 024/** 025Manages various {@link Action} available to a servlet. Subclasses 026should add and manage appropriate actions. 027 028@author hursh jain 029**/ 030public abstract class ActionMgr 031{ 032protected final SystemLog log; 033protected final Map actionMap; 034 035/** 036Constructs a new ActionMgr 037**/ 038protected ActionMgr() 039 { 040 log = Log.getDefault(); 041 actionMap = new HashMap(); 042 } 043 044/** 045Registers an action. Action names are case <u>insensitive</u>. 046**/ 047public final void addAction(Action action) 048 { 049 //log.entering("ActionMgr", "addAction"); 050 051 String name = action.getName().toLowerCase(); 052 053 if (actionMap.containsKey(name)) { 054 throw new IllegalArgumentException("An action with the name '" + name + " already exists"); 055 } 056 actionMap.put(name, action); 057 058 log.bug("ActionMgr: installed new action=", name); 059 } 060 061/** 062Handles a request from a web client. Expects certain parameters to 063be present in the specified <tt>HttpServletRequest</tt>. The main 064parameter needed by this method is: 065<blockquote> 066<ul> 067 <li>Param name:<tt>act</tt><br> 068 Param value: A case-insenstive class name of the {@link Action} 069 class that will be invoked (for example: "showdir"). Case is not 070 important but using all lower case names will save a few machine 071 cycles. This should match the name with which a particular action 072 object was constructed. 073</ul> 074</blockquote> 075Various actions expect action-specific parameters via the request 076object parameter. This parameters can be set programatically or via 077the web client and optionally, actions can also return results via 078setting them in the request object. The documentation for each action 079method should give more detail. 080 081@throws Exception if the action parameter is missing or not understood 082**/ 083public void handleWebRequest(HttpServletRequest req, HttpServletResponse res) 084throws Exception 085 { 086 log.bug("enter"); 087 if (log.canLog(SystemLog.DEBUG)) { 088 log.bug("requested URL=" + WebUtil.getRequestURL(req), "req=", req); 089 } 090 String actionName = WebUtil.getRequiredParam(req, "act").toLowerCase(); 091 092 Action action = null; 093 if (actionMap.containsKey(actionName)) { 094 action = (Action) actionMap.get(actionName); 095 } 096 else { //action not found 097 log.warn("Could not find action for action=" + action, "installed actions=", actionMap); 098 throw new ServletException("ActionMgr: Could not understand the web request, request=" + req); 099 } 100 101 action.handle(req, res); //the op will extract further params as needed 102 log.bug("exit"); 103 } 104 105public String toString() { 106 return getClass().getName() + "; actions=" + actionMap; 107 } 108 109} //~class ActionMgr