That's an interesting idea - I had not tried to set up
a framework that could be used both with a web- and
a swing-frontend... maybe because I rarely use Swing.
Best,
Ph.
On Tuesday 03 September 2002 11:06, James Higginbotham wrote:
> Interesting.. You've take a similar approach to what I've done in the
> past, with some caching of the Methodsthat I didn't do.. Here is what I
> did in text form (no diags available right now):
>
> Create a base action class that implements the perform() method and
> offers an abstract method handleRequest( UserRequest ) that the subclass
> must implement. UserRequest is created and populated in the perform()
> and has things like the request, response, and other needed references.
> It also offers methods to replace the request.getParameter() and
> request.getAttribute(), like: userRequest.getParameter( key, default ),
> userRequest.getAttribute( key, default ), and userRequest.getFormBean().
> This allows me to later adapt the action subclass to work from within a
> unit test or swing application (if the pages map to panels the same)
> without binding the concrete action class to HTTP. I've always believed
> that this abstraction would have been helpful in Struts, even though the
> action is the HTTP glue - its easy and just makes sense, since we mostly
> need access to a HashMap rather than anything HTTP specific anyway. I
> know mock objects are out there for testing struts and I've used them -
> very nice!
>
> The next thing I did was to extend this base action class into a
> WizardAction and implement the new handleRequest() method to look for a
> predefined button name that is used to construct a dynamic method call..
> So, if the button pressed was 'create', then it would call
> processCreateEvent(UserRequest request). Same goes for things like Next,
> Back, Cancel, and other types of multi-button forms. This allows me to
> remove large if or switch statements to determine which button was
> pressed and tackle that logic should I want 1 action for multiple
> buttons on a page.
>
> I can't wait until JDK 1.5 where we can start attaching metadata to a
> method and get to it via runtime calls (ala C#), which would allow me to
> tag a method with its required roles and have the code find those roles
> and do the checks - no more XML config -> whatever mapping files and no
> more custom access control methods!
>
> James
>
> > -----Original Message-----
> > From: Philipp K. Janert [mailto:[EMAIL PROTECTED]]
> > Sent: Tuesday, September 03, 2002 9:48 AM
> > To: [EMAIL PROTECTED]
> > Cc: [EMAIL PROTECTED]
> > Subject: Call for comments: Method dispatching and access
> > control framework.
> >
> >
> >
> > Dear All!
> >
> > I would like to invite comments on some extensions I have
> > made to get around some limitations in the Struts framework.
> >
> > When working with Struts, I quickly developed the following
> > wishlist of things that I wanted Struts to do:
> >
> > 1) Be able to bind a user request to an arbitrary function
> > in an Action class, not just to perform().
> >
> > 2) Be able to bind each button in a form with multiple submit
> > buttons to an arbitrary function (such that control is
> > transferred to a specific functions based on which button
> > was clicked).
> >
> > 3) Provide the ability to restrict access to actions as part
> > of the configuration (ie in struts-config.xml).
> >
> > 4) Reduce the number of runtime String lookups (such as when
> > writing: mapping.findForward( "success" ) ).
> >
> > I have written a few classes that provide items 1) - 3), and
> > also suggest a step towards dealing with item 4).
> >
> > The code is available on my website at:
> > http://www.beyondcode.org/projects
> > There you can also find Javadoc, as well as a little example
> > application, meant to demonstrate all of the above features.
> >
> > Feel free to take a look and let me know what you think!
> >
> > In the following, I am going to provide a more detailed
> > description and rationale for my dispatcher framework.
> >
> > interface DispatcherMapping
> > ===========================
> >
> > When attempting to dispatch requests to individual methods
> > within an action class, additional mapping information is
> > necessary. Fortunately, the struts-config DTD allows for the
> > <set-property> element, so that such information can be
> > included in struts-config.xml without having to change the
> > DTD. The interface DispatcherMapping provides two additional
> > properties: "method" (ie the name of the method that this
> > action should be dispatched to) and "access" (which can be
> > used to implement access control to individual actions/methods).
> >
> > Any ActionMapping implementation to be used with the present
> > dispatcher framework needs to implement this interface.
> > By making this functionality available as an *interface*,
> > rather than as a specific mapping *class*, applications are
> > still free to use other mapping implementations, as needed.
> >
> > See the section on "Standard Forwards" below for the other
> > properties defined in this interface.
> >
> > class MethodDispatcherAction
> > ============================
> >
> > This is the central class of the framework. On startup (ie in
> > its constructor) it reflects itself and builds up a HashMap
> > of member functions having the same signature as the perform
> > method. It is to these functions that requests can be dispatched.
> >
> > Of course, this class takes a major leaf from
> > org.apache.struts.actions.DispatchAction. However, several
> > things are different: introspection is "eager" rather than
> > "lazy". Since the HashMap is accessed read-only once the ctor
> > has completed, we can dispense w/ synchronization (??!?).
> > This also allows to check at boot-time, whether all required
> > methods are found (more on this below). Finally, this class
> > requires the mapping to be used to implement
> > DispatcherMapping, because it expects the additional properties.
> >
> > (Note: org.apache.struts.actions.DispatchAction puts the
> > method name to dispatch to onto the request as request
> > parameter. I am unhappy with the actual names of my methods
> > being accessible to the client. I also wanted *actions* (or
> > rather action mappings) to be dispatchable to methods, not
> > *requests*.)
> >
> > Furthermore, MethodDispatcherAction provides access control
> > on the granularity level of individual member functions (ie
> > individual actions). Before the request is dispatched, the
> > member function hasAccess( dispatcherMapping, request ) is
> > called. The default
> > implementation of this method always returns true. Application
> > developers can override this method to implement their own access
> > control. Note that this method has access to the "access"
> > property from struts-config.xml, as well as to the
> > HttpSession (through request). The access property can be
> > used to hold an access mask, which must match some
> > information contained either in the request or on the session.
> >
> > class FormDispatcherAction
> > ==========================
> >
> > This class is meant to be used with forms with multiple
> > submit buttons. It does no work itself, it just forwards
> > incoming requests to other actions. As opposed to the
> > MethodDispatcherAction above, it is not meant to be extended
> > for individual applications.
> >
> > Each submit button generates a request parameter, the name
> > of which is the value of the "property" attribute in the JSP.
> > The FormDispatcherAction class looks for a local
> > ActionForward with the same name, and dispatches the request
> > to this action, as a local forward (ie redirect=false).
> >
> > There is no access control in this class - it is expected
> > that all forwards from this class are dispatched to
> > subclasses of MethodDispatcherAction.
> >
> > class DispatcherMappingImpl
> > ===========================
> >
> > This is a ready-to-use implementation of the
> > DispatcherMapping interface mentioned above. Otherwise it
> > just extends the original ActionMapping class.
> >
> > See the section on "Standard Forwards" below for more info.
> >
> > class DispatcherTestServlet
> > ===========================
> >
> > This is an alternate ActionServlet, which overrides the
> > initMapping() method and tries to perform boot-time
> > consistency checks on it (cf. below).
> >
> > Appendix: Standard Forwards
> > ===========================
> >
> > It seems that there are quite a few places in Struts where
> > information is available (and could therefore be checked) at
> > compile time (or at least at boot time), but is not accessed
> > until actual run time! Examples are: findForward() (String
> > lookup), action mappings (consistency between JSP and
> > struts-config), bean-property/request parameter names
> > (consistency between JSP and code), etc.
> >
> > Ever made an innocuos change to a JSP, exercised the
> > application (manually!) to the respective page, only to
> > have the page blow up on you because you made a typo
> > (so that no corresponding bean property could be found)?
> > That's what I mean!
> >
> > I sometimes dream of a lint-like tool that I could run
> > over an entire Struts application and that would flag all
> > inconsistencies between classes, JSPs, struts-config, and the
> > file system (ie referring to a non-existent JSP in
> > struts-config) for me.
> >
> > While a complete compile-time checking tool might be
> > a challenge, some boot-time consistency checking seems
> > possible.
> >
> > DispatcherMapping and DispatcherTestServlet attempt to
> > show how this could be done for the case of findForward().
> > It seems to me that there are 4 standard forwards which
> > are appropriate for most actions: "success", "failure",
> > "error", and "access denied" (the latter makes sense only in
> > the context of access control to individual actions).
> > DispatcherMapping therefore provides eponymously named
> > methods. The DispatcherTestServlet examines all action
> > mappings at boot time, and reports those for which any of the
> > standard forwards return null. The DispatcherMappingImpl
> > finally tries to provide meaningful defaults, by looking for
> > appropriate global forwards, when no "error" or "denied"
> > forward is defined locally. All other forwards are of course
> > still accessible via findForward().
> >
> > Rather than finding out during functional testing, it
> > is now possible to find out whether you mistyped "succes"
> > simply by looking into the servlet log...
> >
> >
> > That's it. I am looking forward to your comments and suggestions.
> >
> > Best regards,
> >
> > Ph.
> >
> >
> > -----------------------------------------------------------------
> >
> > Philipp K. Janert, Ph.D. janert at ieee dot org
> >
> > --
> > To unsubscribe, e-mail:
> > <mailto:struts-user-> [EMAIL PROTECTED]>
> > For
> > additional commands,
> > e-mail: <mailto:[EMAIL PROTECTED]>
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>