| -----Ursprüngliche Nachricht-----
| Von: Sylvain Wallez [mailto:[EMAIL PROTECTED]
| Gesendet: Montag, 1. Mai 2006 11:11
| An: dev@cocoon.apache.org
| Betreff: Re: AW: AW: Desparately seeking help with pipeline implementation
| 
| Stefan Pietschmann wrote:
| > Hi Sylvain (and others),
| >
| > thank you for the quick response which finally helped me understand how
| the
| > pipeline is used at runtime.
| >
| 
| Great! The main point about pipelines is that they are basically empty
| shells that are filled with components by the sitemap engine, and
| cleaned up after the pipeline has been executed.
| 
| They don't keep component between different requests, since the actual
| components used and their parameters can change for every request, even
| for the same URL.
| 
| The fact that pipelines are recyclable (i.e. poolable) is just here to
| avoid having to go through the Avalon initialization stuff on each
| request. Now there initialization is so simple that they actually could
| be SingleThreaded rather than Recyclable and thus created anew at each
| request rather than pooled.
| 
| > What I do is to throw transformers out depending on their attributes
| (it's a
| > bit more complicated, but anyway..). Now that I see that the
| transformerlist
| > is built anew for every request I do not need to backup the original
| list
| > and load it everytime.
| 
| Right.
| 
| > I thought it would be built only once at the beginning.
| >
| 
| At the beginning of what? ;-)
| 
| > So my choices now are to overload the addTransformer() method, only
| adding a
| > transformer under certain circumstances, or leave my current
| implementation
| > which goes through this.transformers, this.transformerSources and
| > this.transformerParams, checks the parameters and throws the
| transformers,
| > sources and parameters out of the lists.
| > The first way seems easier, but it means that I have to copy the whole
| > method from the super class to my pipeline and change it there - I don't
| > like that because you I have to check for changes with every Cocoon
| update.
| > With the second way I can simply outsource the code going through the
| lists
| > to my own method and call it at the beginning of setupPipeline().
| >
| 
| Why would you have to copy the superclass source code? Just call
| super.addTransformer() if you need to and that's all, isn't it?
| 
| public void addTransformer(String role, String source, Parameters param,
| Parameters hintParam) {
|     if (keepTransformer(role, source, params, hintParam) {
|         super.addTransformer(role, source, params, hintParam);
|     }
| }

Right, this would be sufficient if I only had conditional transformers, but
my transformers have adaptable attributes as well which I would have to
check and adapt within addTransformer().

| Another option, if you need to do some complex computation on the
| transformer list is to overload setSerializer(). When this method is
| called, all transformers in the pipeline are there.
| 
| > I do have one more question - to make it right this time. If I prevent a
| > transformer from being added to the list in addTransformer(), or if I
| kick
| > it out in my method, I see I have to release it.
| 
| Yes.
| 
| > This is done by the following in AbstractProcessingPipeline:
| >
| > int size = this.transformerSelectors.size();
| > for (int i = 0; i < size; i++) {
| >   final ComponentSelector selector = (ComponentSelector)
| > this.transformerSelectors.get(i);
| >   selector.release((Component) this.transformers.get(i));
| >   this.newManager.release(selector);
| > }
| >
| > In my method it would look like:
| >
| > Iterator transformerItt = this.transformers.iterator();
| > ...
| > int i = 0;
| > while (transformerItt.hasNext()) {
| >       Transformer trans = (Transformer) transformerItt.next();
| >     ...
| >     // check if the transformer should be run
| >     ..
| >     // kick it out
| >       transformerItt.remove();
| >     // release transformer
| >     final ComponentSelector selector = (ComponentSelector)
| > this.transformerSelectors.get(i);
| >       selector.release((Component) trans);
| >     this.newManager.release(selector);
| >     i++;
| > }
| >
| > Right?
| >
| 
| That's the idea, but you have some bugs here since when you remove a
| transformer, you should also remove the corresponding selector and
| parameters:
| 
| for (int i = 0; i < this.transformers.size(); /* do not increment here */)
| {
|     if (trashTransformerAt(i)) {
|         // Release what needs to be
|         Transformer transf = (Transformer)this.transformers.get(i);
|         ComponentSelector selector =
| (ComponentSelector)this.transformerSelectors.get(i);
|         selector.release(transf);
|         this.newManager.release(selector);
| 
|         // Update lists
|         this.transformers.remove(i);
|         this.transformerSelectors.remove(i);
|         this.transformerParams.remove(i);
|         this.transformerSources.remove(i);
|     } else {
|         i++;
|     }
| }

I updated my code in the last mail I sent... including releasing the
selector. I did it with iterators though, which should work the same :\

| Be careful also that depending on the class you extend, there are a
| couple of other lists to update as well:
| - transformerRoles in AbstractCachingProcessingPipeline
| - isCachePoint in CachingPointPipeline

I'm extending the NonCachingProcessingPipeline at the moment, but need to do
that for the Caching one as well, so thank you!
 
| Sylvain
| 
| --
| Sylvain Wallez - http://bluxte.net

Reply via email to