cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Reinhard Pötz <>
Subject [c3] Pipeline results
Date Tue, 23 Dec 2008 07:28:38 GMT

Triggered by some discussions that Steven and I had with our students we
were thinking again about the pipeline API. Compared to previous
pipeline implementations we already made one improvement by making the
pipeline unaware of the data that flows between its components. This
means that the Cocoon 3 pipeline implementation doesn't impose any
limitations if it is SAX or StAX or whatever that is passed
from one component to another.

But still there is one limitation that has bugged me several times: The
result of all pipelines is that they write something into an output stream.
That's the original use case for pipelines used in servlet environments
and probably true in many cases but not in all.
One use case that I have is that I want to get the SAX events written
into a SAX buffer or some might want to make the pipeline write into
some content handler directly that they pass to it.

Another use case is when you want to use pipelines to create business
objects as their result. (I guess Simone can give more details here.)

In all these cases you don't need an output stream.

                                  - o -

In order to make the pipeline result pluggable, I propose following

I would like to introduce a generic Result interface which is the
transport vehicle for the actual result:

public interface Result<T> {

    void setResultObject(T o);

    T getResultObject();

And here is a possible implementation of a Result that carries
an output stream:

public class OutputStreamResult implements Result<OutputStream> {

    private OutputStream os;

    public OutputStream getResultObject() {
        return os;

    public void setResultObject(OutputStream o) {
        this.os = o;

    public String getContentType() {

    public long getLastModified() {

The pipeline interface would have to change accordingly:

public interface Pipeline<T> {

    void addComponent(PipelineComponent pipelineComponent);

    void addComponent(Finisher<T> finisher);

    void execute() throws Exception;

    void setup(Result<T> result);

    void setup(Result<T> result, Map<String, Object> parameters);

    void setConfiguration(Map<String, ? extends Object> parameters);

As you can see, the methods getContentType() and getLastModified() were
moved to the result object where they fit much better IMO because both
are specific for our output stream use case.

And thanks to generics, the compiler makes sure that only a Finisher (=
serializer) can be added to the pipeline if it supports a particular
result type:

public interface Finisher<T> extends PipelineComponent {

    void setResult(Result<T> result);


Reinhard Pötz                           Managing Director, {Indoqa} GmbH

Member of the Apache Software Foundation
Apache Cocoon Committer, PMC member        

View raw message