cocoon-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Grzegorz Kossakowski <g...@tuffmail.com>
Subject Re: C2.2: Accessing form via servlet services?
Date Wed, 20 Feb 2008 19:38:11 GMT
Hi Rainer. I'm very sorry that I have not been responding for so much time but there were lots
of
issues lately. The last one I got injured while skiing in Austria and I had no motivation
to touch
computers for some time...

Before I start to address your specific points I would like to say that I have spoken with
Reinhard
and he told me that he liked ideas posted in this thread and he told me he was going to take
proposed approach in his next work on top of 2.2. That gave me more conviction that I'm on
right
track giving you advice.

I hope that Reinhard could speak about his thoughts on the list himself, though... :)

Rainer Pruy pisze:
> Agreed, that would better reflect it's role in page composition.
> However, a small but nevertheless important role is authentication and (global) authorization.
> I have the firm conviction that it is bad design to rely on each subordinate block (the
"A"s) to correctly implement the
> authentication and authorization contract of the overall application. Especially if we
allow for such blocks to be contributed by
> "third parties". Not involved with putting up the application in the first place (e.g.
customers).

I've been thinking about authentication and authorization as well. I agree it's bad design
to rely
on subordinate blocks implementing such important piece of functionality. However, I think
it's also
a bad design to mix content generation/aggregation with authentication and authorization.
My idea is
to create another sitemap (or maybe whole block) just handling authorization. It would exploit
all
the power that comes from sitemap matching so you could create a sophisticated patterns.

The idea is to make a request (having the same information as the request coming from browser)
to
your special block and let it to return only a status code:
  a) 202 Accepted if request should be dispatcher to its target block
  b) 401 Unauthorized if user is not authorized
  c) 403 Forbidden in case when user does not have necessary karma

In cases b and c original request would never reach its target block. This functionality could
be
easily implemented in a DispatcherServlet of servlet service framework for example by overriding
its
service() method. Probably it would a good idea to refactor code in DispatcherServlet class
so its
easier for extending classes to plug such special handlers.

I think it's quite obvious that this resembles the AOP functionality from Spring. I think
such
design would be very clear and would keep things like content authorization and content generation
that are orthogonal separate.

> If there is no inversion of control, and passing (POST) requests resulting from submitting
forms does not work transparently, the
> there must be provisions with M to process forms from any subordinate block.

I don't get your point. Why do you want M to bother of POST request that A block should handle
directly?

> As it adds "single point of authentication/authorization" it is not redundant in the
first place.
> When just considering contribution to resulting page, you are right.

See above. M should not be involved in authentication/authorization because it's responsible
for
content generation only.

>> If you invert roles, then A block also uses delegation for generating common layout
but this time
>> there is only one procedure taking numerous parameters and the second, responsible
for generation of
>> common stuff, takes only a few of them or maybe even none. I see such situation as
improvement and
>> less complex code.
> 
> Yes, it will simplify code for M while adding a bit to each subordinate ("A").

Yep, but it's better to distribute the complexity among many blocks instead of creating one
big
beast that in the end must be tied to all of blocks because it must handle all edge cases.

Having one central point makes sense if the complexity can be reduced but here we are talking
about
only about complexity management and not reduction.

>>> 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.
>> Yes, this is about a portal case.
> 
> It will extend to it a bit more, if M would have areas, where more than one subordinate
is to be displayed at a time with the
> resulting page. In such case there would be more changes required to both blocks involved
as only one of them can take over control.
> (Imagine, both subordinates are going to show forms...)

Yep, but the data coming from browser is interesting for one block only at the time. It's
the block
whose form has been submitted. Other blocks should redisplay its content without any extra
processing because there was no data to process, right?

>>> 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 also try to think about whole problem in OO terms but apart from plain concepts
of OO I try to
>> take into account best practices like isolation.
>>
>> If you are programming in any OO language you probably consider global variables
a bad practise as
>> well as passing heavy amounts of data all over around. You strive for design where
methods of
>> objects are specialized, don't you?
> 
> I can not see where in the current structure we would have something resembling global
variables.

The global variable here is the request coming from browser. Your original idea was to let
every
block access the whole request coming from browser. I think it's a bad idea and it resembles
global
variable to some extent.

