Hi Carsten, I have to disagree. Treating all languages the same will result in an API that does not match the concepts of most languages supported. Different programming languages have different concepts and if possible, we should support these concepts.
This does not interfere with implementing the listChildren() method in a clean way, but we should also keep in mind that some languages we support do not have a concept of methods alltogether (Javascript, Velocity, Freemarker), some are dynamically typed and some are untyped. By disregarding this fact we create a cumbersome API that feels like the DOM API (that was designed to be language-independent and lead to implementations like DOM4j or JDOM that fit better to the concepts of the programming language environment) To sum it up: When implementing scripting support, we should allow the scriptingengine to add additional convenience accessors and type conversions, but we should not implement some concepts (like listChildren()) exclusively for one language. regards, Lars On Wed, 2008-02-13 at 09:42 +0100, Carsten Ziegeler wrote: > 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 well defined > > 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 > >> > > > > > >
