on 5/27/03 4:06 AM Sylvain Wallez wrote:
Object getComponent(id) -> obtains the component indicated by the given ID
Why don't you use the traditional lookup() name ? Also, release() is missing. So what about lookupComponent(id) and releaseComponent(id)?
release() is missing on purpose. It follows the same principle of "malloc considered harmful" that Java uses for garbage collection. [and the principle that Avalon 5 is supposed to use]
as for changing the name from "get" to "lookup" I'm neutral on this.
An important question, also : how does component management fit with continuations ?
if you store your component in a variable, that instance is kept into the continuation object.
Can a component be frozen by a continuation and unfrozen in a different environment ?
it's not the component that is frozen into the continuation, but it's instance. a continuation cannot freeze the state of a java component.
Ok. By "component", I actually meant "instance" obtained by lookup() or getComponent(). Then we have a big problem here : automatic component release is very likely to be handled by the container at special times such as end of request processing. This means the continuation will use released components, thus eventually leading to concurrent access problems since the container is likely to have given the instance to someone else through another lookup().
On the other hand, explicit release like we have today means that the continuation becomes heavyweight since it keeps references to instances that may have been taken out of a pool. And even worse, if a continuation is abandoned we have some leaks since the instance is never released.
Mmmh... A solution may be to use the catch(break)/catch(continue) to release components when a continuation is created, and control this at creation time, raising an error if there are still some unreleased components. This should do the job, at the price of important constraints for the flowscript writer.
We could have some hooks that automatically relase components when a continuation is frozen, but then what about stateful components ?
Ricardo told me that the EJB community has already discussed these issues extensively (not for continuations, but for stateful components).
Ricardo, anything to add here?
Yes, please.
<snip/>
Load support is IMO required because JS lacks an import statement. Not having it means we'll have to write a <map:script> for the script we want to use, but also for *all the scripts it depends on*, recursively. This will be very difficult to manage.WARNING: removing load() does *NOT* imply that you have to force all your flow in one big file. The way to fragment your flow into different files is to use several <map:script> elements in the <map:flow> section of the sitemap.
Hmmm, I see your point, but let me point something out. In the future, I foresee something like
<map:flow> <map:script src="block:whatever:/flow/flow.js"/> <map:script src="cocoon:/myDynamicFlow.js"/> <map:script src="myStaticFlow.js"/> </map:flow>
since we agreed that blocks only expose a URI space controlled by the sitemap (they don't expose resources directly!) you can use a reader to get the flow to the dependent block, or you can use a pipeline to generate your flow (for example, traducing a workflow written using a markup language into the equivalent flow instructions).
Here you have all the machinery you need to compose your flows as you like. Recursively.
The difference between the above and load() is thin but real: while load() has to be executed at runtime, the <map:script> calls can be done at sitemap assembly time. It could have a big impact on runtime performance of the flowscripts.
Mmmh... what you're stating here is that we can have "families" of flowscripts (I was about to write "classes") whose contract is defined by the toplevel functions (and hence object classes) they provide, and that a sitemap will assemble its flow script by loading an "instance" of each of the required "families".
So through it's URI contract, a block will provide not only XML processing services, but also flow code. That's interesting...
:-)------- properties ---------A simple reason : the context object (the environment one) gives access to context parameters defined in web.xml. In many situations, this is where parameters depending on the deployment environment are located, as it allows the sysadmin to use it's favorite app server GUI to set them and avoids editing cocoon.xconf. (yes, I've seen some installs being totally screwed up because the sysadmin didn't knew what a well-formed XML file was).
cocoon.request -> the request object cocoon.response -> the response object cocoon.log -> the log object
NOTE: the absence of the context object is intentional! we couldn't come up with a reasonable need for such an object at the flow level. So, for the principle of 'less is more', we don't consider it. Be aware that if you want to propose its addition, you have to come up with a reason for it.
Ok, this is exactly the real-life good point I was looking for. +1 for adding context.
Do you need read/write or read-only could be sufficient? (I would go for read-only)
AFAIK, the only write method is setAttribute(), which can be used to define server-wide data. Considering that flow global variables are bound to the session, this may be useful.
<snip/>
Huh ? A logger is not a component.--------------------------------------------------------------------------- The Log Object ---------------------------------------------------------------------------
This is a convenience method to access the cocoon logger. It could be the same of doing
cocoon.getComponent(...)
Why not?
Huh ? again ;-)
Or is the notion of component in the FOM different that the one in the other parts of Cocoon ?
Mmmh... I know you want to avoid abuses, but at the same time, we must not make the flow a strange beast compared to other parts of Cocoon. This is especially important if we want to allow users to migrate big flows to clean Java classes and new components.
What makes Cocoon so nice is that a few concepts are used to define everything : the Avalon component architecture, a few interfaces (didn't actually count, but I'm sure the main core interfaces are less than 20), and this it. Everything else are implementations built on these few abstractions. So let's be careful and keep the FOM consistent with Cocoon.
<snip/>
Is it "type" here instead of "name" ?Yes. But the problem here is that the sitemap will be come super-verbose since you'll have to add such a transformer all over the place.
Well, in my post-2.1 RT on sitemap additions, I will outline the concept of "macro components", basically allow you to create an 'overloaded serializer' which is, in fact, a composition of a transformer and a serializer. Something like
<map:serializers> <map:serializer name="xhtml"> <map:transformer name="link-translate"/>
Again, shouldn't the two "src" above be "type" ?<map:serializer/> <-- this is the equivalent of super() </map:serializer> </map:serializer>
NOTE: the above is meaningful in a subsitemap where "xhtml" was already defined, so the above is a "wrapper" around the original component. Alternatively you could have something like
<map:serializers> <map:serializer name="xhtml"> <map:transformer src="..."/> <map:serializer src="..."/>
</map:serializer> </map:serializer>
where the components that constitute the fragment are not accessible independently, but only aggregated in the macro component.
The above removes the magic and increases readability. In fact, it can be applied to all pipeline components (generators, transformers and serializers).
How is this different from a resource ? Resources also allow to define overloaded generators and transformers. So do we really need a new concept ?
What about the Avalon context ? Is it omitted on purpose ?yes. do you envision a need for it?
Don't know... Still my quest for consistency with the other parts of Cocoon ;-)
Sylvain
-- Sylvain Wallez Anyware Technologies http://www.apache.org/~sylvain http://www.anyware-tech.com { XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }