one problem with tiles (or even just includes) and multi app is the need to do a save/restore of the struts request application context variables across includes (does that make sense) an example: have a page in a sub app with a bunch of tiles in, one of the tile's source is an action in a different sub abb. struts goes into the different sub app, changes the app context (and resources etc), does its work and returns. the old sub app context is not restored, making all context relative stuff from then on in the page wrong. is that clear? im not sure.
>>> [EMAIL PROTECTED] 07/18/02 02:22pm >>> Hi, In order to solve some problems encountered with Tiles and multi modules, I have tried to formalize what is the "workflow" of an incoming request sent to an action. Ideally, it should be (from a very high level point of view): http://action.do | V request preprocessing (populate formbean, validate, ...) | V struts action call | V request dispatch (usually to a view rendering page) In Struts, the "request dispatch" block usually takes an ActionForward as parameter and forward to requested URI. This is done in the RequestProcessor.processActionForward(...) method. Formalizing this workflow help to explain how Tiles fit in it. Tiles are mainly rendering views. A tiles can be inserted by using its logical names (the definition name) as URI in an actionForward, or anywhere a path URI could takes place. Tiles insertion is done in the "request dispatch" block: if the URI correspond to a Tiles, this Tiles is inserted. Otherwise, normal Struts mechanism is used (forward to the URI). Struts always follows this workflow, except in some cases ;-(. This is where problems arise. Checking the struts-config.dtd file, I have listed where a path URI could takes place, and then I have check the associated "workflow": * <action ...> ... <forward path="URI" ....> o This is the general mechanism. It end by calling RequestProcessor.processActionForward(...) * <exception path="URI" ....> o This also end by calling RequestProcessor.processActionForward(...) * <action forward="URI" ...> o Dispatching is embedded in processForward(...), o code: String uri = appConfig.getPrefix() + uri; doForward(); * <action include="URI" ....> o Dispatching is embedded in processInclude(...), o code: String uri = appConfig.getPrefix() + uri; doInclude(); * <action input="URI or forwardName" ...> o Dispatching is embedded in processValidate(...) o code: String uri = null; if (appConfig.getControllerConfig().getInputForward()) { ForwardConfig forward = mapping.findForward(input); uri = RequestUtils.forwardURL(request, forward); } else { uri = appConfig.getPrefix() + input; } doForward(uri, request, response); The point to note is that all paths are not process in the same way ! Paths in <forward ...> can be flagged as contextRelative, while path from attribute input/forward/include can't (they are always module relatives). Also, a forward used in attribute "input" doesn't take into account the sendRedirect flag. The attributes "forward" and "include" can only take URI, while "input" can also takes an actionForward name. Question: Do these different behaviors are voluntary, or just a consequence of the growing code ? What I would like to do is to factorize the way paths are processed in one "request dispatch" block. This will help the integration of Tiles, but also the integration of others framework providing rendering views. Tiles, and others tools will subclass the RequestProcessor and override the methods doing the "request dispatch". Typically, Tiles interception should happen before the URI is modified by concatenation of the module prefix. I can put some code everywhere, but it will not be so nice, and not maintainable. Ideally, factorization should be done in one single method (or two: one forward, one include). For example, this can happen by calling processActionForward(..., ActionForward ). This imply that the URI string (from attributes include, forward, input) should be wrapped in an ActionForward object. The advantage is that such URI can in a future release be associated with the same properties than an actionForward, and also that processing is the same for all. An intermediate solution is to have 3 kinds of "request dispatch" blocks : * processActionForward(..., ActionForward ): o Same method as today. Called when we want to forward the request according to actionForward content. * doContextRelativeForward(String uri, request, response) o Called when we want to do a forward to a context relative uri. Method add module prefix to uri and do the forward. * doContextRelativeInclude(...) o Called when we want to do an include to a context relative uri. Method add module prefix to uri and do the include In this solution, the action's attribute "input" will end with a call to processActionForward(...) or a call to doContextRelativeForward(...). This solution avoid the extra creations of actionForward objects. Please send me your comments asap, I experiment the second solution and will be ready to commit it soon. Cedric -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>