Thanks Grzegorz for illustrating some aspects of the basic concepts. >From my first post in this thread you can read that I already had the >impression that on the way from M to A some POST call might be missing in the interaction. And thus unsuccessfully tried to abuse some mechanisms of SSP to get the trick done.....
I think, you're right that inverting control will allow for keeping the necessary control for a e.g. form contained within block A. I'm still pondering the structural difference between my approach and the structure and ideas laid out by you. I'm not yet sure, I'll get convinced to it, but more on this further down.... To put the reasoning behind my structure a bit clearer: M is the master entry point of a web based application. There reside access control, (top) navigation logic and basic contract for presentation (e.g. themes). The application consists of a dynamic set of modules (e.g. A) that implement various aspects of possible interactions and functionality of the application. Thus, the basic contract and interface of M is most likely known when e.g. A is implemented. However, in the end, I'd like to implement M without knowledge of any of the (possible) blocks (e.g. A) that the application installation is composed of at a given time. (So, just add a new block and there are new menu entries and is new functionality) Spring does help a lot here (e.g. registering new menu entries with a "global" manager located with block M). Nevertheless the whole idea fails miserably, if any menu from a subsidiary block requires some additional "coding" with M. So, yes, I'am making use of delegation of control here (at least for some detail aspects of the final page). But that should just resemble "standard" functional delegation, same as it is quite natural with "calling" functions in classic programming languages. Responsibility of interactional behaviour for a certain region of the final page is delegated to block A (actually one of the forms implemented there). Probably the use case is closer to portal cases than to normal "plain" interactions. I'm looking at the whole structure like I would at an OO object instance. I do have an instance that has provisions of calling some methods on local "data" instances (fields). The signature is quite clear. The actual implementation might cover a wider range of known or not yet known behaviour. Nevertheless _control_ is delegated to such methods. Of course you could restructure the whole thing to always call the instance data method and cause it to use some implementation parts of the (former) entry class making the former instances derived classes in the new structure. This is what I did understand to be the equivalent of the solution you suggested. But I doubt this will lead to a "natural" structure of responsibilities, especially if not all methods of the original instance data classes should be exposed to (arbitrary) callers of M. I totally agree with you that exhibiting the original web request to a subordinate block is a bad idea. A clean solution must provide a "new" request providing (some) control over what is contained in it and how to handle responses (and what information to provide to the subordinate block. For sure this will not be the most optimally performing semantics, but it might be a valid internal optimisation to pass the original request (properly enveloped to guarantee contracts) in some situations. But never ever should the specification require the original request to be visible to any block other than the initial target. (If I followed previous discussions correctly, current approach involves serializing and deserializing requests to Thus, if the current SSP already is creating some kind of request, what does prevent it to allow for setting up a POST (or any other request method besides GET). Ok, there is some need for a syntax to make clear what kind of request should be performed, while the regular use case would prefer following the request method that triggered the subsequent call. This will also provide a clean transitive semantics for internal resources: some are best exposed using GET, others require POST, or other methods. And it is up to any caller can ensure correct usage. I have the impression (or some kind of inkling of) that what we are discussing here is equivalent to (direct) field access in classical OO and we now are about to recognize that objects (aka blocks here) might also have methods and our field access semantics should consistently be extended to such method calls. URLs being resolved to pipelines somehow resemble accessing fields in OO languages. It sounds quite unnatural to just invert algorithmic control to cleanly get access to some (probably overloaded) fields when delegating control would be more appropriate? (Leaving the question unanswered whether my initial use case would serve a good argument example here). Rainer Grzegorz Kossakowski schrieb: > Rainer Pruy pisze: >> Hi Grzegorz, >> thanks for your help. >> >> Sorry for the confusion about naming the blocks, forget about B, it should >> have read A, of course. >> >> Before going into the details of my scenario, I have to admit, that >> there is a "workaround" to overcome the problem and that I am using it >> already: >> >> Of course, one can use the resource components of the form (fd,ft,script), >> add them in a suitable way to the toplevel sitemap (M in >> the example case), apply a little tweaking and you are done. >> >> >> Nevertheless this "workaround" is breaking the idea of blocks being units of >> abstraction (You see, I am a bit contaminated by OO ideas >> and probably a bit overenthusiastic due to new inheritance concepts >> available with blocks). Recreating the interaction logic of a form >> in an outside sitemap forces exhibiting internal resources that one might >> not be willing to document or make accessible to the >> outside. > > Yep, you are right to every detail above. It's a basic idea behind block to > provide an effective way > of making resources and services separated and package them as reusable units. > > I don't think you can be even more overenthusiastic about Servlet Services > features than me. ;) > I really believe that SSF has a great potential and to be honest I'm little > bit sad that we haven't > show all its power up to date. > >> I, for my part, do expect, that if an URL I'm calling leads to some form >> interaction, such form interaction will also be >> available when the basic form entry url is called from a client block and >> not only if the interaction is directly with the end user >> (browser). > > I wonder about the situation when you just call an external form handling > without taking any further > actions. Why don't you just delegate entirely the form processing to A block > and complete about M > completely? > >> So my question might end up to be more a fundamental question about >> abstraction functionality available with the block concept and not >> about a detail problem in the first place. >> >> Besides that fundamental aspect, I'm not sure, whether I can get the >> scenario small enough to exhibit a problem, as I do not have >> enough time to check, whether a minimum example still shows the problem. So, >> let me sketch up a minimum example (untested) and add >> some words on the complications I added around in my real world example. >> >> Now the details of my scenario: >> >> A block A has a form interaction. For simplicity assume it to be the sample >> from cocoon forms block >> (see http://cocoon.apache.org/2.2/blocks/forms/1.0/478_1_1.html) >> And assume also, the the block can be accessed with name "reg". >> >> Now this block is (re-)used from a new block M. >> >> -----M sitemap fragment------------------- >> <map:pipeline> >> <map:match pattern="register/**"> >> <map:generate src="servlet:reg:/{1}" >> </map:match> >> <map:serialize type="xhtml"/> >> </map:pipeline> >> ------------------------------------------ >> >> As you can see, any call with a URL prefix if "register/" is forwarded to >> block A. >> This will cause the form to be displayed correctly. But on submit the form >> is just redisplayed and continued as one would expect. > > If you just forward I would expect that you just redirect to A block and give > it a full > responsibility of further request but I guess it's not that simple. :) > >> To make the whole a bit more complex. >> The paradigm as shown above is not used directly, but with aggregation. >> >> Block M generates pages as an aggregation from navigation data (some kind of >> menu entries) and some page content. >> Block A does something similar. It also aggregates it's own (sub) menu with >> actual page content (that in some cases is a form) >> Due to this, usually "calls" to the foreign block usually are from >> <map:part> and not from <map:generate> (or one would have to add >> another level of indirection for calling a local pipeline from <map:part> >> that itself issues the map:generate based reference to the >> foreign block. >> >> I hope you can make some sense out of this quite short sketch and (probably >> a bit weird) use case. > > Yes, I understand your use case and I even know what's kind of problem you > are experiencing. > >> Am I misled in believing forms should be integral kind of resource to be >> exposed with blocks (and not only files contained there)? >> Is my approach in "calling" the form completely off? > > I think that your use case is valid and you are not making any fundamental > mistake by just having > such use case but I don't like your design. I agree that your situation is > rather edge case that, as > it turns out, exhibits some weaknesses of current implementation (read it: > lack of necessary > features) of SSF. Let me explain where is the exact problem. > > When form is being submitted by the browser the POST request is being made. > The POST request comes > to M block; it's matched by "register/**" pattern and generation starts by > calling servlet:reg:{1}. > We are close to disaster because, using servlet:reg calls means using > internal HTTP requests made by > M to A block. This internal request is being processed by A block just as it > would come from the > browser but it doesn't. When internal request is made, it's a GET (at least > in our situation) so > Form logic in A block thinks it's a first browser request thus serves clean > form. > > The first impression of mine was that we just need to add a feature of > passing original request in > almost virgin state so if original was POST the internal should be also a > POST, etc. After a > thinking about it for a while I came to conclusion that something > fundamentally wrong is with such > approach when two blocks are having access to the whole browser's request. > Yes, I meant exactly > that: it's fundamentally wrong two forward browser's request. > > When you think about content of the final page served to browser the way you > aggregate data might > look proper and logical. You have common snippets like menus, headers and > variable content that > might be some article or form. It's ok to pull variable content from other > blocks (realizing various > parts of site) and aggregate it with common layout. It's ok if it's really > aggregation of /data/. > > However, in your case the call to A is not about asking a data. In fact, it's > delegation of the > _control_ because it depends on A block implementation how sequence of > browser-server interactions > will look like. In such scenario block M is redundant (as being only dumb > proxy) and breaks > cleanness of the design. I think that the best practise is always keep > control layer in a one block, > and it should always be the one handling browser's request directly. I think > following such rule > guarantees clear, easy to maintain code. > > What to do exactly in your situation? In short: invert roles. It must be A > block the one handling > browser's request and pulling data (common layout) from M block. You may be > worried that A is > closely tied to M block which does not seem to look good. However, you should > bear in mind that A > must be tied to _interface_ M is implementing. The interface is in this case > the set of resources > served by block. A block relies only on the interface and you can replace use > of M block by any > other if you wish without touching A block's code. > > If you don't know the interface of M block at the time of implementation of A > you can chose another > way. You can extend raw (read: not being aware of final layout) A block and > *override* pipeline from > A responsible for rendering form. In overridden pipeline, you can implement > easily an aggregation of > other resources and even call original pipeline (think of super call) as one > part of the aggregation. > > - o0o - > > I think that you have touched a really interesting area of Servlet Service > Framework's application. > Your case brings some problems but at the same time it lets some deeper ideas > behind SSF design > shines. It's quite exciting because we seem to be at this point in time when > we start inventing > /design patterns/ similarly as it happened for Object Oriented programming > languages. > > > Rainer, I would like you to think about what I have said above and share your > comments. It's really > crucial to think about it thoroughly because we are the stage of carving in > stone various design > decisions behind SSF. > > Best regards, > -- Rainer Pruy Geschäftsführer Acrys Consult GmbH & Co. KG Untermainkai 29-30, D-60329 Frankfurt Tel: +49-69-244506-0 - Fax: +49-69-244506-50 Web: http://www.acrys.com - Email: [EMAIL PROTECTED] Handelsregister: Frankfurt am Main, HRA 31151 --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