> I'm just trying to apply some abstract concepts (from OO world in this case) to SSP.
> 
> We are providing derivation and overriding semantics for "data".
> A block currently exposes (some) pipelines to be "called" (used) from other blocks.
> Any such pipeline will get called on the purpose of retrieving the "data" associated
with said pipeline.
> A contract will usually include basic semantics and format of such data.
> 
> This will suffice for most cases. nevertheless, as long as a pipeline is allowed to provide
aspects of control (flow via map:call
> (function or continuation) the actual data just is a side effect (the activities carried
out while retrieving the data result are a
> side effect in the first place but as the initial side effect is the main interest here,
view on things and attributions should be
> changed).
> 
> This is close to the difference on stateless and stateful classes with OO languages.
(and please everyone, do not start a discussion
> on whether stateless or stateful designs are superior).
> 
> Current use of SSP supports "functional" calls, where result just depends on parameters.
The question effectivly no is, whether SSP
> should/will/must support any stateful semantics that cocoon itself has provisions for.

Yup, you have got the point. My own opinion is that it's the best if SSF did not support stateful
semantics or at least it shouldn't be done the way when you pass everything everywhere.

>> The second one is the most important because it destroys the whole idea of your M
block. You
>> probably wanted to have one nice, universal pipeline delegating generation of some
parts of your
>> pages to subordinate blocks. However, if some of them require M block to pass some
data of original
>> request it becomes kind of troublesome because you need to dynamically chose if you
need to pass
>> data or not. I bet you (or one of your young developers) will end up with passing
everything to
>> every block. That would be a complete disaster and contradiction of ideas behind
SSF.
> 
> I'm fully aware, that in practice implementors will choose to just pass the complete
request (at least for avoiding to seriously
> consider what really would be needed or really should be available with subordinate blocks).
This was reasoning behind my remark for
> probably short circuiting such special case to improve performance. But risk of misuse
by programmers might not be sound ground for
> rejecting a major concept.

Let me explain my hesitation on making SSF more sophisticated. We already have something that
you
ask for in Cocoon, it's cocoon: protocol. It provides access to the data coming from original
request when you make internal pipeline calls (internal requests). I tell you, it gave people
a lot
of freedom but at the same time it allowed them to bake sitemap full of crap that I wouldn't
call
the best practice but it's my own opinion. More objective part is a point of view of Cocoon
developer. I'm such and believe me I become sick when I hear about cocoon: protocol because
it (with
it's friend map:mount) the main reason why we got to the point where almost nobody can maintain
Cocoon's core because it is so complex. Yes, I'm speaking about implementation details but
they are
hell important to me and I think they should be important to the whole community because
unmaintainable code will hurt everyone in the long term...

Personally, I don't believe that the functionality we are talking about can be implemented
in a
clean way leading to maintainable code. Moreover, I don't care that much when I can give you
example
of a much better architecture that Cocoon applications should take that doesn't require
functionality of cocoon: protocol.

Anyway, I'm still open and willing to discuss. :-)

>> Imagine you have many, many roads crossing each other in one point. You can easily
imagine that no
>> matter how big crossroads you will build with how many fancy spiral ramps you will
build it's going
>> to be a major bottleneck in the whole traffic. What I suggest is to build more, smaller
crossroads
>> that will distribute the overall hindrance among many different places.
> 
> You're absolutely right, M is a major bottleneck and that is on purpose. M in my case
(the central crossing) is just the big toll
> station (to keep the picture)
>>> 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.
>> There is a subtle problem with this approach. You mentioned servlet service calls
in your previous
>> e-mails so you are aware of the fact that internally they use POST requests to pass
XML data to be
>> processed. What if someone stumbles upon the idea of creating a service that requires
access to the
>> original request. Sure, let's pass the POST data coming from browser, but what the
heck are going to
>> do with the XML data that needs to be passed as well?
> 
> Sorry, here I got lost.
> Where does XML data come in here?
> For my (probably simplistic perspective) SSP is the method call runtime implementation
for an object based structure based on cocoon
> blocks. Calls my result from a "browser" or form other blocks (or probably from other
sources e.g. web services...).
> Naively, I assume a block should be provided the very same "calling" possibilities than
a browser would have (and currently does have,
> obviously).

Your probably should study this thread[1] and this[2] issue. Postable source is already implemented
and used in 2.2's demos (for styling). Internally, postable source makes a POST request, more
details you will find in referenced thread. How would you handle request coming from postable
source
when you would need to pass original post data coming from browser as well?

>>> 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).
>> It's more making methods call than accessing to the fields. What if you take argument
of redundant
>> parameters (data) passing?
> 
> Can you explain a bit more here on what you have in mind?

Still the same: passing whole request to the called is like passing parameters to the methods
that
completely do not need them.

[1] http://thread.gmane.org/gmane.text.xml.cocoon.devel/67477/focus=67480
[2] https://issues.apache.org/jira/browse/COCOON-2046

Best regards.

-- 
Grzegorz Kossakowski

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org


Mime
View raw message