On 12/27/05, Craig McClanahan <[EMAIL PROTECTED]> wrote:
>
> A recent RFE[1] in our issue tracking system, plus discussions with
> several
> folks at the recently completed ApacheCon US conference in San Diego, has
> motivated me to attempt a distillation of where I think Shale's support
> for
> "remoting" should go. For comparision (since there isn't any
> feature-related documentation to speak of), I'll start with a brief
> description of the current functionality, and then talk about what seems
> like a good idea for the future.
>
>
> CURRENT REMOTING FUNCTIONALITY:
>
> Shale's application level functionality is supplied by a Servlet filter (
> org.apache.shale.faces.ShaleApplicationFilter). One of the features of
> this
> filter is that it executes a standard Commons Chain[2] chain of commands
> for
> each request. In turn, the default chain that is executed includes a
> command (org.apache.shale.remote.RemoteCommand) that is invoked if the
> request URL matches an extension mapping (default is "*.remote"). In
> turn,
> this command performs the following tasks:
>
> * Creates a ShaleWebContext instance (extension of Commons Chain
> ServletWebContext implementation)
> to represent the "context" passed to each command.
>
> * Extracts the context relative path such as "/foo/bar.remote" from the
> servlet request path properties.
>
> * Looks for a corresponding Commons Chain command in a catalog named
> "remote". If there is such a
> command, invoke it (passing in the constructed ShaleWebContext). This
> command is responsible for
> constructing a response, which can be done by the usual
> RequestDispatcher.forward() call -- normally
> to a JSP page that might use JSTL and EL expressions -- or programmatic
> construction via an
> instance of org.apache.shale.remote.ResponseWrapper that acts much like
> a
> standard JSF ResponseWriter.
>
> * Several default command implementations are provided, including one that
> invokes an arbitrary JSF
> value binding expression and stores the result as a ShaleWebContext
> attribute.
>
> While this functionality does support achieving the original goal of this
> portion of Shale (providing back-end support for AJAX enabled JSF
> components), it has several issues, including:
>
> * Bound to Servlet API objects, so not directly portable to a portlet
> environment.
>
> * As described in [1], requires quite a lot of work (plus an understanding
> of
> Commons Chain itself) simply to map an incoming URL to a piece of
> business
> logic that produces the response.
>
> * Does not directly support serving of static resources (images,
> JavaScript
> files,
> stylesheets) without mapping each individual resource as an individual
> command.
>
>
> PROPOSED REMOTING FUNCTIONALITY - GOALS:
>
> The remoting support in Shale should be focused on providing
> client-technology-agnostic mapping of incoming HTTP requests to server
> side
> dynamic logic for AJAX-enabled widgets (including AJAX-enabled JavaServer
> Faces components), plus an easy way to serve static resources (from either
> the web application itself or from class loader resources) that the client
> side widgets might require. This support must operate in either a servlet
> or portlet environment, and require minimal (ideally none in the simplest
> case) configuration at the application level.
>
>
> PROPOSED REMOTING FUNCTIONALITY - IMPLEMENTATION STRATEGY:
>
> Shale will provide a PhaseListener implementation that receives
> notification
> after the Restore View phase of the request processing lifecycle has been
> completed. At this point, a "view identifier" (a context-relative path to
> the resource to be processed) will have been identified. This view
> identiifer will be compared to one or more preregistered mapping patterns
> --
> if the view identifier matches, this request will be processed by a
> corresponding processing logic module, instead of following the usual JSF
> request processing lifecycle.
>
> Registering processing logic modules will be easy and extensible. To
> minimize the effort required to assemble an application, however, the
> following standard processing logic modules will be provided:
>
> * Serve a static resource corresponding to this view identifier, from the
> web application's
> static resources (i.e. starting from the document root). To be
> consistent
> with a servlet
> container's standard behavior, no such resources will be served directly
> from the "/WEB-INF"
> or "/META-INF" paths.
I'm not sure I understand why I would want to use this. Requests for static
content such as this would be processed more efficiently by letting the
container treat them as static content - or, even better for a high load
app, moving these files off the web container completely, and into a
fronting HTTP server.
* Serve a static resource corresponding to this view identifer, from the
> class loader resources
> of this web application. For example, this facilitates component
> libraries that wish to make
> JavaScript files available to the client pages that utilize those
> components, without requiring
> *any* specific configuration in web.xml, or manual assembly of resources
> into a reserved
> directory of the web application.
While I do understand how this would simplify the deployment of components,
again performance will suffer if this is used extensively. Perhaps there
could be some way to have components extract their static resources at
startup time, so that they could subsequently be treated as static by the
web container? Such resources would be harder to deploy to a fronting HTTP
server, but not impossible if a suitable extraction method can be defined.
But perhaps that would have to be dealt with in the JSF spec.
--
Martin Cooper
* Map the view identifier (such as "/foo/bar.remote") to a method binding
> expression (such as
> "#{foo.bar}"), identifying a public method that will be invoked to
> create
> the response for this
> HTTP request. The bean containing this method can be a managed bean,
> and
> thus created
> on demand if needed. The method itself can call
> FacesContext.getCurrentInstance() to retrieve
> the per-request state information for this request (since we are, by
> defnition, performing a JSF
> request at this point), and can use any desired JSF facilities
> (including
> the standard ResponseWriter)
> to prepare the actual response.
>
> * (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).
>
> * (Optional) alternative dynamic execution mapping to execute an XWork
> action (essentially
> equivalent to what WebWork currently does for mapping incoming URLs to
> business logic).
>
> In addition, the configuration information mapping incoming URL patterns
> to
> corresponding processing logic modules will be made available in a simple
> JavaBean stored in application scope, so that dynamic code (such as the
> renderer for a JSF component wanting to utilize these facilities) will
> know
> what kind of context relative URL is required).
>
> Given these capabilities, and assuming some default mappings, one could
> have
> all of the following facilities with *zero* application level
> configuration,
> other than including the appropriate Shale library into /WEB-INF/lib:
>
> * For a context relative URL of the form "/web/foo/bar.js", serve the
> static
> resource at "/foo/bar.js"
> with appropriate content type settings.
>
> * For a context relative URL of the form "/classpath/foo/bar.css", serve
> the
> resource "/foo/bar.css"
> from the webapp classpath (typically, a resource file embedded in the
> JAR
> file containing the
> component whose renderer requested this resource), with appropriate
> content type settings.
>
> * 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.
>
>
> SUMMARY:
>
> Thoughts?
>
> Craig
>
> [1] http://issues.apache.org/bugzilla/show_bug.cgi?id=38050
> [2] http://jakarta.apache.org/commons/chain/
>
>