webwork/src/main/webwork/dispatcher ServletDispatcher.java,1.37,1.38
[email protected] Thu, 13 Jun 2002 10:18:23 -0700
| Newsgroups | gmane.comp.java.webwork.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/webwork/webwork/src/main/webwork/dispatcher In directory usw-pr-cvs1:/tmp/cvs-serv24270 Modified Files: ServletDispatcher.java Log Message: added action chaining support Index: ServletDispatcher.java =================================================================== RCS file: /cvsroot/webwork/webwork/src/main/webwork/dispatcher/ServletDispatcher.java,v retrieving revision 1.37 retrieving revision 1.38 diff -u -d -r1.37 -r1.38 --- ServletDispatcher.java 30 May 2002 22:58:59 -0000 1.37 +++ ServletDispatcher.java 13 Jun 2002 17:18:20 -0000 1.38 @@ -17,6 +17,7 @@ import webwork.multipart.MultiPartRequestWrapper; import webwork.util.LoggerUtil; import webwork.util.ValueStack; +import webwork.util.BeanUtil; import javax.servlet.RequestDispatcher; import javax.servlet.ServletConfig; @@ -39,6 +40,7 @@ * of the package names in the comma-separated "packages" servlet init parameter. * * @author Rickard Öberg ([email protected]) + * @author Matt Baldree ([email protected]) * @version $Revision$ */ public class ServletDispatcher @@ -155,7 +157,13 @@ } /** - * Service a request + * Service a request. + * The request is first checked to see if it is a multi-part. If it is, then the request + * is wrapped so WW will be able to work with the multi-part as if it was a normal request. + * Next, we will process all actions until an action returns a non-action which is usually + * a view. For each action in a chain, the action's context will be first set and then the + * action will be instantiated. Next, the previous action if this action isn't the first in + * the chain will have its attributes copied to the current action. * * @param aRequest * @param aResponse @@ -168,101 +176,103 @@ aRequest = wrapRequest(aRequest); // Get action - String pathInfo = (String) aRequest.getAttribute("javax.servlet.include.path_info"); - if (pathInfo == null) - pathInfo = aRequest.getPathInfo(); String servletPath = (String) aRequest.getAttribute("javax.servlet.include.servlet_path"); if (servletPath == null) servletPath = aRequest.getServletPath(); - // Get action name ("Foo.action" -> "Foo" action) - final String actionName; - String actionPath = "/"; - int idx = servletPath.lastIndexOf("/"); - actionName = servletPath.substring(idx + 1, servletPath.lastIndexOf(".")); - // Path is always original path, even if it is included in page with another path - actionPath = aRequest.getServletPath(); + String actionPath = aRequest.getServletPath(); actionPath = actionPath.substring(0, actionPath.lastIndexOf("/") + 1); - final Action action; - // Set thread locals so that actions can be initialized properly ActionContext oldContext = ActionContext.getContext(); - try { - ActionContext context = new ActionContext(); - context.setName(actionName); - context.setRequest(aRequest); - context.setResponse(aResponse); - context.setServletContext(getServletContext()); - ActionContext.setContext(context); + try + { + String candidateAction = servletPath; + String actionName = ""; + String result = ""; + Action action = null; + Action prevAction = null; - try { - action = ActionFactory.getAction(actionName); - } catch (Exception e) { - // Log the error - log.error("Could not instantiate action:" + actionName, e); + //--------------- run action chain + while(isAction(candidateAction)) + { + //strip directories and extension + actionName = getActionName(candidateAction); + //set action's context + setActionContext(actionName, aRequest, aResponse); + //instantiate action and set its attributes from context try { - aResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage()); - return; - } catch (IOException ex) { - throw new ServletException(ex); + prevAction = action; + action = ActionFactory.getAction(actionName); + } catch (Exception e) { + // Log the error + log.error("Could not instantiate action:" + actionName, e); + + try { + aResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage()); + return; + } catch (IOException ex) { + throw new ServletException(ex); + } } - } - // Execute action - String result = null; - log.debug("Action:" + actionName); - NDC.push(actionName); - try { - result = action.execute(); - } catch (SecurityException e) { - // Security exception thrown - throw new ServletException("You're not allowed to access the action " + actionName, e); - } catch (ResultException e) { - // Show chosen view - result = (String) e.getResult(); - } catch (Exception e) { - log.debug("Action execution exception", e); - throw new ServletException("System error while executing " + action.getClass(), e); - } finally { - NDC.pop(); - } + //copy previous actions attributes to new action + try { + if (prevAction!=null) { + BeanUtil.copy(prevAction, action); + prevAction = null; + } + } catch (IllegalArgumentException e) { + log.error("Error copying previous action to current action.", e); + throw new ServletException("Unable to copy previous action attributes to current action."); + } - log.debug("Result:" + result); + // Execute action + result = null; + log.debug("Action:" + actionName); + NDC.push(actionName); + try { + result = action.execute(); + } catch (SecurityException e) { + // Security exception thrown + throw new ServletException("You're not allowed to access the action " + actionName, e); + } catch (ResultException e) { + result = (String) e.getResult(); + } catch (Exception e) { + log.debug("Action execution exception", e); + throw new ServletException("System error while executing " + action.getClass(), e); + } finally { + NDC.pop(); + } - // No result - if (result == null) { - log.debug("Action has no result"); - throw new ServletException("System error while executing " + action.getClass()); - } + log.debug("Result:" + result); - // Get view corresponding to result - // Check request override first - String view; - if ((view = aRequest.getParameter(result)) == null) { - try { - view = (String) mapping.getView(actionName, result); - } catch (IllegalArgumentException e) { - // No view found - log.debug("No view found for action " + actionName); + // No result + if (result == null) { + log.debug("Action has no result"); + throw new ServletException("System error while executing " + action.getClass()); } - } + candidateAction = getView(aRequest, actionName, result); + }//while + + //------------ show view + String view = candidateAction; // Only show if a view is assigned to this actions result - if (view != null) { + if (view != null) + { // Show view if (!view.startsWith("/")) view = actionPath + view; // Add path prefix - - try { + try + { log.debug("View:" + view); // Push view name onto NDC NDC.push(view); - RequestDispatcher dispatcher = null; try { dispatcher = aRequest.getRequestDispatcher(view); @@ -304,8 +314,79 @@ } finally { // Reset context. Important if this action was included ActionContext.setContext(oldContext); + }//try + } + + + /** + * Get view corresponding to result of action execution but + * first check servlet request for an override. + * + * @param aRequest The servlet request. + * @param actionName The action name. This includes the full name minus the extension. + * @param result The result from the execution of the action. + * @return String + */ + private String getView(HttpServletRequest aRequest, String actionName, String result) + { + String view = null; + if ((view = aRequest.getParameter(result)) == null) + { + try { + view = (String) mapping.getView(actionName, result); + } catch (IllegalArgumentException e) { + // No view found + e.printStackTrace(); + log.debug("No view found for action " + actionName); + } } + return view; + } + + + /** + * Set action context for action name. + */ + private void setActionContext(String actionName, + HttpServletRequest request, + HttpServletResponse response) + { + ActionContext context = new ActionContext(); + context.setName(actionName); + context.setRequest(request); + context.setResponse(response); + context.setServletContext(getServletContext()); + ActionContext.setContext(context); + } + + + /** + * Determine action name by extracting last string and removing + * extension. (/.../.../Foo.action -> Foo) + */ + private String getActionName(String name) + { + // Get action name ("Foo.action" -> "Foo" action) + int beginIdx = name.lastIndexOf("/"); + int endIdx = name.lastIndexOf("."); + return name.substring((beginIdx==-1 ? 0 : beginIdx + 1), + endIdx==-1 ? name.length() : endIdx); } + + /** + * Is this string an action? Determines if the string + * ends with the action extension which is defined by + * the property "webwork.action.extension" + * + * @param action The string to test + * @return boolean Whether the string is an action + */ + private boolean isAction(String action) + { + return (action==null) ? false : + action.endsWith(Configuration.getString("webwork.action.extension")); + } + /** * Wrap servlet request with the appropriate request. It will check to _______________________________________________________________ Don't miss the 2002 Sprint PCS Application Developer's Conference August 25-28 in Las Vegas - http://devcon.sprintpcs.com/adp/index.cfm?source=osdntextlink