Re: [Corona] PIpeline API

2008-07-17 Thread Ralph Goers



Carsten Ziegeler wrote:


Now all these examples assume that the calling code knows the components.
For my use case - and it's the same with the Cocoon sitemap - I've a
description of a pipeline (think of the sitemap) which has just the name
of the pipeline components to chain. A generic code instantiates these
pipeline components - through a service registry - and does not know 
anything about these components apart from the fact that they are 
pipeline components.



Can you show an example?

Can they be declared as Spring beans and wired with the appropriate 
parameters, or at least beans that know how to dynamically obtain the 
correct information and then be referenced in the sitemap?


Ralph


Re: [Corona] PIpeline API

2008-07-17 Thread Carsten Ziegeler

Ralph Goers wrote:



Can you show an example?

Can they be declared as Spring beans and wired with the appropriate 
parameters, or at least beans that know how to dynamically obtain the 
correct information and then be referenced in the sitemap?


Ok, this all depends on what you consider configuration vs execution 
information. If you look at the current Cocoon sitemap components 
they've only a little configuration (everything that can be configured 
in the components section of the sitemap). Most information is passed 
in as execution information like the source to read from or any 
additional paramter.


The component configuration can be easily done by a spring bean 
configuration. The execution information is the interesting part as this 
is different between each pipeline run.


So, some pseudo code could look like this:

// read configuration of pipeline from somewhere
String type = // the component type
Map m = // the execution information

Transformer t = springContext.getBean(type);
t.setup(m);

Now, my configuration of the pipeline is actually stored in a JCR :) but 
this is comparable with using the sitemap.xmap. Of course it should 
contain a src information for the transformer to work.


Carsten
--
Carsten Ziegeler
[EMAIL PROTECTED]


Re: [Corona] PIpeline API

2008-07-17 Thread Ralph Goers

Carsten Ziegeler wrote:


Ok, this all depends on what you consider configuration vs execution 
information. If you look at the current Cocoon sitemap components 
they've only a little configuration (everything that can be configured 
in the components section of the sitemap). Most information is 
passed in as execution information like the source to read from or any 
additional paramter.


The component configuration can be easily done by a spring bean 
configuration. The execution information is the interesting part as 
this is different between each pipeline run.
You've seen the sitemaps and configuration we used. Often we would code 
something like src=${request:bankid}/somedata.xml in the xconf (Spring 
configuration). On every execution bankid would be dynamically resolved 
so that every request could be on behalf of different banks. Of course, 
the ability to do this is highly dependent on the components ability (or 
the sitemap's) ability to perform variable resolution. We were often 
force to do something like src=cocoon://${request:bankid}/somedata.xml 
just to get around this. 
Wouldn't liberal use of this concept solve the problem?


So, some pseudo code could look like this:

// read configuration of pipeline from somewhere
String type = // the component type
Map m = // the execution information

Transformer t = springContext.getBean(type);
t.setup(m);

Now, my configuration of the pipeline is actually stored in a JCR :) 
but this is comparable with using the sitemap.xmap. Of course it 
should contain a src information for the transformer to work.
Are you just getting the pipeline via WebDav? If so that isn't really 
any different. If you are using the JCR API that could probably just be 
abstracted into a JCR protocol handler.


Am I missing something?

Ralph


Re: [Corona] PIpeline API

2008-07-17 Thread Andreas Hartmann

Hi Carsten,

Carsten Ziegeler schrieb:

[…]


I'd imagine something like this:

public void parameterizeTransformers(Request req, Pipeline pipeline) {
  for (Iterator i = pipeline.getTransformers().iterator(); … ) {
Transformer t = (Transformer) i.next();
if (t instanceof WebappXsltTransformer) {
  WebappXsltTransformer xsltTr = (WebappXsltTransformer) t;
  if (xsltTr.useRequestParameters()) {
xsltTr.setXsltParams(req.getParameterMap());
  }
}
  }
}


Now all these examples assume that the calling code knows the components.


Maybe we have to differentiate between two aspects of execution environment:

1) Information that is not contained in the pipeline description, e.g. 
the request in a web application


2) Parameters which are part of the pipeline description DSL (like 
map:parameter/ in Cocoon)


The second aspect could be handled by the pipeline DSL interpreter in a 
generic way. I imagine something like this:


  match wildcard(pattern: *) :
  generate xml(uri: context://{1}.xml) 
  transform xslt(stylesheet: {request-param:style}, xsltParams: …) 
  serialize xml;

The DSL interpreter would use reflection to call the setStylesheet() and 
setXsltParams() methods of the XsltTransformer. A resolver service would 
be used for parameter expansion, e.g. for input module calls in Cocoon.


About the first aspect:

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. Maybe I can try to come
up with a more generic example:

public interface WebappPipelineComponent extends PipelineComponent {
  void setRequest(Request request);
}

Client code inside a web application:

public void parameterizeComponents(Request req, Pipeline pipeline) {
  for (Iterator i = pipeline.getComponents().iterator(); … ) {
PipelineComponent c = (PipelineComponent) i.next();
if (c instanceof WebappPipelineComponent) {
  WebappPipelineComponent wpc = (…) c;
  wpc.setRequest(req);
}
  }
}

The pipeline is executed in a specific environment. The actual
pipeline object itself is oblivious of the environment information, but
the pipeline components are directly dependent on the environment.

You gave this example in a subsequent mail:

  String type = // the component type
  Map m = // the execution information

  Transformer t = springContext.getBean(type);
  t.setup(m);

IIUC this code would be part of the pipeline executor implementation. 
I assume that m only contains information in the sense of aspect 1 
described above, because the DSL params wouldn't have to be passed to 
the pipeline. If this is the case, there has to be client code like this:


  Map m = new HashMap();
  m.put(request, this.request);
  pipelineExecutor.setEnvironment(m);

Passing the environment to the pipeline is only necessary if there might 
be some pipeline components which could be interested in the request 
object. Wouldn't it then make sense to pass this information directly to 
these components, like in the parameterizeComponents() method above?


-- Andreas



--
Andreas Hartmann, CTO
BeCompany GmbH
http://www.becompany.ch
Tel.: +41 (0) 43 818 57 01



Re: [Corona] PIpeline API

2008-07-17 Thread Carsten Ziegeler

Andreas Hartmann wrote:
 SNIP/


The DSL interpreter would use reflection to call the setStylesheet() and 
setXsltParams() methods of the XsltTransformer. A resolver service would 
be used for parameter expansion, e.g. for input module calls in Cocoon.
Yes, sure, reflection tricks could be used instead of course. This would 
also detect typos in the parameters as the according set method would 
not be available.



About the first aspect:

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. 

Agreed.

 Maybe I can try to come

up with a more generic example:

public interface WebappPipelineComponent extends PipelineComponent {
  void setRequest(Request request);
}

Client code inside a web application:

public void parameterizeComponents(Request req, Pipeline pipeline) {
  for (Iterator i = pipeline.getComponents().iterator(); … ) {
PipelineComponent c = (PipelineComponent) i.next();
if (c instanceof WebappPipelineComponent) {
  WebappPipelineComponent wpc = (…) c;
  wpc.setRequest(req);
}
  }
}

The pipeline is executed in a specific environment. The actual
pipeline object itself is oblivious of the environment information, but
the pipeline components are directly dependent on the environment.
Hmm, yes this would work, but :) this would make it harder to have a 
reusable pipeline implementation that frees my application from passing 
the information to the components.
Currently the app creates a map, passed it to the pipeline 
implementation and this implementation passes the map on to the components.
With the approach above, I would need a custom pipeline implementation 
to do this. Furthermore there might be a lot of marker interfaces to test.

Actually I'm not sure which approach is nicer :)

Carsten


--
Carsten Ziegeler
[EMAIL PROTECTED]


Re: [Corona] PIpeline API

2008-07-17 Thread Peter Hunsberger
On Thu, Jul 17, 2008 at 9:22 AM, Carsten Ziegeler [EMAIL PROTECTED] 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

 Agreed.

 Maybe I can try to come

 up with a more generic example:

 public interface WebappPipelineComponent extends PipelineComponent {
  void setRequest(Request request);
 }

 Client code inside a web application:

 public void parameterizeComponents(Request req, Pipeline pipeline) {
  for (Iterator i = pipeline.getComponents().iterator(); … ) {
PipelineComponent c = (PipelineComponent) i.next();
if (c instanceof WebappPipelineComponent) {
  WebappPipelineComponent wpc = (…) c;
  wpc.setRequest(req);
}
  }
 }

 The pipeline is executed in a specific environment. The actual
 pipeline object itself is oblivious of the environment information, but
 the pipeline components are directly dependent on the environment.

 Hmm, yes this would work, but :) this would make it harder to have a
 reusable pipeline implementation that frees my application from passing the
 information to the components.
 Currently the app creates a map, passed it to the pipeline implementation
 and this implementation passes the map on to the components.
 With the approach above, I would need a custom pipeline implementation to do
 this. Furthermore there might be a lot of marker interfaces to test.
 Actually I'm not sure which approach is nicer :)

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) i.next();
  c.setup(adp);
}

And then in the component:

Object myConfigParam = adp.getParam( NAME );

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

-- 
Peter Hunsberger


Re: [Corona] PIpeline API

2008-07-17 Thread Andreas Hartmann

Carsten Ziegeler schrieb:

[…]


Client code inside a web application:

public void parameterizeComponents(Request req, Pipeline pipeline) {
  for (Iterator i = pipeline.getComponents().iterator(); … ) {
PipelineComponent c = (PipelineComponent) i.next();
if (c instanceof WebappPipelineComponent) {
  WebappPipelineComponent wpc = (…) c;
  wpc.setRequest(req);
}
  }
}

The pipeline is executed in a specific environment. The actual
pipeline object itself is oblivious of the environment information, but
the pipeline components are directly dependent on the environment.


Hmm, yes this would work, but :) this would make it harder to have a 
reusable pipeline implementation that frees my application from passing 
the information to the components.


Does it make a big difference if the information is passed to the 
pipeline or to the components? To get rid of the boilerplate loop above, 
the visitor pattern could be used:


public class Webapp implements PipelineEnvironment {

  public void preparePipelineForExecution() {
// let the pipeline visit its components
this.pipeline.setEnvironment(this);
  }

  /**
   * @see PipelineEnvironment.environmentalize(…)
   */
  public void environmentalize(PipelineComponent c) {
if (c instanceof WebappPipelineComponent) {
  WebappPipelineComponent wpc = (…) c;
  wpc.setRequest(req);
}
  }

}


Currently the app creates a map, passed it to the pipeline 
implementation and this implementation passes the map on to the components.
With the approach above, I would need a custom pipeline implementation 
to do this.


Hmm, why would you need a custom pipeline implementation? Wouldn't this 
be generic enough:


public class PipelineImpl implements Pipeline {

  public void setEnvironment(PipelineEnvironment env) {
for (Iterator i = getComponents().iterator(); … ) {
  PipelineComponent c = (…) i.next();
  env.environmentalize(c);
}
  }

}



Furthermore there might be a lot of marker interfaces to test.


The marker interfaces wouldn't be generic, but application-specific, so 
there would only be one needed per application.


I imagine to use application-specific wrappers for standard pipeline 
components, e.g.


public class WebappXsltTransformerWrapper implements Transformer,
  WebappPipelineComponent {

  private XsltTransformer delegate;

  public void setRequest(Request req) {
if (this.useRequestParams()) {
  this.delegate.setXsltParams(req.getParameterMap());
}
  }
}

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.


-- Andreas



--
Andreas Hartmann, CTO
BeCompany GmbH
http://www.becompany.ch
Tel.: +41 (0) 43 818 57 01



Re: [Corona] PIpeline API

2008-07-17 Thread Andreas Hartmann

Hi Peter,

Peter Hunsberger schrieb:

On Thu, Jul 17, 2008 at 9:22 AM, Carsten Ziegeler [EMAIL PROTECTED] 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. 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) i.next();
  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 …


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!



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 …


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

-- Andreas


--
Andreas Hartmann, CTO
BeCompany GmbH
http://www.becompany.ch
Tel.: +41 (0) 43 818 57 01



Re: [Corona] PIpeline API

2008-07-17 Thread Peter Hunsberger
On Thu, Jul 17, 2008 at 11:22 AM, Andreas Hartmann [EMAIL PROTECTED] wrote:
 Hi Peter,

 Peter Hunsberger schrieb:

 On Thu, Jul 17, 2008 at 9:22 AM, Carsten Ziegeler [EMAIL PROTECTED]
 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).



Yup...

[…]

 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) i.next();
  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 

Re: [Corona] PIpeline API

2008-07-17 Thread Steven Dolg

Peter Hunsberger schrieb:

On Thu, Jul 17, 2008 at 9:22 AM, Carsten Ziegeler [EMAIL PROTECTED] 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

  

Agreed.



Maybe I can try to come

up with a more generic example:

public interface WebappPipelineComponent extends PipelineComponent {
 void setRequest(Request request);
}

Client code inside a web application:

