Return-Path: Delivered-To: apmail-jakarta-struts-dev-archive@apache.org Received: (qmail 66302 invoked from network); 9 Sep 2002 11:34:35 -0000 Received: from unknown (HELO nagoya.betaversion.org) (192.18.49.131) by daedalus.apache.org with SMTP; 9 Sep 2002 11:34:35 -0000 Received: (qmail 28749 invoked by uid 97); 9 Sep 2002 11:34:39 -0000 Delivered-To: qmlist-jakarta-archive-struts-dev@jakarta.apache.org Received: (qmail 28618 invoked by uid 97); 9 Sep 2002 11:34:37 -0000 Mailing-List: contact struts-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Struts Developers List" Reply-To: "Struts Developers List" Delivered-To: mailing list struts-dev@jakarta.apache.org Received: (qmail 28578 invoked by uid 98); 9 Sep 2002 11:34:36 -0000 X-Antivirus: nagoya (v4218 created Aug 14 2002) Subject: Re: Multiple RequestProcessors To: "Struts Developers List" X-Mailer: Lotus Notes Release 5.0.8 June 18, 2001 Message-ID: From: Christopher Seekamp Date: Mon, 9 Sep 2002 07:33:07 -0400 X-MIMETrack: Serialize by Router on D03NM118/03/M/IBM(Build V60_09042002A|September 04, 2002) at 09/09/2002 05:33:38 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N Gerrie: Yes, I agree with your analysis. We were forced to override multiple methods of RequestProcessor. I was also at one time thinking about how one might want to control the ordering of extensions to each method of RequestProcessor individually, which is what you are allowing for the one method, processActionPerform. I think that would be too difficult for users to deal with for many methods, but doing something like that for a single method like you are doing is a lot easier for some to understand and deal with. So, somehow merging these ideas sounds fine to me. I do like the additional flexibility your XML approach affords, although I was assuming that the RequestProcessor extension would typically be done as part of a regular PlugIn as is now done with Tiles. I guess it is unavoidable, but one thing I am concerned about is how much the user has to understand to get different extensions to work in concert. Both approaches are clearly better than requiring source code changes or many different combinations based on compile-time inheritance, but still the user has to understand the order to place them in. It would be nice if there were an easier way. Maybe someone will be able to step back from the current RequestProcessor approach and come up with a different approach to processing requests in general which would make supporting multiple extensions easier. Of course that might break existing extensions (and make backward compatibility difficult if not impossible), but in a new version maybe that would be the thing to do. Chris Seekamp |---------+----------------------------> | | "Gerrie Kimpen" | | | | | | | | | 09/05/2002 05:26 | | | PM | | | Please respond to| | | "Struts | | | Developers List" | | | | |---------+----------------------------> >---------------------------------------------------------------------------------------------------------------------------------------------| | | | To: "Struts Developers List" | | cc: | | Subject: Re: Multiple RequestProcessors | | | | | >---------------------------------------------------------------------------------------------------------------------------------------------| The Struts Action Plugin Extension focuses on 'decorating' only the RequestProcessor::processActionPerform method. This is (conceptually) the big difference with the RequestProcessor decorator implementation of Chris, which enables you to decorate all the protected RequestProcessor methods (that are not just support methods). (My decorating needs were not as broad as Chris's.) However, our reasons (or motivation) for creating this architectural enhancement were exactly the same. Another difference is that the Action Plugin Extension uses a separate XML configuration file (see example below) in which you can declare a chain of 'decorators' (= ActionPlugIn implementations). This gave me the opportunity to specifiy 'init params' and 'disable conditions' for each decorator. With 'disable conditions' I mean that you can disable specific decorators in the request processing chain, for specific action paths (). For example: com.yourapp.web.struts.AuthenticationActionPlugIn accountSessionKey userAccount /logon com.yourapp.web.struts.WorkflowActionPlugIn Brandon Goodin (mail@phase.ws) and I have some ideas to extend this XML grammer to end up with an even more flexible and conditional decorator chain. When the time is right (after 1.1, I suppose) we migth merge some ideas around this topic to make Struts (again) a little bit better :) Gerrie Kimpen ----- Original Message ----- From: "Martin Cooper" To: "'Struts Developers List'" Sent: Wednesday, September 04, 2002 6:44 AM Subject: RE: Multiple RequestProcessors > Sorry I'm a bit late to the party... > > It strikes me that what you describe has some interesting similarities to > the Struts Action Plugin Extension that was described recently: > > http://marc.theaimsgroup.com/?l=struts-dev&m=102933179909461&w=2 > > It looks like both of these approaches will have useful input into an > eventual post-1.1 solution. > > -- > Martin Cooper > > > > -----Original Message----- > > From: Chris Seekamp [mailto:seekamp@us.ibm.com] > > Sent: Monday, August 26, 2002 1:56 PM > > To: struts-dev@jakarta.apache.org > > Subject: Multiple RequestProcessors > > > > > > Although the change in Struts 1.1 to implement the RequestProcessor > > was a great improvement over having to extend the ActionServlet, > > as has been pointed out before, there can be issues when multiple > > people want to extend the RequestProcessor. For instance, my group > > extended the RequestProcessor so Struts would work well in our > > particular environment. Suppose we or our users want to > > utilize Tiles, > > which has some really great capabilities? Well, if we could > > extend the > > Tiles RequestProcessor we would now need another version of our > > RequestProcessor that extended the Tiles RequestProcessor rather than > > the base RequestProcessor. But in our case, we override doForward too > > (like Tiles does) and we would actually need Tiles to sit on top of > > (subclass) our RequestProcessor rather than the other way > > around. So we > > would have to take the Tiles source and generate another subclass of > > the TilesRequestProcessor that extended our RequestProcessor rather > > than the plain RequestProcessor. > > > > And as more and more extensions become available, ideally we > > would like > > to be able to choose various combinations of extensions to use. Of > > course, using subclassing this becomes rather problematic for obvious > > reasons. If there are 3 different extensions you want to > > build upon, if > > you are lucky you could just create three different versions of your > > own RequestProcessor subclassing each of the those 3 separately. Of > > course, if you want to build on two at the same time..... > > Well, you get > > the idea. > > > > So, we, and we expect others, would like to improve the chances that > > our various extensions can be used together. We have implemented an > > approach based on the Decorator (Wrapper) pattern that allows > > processors to be chained together. If you choose not to subclass from > > this wrapper class things are the same. But if you make your > > RequestProcessor subclass from the wrapper and follow some simple > > steps, you can be part of an ordered chain of RequestProcessor > > instances. In addition to adding the wrapper, we had to make small > > changes to ActionServlet in getRequestProcessor (to build the > > chain the > > first time it is called) and the RequestProcessor itself to call the > > top (last) processor's methods and ControllerConfig to keep the > > chain of classes. Besides subclassing the wrapper class > > rather than the RequestProcessor, the only new things processors need > > to worry about is making sure to all the subclass version of > > the method > > they are extending and to call the top processors version's of other > > processor methods they call. For example, if you have your own > > processActionForward method you should remember to > > call super.processActionForward. You normally would want to do this > > anyway. Continuing the example if processActionForward wants to call > > doForward, it should call the top processors doForward instead because > > it might not be the top (last) processor in the chain. > > > > We know others have brought up the problem of multiple > > RequestProcessors before. We would be happy to donate our approach as > > a starting point, because we would like different extensions that > > require extensions to RequestProcessor to be usable together > > as much as > > possible without having to compile numerous different versions. For > > example, using the straight inheritance approach we would have to be > > prepared to generate a new version of the Tiles RequestProcessor > > extending our RequestProcessor every time there was a change made in > > the Tiles RequestProcessor. So maybe there are some > > far-reaching plans > > to address this issue in Struts or maybe someone else is already > > working on a different solution? > > > > If not, is there any interest in discussing extending the > > RequestProcessor support to support some kind of chaining approach? I > > would be happy to give more details on what we have come up with. I > > haven't submitted any patches yet, but I assume this is not > > the kind of > > thing one should simply submit as a patch anyway, at least not without > > discussing the appropriateness of the approach first. > > > > Thanks and sorry for the long post. > > > > Chris Seekamp > > > > > > > > -- > > To unsubscribe, e-mail: > > > > For additional commands, e-mail: > > > > > > > > > -- > To unsubscribe, e-mail: > For additional commands, e-mail: > > -- To unsubscribe, e-mail: For additional commands, e-mail: -- To unsubscribe, e-mail: For additional commands, e-mail: