Author: pbenedict Date: Mon Aug 28 21:26:25 2006 New Revision: 437956 URL: http://svn.apache.org/viewvc?rev=437956&view=rev Log: STR-2864
Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/action/RequestProcessor.java struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/AbstractPerformInclude.java struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/PerformForward.java struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/PerformInclude.java struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ActionConfig.java struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ForwardConfig.java struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ModuleConfig.java struts/struts1/trunk/core/src/main/java/org/apache/struts/config/impl/ModuleConfigImpl.java struts/struts1/trunk/core/src/main/java/org/apache/struts/util/RequestUtils.java Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/action/RequestProcessor.java URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/action/RequestProcessor.java?rev=437956&r1=437955&r2=437956&view=diff ============================================================================== --- struts/struts1/trunk/core/src/main/java/org/apache/struts/action/RequestProcessor.java (original) +++ struts/struts1/trunk/core/src/main/java/org/apache/struts/action/RequestProcessor.java Mon Aug 28 21:26:25 2006 @@ -364,6 +364,15 @@ String forwardPath = forward.getPath(); String uri; + // If the forward can be unaliased into an action, then use the path of the action + String actionIdPath = RequestUtils.actionIdURL(forward, request, servlet); + if (actionIdPath != null) { + forwardPath = actionIdPath; + ForwardConfig actionIdForward = new ForwardConfig(forward); + actionIdForward.setPath(actionIdPath); + forward = actionIdForward; + } + // paths not starting with / should be passed through without any // processing (ie. they're absolute) if (forwardPath.startsWith("/")) { @@ -545,6 +554,12 @@ return (true); } + // If the forward can be unaliased into an action, then use the path of the action + String actionIdPath = RequestUtils.actionIdURL(forward, this.moduleConfig, this.servlet); + if (actionIdPath != null) { + forward = actionIdPath; + } + internalModuleRelativeForward(forward, request, response); return (false); @@ -571,6 +586,12 @@ if (include == null) { return (true); + } + + // If the forward can be unaliased into an action, then use the path of the action + String actionIdPath = RequestUtils.actionIdURL(include, this.moduleConfig, this.servlet); + if (actionIdPath != null) { + include = actionIdPath; } internalModuleRelativeInclude(include, request, response); Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/AbstractPerformInclude.java URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/AbstractPerformInclude.java?rev=437956&r1=437955&r2=437956&view=diff ============================================================================== --- struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/AbstractPerformInclude.java (original) +++ struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/AbstractPerformInclude.java Mon Aug 28 21:26:25 2006 @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright 2003-2005 The Apache Software Foundation. + * Copyright 2003-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,7 +39,6 @@ */ public boolean execute(ActionContext actionCtx) throws Exception { - ModuleConfig moduleConfig = actionCtx.getModuleConfig(); // Is there an include to be performed? String include = actionCtx.getInclude(); @@ -49,7 +48,7 @@ } // Determine the currect uri - String uri = moduleConfig.getPrefix() + include; + String uri = includePath(actionCtx, include); // Perform the appropriate processing on this include uri perform(actionCtx, uri); @@ -59,6 +58,19 @@ // ------------------------------------------------------- Protected Methods + /** + * <p>Returns the path to perform the include. Override this method to provide + * a different path.</p> + * + * @param actionContext The context for this request + * @param include The forward to be performed + * @since Struts 1.3.6 + */ + protected String includePath(ActionContext actionContext, String include) { + ModuleConfig moduleConfig = actionContext.getModuleConfig(); + return moduleConfig.getPrefix() + include; + } + /** * <p>Perform the appropriate processing on the specified include * uri.</p> Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/PerformForward.java URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/PerformForward.java?rev=437956&r1=437955&r2=437956&view=diff ============================================================================== --- struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/PerformForward.java (original) +++ struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/PerformForward.java Mon Aug 28 21:26:25 2006 @@ -69,6 +69,15 @@ ServletContext servletContext = sacontext.getContext(); HttpServletResponse response = sacontext.getResponse(); + // If the forward can be unaliased into an action, then use the path of the action + String actionIdPath = RequestUtils.actionIdURL(forwardConfig, sacontext.getRequest(), sacontext.getActionServlet()); + if (actionIdPath != null) { + uri = actionIdPath; + ForwardConfig actionIdForwardConfig = new ForwardConfig(forwardConfig); + actionIdForwardConfig.setPath(actionIdPath); + forwardConfig = actionIdForwardConfig; + } + if (uri.startsWith("/")) { uri = resolveModuleRelativePath(forwardConfig, servletContext, request); } Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/PerformInclude.java URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/PerformInclude.java?rev=437956&r1=437955&r2=437956&view=diff ============================================================================== --- struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/PerformInclude.java (original) +++ struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/PerformInclude.java Mon Aug 28 21:26:25 2006 @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 The Apache Software Foundation. + * Copyright 2003-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import org.apache.struts.chain.commands.AbstractPerformInclude; import org.apache.struts.chain.contexts.ActionContext; import org.apache.struts.chain.contexts.ServletActionContext; +import org.apache.struts.util.RequestUtils; import javax.servlet.RequestDispatcher; import javax.servlet.http.HttpServletRequest; @@ -48,5 +49,16 @@ RequestDispatcher rd = swcontext.getContext().getRequestDispatcher(uri); rd.forward(request, swcontext.getResponse()); + } + + protected String includePath(ActionContext actionContext, String include) { + ServletActionContext swcontext = (ServletActionContext) actionContext; + String actionIdPath = RequestUtils.actionIdURL(include, swcontext.getModuleConfig(), swcontext.getActionServlet()); + if (actionIdPath != null) { + return super.includePath(actionContext, actionIdPath); + } else { + return super.includePath(actionContext, include); + } + } } Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ActionConfig.java URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ActionConfig.java?rev=437956&r1=437955&r2=437956&view=diff ============================================================================== --- struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ActionConfig.java (original) +++ struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ActionConfig.java Mon Aug 28 21:26:25 2006 @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,6 +70,8 @@ /** * <p>The internal identification of this action mapping. Identifications are * not inheritable and must be unique within a module.</p> + * + * @since Struts 1.3.6 */ protected String actionId = null; @@ -220,7 +222,9 @@ * as a shortcut in a URI. For example, an action with an identification of "editPerson" * may be internally forwarded as "editPerson?id=1" which will then resolve to the * real URI path at execution time.</p> + * * @return the actionId + * @since Struts 1.3.6 */ public String getActionId() { return this.actionId; @@ -229,7 +233,9 @@ /** * <p>The internal name of this action mapping. The name is not inheritable, * and must be unique within a module. </p> + * * @param actionId the action identifier + * @since Struts 1.3.6 */ public void setActionId(String actionId) { if (configured) { @@ -1171,10 +1177,10 @@ sb.append("cancellable="); sb.append(cancellable); - sb.append("path="); + sb.append(",path="); sb.append(path); - sb.append("validate="); + sb.append(",validate="); sb.append(validate); if (actionId != null) { Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ForwardConfig.java URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ForwardConfig.java?rev=437956&r1=437955&r2=437956&view=diff ============================================================================== --- struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ForwardConfig.java (original) +++ struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ForwardConfig.java Mon Aug 28 21:26:25 2006 @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -146,6 +146,18 @@ setPath(path); setRedirect(redirect); setModule(module); + } + + /** + * <p>Construct a new instance based on the values of another + * ForwardConfig.</p> + * + * @param copyMe A ForwardConfig instance to copy + * @since Struts 1.3.6 + */ + public ForwardConfig(ForwardConfig copyMe) { + this(copyMe.getName(), copyMe.getPath(), copyMe.getRedirect(), + copyMe.getModule()); } public String getExtends() { Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ModuleConfig.java URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ModuleConfig.java?rev=437956&r1=437955&r2=437956&view=diff ============================================================================== --- struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ModuleConfig.java (original) +++ struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ModuleConfig.java Mon Aug 28 21:26:25 2006 @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -186,6 +186,17 @@ * none, a zero-length array is returned. </p> */ ActionConfig[] findActionConfigs(); + + /** + * <p>Returns the action configuration for the specifed action + * action identifier.</p> + * + * @param actionId the action identifier + * @return the action config if found; otherwise <code>null</code> + * @see ActionConfig#getActionId() + * @since Struts 1.3.6 + */ + ActionConfig findActionConfigId(String actionId); /** * <p> Return the exception configuration for the specified type, if any; Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/config/impl/ModuleConfigImpl.java URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/config/impl/ModuleConfigImpl.java?rev=437956&r1=437955&r2=437956&view=diff ============================================================================== --- struts/struts1/trunk/core/src/main/java/org/apache/struts/config/impl/ModuleConfigImpl.java (original) +++ struts/struts1/trunk/core/src/main/java/org/apache/struts/config/impl/ModuleConfigImpl.java Mon Aug 28 21:26:25 2006 @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright 1999-2005 The Apache Software Foundation. + * Copyright 1999-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,6 +64,12 @@ * the <code>path</code> property.</p> */ protected HashMap actionConfigs = null; + + /** + * <p>The set of action configuration for this module, if any, keyed by + * the <code>actionId</code> property.</p> + */ + protected HashMap actionConfigIds = null; /** * <p>The set of action configurations for this module, if any, listed in @@ -160,6 +166,7 @@ super(); this.prefix = prefix; this.actionConfigs = new HashMap(); + this.actionConfigIds = new HashMap(); this.actionConfigList = new ArrayList(); this.actionFormBeanClass = "org.apache.struts.action.ActionFormBean"; this.actionMappingClass = "org.apache.struts.action.ActionMapping"; @@ -276,13 +283,30 @@ throwIfConfigured(); config.setModuleConfig(this); - String key = config.getPath(); - - if (actionConfigs.containsKey(key)) { - log.warn("Overriding ActionConfig of path " + key); + String path = config.getPath(); + if (actionConfigs.containsKey(path)) { + log.warn("Overriding ActionConfig of path " + path); + } + + String actionId = config.getActionId(); + if ((actionId != null) && !actionId.equals("")) { + if (actionConfigIds.containsKey(actionId)) { + if (log.isWarnEnabled()) { + ActionConfig otherConfig = (ActionConfig) actionConfigIds.get(actionId); + StringBuffer msg = new StringBuffer("Overriding actionId["); + msg.append(actionId); + msg.append("] for path["); + msg.append(otherConfig.getPath()); + msg.append("] with path["); + msg.append(path); + msg.append("]"); + log.warn(msg); + } + } + actionConfigIds.put(actionId, config); } - actionConfigs.put(key, config); + actionConfigs.put(path, config); actionConfigList.add(config); } @@ -413,6 +437,22 @@ } return config; + } + + /** + * <p>Returns the action configuration for the specifed action + * action identifier.</p> + * + * @param actionId the action identifier + * @return the action config if found; otherwise <code>null</code> + * @see ActionConfig#getActionId() + * @since Struts 1.3.6 + */ + public ActionConfig findActionConfigId(String actionId) { + if (actionId != null) { + return (ActionConfig) this.actionConfigIds.get(actionId); + } + return null; } /** Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/util/RequestUtils.java URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/util/RequestUtils.java?rev=437956&r1=437955&r2=437956&view=diff ============================================================================== --- struts/struts1/trunk/core/src/main/java/org/apache/struts/util/RequestUtils.java (original) +++ struts/struts1/trunk/core/src/main/java/org/apache/struts/util/RequestUtils.java Mon Aug 28 21:26:25 2006 @@ -32,6 +32,7 @@ import org.apache.struts.upload.MultipartRequestHandler; import org.apache.struts.upload.MultipartRequestWrapper; +import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @@ -262,6 +263,18 @@ return (instance); } + + /** + * <p>Retrieves the servlet mapping pattern for the specified [EMAIL PROTECTED] ActionServlet}.</p> + * + * @return the servlet mapping + * @see Globals#SERVLET_KEY + * @since Struts 1.3.6 + */ + public static String getServletMapping(ActionServlet servlet) { + ServletContext servletContext = servlet.getServletConfig().getServletContext(); + return (String)servletContext.getAttribute(Globals.SERVLET_KEY); + } /** * <p>Look up and return current user locale, based on the specified @@ -955,5 +968,99 @@ serverUri.append(uri); return serverUri; + } + + /** + * <p>Returns the true path of the destination action if the specified forward + * is an action-aliased URL. This method version forms the URL based on + * the current request; selecting the current module if the forward does not + * explicitly contain a module path.</p> + * + * @param forward the forward config + * @param request the current request + * @param servlet the servlet handling the current request + * @return the context-relative URL of the action if the forward has an action identifier; otherwise <code>null</code>. + * @since Struts 1.3.6 + */ + public static String actionIdURL(ForwardConfig forward, HttpServletRequest request, ActionServlet servlet) { + ModuleConfig moduleConfig = null; + if (forward.getModule() != null) { + String prefix = forward.getModule(); + moduleConfig = ModuleUtils.getInstance().getModuleConfig(prefix, servlet.getServletContext()); + } else { + moduleConfig = ModuleUtils.getInstance().getModuleConfig(request); + } + return actionIdURL(forward.getPath(), moduleConfig, servlet); + } + + /** + * <p>Returns the true path of the destination action if the specified forward + * is an action-aliased URL. This method version forms the URL based on + * the specified module. + * + * @param originalPath the action-aliased path + * @param moduleConfig the module config for this request + * @param servlet the servlet handling the current request + * @return the context-relative URL of the action if the path has an action identifier; otherwise <code>null</code>. + * @since Struts 1.3.6 + */ + public static String actionIdURL(String originalPath, ModuleConfig moduleConfig, ActionServlet servlet) { + if (originalPath.startsWith("http") || originalPath.startsWith("/")) { + return null; + } + + // Split the forward path into the resource and query string; + // it is possible a forward (or redirect) has added parameters. + String actionId = null; + String qs = null; + int qpos = originalPath.indexOf("?"); + if (qpos == -1) { + actionId = originalPath; + } else { + actionId = originalPath.substring(0, qpos); + qs = originalPath.substring(qpos); + } + + // Find the action of the given actionId + ActionConfig actionConfig = moduleConfig.findActionConfigId(actionId); + if (actionConfig == null) { + if (log.isDebugEnabled()) { + log.debug("No actionId found for " + actionId); + } + return null; + } + + String path = actionConfig.getPath(); + String mapping = RequestUtils.getServletMapping(servlet); + StringBuffer actionIdPath = new StringBuffer(); + + // Form the path based on the servlet mapping pattern + if (mapping.startsWith("*")) { + actionIdPath.append(path); + actionIdPath.append(mapping.substring(1)); + } else if (mapping.startsWith("/")) { // implied ends with a * + mapping = mapping.substring(0, mapping.length() - 1); + if (mapping.endsWith("/") && path.startsWith("/")) { + actionIdPath.append(mapping); + actionIdPath.append(path.substring(1)); + } else { + actionIdPath.append(mapping); + actionIdPath.append(path); + } + } else { + log.warn("Unknown servlet mapping pattern"); + actionIdPath.append(path); + } + + // Lastly add any query parameters (the ? is part of the query string) + if (qs != null) { + actionIdPath.append(qs); + } + + // Return the path + if (log.isDebugEnabled()) { + log.debug(originalPath + " unaliased to " + actionIdPath.toString()); + } + return actionIdPath.toString(); } }