public void parameterizeComponents(Request req, Pipeline pipeline) {
 for (Iterator i = pipeline.getComponents().iterator(); … ) {
   PipelineComponent c = (PipelineComponent) i.next();
   if (c instanceof WebappPipelineComponent) {
 WebappPipelineComponent wpc = (…) c;
 wpc.setRequest(req);
   }
 }
}

The pipeline is executed in a specific environment. The actual
pipeline object itself is oblivious of the environment information, but
the pipeline components are directly dependent on the environment.
  

Hmm, yes this would work, but :) this would make it harder to have a
reusable pipeline implementation that frees my application from passing the
information to the components.
Currently the app creates a map, passed it to the pipeline implementation
and this implementation passes the map on to the components.
With the approach above, I would need a custom pipeline implementation to do
this. Furthermore there might be a lot of marker interfaces to test.
Actually I'm not sure which approach is nicer :)



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) i.next();
  c.setup(adp);
}

And then in the component:

Object myConfigParam = adp.getParam( NAME );

has no knowledge of how the param (or params) was passed into the adapter.
  

AFAIK an adapter is used to adapt one interface or class to another.
So what does the adapter adapt - what's the adapted class/interface?

Since c.setup(adp) belongs to the general PipelineComponent, the 
MyUseCaseAdapter has to be passed as Adapter (exactly as described above).
So this way providing parameters might become easier, but IMO reading 
parameters (inside the component) is just the same as using a map (also 
exactly as described above).

Except you want to go for a downcast... ;-)

Furthermore MyUseCaseAdapter would have to account for every possible 
configuration requirement of every component that might be in the pipeline.

This could be become quite messy if the pipeline is assembled dynamically.


The other thing I'm sure about:
Why would I want to iterate over the pipeline components?
Somehow I think it should not be necessary that client (or sitemap) code 
directly accesses the components of a pipeline after it is assembled.
That's also the reason, why there is no method to expose the components 
on the pipeline interface.


The Law of Demeter is surely something to argue about, but IMO it is 
usually better to follow it - unless you have a good reason, which I 
fail to see here.



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

  




Re: [Corona] PIpeline API

2008-07-17 Thread Peter Hunsberger
On Thu, Jul 17, 2008 at 5:27 PM, Steven Dolg [EMAIL PROTECTED] wrote:
 Peter Hunsberger schrieb:


snip/

 AFAIK an adapter is used to adapt one interface or class to another.
 So what does the adapter adapt - what's the adapted class/interface?

Well given that the entire discussion is abstract that's sort of hard
to answer.  However, I sort of covered a bit of this, if Corona is
going to support non SAX pipelines they you've to assume source and
sinks that you'll want to mix and match.  In addition you can assume
multiple  types of applications, for example Servlets and Command Line
(and I'm sure others).  Whenever I see three distinct orthogonal class
dimensions like this it seems that you end up with a multitude of
constructors or initialization methods each taking a set of different
of classes. I'm basically proposing that instead we end up with a
single set of Adapter classes instead.  The exterior classes (being
adapted from)  come from  the application specific environments and
may be Servlet context, pipeline config, command line params or even
the output of other pipelines (I've got a secret agenda here).  The
interior classes (those we adapting to) are yet to be defined but are
basically going to configure the pipeline components.



 Since c.setup(adp) belongs to the general PipelineComponent, the
 MyUseCaseAdapter has to be passed as Adapter (exactly as described above).
 So this way providing parameters might become easier, but IMO reading
 parameters (inside the component) is just the same as using a map (also
 exactly as described above).
 Except you want to go for a downcast... ;-)

Umm no,  I'm trying to move away from something like a Map, the
example was just  because Carsten was already using a Map and there
shoudl be no reason that the Adapter shouldn't make it easy for him to
retain most of his existing code.


 Furthermore MyUseCaseAdapter would have to account for every possible
 configuration requirement of every component that might be in the pipeline.
 This could be become quite messy if the pipeline is assembled dynamically.


nto sure how you figure this?  If there is a mess the adapter makes it
easier to handle, not worse, since you;'re basically converting to a
canonical form instead of having something like N X M transforms.


 The other thing I'm sure about:
 Why would I want to iterate over the pipeline components?

That was from the previous code as an example of pipeline
configuration (I think).  I'm guessing this is similar to Cocoon where
all the Setup methods are run for the pipelnie.

 Somehow I think it should not be necessary that client (or sitemap) code
 directly accesses the components of a pipeline after it is assembled.
 That's also the reason, why there is no method to expose the components on
 the pipeline interface.

Yea, the implementation sketched out is part of the internal Corona
code, it's not something the client / app code should see.

Gotta run, hope that doesn't confuse things even more...

-- 
Peter Hunsberger


Re: [Corona] PIpeline API

2008-07-16 Thread Joerg Heinicke
Torsten Curdt tcurdt at apache.org writes:

 The question if those configuration are needed in a generic form in  
 the API. (I doubt it) As I would expect them to be implementation  
 specific a configuration callback that sets up the pipeline might be a  
 way around this?

I guess we are on the same position on this one, setup and clean up are usually
implementation specific and should therefore not be part of the API. Even for
the finish() method it might be necessary to pass a context or parameters.
Already passing it in setup() might be an option, but then you force the
component to have special handling for thread-safety.

Carsten Ziegeler cziegeler at apache.org writes:

 I added now a finish method which is called by the pipeline implementation.
 This keeps me free from any configuration hassels with the various 
 containers. Some want to use spring, some others something different.

But that's exactly what these container are there for.

 And perhaps someone doesn't want to use a container at all, just 
 instantiate the objects, run the pipeline and that's it.

By just instantiating the objects you know exactly with which implementation you
work - and which setup and finish method you are supposed to call.

 Therefore I really think that these lifecycle methods belong to the api.

That's what I don't agree with :-)

 I see no other reliable way of closing resources.

A listener/callback approach would be cleaner for the API, but more complex.
Question is if it needs to be part of the API at all.

Joerg



Re: [Corona] PIpeline API

2008-07-16 Thread Carsten Ziegeler

Joerg Heinicke wrote:


A listener/callback approach would be cleaner for the API, but more complex.
Question is if it needs to be part of the API at all.

We're not talking about component configuration here, we are talking 
about providing runtime/environment information for a pipeline run. 
Think of the request/response object for the servlet case. I think it's 
more convenient to pass this information through the api, than providing 
some callback. And then is the question, how does a component get the 
object it cann call as a callback?


Carsten

--
Carsten Ziegeler
[EMAIL PROTECTED]


Re: [Corona] Pipeline API

