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]>


Reply via email to