Hi guys,
The discussion initiated by rather *technical* question about JNet integration with SSF turned into
heated discussion on whether standard URL API is capable enough to replace Excalibur's
Source/SourceFactory interfaces. Actually, it was Rainer Pruy who gave a nice summary[1] of
discussed aspects up to now.
Even though, it's real fun to see interesting solutions like one proposed by Sylvain[2] I'm still
rather interested in that particular COCOON-2176[3] problem at the moment as it blocks any out of
Cocoon world SSF usage.
--- o0o ---
Right from the beginning of my playings with JNet and URL replacement for SourceResolver I had
constant feeling that something is stinky about the approach I taken. That's been reflected in bunch
of dirty hacks in first, prototype implementation of JNet integration.
I've taken a closer look at our current Source interface usage pattern. Obviously, started with
blockcontext source that I'm mostly interested in at the moment and seen something like this in
BlockContextSourceFactory:
String blockContext = (String) blockContexts.get(blockName);
[...]
// construct the path relative the block context
String resolvedPath = blockContext + path;
[...]
resolver = (SourceResolver)
this.serviceManager.lookup(SourceResolver.ROLE);
return resolver.resolveURI(resolvedPath);
Some comments explaining what's happening here. If you try to resolve blockcontext:/myBlock/path it
will obtain blockContext from Map of contexts. This map contains base URLs for corresponding blocks.
Current implementation allows file: and jar: protocols.
As you see, BlockContextSourceFactory returns Source implementations of protocols that have
_nothing_ to do with BlockContextSource. Let's have a look at how resolved source is used (in
ServletFactoryBean):
source = resolver.resolveURI(contextPath);
contextPath = source.getURI();
Where contextPath contains "blockcontext:/myBlock/path" at the beginning of processing. It's clear
now, that ServletFactoryBean is interested only in String representation of base URL (Source) and
nothing else.
Don't you think that is little bit weird that following instructions:
contextPath = "blockcontext:/myBlock/path";
source = resolver.resolveURI(contextPath);
contextPath = source.getURI();
Will result with "file://.../myBlock/path" stored in contextPath instead of original
"blockcontext:/myBlock/path"?
I think that contract of URL/SourceFactory should be to to act as identity transform when above code
is being executed. I mean, returned URL/Source instance should always be implementing the protocol
we asked for.
Do you agree?
--- o0o ---
My conclusion is that SSF exploits semantics of Source/SourceFactory interfaces for resolving
*expressions*. My view on "blockcontext:/myBlock/path" is that we deal with an expression that
should be resolved to real URL with real protocol implementation available.
Having said all of this I would like to propose treating strings in contextPath attribute as
expressions and using cocoon-expression-language-api module for resolving them. Then
cocoon-servlet-service-components could provide implementation of blockcontext expression language
that would use blockContext Map for resolving expressions to real base URLs.
This way we can get rid of dependency on CocoonSourceResolver and Excalibur in one go. Moreover, it
means that SSF won't mess with URL/Source handling anymore which was my intention right from the
beginning. I think such functionality is far from SSF scope and should be implemented elsewhere,
probably as a Spring AOP's /around advice/ so you could get more fine-grained control in which
servlets you want to have extended URL support.
WDYT?
[1] http://article.gmane.org/gmane.text.xml.cocoon.devel/77432
[2] http://article.gmane.org/gmane.text.xml.cocoon.devel/77352
[3] https://issues.apache.org/jira/browse/COCOON-2176
--
Grzegorz Kossakowski