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
006 package fc.web.servlet;
007
008 import java.io.*;
009 import java.util.logging.*;
010 import java.util.*;
011 import javax.servlet.*;
012 import javax.servlet.http.*;
013
014 import fc.io.*;
015 import fc.web.*;
016 import 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 /**
025 Manages various {@link Action} available to a servlet. Subclasses
026 should add and manage appropriate actions.
027
028 @author hursh jain
029 **/
030 public abstract class ActionMgr
031 {
032 protected final SystemLog log;
033 protected final Map actionMap;
034
035 /**
036 Constructs a new ActionMgr
037 **/
038 protected ActionMgr()
039 {
040 log = Log.getDefault();
041 actionMap = new HashMap();
042 }
043
044 /**
045 Registers an action. Action names are case <u>insensitive</u>.
046 **/
047 public 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 /**
062 Handles a request from a web client. Expects certain parameters to
063 be present in the specified <tt>HttpServletRequest</tt>. The main
064 parameter 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>
075 Various actions expect action-specific parameters via the request
076 object parameter. This parameters can be set programatically or via
077 the web client and optionally, actions can also return results via
078 setting them in the request object. The documentation for each action
079 method should give more detail.
080
081 @throws Exception if the action parameter is missing or not understood
082 **/
083 public void handleWebRequest(HttpServletRequest req, HttpServletResponse res)
084 throws 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
105 public String toString() {
106 return getClass().getName() + "; actions=" + actionMap;
107 }
108
109 } //~class ActionMgr