You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Marc Portier <mp...@outerthought.org> on 2003/07/25 13:54:51 UTC
[apples] research-report on alternative flow implementations
Hi all,
I've set myself to hacking up some of my alternative flow ideas
so it could feed the 'generalized flow' discussion (and guide us
through understanding possibly required refactoring)
I dubbed the thing 'apples' for now:
It basically sprung off from the short 'app' for application and
'applet' was already taken :-p (I also like the implied wit that
we shouldn't compare any of his to pears)
For those that find emails longer then 20 words ;-) difficult to
grasp, here is the TOC:
[1] explanation of current apples
[2] proposed refactoring to the current flow-codebase
[3] reflections on code sharing
[4] future directions
I think section [2] holds the most info related to the rest of
the community (at least on short notice)
I hope (expect) for some discussion to come round those section
[2] topics for sure... all comments on the rest is highly
appreciated of course
-o0o-
[1][explanation of current apples]
The goal
(appart from 'doing research' which is a goal an sich ;-))
- explore the creation of a Java API to disclose the flow concepts
- such that people could reuse their OO thinking and their
Java-class and Avalon-component coding skills to write 'Apples'
- which would be Avalon components hosting your business logic
and making flow and publication decissions (i.e. selecting the
uri and preparing the bizdata)
Here is what goes on to date:
The core is called the ApplesProcessor which is currently hooked
up as a subclass of the existing Interpreter class
1/config:
- it gets declared inside cocoon.xconf with some
<component-instance name="apples" logger="apples"
class="org.apache.cocoon.components.flow.apples.ApplesProcessor"
>
among the <flow-interpreters>
- and gets selected as the flow-impl to use in any sitemap by
adding the:
<map:flow language="apples"/>
2/usage:
calling the logic inside your java-'apple' is based on the
existing flow-directives in the sitemap:
<map:match pattern="**/*.kont">
<map:call continuation="{2}"/>
</map:match>
<map:match pattern="start/use-case_X/*">
<map:call function="package.names.MyXApple">
<map:parameter name="param_A" value="val_A"/>
</map:call>
</map:match>
3/processing:
These sitemap directives directly map onto the following methods
of the Interpreter interface:
void callFunction(String fqcn, List args, Environment env)
void handleContinuation(String id, List args, Environment env)
the AppleProcessor will do the following:
in the event of callFunction(fqcn, args, env)
- make an instance of the class specified in fqcn
- cast it to its interface of interest: AppleController
- pull it through the avalon lifecycles (lifecycehelper)
- wrap it up in a WebContinuation object (full reuse of the
existing ContinuationsManagerImpl)
- let this fresh Apple process the 'request'
- get uri and bizdata from the 'response'
- use those in the forwardTo(uri, bizdata, wk, env) of the
Intrepreter interface
and in the event of handleContinuation(id, args, env)
- find the nested continuation in the WebContinuation pointed to
by id
- cast that to its interface of interest: AppleController
- let this re-found (stateful) Apple process the 'request'
- get uri and bizdata from the 'response'
- use those in the forwardTo(uri, bizdata, wk, env) of the
Intrepreter interface
4/coding:
Your arbitrary business logic can be a sample Java class that
- can exploit the following avalon lifecycle-interfaces
(Serviceable, (not yet Composable) and LogEnabled) -- (not yet
Disposable)
- needs to implement void processRequest(AppleRequest, AppleResponse)
these new Request-Response objects are just convenient ways to
control the access these Apples have to anything that is
available to the AppleProcessor at the time of the call.
Basically:
- AppleRequest gives access to the CocoonRequest and the map of
parameters (args) passed over...
- AppleResponse allows to set uri and bizdata
-o0o-
[2] proposed refactoring to the current flow-codebase
If above seemed like not that big a thing then you are absolutely
correct: the layers to hook up any FlowImplementation you like
are already present inside Cocoon, and it's a real pleasure to
work with them.
There is only a slight tendency in naming and argument-passing
that directs implementations towards using a
scripting-language-interpreter to do the job.
Also, getting in some closer to the flow from a slightly
different angle then the current js makes me suggest a number of
additional modifications...
Here goes my set of proposed refactorings
(There is a fair chance that continued investigation will bring
up some more of these...)
1/ modified forwardTo() in the AbstractInterpreter
All flow implementations just need to implement Interpreter but
are likely to subclass AbstractInterpreter to do so. In that
event they inherit already the implementation of the forwardTo()
method.
Changing that implementation to this:
public void forwardTo(String uri, Object bizData,
WebContinuation continuation,
Environment environment) throws Exception
{
if (SourceUtil.indexOfSchemeColon(uri) == -1) {
uri = "cocoon:/" + uri;
}
Map objectModel = environment.getObjectModel();
FlowHelper.setContextObject(objectModel, bizData);
FlowHelper.setWebContinuation(objectModel, continuation);
PipelinesNode.getRedirector(environment)
.redirect(false, uri);
}
will proclaime the same forwarding behaviour accross all
implementations:
forward-uri --> results in actual forward to
no-leading-slash/whatever --> cocoon:/no-leading-slash/whatever
which maps onto a pipe in the current sitemap
/with-leading-slash/more --> cocoon://with-leading-slash/more
which maps to a pipe in the top-sitemap
scheme://full-uri --> unchanged
which assumes that the flowscript writer knows what he is
doing himself. this could even be a http:// uri which results in
a client-side redirect.
(see also
http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=105888316704512&w=2)
2/ renaming interfaces, classes and methods (and sitemap nodes)
Interpreter --> FlowProcessor
AbstractIntrepreter --> AbstractFlowProcessor
this probably ties up to the <flow-interpreters> becoming
<flow-processors> in the xconf
Interpreter.callFunction() --> FlowProcessor.initiateFlow()
Interpreter.handleContinuation() --> FlowProcessor.continueFlow()
which brings us back to the non-closed vote on changing sitemap
semantics that could be mirrored by one of the proposals:
map:call/@function --> map:initiate/@flow
map:call/@continuation --> map:continue/@flow
3/ signature change of callFunction and handleContinuation
In both methods the 2nd argument is a java.util.List of
Interpreter.Argument objects.
I understand that the scripting implementations require the thus
implied order on the <parameters>/arguments, however it would
make sense to maybe redesign this passed 2nd argument to allow
for both named or indexed lookup of the arguments...
(Currently just filling an additional hashmap from the List,
actuall it's no big hastle, just 'additional', and giving some
cosmetical unease)
4/ dispose() the wrapped continuation object upon invalidation
I'ld like the ContinuationsManager to check if the wrapped
continuation is implementing Disposable upon invalidation of it's
wrapper WebContinuation.
While at it it might preform the same service on the wrapped
'userObject' (although I have no direct need for this, it seems a
logical extension of the reasoning)
5/ multiple flow declarations inside one sitemap
Well, to be fair I haven't seen the need here and now, but the
discussion was also still open.
It still makes sense IMHO but I haven't got into proposing here
something myself.
-o0o-
[3][reflections on code-sharing]
For those that need to read the code to think about all of this I
am in the process of bundling up a first cut (rough stuff) as a
src-zip/jar file that could (eventually) be added as some sort of
a premature block....
I'm wide open to any suggestions about getting it to each or all
of you (bugzilla being my natural choice unless someone makes me
see differently)
-o0o-
[4][future directions]
First of all I'ld like to welcome any thought and code
participation on this, so this can really go into any direction...
here is some directions/aspects where I'ld like to get some
future investigation into:
(all of these should probably start off with checking up on the
current js implementation -- if someone knows by heart please
speak up)
- access control on live continuations (what if someone else uses
your kont-id?)
- synchronization/locking on live continuations (what if two
requests hit the same kont-id simultaneously)
- allow to programmically control the 'end-of-use-case' from the
Apple itself
- make time-to-live somewhat more configurable and maybe even
use-case controlled?
- get into the class-loader horror for dynamic reloading of these
Apples (possibly through some -hopefully existing- Avalon component)
thx for reading up to here...
regards,
-marc=
--
Marc Portier http://outerthought.org/
Outerthought - Open Source, Java & XML Competence Support Center
Read my weblog at http://radio.weblogs.com/0116284/
mpo@outerthought.org mpo@apache.org