Re: [Corona] PIpeline API
On Thu, Jul 17, 2008 at 5:27 PM, Steven Dolg <[EMAIL PROTECTED]> wrote: > Peter Hunsberger schrieb: >> > 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
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
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
Re: [Corona] PIpeline API
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
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
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
Andreas Hartmann wrote: > 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
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 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
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
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
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
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
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
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
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
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
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
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(Map 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
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
Joerg Heinicke wrote: Torsten Curdt 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 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
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
Torsten Curdt 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 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
Carsten Ziegeler wrote: Joerg Heinicke wrote: Carsten Ziegeler 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
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(Map 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
Joerg Heinicke wrote: Carsten Ziegeler 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
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(Map 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
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(Map inputParameters) I'd be fine by this. Yes, this is what I did. Carsten -- Carsten Ziegeler [EMAIL PROTECTED]
Re: [Corona] PIpeline API
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(Map 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
Carsten Ziegeler 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
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(Map 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
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
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
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
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
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
[Corona] PIpeline API
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 :) 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. 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. 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. 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. WDYT? Regards Carsten -- Carsten Ziegeler [EMAIL PROTECTED]