struts-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Craig McClanahan <craig...@gmail.com>
Subject Re: [shale] Re: Struts Shale
Date Fri, 21 Jan 2005 16:50:55 GMT
(Note - since viewcvs is currently not working against the SVN
repository, I've posted the original Shale proposal directly at:

  http://www.apache.org/~craigmcc/struts-shale-README.html

It has details relevant to the questions below.)


On Fri, 21 Jan 2005 08:05:31 -0600, David Suarez
<Suarez.David@jobcorps.org> wrote:
> I've been watching this conversation from the sidelines.  I see in the email description
below the purpose of the new "Dialog" object:
> 
> 1.
> >> To me, the lifetime of the state information is the key
> >> distinguishing feature to this gadget -- so if we don't like
> >> "dialog" then maybe some name around that idea would be more
> >> appropriate.
> 
> Are there any other things that make this object unique?  Are there current examples
of how it would be set up or used?  I was thinking about how this idea would be implemented
if #1 was the only requirement and came up with the following.  I hope it adds value to the
discussion.

It's not the only requirement, but it is a a key one.

> 
> I took a look at the DialogController Shale source and it seems that the methods are
defined via "code" but the goal is essentially to replicate session at a smaller level.  If
this is the only case (and I may be way off base here) why not introduce a mock "session"
object so that the actions/etc are none the wiser.  The end of a dialog would be defined by
some "final" action that would clean up the session so the Cancel/Complete wouldn't matter.
 Here's some pseudo-code to show what I was thinking:
> 
>         // I have no clue on Shale config so this is basically a struts example that
would need to be modified for the equivalents in Shale
>         <action
>             path="/action/rates/GetAutoRateQuote"
>             type="com.xxx.xxx.StartAutoRateQuote"
>             name="formName"
>             dialogName="dialogName"  /* THIS WOULD BE HOW MULTIPLE ACTIONS CAN BE GROUPED
AS A DIALOG" */
>             validate="false">
>             <forward name="success" path="/jsp/path/thejsp.jsp"/>
>         </action>
> 
> At the server you check if a dialogName exists, if so then it's a dialog.  If that dialog
is not currently in existence, then create a session space for it:
> 
>         if(session.getActiveDialogs().get(dialogName)==null){ //no session with that
name exists
>                 webSession = session; // Just to illustrate that this is the "REAL" session
>                 dialogSession = new dialogSession(session); // session is passed so the
user can use the same session life-cycle methods on a mini scale and it has a reference to
the "real" session object as needed to look up objects.  If it is not found in dialog session
it can then check "real" session
>                 webSession.set(DIALOGSESSION+"_"+dialogName, dialogSession);   //Give
the dialog session a spot in the real session
>         }
>         //The call to the action/dialog in this case would pass the dialogSession instead
of the real session in this case.  So a call to session.invalidate() would just remove the
dialog from the real session.
> 

JSF has a facility called "managed beans" which does something like
what Struts does for form beans (create them on demand if necessary),
but more general -- in the course of evaluating any value binding or
method binding expression, if the first element of the expression is
not found in request/session/application scope, it tries to create
such a bean.  Therefore, JSF handles all the grunt work about getting
the DialogController instance created, and installed in session scope,
with no extra work needed by the framework or the application.

In the struts-shale-usecases example app, you can see how this works. 
There is a managed bean declaration for the dialog controller for the
logon dialog:

    <managed-bean>
        <managed-bean-name>logon$dialog</managed-bean-name>
        <managed-bean-class>org.apache.shale.usecases.logon.Dialog</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
        ... also configures some properties here ...
    </managed-bean>

Thus, if you click the hyperlink to enter the logon dialog from the main menu:

    <h:commandLink action="#{logon$dialog.enter}">
        <h:outputText value="#{messages['usecases.logon']}"/>
    </h:commandLink>

JSF will notice that no bean named "logon$dialog" exists ... so it
creates one for you.

The interesting part is getting it back out again, though :-)

> Maybe there are other goals for dialog that I am not aware of that this would not work
for.  I think the above would essentially make a struts app a series of dialogs for the most
part except probably the login/logout and other universal functions.  Of course the naming
above would be confusing as hell so you'd probably want to use better names in the "execute"
type method so the user doesn't think they're working with a session.  Maybe a name like "Scope",
so you're passed a scope as part of the execute method to make it clear that any of the work
you do is limited to whatever the configuration scope is (handled as part of config).

Yes, I would envision that large portions of a Shale-based application
woud be organized as a set of dialogs -- and you'd be able to "nest"
them, by starting one dialog, calling into another, and returning to
where you were.  More info on the original thinking is in the Shale
proposal at the hyperlink above.

> 
> Please advise how this may or may not suit your needs.  I hope I'm not 100% off-base
here.

In general, JSF is architected differently than Struts in that you
don't pass a whole bunch of arguments in to an execute method. 
Instead, event handlers can ask for the context of the current request
if they need it:

    FacesContext context = FacesContext.getCurrentInstance();

or the context object will be passed in.  Therefore, mocking doesn't
really help, unless you want to mock a complete FacesContext
(technically feasible, but quite a bit of work).

However, your discussion DID trigger a thought of how to implement the
cleanup more elegantly.  It turns out that the JSF logic that does the
managed bean trick is a pluggable API (VariableResolver).  I can add a
gadget that, if the new bean is indeed a DialogController, then call a
property setter on it, telling this instance what name it was stored
under.  Then, the instance can just use that name when it wants to
clean itself up.

For that little inspiriation, thank you!

> 
> Regards...djsuarez
> 

Craig

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org


Mime
View raw message