cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Peter Hunsberger" <>
Subject Re: [Corona] PIpeline API
Date Thu, 17 Jul 2008 17:47:34 GMT
On Thu, Jul 17, 2008 at 11:22 AM, Andreas Hartmann <> wrote:
> Hi Peter,
> Peter Hunsberger schrieb:
>> On Thu, Jul 17, 2008 at 9:22 AM, Carsten Ziegeler <>
>> wrote:
>>> Andreas Hartmann wrote:
>>>> I don't think that the calling code has to know the actual components,
>>>> but rather the environment-specific interfaces of the components. It
>>>> only makes sense to pass an environment to a pipeline component if the
>>>> component is designed to use this environment.
>> Yeah, but if you've got really generic code this can be hard to figure
>> out....
> IMO there are two types of components which have to be generic:
> * the pipeline implementation
> * multi-purpose pipeline components
> The application itself is not generic, it knows which environment
> information to provide to the application-specific components.

Well yes and no.  In our case the application is generic, but that's
not the issue;  you're right that the application knows what to pass
in to the adapter (for any given application), the point is that
multiple applications can exist and all use the same adapter but pass
in different things.  For example, a servlet may have a Map of request
parameters but a CLI app may have a Array of command line parameters.

> For
> multi-purpose pipeline components (e.g., an event logger), an adapter class
> could be used (e.g., to pass an application-specific output stream to log
> the events to).


>> I keep wondering if this perhaps an Adapter type pattern?  You've
>> potentially got a lot of different types of applications that each
>> could have different requirements for setting up pipelines.
>> Similarly, you've potentially got a lot of different types of
>> pipelines (in particular since Corona isn't just SAX).   So what you
>> do is define some adapter that gets passed around and leave it up to
>> the adapter to manage the use case specifics,
>> Adaper adp = new MyUseCaseAdapter();
>> adp.setRequest(  req );
>>   .
>>   .
>>   .
>>  for (Iterator i = pipeline.getComponents().iterator(); … ) {
>>    PipelineComponent c = (PipelineComponent);
>>      c.setup(adp);
>>    }
> I'm not quite sure what c.setup() would look like. Perhaps like this?
> class XsltTransformer {
>  public void setup(Adapter adp) {
>    setXsltParams(adp.getXsltParams());
>  }
> }
> In this case, the Adapter implementation would have to provide methods for
> various types of pipeline components …
>> And then in the component:
>> Object myConfigParam = adp.getParam( NAME );
> But wouldn't this require a contract between the application and the
> components based on parameter names? I thought this is what we wanted to
> avoid, otherwise we could just use the Map suggested by Carsten …

Well yes, but that's a loose example.  I'd rather have specific setter
/ getters that the adapter knows how to handle.  But if someone (eg.
Carsten) has a pipelines that use maps with named parameters that's
fine,  one should be able to write (or extend) a generic adapter to
handle the specific expectations of a given pipeline.

> But I guess I'm misunderstanding something :)
>> has no knowledge of how the param (or params) was passed into the adapter.
>> The app is responsible for setting up the adapter with app specific
>> data and the adapter has multiple standard methods for allowing this
>> (and can be extended for new use cases).  The adapter is responsible
>> for passing it into the components in some more standardized way.
>> Think of the adapter as a data class with extra logic for converting
>> use case specific data into generic data.
> Hmm, what does the term "generic data" refer to? Would you mind giving an
> example? TIA!

In this case it would be up to the pipeline.  Like in the example
above, where someone  has a pipeline expecting a Map.

>> As such, the adapter can also be responsible for more than
>> initialization data, it can become the use case specific way of
>> communicating between the app and the components.  Instead of using
>> marker interfaces to define the use case specific responsibilities you
>> end up with the adapter having multiple methods for different use
>> cases as needed.
> As I understand it, one would have to provide application-specific adapters
> to "environmentalize" multi-purpose components; I don't see a way how this
> could be handled by a single adapter class for the whole application …

You do end up extending adapters for specific applications, but in
general you don't need a lot of them for any given application.
Instead of adding new adapters for new use cases you end up adding
methods to the adapters for the new use cases. The main reason to add
new adapters is to reduce unnecessary work; you don't want the adapter
converting  data into generic formats if it's not needed, but most of
the time this can be avoided by having the getters do the conversion
and not the setters.

> I'll think a bit more about this, sorry if my remarks are rubbish :)

This is such an abstract discussion I don't see how any of this could
be rubbish! Go back to your previous email on the Visitor pattern, you
summarized with:

> In this case the application can provide a layer of classes to adapt the standard pipeline
components to the application-specific environment.
> The marker interface check would allow to use other components as well - they just wouldn't
be "environmentalized".

I think we're chasing the same basic ideas it's a problem of fiduring
out where to do the work. I'm suggesting, in part, that we avoid the
Marker interfaces by adding use case specific methods to the "extra
layer of classes".   Basically take the code you run as a result of
finding a Marker interface and move it into a use case specific method
in the Adapter class.  Think of it this way, any time you would have
to recognize the existence of a Marker interface you instead call a
method in the adapter (that may or may not do anything depending on
the use case at hand).

This might all be overkill for the problem at hand, but I find it a
powerful way to build really generic code...

Peter Hunsberger

View raw message