OK, I've assigned myself the following bugzilla ticket: http://nagoya.apache.org/bugzilla/show_bug.cgi?id=16603
and am trying to decide how to deal with it. I think I understand what the reporter (cc'd above) is proposing. What's not clear is whether we should make any change now, or perhaps ever. I'd like to discuss that here before deciding. Background: ---------- For a while now, we have supported the "forwardPattern" and "pagePattern" properties on the ControllerConfig object. These patterns support certain substitutions so that you can, for example, declare that you want your JSP pages under /WEB-INF so that they can be accessible only via RequestDispatcher.forward() calls. Example scenario (assume a module prefix of "/mymodule"): <global-forwards> ... <forward name="Main Menu" path="/mainmenu.jsp" contextRelative="false"/> ... </global-forwards> <controller ... forwardPattern="/WEB-INF/pages$M$P" .../> If an Action returns the "Main Menu" ActionForward (nee ForwardConfig) object, the request procesor will ultimately call RequestUtils.forwardURL() to calculate the context-relative path of "/WEB-INF/pages/mymodule/mainmenu.jsp". If no forward pattern had been specified, the default mechanism would have returned "/mymodule/mainmenu.jsp" instead. So far, so good. Now we've got a way to "globally redirect" the URLs within a module, without having to modify all of the individual paths in our forward directives. The problem pointed out by the Bugzilla ticket, though, is that we do not respect forwardPattern universally; it is *only* used in the scenario described above, plus in a couple of other special cases. Other Potential Remapping Scenarios: ----------------------------------- Scanning the code for the core Struts controller (I didn't check the Tiles request processor, but suspect it might have similar issues), there are several other scenarios where one might argue that the remapping through the specified forwardPattern would make sense. The ones I found are as follows, numbered for reference in later discussion: (1) <action ... forward="/foo" .../> Tells request processor to handle this request by performing a RequestDispatcher.forward() to the specified "module-relative path of the servlet or other resource that will process this request", instead of invoking an Action. This path is not currently processed by any specified "forwardPattern", instead a pattern of "$M$P" is assumed. (2) <action ... include="/foo" .../> Tells request processor to handle this request by performing a RequestDispatcher.include() to the specified "module-relative path of the servlet or other resource that will process this request", instead of invoking an Action. This path is not currently processed by any specified "forwardPattern", instead a pattern of "$M$P" is assumed. (3) <action ... input="/foo" .../> There are actually two subcases here, depending on the state of the "inputForward" property of our module's ControllerConfig: (3a) <controller ... inputForward="true" .../> The value of the "input" property is treated as the name of a local or global ForwardConfig, which is then processed through the forwardPattern remapping just like an ActionForward returned from an Action would be. (3b) <controller ... inputForward="false" .../> The value of the "input" property is treated as the "module-relative path of the action or other resource to which control should be returned if the form bean returns validation errors. This path is not currently processed by any specified "forwardPattern", instead a pattern of "$M$P" is assumed. Note that 3b is the default for backwards compatibility: (4) <action ... path="/foo" .../> This is the module-relative path that is used to match a request to a particular action. It is not currently mapped through any specified "forwardPattern", instead a pattern of "$M$P" is assumed. (5) <exception ... path="/foo" .../> This is the module-relative path of the resource that should complete this request/response if an Action throws an exception of the specified type. Whether remapping occurs or not is up to the ExceptionHandler that is invoked; the default implementation constructs an ActionForward based on this path (but sets the contextRelative property, which looks like a bug but isn't related to the issue at hand here), which will get processed through the "forwardPattern" remapping if we fixed the contextRelative bug. So, we currently do the remapping in case (3b), and ought to be doing it in case (5). But what about the other scenarios? Analysis: -------- The underlying issue is that we have fallen into the (bad, but that's hindsight for you) habit of using ActionForward instances to point at (at least) three very different kinds of things: (a) The view tier component that should actually render the response (typically a JSP page) (b) The next action to execute, if you are doing action chaining (c) The "application resource" that should handle a thrown exception from an action (which could be a view tier component, an arbitrary servlet, or an action) The original intent of "forwardPattern" was to cover case (a) only, because it was (in theory) only the view tier components that you'd want to redirect for (i.e. to put JSP pages under /WEB-INF, or otherwise remap the set of view components for a particular module). Case (b) seems like it should NOT be mapped, for consistency with how case (4) is handled (mapping the original request to the original action in the first place). Case (c) should probably be remapped if it's a view component, but not if it's an action. But there is nothing about an ActionForward that lets you unambiguously determine whether it points at a view component or not. :-( Recommendation: -------------- If we were not imminently trying to release a 1.1 final, I would be tempted to design and work out a strategy for dealing with this ambiguity problem, and hash out what the right behavior should be in each case. However, at this point in time, I'm going to suggest that we resolve this one as LATER and put it into the "1.2 Family" camp. We're going to need to deal with it in a 1.2 time frame anyway, especially if we try to implement any sort of "module configuration inheritance" mechanisms, which are only going to make the problem worse. In a 2.0 time frame, the lesson I draw from this is that we will want to be very specific in defining how mapping of logical paths to physical paths is performed, including a way to distinguish what kind of logical path you're talking about (so that you can apply different rules for view components and for action components, for example). Does this sound like a plan that we (committers) can agree to? Craig --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]