2008-07-16 Thread Reinhard Pötz

Joerg Heinicke wrote:

Torsten Curdt tcurdt at apache.org writes:

The question if those configuration are needed in a generic form in  
the API. (I doubt it) As I would expect them to be implementation  
specific a configuration callback that sets up the pipeline might be a  
way around this?


I guess we are on the same position on this one, setup and clean up are usually
implementation specific and should therefore not be part of the API. Even for
the finish() method it might be necessary to pass a context or parameters.
Already passing it in setup() might be an option, but then you force the
component to have special handling for thread-safety.

Carsten Ziegeler cziegeler at apache.org writes:


I added now a finish method which is called by the pipeline implementation.
This keeps me free from any configuration hassels with the various 
containers. Some want to use spring, some others something different.


But that's exactly what these container are there for.

And perhaps someone doesn't want to use a container at all, just 
instantiate the objects, run the pipeline and that's it.


By just instantiating the objects you know exactly with which implementation you
work - and which setup and finish method you are supposed to call.


Therefore I really think that these lifecycle methods belong to the api.


That's what I don't agree with :-)


I see no other reliable way of closing resources.


A listener/callback approach would be cleaner for the API, but more complex.
Question is if it needs to be part of the API at all.


Can you provide an example how your ideas would materialize as Java code?

--
Reinhard Pötz   Managing Director, {Indoqa} GmbH
 http://www.indoqa.com/en/people/reinhard.poetz/

Member of the Apache Software Foundation
Apache Cocoon Committer, PMC member  [EMAIL PROTECTED]



Re: [Corona] PIpeline API

2008-07-16 Thread Andreas Hartmann

Hi Cocoon devs,

I'd be very interested in a pipeline API for Sling, so I'd like to 
understand this discussion. Please excuse any unqualified remarks :)


Carsten Ziegeler schrieb:
A listener/callback approach would be cleaner for the API, but more 
complex.

Question is if it needs to be part of the API at all.

We're not talking about component configuration here, we are talking 
about providing runtime/environment information for a pipeline run. 
Think of the request/response object for the servlet case. I think it's 
more convenient to pass this information through the api, than providing 
some callback. And then is the question, how does a component get the 
object it cann call as a callback?


Just for my understanding:

Is the context (runtime/environment) information used by the pipeline 
itself, or only by the pipeline components? From an SoC point of view 
I'd assume that the pipeline implementation is independent from the 
execution environment. I'd imagine it to handle only pipelining aspects:


* wiring components together
* passing events
* caching
* … ?

If this is the case, wouldn't it be more appropriate to pass the context 
information to the pipeline components without bothering the pipeline 
object itself? Or is it intended that the pipeline is seen as a black 
box after it has been set up, to simplify the parameterization of all 
its components?


Thanks for any clarification!

-- Andreas



--
Andreas Hartmann, CTO
BeCompany GmbH
http://www.becompany.ch
Tel.: +41 (0) 43 818 57 01



Re: [Corona] PIpeline API

2008-07-16 Thread Sylvain Wallez

Carsten Ziegeler wrote:

Peter Hunsberger wrote:
On Tue, Jul 15, 2008 at 5:42 AM, Reinhard Pötz [EMAIL PROTECTED] 
wrote:



Are you talking about passing the input parameters as parameters of the
setup() method?

void setup(MapString, Object inputParameters)

I'd be fine by this.



I hate seeing Maps used as dumping grounds for randomly typed objects.
Could you use something that gives a little more strong typing?
Perhaps more like a ServletContext though I don't think I'd go that
far in this case?

I agree that strong typing would be great - but the pipeline api does 
not define any concrete key/object for the map. So this is use-case 
specific. Therefore I think a map is the best we can come up.


Trying to catch up on this discussion. What parameters are we talking 
about exactly? Are these pipeline parameters?


What's the need for that? Can't we just give the parameters they need 
individually to every pipeline component, thus allowing per-component 
strongly typed and well defined contracts?


Sylvain

--
Sylvain Wallez - http://bluxte.net



Re: [Corona] PIpeline API

2008-07-16 Thread Grzegorz Kossakowski

Andreas Hartmann pisze:

Just for my understanding:

Is the context (runtime/environment) information used by the pipeline 
itself, or only by the pipeline components? From an SoC point of view 
I'd assume that the pipeline implementation is independent from the 
execution environment. I'd imagine it to handle only pipelining aspects:


* wiring components together
* passing events
* caching
* … ?


I agree here. Thanks Andreas for reminding me my own thoughts (that are similar to yours) that I had 
at ApacheCon when Reinhard was explaining Corona's design.


Now I can join the discussion. :-)

If this is the case, wouldn't it be more appropriate to pass the context 
information to the pipeline components without bothering the pipeline 
object itself? Or is it intended that the pipeline is seen as a black 
box after it has been set up, to simplify the parameterization of all 
its components?


Even if it's the case, should be this black box pipeline just one of the possible implementations? 
Then it would be a pipeline implementation that sets up components and passes what's needed. In some 
cases that would make a perfect sense.


--
Best regards,
Grzegorz Kossakowski


Re: [Corona] PIpeline API

2008-07-16 Thread Bertrand Delacretaz
On Wed, Jul 16, 2008 at 5:14 AM, Sylvain Wallez [EMAIL PROTECTED] wrote:

 ...Can't we just give the parameters they need
 individually to every pipeline component, thus allowing per-component
 strongly typed and well defined contracts?..

I'm also catching up on this thread but I tend to agree with the above
suggestion, i.e. something like

  Transformer t = new XsltTransformer();
  t.setXslt(cocoon:/mytransform.xsl);
  t.setRequestParameters(request.getParameterMap());
  ...

looks clearer than

  Transformer t = new XslTransformer(opaqueMapOfParameters);

And the second form could be added later, if needed for some other reason.

I didn't even look at Corona lately, no idea how things work
currently, just trying to explain how I'd like things to be.

-Bertrand


Re: [Corona] PIpeline API

2008-07-16 Thread Carsten Ziegeler

Bertrand Delacretaz wrote:

On Wed, Jul 16, 2008 at 5:14 AM, Sylvain Wallez [EMAIL PROTECTED] wrote:


...Can't we just give the parameters they need
individually to every pipeline component, thus allowing per-component
strongly typed and well defined contracts?..


I'm also catching up on this thread but I tend to agree with the above
suggestion, i.e. something like

  Transformer t = new XsltTransformer();
  t.setXslt(cocoon:/mytransform.xsl);
  t.setRequestParameters(request.getParameterMap());
  ...

Ok, in this case you can't use Transformer as the class type. This 
would be:

