Argh, I must have hit a secret key that sends the mail before it was
finished, here's the full story:
Now, rethinking as well :) I would also go one step further
All languages should be treated the same. It's too confusing that one
script language provides additional behaviour/methods on objects that
other language do not provide. This will cause problems over time.
A resource should not provide a way to get the resource resolver. I
think this is the root cause of the problem (ok, so far it is actually
the resource provider). We already have a way to get the resource
resolver and that's the request object, so instead of using:
resource.getResourceResolver().listChildren(resource)
you use
request.getResourceResolver().listChildren(resource)
which frees us from passing the resource resolver to the providers.
And it's even much cleaner as a resource does not need to know anything
about the resource resolver.
I don't think that going this clean api way :) is too much to type for
all our script fans here. Assuming that you iterate over children once
in a script, you have to type approx. 30 more characters - compared to
the overall size of a script its negletable :)
Ok, more seriously, this gives us a well defined api and contracts:
- How to you get resources? using the resource resolver
- How to you get the resource resolver? from the request
There are no other ways and no additional magic.
Nice and clean imho
Carsten
Felix Meschberger wrote:
Hi all,
I have been rethinking all these and also Carsten's input on our past
discussion regarding "intelligence of a Resource". I also looked at the
API and the intentions of it again, which I summarize as follows:
Resource - The object representating some datum in Sling. This may be
a JCR Node or
Property or an OSGi Bundle resource or an OS filesystem file.
ResourceResolver - The object providing access to Resource instances
from the
application context. The ResourceResolver represents the
external view of
the Resource tree.
ResourceProvider - The object capable of representing certain data as
Resource
objects.
The ResourceResolver interface is typically implemented once. It
incorporates the logic of dealing with multiple ResourceProvider
services. ResourceProvider instances may be provided by multiple parties
outside of the scope of the ResourceResolver. The ResourceProvider
instances are the factories of Resource objects: The ResourceResolver
asks the ResourceProvider for the creation of Resource objects. That is,
Resource objects are created under the auspices of the ResourceProvider
and not of the ResourceResolver.
What this means is, that Resource objects have absolutely no means of
accessing the mechanism of how a ResourceResolver uses ResourceProvider
services to find and create Resource objects. Consequently, the Resource
cannot list children and cannot access relative resources.
Therefore I have to revert and agree with Carsten, that any such child
and relative resource accessor methods must be provided by the
ResourceResolver. Any such API on the Resource interface may always only
be defined in terms of "implemented by calling the respective methods on
the ResourceResolver object". Thus defining such an API prescribes an
actual implementation, which is not the best of all things to be done by
an API ;-) Unless we define Resource as an abstract class with child and
relative resource accessor methods already implemented.
Undisputed is the fact, that the Resource should have a link to the
ResourceResolver and not to the ResourceProvider. In this respect, the
ResourceProvider interface will have to be enhanced to take the
ResourceResolver asking for a Resource from the ResourceProvider.
Remains the question of whether we actually should provide additional
public methods and properties on an interface in a single scripting
language which is not available in any other context. In other words: Is
it ok to have a JavaScript "Resource" host object with a "children"
property not matched by a respective Resource.getChildren() method ?
Wouldn't this be too confusing ?
Regards
Felix
Am Montag, den 11.02.2008, 09:11 +0100 schrieb Carsten Ziegeler:
Felix Meschberger wrote:
Hi,
I don't like this, and here is why: By adding this method, you add
functionality to a single location creating the impression, that this is
core functionality. That is you create a JavaScript-only
Resource.listChildren() method. The problem with this is, that migrating
such code to e.g. Java or trying to create similar code in other
languages will create tons of issues.
In addition, this implementation does not actually work, because it only
considers children of the current resource's ResourceProvider neglecting
any other ResourceProviders which might have "children" to the resource.
I understand, that it is cumbersome to revert to the ResourceResolver to
list the children of a resource - not just in JavaScript. So I would
like to propose these changes to the Resource interface:
Add Methods:
Iterator<Resource> listChildren(); // equivalent to
getResourceResolver().listChildren()
ResourceResolver getResourceResolver();
Remove Method:
ResourceProvider getResourceProvider(); // replaced by
getResourceResolver()
I'm not against these changes, but I think we discussed this some months
ago when we
discussed the Resource interface. And there were some arguments against
doing this (which I can't remember and haven't looked up).
I just hope that we are not going back and force with adding and
removing method just because someone needs them somewhere.
For now, I think adding the getResourceResolver and removing
getResourceProvider should be sufficient. I see no real value in adding
the listChildren method which is just a shortcut.
Carsten
--
Carsten Ziegeler
[EMAIL PROTECTED]