| -----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