XsltTransformer t = ...

Now, it seems that we are still mixing up things here. As I said, I'm 
not talking about configuration of the components. The stylesheet from 
above is a configuration.
We're talking about information about the current environment for 
executing the already configured pipeline.


Carsten

--
Carsten Ziegeler
[EMAIL PROTECTED]


Re: [Corona] PIpeline API

2008-07-16 Thread Andreas Hartmann

Carsten Ziegeler schrieb:

Bertrand Delacretaz wrote:
On Wed, Jul 16, 2008 at 5:14 AM, Sylvain Wallez [EMAIL PROTECTED] 
wrote:



...Can't we just give the parameters they need
individually to every pipeline component, thus allowing per-component
strongly typed and well defined contracts?..


I'm also catching up on this thread but I tend to agree with the above
suggestion, i.e. something like

  Transformer t = new XsltTransformer();
  t.setXslt(cocoon:/mytransform.xsl);
  t.setRequestParameters(request.getParameterMap());
  ...

Ok, in this case you can't use Transformer as the class type. This 
would be:

XsltTransformer t = ...

Now, it seems that we are still mixing up things here. As I said, I'm 
not talking about configuration of the components. The stylesheet from 
above is a configuration.
We're talking about information about the current environment for 
executing the already configured pipeline.


IIUC the request parameters in the above example would belong to the 
execution environment, wouldn't they?


I'd imagine something like this:

public void parameterizeTransformers(Request req, Pipeline pipeline) {
  for (Iterator i = pipeline.getTransformers().iterator(); … ) {
Transformer t = (Transformer) i.next();
if (t instanceof WebappXsltTransformer) {
  WebappXsltTransformer xsltTr = (WebappXsltTransformer) t;
  if (xsltTr.useRequestParameters()) {
xsltTr.setXsltParams(req.getParameterMap());
  }
}
  }
}

IMO passing the execution environment to a pipeline component depends 
very much on the nature of the environment, and also on the nature of 
the individual components. I'm not sure if it should be attempted to 
find a generic API for this. Wouldn't it be sufficient to let the client 
code handle this? I guess this is what Torsten and Jörg had in mind when 
they suggested a callback mechanism:



public class ServletPipelineInvoker {

  protected Pipeline createPipeline() {
Pipeline pipeline = new NonCachingPipeline();
pipeline.addListener(this);
return pipeline;
  }

  /**
   * Called before pipeline execution.
   * @see PipelineListener.contextualizePipeline(Pipeline)
   */
  public void contextualizePipeline(Pipeline pipeline) {
parameterizeTransformers(this.request, pipeline);
  }

}


-- Andreas


--
Andreas Hartmann, CTO
BeCompany GmbH
http://www.becompany.ch
Tel.: +41 (0) 43 818 57 01



Re: [Corona] PIpeline API

2008-07-16 Thread Carsten Ziegeler

Andreas Hartmann schrieb:

Carsten Ziegeler schrieb:

Bertrand Delacretaz wrote:
On Wed, Jul 16, 2008 at 5:14 AM, Sylvain Wallez [EMAIL PROTECTED] 
wrote:



...Can't we just give the parameters they need
individually to every pipeline component, thus allowing per-component
strongly typed and well defined contracts?..


I'm also catching up on this thread but I tend to agree with the above
suggestion, i.e. something like

  Transformer t = new XsltTransformer();
  t.setXslt(cocoon:/mytransform.xsl);
  t.setRequestParameters(request.getParameterMap());
  ...

Ok, in this case you can't use Transformer as the class type. This 
would be:

XsltTransformer t = ...

Now, it seems that we are still mixing up things here. As I said, I'm 
not talking about configuration of the components. The stylesheet from 
above is a configuration.
We're talking about information about the current environment for 
executing the already configured pipeline.


IIUC the request parameters in the above example would belong to the 
execution environment, wouldn't they?


I'd imagine something like this:

public void parameterizeTransformers(Request req, Pipeline pipeline) {
  for (Iterator i = pipeline.getTransformers().iterator(); … ) {
Transformer t = (Transformer) i.next();
if (t instanceof WebappXsltTransformer) {
  WebappXsltTransformer xsltTr = (WebappXsltTransformer) t;
  if (xsltTr.useRequestParameters()) {
xsltTr.setXsltParams(req.getParameterMap());
  }
}
  }
}


Now all these examples assume that the calling code knows the components.
For my use case - and it's the same with the Cocoon sitemap - I've a
description of a pipeline (think of the sitemap) which has just the name
of the pipeline components to chain. A generic code instantiates these
pipeline components - through a service registry - and does not know 
anything about these components apart from the fact that they are 
pipeline components.


Carsten

--
Carsten Ziegeler
[EMAIL PROTECTED]


Re: [Corona] PIpeline API

2008-07-16 Thread Steven Dolg

Carsten Ziegeler schrieb:

Andreas Hartmann schrieb:

Carsten Ziegeler schrieb:

Bertrand Delacretaz wrote:
On Wed, Jul 16, 2008 at 5:14 AM, Sylvain Wallez 
[EMAIL PROTECTED] wrote:



...Can't we just give the parameters they need
individually to every pipeline component, thus allowing per-component
strongly typed and well defined contracts?..


I'm also catching up on this thread but I tend to agree with the above
suggestion, i.e. something like

  Transformer t = new XsltTransformer();
  t.setXslt(cocoon:/mytransform.xsl);
  t.setRequestParameters(request.getParameterMap());
  ...

Ok, in this case you can't use Transformer as the class type. This 
would be:

XsltTransformer t = ...

Now, it seems that we are still mixing up things here. As I said, 
I'm not talking about configuration of the components. The 
stylesheet from above is a configuration.
We're talking about information about the current environment for 
executing the already configured pipeline.


IIUC the request parameters in the above example would belong to the 
execution environment, wouldn't they?


I'd imagine something like this:

public void parameterizeTransformers(Request req, Pipeline pipeline) {
  for (Iterator i = pipeline.getTransformers().iterator(); … ) {
Transformer t = (Transformer) i.next();
if (t instanceof WebappXsltTransformer) {
  WebappXsltTransformer xsltTr = (WebappXsltTransformer) t;
  if (xsltTr.useRequestParameters()) {
xsltTr.setXsltParams(req.getParameterMap());
  }
}
  }
}


Now all these examples assume that the calling code knows the components.
For my use case - and it's the same with the Cocoon sitemap - I've a
description of a pipeline (think of the sitemap) which has just the name
of the pipeline components to chain. A generic code instantiates these
pipeline components - through a service registry - and does not know 
anything about these components apart from the fact that they are 
pipeline components.

