struts-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Craig McClanahan <>
Subject Re: [shale] Overall requirements for "remoting" feature
Date Mon, 02 Jan 2006 01:56:25 GMT
On 1/1/06, Sean Schofield <> wrote:
> > * (Optional) alternative dynamic execution mapping to execute a Commons
> > Chain command
> >   (essentially equivalent to the current functionality, and/or a tie-in
> to
> > Struts Action Framework 1.3.x
> >   type processing logic).
> David has some good points about Chain being a bit of overkill.  I
> didn't have much problem with it but then again I'm pretty familiar
> with Shale and Chain.  And when you think about it, he's right.  A lot
> of situations don't really call for a complex chain.
> Having the *option* to call a chain sounds interesting.  Can you give
> an example of the URL and the naming conventions here?

My general thinking (it's almost done getting coded up) is that a new JSF
PhaseListener would gain control at After Restore View (i.e. when the view
id has been set into the UIViewRoot component, but it's recognized that
there is no state to restore).  Assume we've got FacesServlet mapped to
"*.faces" as usual.  Next, the phase listener would apply another level of
mapping (either prefix or suffix) to pick a "processor" that will take
responsibility for producing all of the output for this response (if no
processor is selected, the request is handled as usual by JSF).  Now, assume
we have mappings like this for some sample processors:

* "/chain/*" maps to a processor that treats the remainder of the URL
  as the name of a Commons command or chain.  It sets up a
  ShaleWebContext and executes the command, like the current
  remote support does.  Amusingly, I'll bet the URLs would be
  identical to today's version if this were mapped to "*.remote"
  instead of "/chain/*".

* "/execute/*" maps to a processor that treats the remainder of the
  URL as a method binding (after doing the syntax transformation
  described below).  This is the easier-to-use thing David is asking for.

* "/webapp/*" maps to a processor that treats the remainder of the
  URL as a path to a class loader resource accessed via the webapp
  class loader (i.e. from WEB-INF/classes or a jar in WEB-INF/lib.

Of course, the scheme should be extensible, and the mappings flexible ...
although we'll probably want to apply a bit of "convention over
configuration" and supply some default mappings if the developer does not.
Given the default mappings above, then, the following URLs would get handled
as follows:

* http://localhost:8080/myapp/index.faces

  Normal JSF handling (no processor mapping matches this)

* http://localhost:8080/myapp/chain/list/stateNames.faces

  Execute the "/list/stateNames" chain from the Use Cases example

* http://localhost:8080/myapp/execute/foo/bar.faces

  Form a method binding expression "#{} and execute it, (optionally)
  loading a managed bean and then executing a method.  The method
  can call FacesContext.getCurrentInstance() because this really is a
  JSF request, do value binding evaluation, and use whatever mechanism
  it wants to produce the output (including the usual JSF ResponseWriter
  that renderers use).


  Return static resource org/apache/shale/usecases/view/
  (which happens to be in WEB-INF/classes of the use cases example app).
  The same processor could easily extract static resources from a jar file
  in WEB-INF/lib, perfect for cases like a JSF component that wanted to
  provide a stylesheet or JavaScript resource without making the developer
  independently extract and package that resource under the document root.

The key ingredient is that the request match the FacesServlet mapping (so
that the JSF lifecycle gets invoked, and therefore our phase listener is
involved), *and* that the calculated view identifier is then mapped again to
potential processor modules that will interrupt the normal lifecycle and
take responsibility for the output.  If no processor is found, it's handled
as usual.


> > * For a context relative URL of the form "/execute/foo/bar", execute the
> > bar() method on the managed
> >   bean named "foo".  This method will take total responsibility for
> > producing the output, so it can do
> >   whatever it needs.
> I like it.  This would be very handy indeed.
> > Craig
> Sean
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:
> For additional commands, e-mail:

  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message