I completely agree here.
Specific situations might allow specific solutions, e.g. providing 
listeners/callbacks while creating the individual components.
However a more general solution that also supports more general 
scenarios like the one described above (components are created by a 
service/factory/etc.) should also be available.


I wouldn't mind having a general purpose setup/teardown (or 
preExecution/postExecution, etc.) method defined and called by the 
pipeline API itself.
Might not be a good example, but JUnit provides such methods for unit 
tests and does not delegate this to another framework/container that 
might or might not be available, since this is a genuine requirement for 
certain tasks to be solved with the framework.


However the listener approach also appears to be appealing to me. 
Although I'm not entirely sure this would be as easy to use as the 
lifecycle methods proposed before (especially when a pipeline is built 
by the sitemap engine or service/factory).


Steven


Carsten





Re: [Corona] PIpeline API

2008-07-15 Thread Carsten Ziegeler

Reinhard Pötz wrote:


currently corona-pipeline (pipeline API, pipeline impls, SAX components) 
only has a dependency on commons-logging. Is this good enough for your 
needs?

:) Ok, that should be fine.

I've moved the action to the sitemap module and split up execute into 
setup and execute. I think we should specify in the contract that a 
modifiable map is passed to the components during setup. Any objections?


I'm wondering if we need the ErrorThrowingAction and the CustomException?

I'll add a setup/cleanup method to the components next.

Carsten


--
Carsten Ziegeler
[EMAIL PROTECTED]


Re: [Corona] PIpeline API

2008-07-15 Thread Reinhard Pötz

Carsten Ziegeler wrote:

Reinhard Pötz wrote:


currently corona-pipeline (pipeline API, pipeline impls, SAX 
components) only has a dependency on commons-logging. Is this good 
enough for your needs?

:) Ok, that should be fine.

I've moved the action to the sitemap module and split up execute into 
setup and execute. I think we should specify in the contract that a 
modifiable map is passed to the components during setup. Any objections?


Currently sitemap components get passed to maps:

 1. the input parameters (a map of all objects that you want to pass
to a pipeline)

 2. the configuration parameters (to provide a way to pass parameters
from the sitemap to the component - for API usage those parameters
are usually passed by constructor parameters or by setters).

Are you talking about passing the input parameters as parameters of the 
setup() method?


void setup(MapString, Object inputParameters)

I'd be fine by this.


I'm wondering if we need the ErrorThrowingAction and the CustomException?


That is only needed for some integration tests in corona-sample where 
they should be moved to.



I'll add a setup/cleanup method to the components next.


ok

--
Reinhard Pötz   Managing Director, {Indoqa} GmbH
 http://www.indoqa.com/en/people/reinhard.poetz/

Member of the Apache Software Foundation
Apache Cocoon Committer, PMC member  [EMAIL PROTECTED]



Re: [Corona] PIpeline API

2008-07-15 Thread Joerg Heinicke
Carsten Ziegeler cziegeler at apache.org writes:

  c) Pre and post processing
  As the pipeline interfaces are not tied to sax or any other model 
  (which is ok), there is no explicit notion of indicating that the 
  processing starts or is finished - the latter is especially 
  interesting for cleanup. So I think we should add these two lifecycle 
  methods to the pipeline component interface.
  
  I don't see any problem either. Being curious, what are your use cases?
 I've some pipeline components that open/close resources, like a JCR 
 session for instance. If the contract includes that the pre and post 
 processing methods are always called, the post processing method acts 
 like kind of a disposal method where I can close my session.
 I've other - in this sense rather obscure - use cases where the pipeline 
 components need to pass information back to the caller before the 
 processing starts. So the caller calls the pre processing method where 
 the pipeline component adds something to the map, the caller can pick it 
 up and then start the processing based in this information.

Isn't that a rather specific use case? It feels kinda wrong when lifecycle
methods will now pollute the pipeline interfaces rather than letting pipeline
components implement lifecycle interfaces. Doesn't Spring show how to do these
kind of things with templates or aspects?

And is there actually something like start and end in a pipeline? How do you
determine that? It's rather easy with SAX since there is startDocument() and
endDocument() but in general?

It's not an objection, just some thoughts ...

Joerg



Re: [Corona] PIpeline API

2008-07-15 Thread Peter Hunsberger
On Tue, Jul 15, 2008 at 5:42 AM, Reinhard Pötz [EMAIL PROTECTED] wrote:

 Are you talking about passing the input parameters as parameters of the
 setup() method?

 void setup(MapString, Object inputParameters)

 I'd be fine by this.


I hate seeing Maps used as dumping grounds for randomly typed objects.
Could you use something that gives a little more strong typing?
Perhaps more like a ServletContext though I don't think I'd go that
far in this case?

-- 
Peter Hunsberger


Re: [Corona] PIpeline API

2008-07-15 Thread Carsten Ziegeler

Reinhard Pötz wrote:

Carsten Ziegeler wrote:

Reinhard Pötz wrote:


currently corona-pipeline (pipeline API, pipeline impls, SAX 
components) only has a dependency on commons-logging. Is this good 
enough for your needs?

:) Ok, that should be fine.

I've moved the action to the sitemap module and split up execute into 
setup and execute. I think we should specify in the contract that a 
modifiable map is passed to the components during setup. Any objections?


Currently sitemap components get passed to maps:

 1. the input parameters (a map of all objects that you want to pass
to a pipeline)

 2. the configuration parameters (to provide a way to pass parameters
from the sitemap to the component - for API usage those parameters
are usually passed by constructor parameters or by setters).

Are you talking about passing the input parameters as parameters of the 
setup() method?


void setup(MapString, Object inputParameters)

I'd be fine by this.


Yes, this is what I did.

Carsten
--
Carsten Ziegeler
[EMAIL PROTECTED]


Re: [Corona] PIpeline API

2008-07-15 Thread Carsten Ziegeler

Peter Hunsberger wrote:

On Tue, Jul 15, 2008 at 5:42 AM, Reinhard Pötz [EMAIL PROTECTED] wrote:


Are you talking about passing the input parameters as parameters of the
setup() method?

void setup(MapString, Object inputParameters)

I'd be fine by this.



I hate seeing Maps used as dumping grounds for randomly typed objects.
Could you use something that gives a little more strong typing?
Perhaps more like a ServletContext though I don't think I'd go that
far in this case?

I agree that strong typing would be great - but the pipeline api does 
not define any concrete key/object for the map. So this is use-case 
specific. Therefore I think a map is the best we can come up.


Carsten

--
Carsten Ziegeler
[EMAIL PROTECTED]


Re: [Corona] PIpeline API

2008-07-15 Thread Carsten Ziegeler

Joerg Heinicke wrote:

Carsten Ziegeler cziegeler at apache.org writes:


c) Pre and post processing
As the pipeline interfaces are not tied to sax or any other model 
(which is ok), there is no explicit notion of indicating that the 
processing starts or is finished - the latter is especially 
interesting for cleanup. So I think we should add these two lifecycle 
methods to the pipeline component interface.

I don't see any problem either. Being curious, what are your use cases?
I've some pipeline components that open/close resources, like a JCR 
session for instance. If the contract includes that the pre and post 
processing methods are always called, the post processing method acts 
like kind of a disposal method where I can close my session.
I've other - in this sense rather obscure - use cases where the pipeline 
components need to pass information back to the caller before the 
processing starts. So the caller calls the pre processing method where 
the pipeline component adds something to the map, the caller can pick it 
up and then start the processing based in this information.


Isn't that a rather specific use case? It feels kinda wrong when lifecycle
methods will now pollute the pipeline interfaces rather than letting pipeline
components implement lifecycle interfaces. Doesn't Spring show how to do these
kind of things with templates or aspects?

And is there actually something like start and end in a pipeline? How do you
determine that? It's rather easy with SAX since there is startDocument() and
endDocument() but in general?

Hmm, someone starts the pipeline and at some point of time it ends :) As 
we have an execute() method on the pipeline, the contract is that if 
execute returns, the pipeline is finished. Therefore it's easy to call 
the according methods inside execute() - regardless which model is used 
between the pipeline components.

We have the pre-execution method already - thats the setup(Map) method.
I added now a finish method which is called by the pipeline implementation.
This keeps me free from any configuration hassels with the various 
containers. Some want to use spring, some others something different. 
And perhaps someone doesn't want to use a container at all, just 
instantiate the objects, run the pipeline and that's it.

Therefore I really think that these lifecycle methods belong to the api.
I see no other reliable way of closing resources.

Carsten
--
Carsten Ziegeler
[EMAIL PROTECTED]


Re: [Corona] PIpeline API

2008-07-15 Thread Torsten Curdt


On Jul 15, 2008, at 18:33, Carsten Ziegeler wrote:


Peter Hunsberger wrote:
On Tue, Jul 15, 2008 at 5:42 AM, Reinhard Pötz  
[EMAIL PROTECTED] wrote:
Are you talking about passing the input parameters as parameters  
of the

setup() method?

void setup(MapString, Object inputParameters)

I'd be fine by this.

I hate seeing Maps used as dumping grounds for randomly typed  
objects.

Could you use something that gives a little more strong typing?
Perhaps more like a ServletContext though I don't think I'd go that
far in this case?
I agree that strong typing would be great - but the pipeline api  
does not define any concrete key/object for the map. So this is use- 
case specific. Therefore I think a map is the best we can come up.


The question if those configuration are needed in a generic form in  
the API. (I doubt it) As I would expect them to be implementation  
specific a configuration callback that sets up the pipeline might be a  
way around this?


Just my 2 cents

cheers
--
Torsten



Re: [Corona] PIpeline API

2008-07-15 Thread Reinhard Pötz

Carsten Ziegeler wrote:

Joerg Heinicke wrote:

Carsten Ziegeler cziegeler at apache.org writes:


c) Pre and post processing
As the pipeline interfaces are not tied to sax or any other model 
(which is ok), there is no explicit notion of indicating that the 
processing starts or is finished - the latter is especially 
interesting for cleanup. So I think we should add these two 
lifecycle methods to the pipeline component interface.

I don't see any problem either. Being curious, what are your use cases?
I've some pipeline components that open/close resources, like a JCR 
session for instance. If the contract includes that the pre and post 
processing methods are always called, the post processing method acts 
like kind of a disposal method where I can close my session.
I've other - in this sense rather obscure - use cases where the 
pipeline components need to pass information back to the caller 
before the processing starts. So the caller calls the pre processing 
method where the pipeline component adds something to the map, the 
caller can pick it up and then start the processing based in this 
information.


Isn't that a rather specific use case? It feels kinda wrong when 
lifecycle
methods will now pollute the pipeline interfaces rather than letting 
pipeline
components implement lifecycle interfaces. Doesn't Spring show how to 
do these

kind of things with templates or aspects?

And is there actually something like start and end in a pipeline? 
How do you
determine that? It's rather easy with SAX since there is 
startDocument() and

endDocument() but in general?

Hmm, someone starts the pipeline and at some point of time it ends :) As 
we have an execute() method on the pipeline, the contract is that if 
execute returns, the pipeline is finished. Therefore it's easy to call 
the according methods inside execute() - regardless which model is used 
between the pipeline components.

We have the pre-execution method already - thats the setup(Map) method.
I added now a finish method which is called by the pipeline implementation.
This keeps me free from any configuration hassels with the various 
containers. Some want to use spring, some others something different. 
And perhaps someone doesn't want to use a container at all


that's IMO the main reason for adding the finish() method.

, just 
instantiate the objects, run the pipeline and that's it.

Therefore I really think that these lifecycle methods belong to the api.
I see no other reliable way of closing resources.


agreed

--
Reinhard Pötz   Managing Director, {Indoqa} GmbH
 http://www.indoqa.com/en/people/reinhard.poetz/

Member of the Apache Software Foundation
Apache Cocoon Committer, PMC member  [EMAIL PROTECTED]



Re: [Corona] PIpeline API

2008-07-14 Thread Carsten Ziegeler

Reinhard Pötz wrote:
I agree with you that the package structure should be cleaned up. It's 
also a good idea to create a 'corona-pipeline-sax' module that contains 
the SAX based components. I'm not so sure if we should really move the 
pipeline implementations into their own modules. This seems to be too 
much modularization for my taste. (The corona-pipeline.jar, that 
currently contains the SAX components, is about 70kb only.)
Yes, I'm not concerned about the jar size itself, I'm concerned about 
dependencies. The ideal solution would be to have an api jar which has 
no other dependencies, perhaps one to a logging framework if we provide 
utility or abstract classes.





b) Actions should not be part of the pipeline api
I think we discussed this some time ago :) Removing actions from the 
pipeline stuff does not really hurt - they are invoked before the 
pipeline, so it shouldn't be too hard to build custom code which 
collects actions, assembles the pipeline, invokes the actions and then 
the pipeline.


no objection ;-)


c) Pre and post processing
As the pipeline interfaces are not tied to sax or any other model 
(which is ok), there is no explicit notion of indicating that the 
processing starts or is finished - the latter is especially 
interesting for cleanup. So I think we should add these two lifecycle 
methods to the pipeline component interface.


I don't see any problem either. Being curious, what are your use cases?
I've some pipeline components that open/close resources, like a JCR 
session for instance. If the contract includes that the pre and post 
processing methods are always called, the post processing method acts 
like kind of a disposal method where I can close my session.
I've other - in this sense rather obscure - use cases where the pipeline 
components need to pass information back to the caller before the 
processing starts. So the caller calls the pre processing method where 
the pipeline component adds something to the map, the caller can pick it 
up and then start the processing based in this information.





d) Splitting setup and execute
I would like to split the Pipeline#execute method into two, one for 
initialisation and one (without arguments) for executing.


I was thinking about this myself because we need this separation also to 
optimize conditional GET operations when the servlet URLs are involved.

Great :)

So how do we proceed? Do you mind if I start with the minor changes?

Carsten

--
Carsten Ziegeler
[EMAIL PROTECTED]


Re: [Corona] PIpeline API

2008-07-14 Thread Reinhard Pötz

Carsten Ziegeler wrote:

Reinhard Pötz wrote:
I agree with you that the package structure should be cleaned up. It's 
also a good idea to create a 'corona-pipeline-sax' module that 
contains the SAX based components. I'm not so sure if we should really 
move the pipeline implementations into their own modules. This seems 
to be too much modularization for my taste. (The corona-pipeline.jar, 
that currently contains the SAX components, is about 70kb only.)
Yes, I'm not concerned about the jar size itself, I'm concerned about 
dependencies. The ideal solution would be to have an api jar which has 
no other dependencies, perhaps one to a logging framework if we provide 
utility or abstract classes.


currently corona-pipeline (pipeline API, pipeline impls, SAX components) 
only has a dependency on commons-logging. Is this good enough for your 
needs?



b) Actions should not be part of the pipeline api
I think we discussed this some time ago :) Removing actions from the 
pipeline stuff does not really hurt - they are invoked before the 
pipeline, so it shouldn't be too hard to build custom code which 
collects actions, assembles the pipeline, invokes the actions and 
then the pipeline.


no objection ;-)


c) Pre and post processing
As the pipeline interfaces are not tied to sax or any other model 
(which is ok), there is no explicit notion of indicating that the 
processing starts or is finished - the latter is especially 
interesting for cleanup. So I think we should add these two lifecycle 
methods to the pipeline component interface.


I don't see any problem either. Being curious, what are your use cases?
I've some pipeline components that open/close resources, like a JCR 
session for instance. If the contract includes that the pre and post 
processing methods are always called, the post processing method acts 
like kind of a disposal method where I can close my session.
I've other - in this sense rather obscure - use cases where the pipeline 
components need to pass information back to the caller before the 
processing starts. So the caller calls the pre processing method where 
the pipeline component adds something to the map, the caller can pick it 
up and then start the processing based in this information.


thanks


d) Splitting setup and execute
I would like to split the Pipeline#execute method into two, one for 
initialisation and one (without arguments) for executing.


I was thinking about this myself because we need this separation also 
to optimize conditional GET operations when the servlet URLs are 
involved.

Great :)

So how do we proceed? Do you mind if I start with the minor changes?


of course not :-)

Corona comes with integration tests that you can run by invoking

mvn clean install -P it -Dhtmlunit.base-url=http://localhost:

from the root directory. Please make sure that they run through after 
your refactorings. Many thanks in advance!


--
Reinhard Pötz   Managing Director, {Indoqa} GmbH
 http://www.indoqa.com/en/people/reinhard.poetz/

Member of the Apache Software Foundation
Apache Cocoon Committer, PMC member  [EMAIL PROTECTED]



Re: [Corona] PIpeline API

2008-07-13 Thread Reinhard Pötz

Carsten Ziegeler wrote:

Hi,

I'm currently looking for a nice and simple pipeline api to be 
integrated with Apache Sling :)
And of course I had a quick look at Corona (as everything else I found 
was not what I was searching for) which would be the prefered way of

implementing pipelines :)


great!


Now, I only need the naked pipeline stuff - and most important here are
the interfaces and perhaps a simple pipeline implementation (without 
caching).


There are some points I would like to discuss:
a) Simple API separated from the implementation
I think it makes sense to put all API stuff into one single package, 
these are only a handfull of classes - perhaps there might be an 
additional util package.
The implementations of the various components should go into a different 
module as they are not needed by everyone. At least they should be in a 
different package for modularization purposes.

I would also package the whole caching stuff into an own module.


I agree with you that the package structure should be cleaned up. It's 
also a good idea to create a 'corona-pipeline-sax' module that contains 
the SAX based components. I'm not so sure if we should really move the 
pipeline implementations into their own modules. This seems to be too 
much modularization for my taste. (The corona-pipeline.jar, that 
currently contains the SAX components, is about 70kb only.)



b) Actions should not be part of the pipeline api
I think we discussed this some time ago :) Removing actions from the 
pipeline stuff does not really hurt - they are invoked before the 
pipeline, so it shouldn't be too hard to build custom code which 
collects actions, assembles the pipeline, invokes the actions and then 
the pipeline.


no objection ;-)


c) Pre and post processing
As the pipeline interfaces are not tied to sax or any other model (which 
is ok), there is no explicit notion of indicating that the processing 
starts or is finished - the latter is especially interesting for 
cleanup. So I think we should add these two lifecycle methods to the 
pipeline component interface.


I don't see any problem either. Being curious, what are your use cases?


d) Splitting setup and execute
I would like to split the Pipeline#execute method into two, one for 
initialisation and one (without arguments) for executing.


I was thinking about this myself because we need this separation also to 
optimize conditional GET operations when the servlet URLs are involved.


--
Reinhard Pötz   Managing Director, {Indoqa} GmbH
 http://www.indoqa.com/en/people/reinhard.poetz/

Member of the Apache Software Foundation
Apache Cocoon Committer, PMC member  [EMAIL PROTECTED]



Re: [Corona] PIpeline API

2008-07-11 Thread Peter Hunsberger
On Fri, Jul 11, 2008 at 8:19 AM, Carsten Ziegeler [EMAIL PROTECTED] wrote:
 Hi,

 I'm currently looking for a nice and simple pipeline api to be integrated
 with Apache Sling :)
 And of course I had a quick look at Corona (as everything else I found was
 not what I was searching for) which would be the prefered way of
 implementing pipelines :)

[snip] Corona refactoring ideas [/snip]


 WDYT?


This sounds like what I'm looking for one project we have.   It makes
sense to me

-- 
Peter Hunsberger