You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Sgarlata Matt <sg...@bah.com> on 2003/09/21 19:45:37 UTC

[Chain] examples XML file available?

I'm interested in possibly using the Chain package in some of my projects
and I was hoping I could get an example XML file to feed to the Digester?  I
don't need the Command classes associated with the file or anything like
that, I'd just like to see an example so I don't have to reverse-engineer
its structure from the ConfigRuleSet.

If I play with the package some more and like it, I could provide a DTD for
the XML file and documentation for it.  That should save Craig and Ted from
some boring work :)

Thanks,

Matt


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] examples XML file available?

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Ted Husted wrote:

> Craig R. McClanahan wrote:
>
>> All of the above use cases could be covered by a ChainServlet to load 
>> the config stuff and store it in a servlet context attribute.  That 
>> doesn't help the non-web case, but a default solution that uses a 
>> static singleton might work out ok there.
>
>
> It just occurred to me that I have a non-web case on my desk now. It 
> converts a file scraped from a HTML page into a couple of fixed-length 
> files that are imported into a database. Problem is, the government 
> agency that creates the HTML page tweaks the format now and again, or 
> adds new information, which makes maintenance an ongoing issue. This 
> seems like a good use for the CoR architechture, since each Command 
> can scan for one of the many possible input formats. If it's not 
> yours, pass it along =:)

Sounds like a pretty exact match to the motivations described in GoF for 
Chain of Responsibility :-).

>
> I've a maintenance ticket open for this now, so I'll think I'll 
> migrate it to Chain. The best part is that the application is already 
> fully tested, and so it will be a good show of using Unit Tests in a 
> non-web applicaton too. 

That will be a useful exercise.

>
>
> -Ted.

Craig

>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org




Re: [Chain] examples XML file available?

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Ted Husted wrote:

> Craig R. McClanahan wrote:
>
>> All of the above use cases could be covered by a ChainServlet to load 
>> the config stuff and store it in a servlet context attribute.  That 
>> doesn't help the non-web case, but a default solution that uses a 
>> static singleton might work out ok there.
>
>
> It just occurred to me that I have a non-web case on my desk now. It 
> converts a file scraped from a HTML page into a couple of fixed-length 
> files that are imported into a database. Problem is, the government 
> agency that creates the HTML page tweaks the format now and again, or 
> adds new information, which makes maintenance an ongoing issue. This 
> seems like a good use for the CoR architechture, since each Command 
> can scan for one of the many possible input formats. If it's not 
> yours, pass it along =:)

Sounds like a pretty exact match to the motivations described in GoF for 
Chain of Responsibility :-).

>
> I've a maintenance ticket open for this now, so I'll think I'll 
> migrate it to Chain. The best part is that the application is already 
> fully tested, and so it will be a good show of using Unit Tests in a 
> non-web applicaton too. 

That will be a useful exercise.

>
>
> -Ted.

Craig

>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] examples XML file available?

Posted by Ted Husted <hu...@apache.org>.
Craig R. McClanahan wrote:
> All of the above use cases could be covered by a ChainServlet to load 
> the config stuff and store it in a servlet context attribute.  That 
> doesn't help the non-web case, but a default solution that uses a static 
> singleton might work out ok there.

It just occurred to me that I have a non-web case on my desk now. It 
converts a file scraped from a HTML page into a couple of fixed-length 
files that are imported into a database. Problem is, the government 
agency that creates the HTML page tweaks the format now and again, or 
adds new information, which makes maintenance an ongoing issue. This 
seems like a good use for the CoR architechture, since each Command can 
scan for one of the many possible input formats. If it's not yours, pass 
it along =:)

I've a maintenance ticket open for this now, so I'll think I'll migrate 
it to Chain. The best part is that the application is already fully 
tested, and so it will be a good show of using Unit Tests in a non-web 
applicaton too.

-Ted.



Re: [Chain] examples XML file available?

Posted by Ted Husted <hu...@apache.org>.
Craig R. McClanahan wrote:
> All of the above use cases could be covered by a ChainServlet to load 
> the config stuff and store it in a servlet context attribute.  That 
> doesn't help the non-web case, but a default solution that uses a static 
> singleton might work out ok there.

It just occurred to me that I have a non-web case on my desk now. It 
converts a file scraped from a HTML page into a couple of fixed-length 
files that are imported into a database. Problem is, the government 
agency that creates the HTML page tweaks the format now and again, or 
adds new information, which makes maintenance an ongoing issue. This 
seems like a good use for the CoR architechture, since each Command can 
scan for one of the many possible input formats. If it's not yours, pass 
it along =:)

I've a maintenance ticket open for this now, so I'll think I'll migrate 
it to Chain. The best part is that the application is already fully 
tested, and so it will be a good show of using Unit Tests in a non-web 
applicaton too.

-Ted.



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] examples XML file available?

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Ted Husted wrote:

> Craig R. McClanahan wrote:
>
>> Once ChainServlet has assembled the Catalog, how are you planning to 
>> make it available to the rest of the application?  Storing it as a 
>> servet context attribute still ties you to the servlet API, and 
>> that's (IMHO) too restrictive for a configuration mechanism inside 
>> commons-chain itself, which should be perfectly usable in a non-web 
>> environment.
>
>
> Right now, the Commands I have in place are quite simple and don't 
> need to refer back to the Catalog. (Just simple calls to a DAO layer 
> designed to that share the same Context.) So, I just bootstrap the 
> call from the presentation layer controller (e.g. Action class). The 
> chain I'm calling is passed up from the configuration file, so I can 
> use the same base class for most everything. [Which might sound 
> familiar :0)]
>
> When things become more complex, I'm thinking that a reference to the 
> Catalog (or Catalogs) can be stored in the Context, along with 
> everything else. So the presentation layer factory (or independent 
> test case) can include a reference to the Catalog when it assembles 
> the rest of the Context. If a Command needs a reference to the 
> Catalog, it can get it from the Context. The Catalog may be stored in 
> the servlet context, but the Command doesn't need to know that. 

The Struts request processor experiment does this (puts the Catalog at a 
well-known attribute name in the Context).

>
>
> Some applications could devolve to a Context that executes itself by 
> checking for a Command name under a default attribute and then 
> executing that Command using a Catalog stored under another default 
> attribute.
>
> Of course, another way to go would be to make the Catalog a singleton, 
> or available through some registry, but I'm thinking that going 
> through the Context may be the cleanest approach, since the Context is 
> essentially a Registry too.

I think singletons would cause name clash problems when trying to 
combine multiple sets of independently developed chains into a single 
entity.  It would also disable an interesting pattern I've been thinking 
about -- a delegating Catalog that is essentially "all the defined 
commands in my parent catalog plus some that are private to me" similar 
to some of the ideas we've been musing about in Struts for hierarchical 
sub-application modues.

>
>> This is the kind of reason why I stopped at providing you 
>> environment-independent APIs (and even using Digester to read XML 
>> files is an option -- you're perfectly free to configure the Catalog 
>> in other ways as well) to assemble your own configuration loading; 
>> tying it in to the rest of the "container" or "environment" you are 
>> running in should be the business of the client application, not the 
>> commons-chain package itself.
>
>
> Agreed. But if we are offering standard optional packages for 
> JavaServer Faces, Servlets, and Portlets, it seems like we can do the 
> same for Struts too. If the Struts JAR isn't there, the plugin package 
> wouldn't be compiled. In this way, Struts 1.1 people can start using 
> the package right away, without having to get the Struts contrib as 
> well. And if someone contributed a standard servlet implementation, 
> then Struts 1.0 people, as well as most anyone else, could also start 
> using it "out of the box".

All of the above use cases could be covered by a ChainServlet to load 
the config stuff and store it in a servlet context attribute.  That 
doesn't help the non-web case, but a default solution that uses a static 
singleton might work out ok there.

>
> -Ted 

Craig


>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org




Re: [Chain] examples XML file available?

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Ted Husted wrote:

> Craig R. McClanahan wrote:
>
>> Once ChainServlet has assembled the Catalog, how are you planning to 
>> make it available to the rest of the application?  Storing it as a 
>> servet context attribute still ties you to the servlet API, and 
>> that's (IMHO) too restrictive for a configuration mechanism inside 
>> commons-chain itself, which should be perfectly usable in a non-web 
>> environment.
>
>
> Right now, the Commands I have in place are quite simple and don't 
> need to refer back to the Catalog. (Just simple calls to a DAO layer 
> designed to that share the same Context.) So, I just bootstrap the 
> call from the presentation layer controller (e.g. Action class). The 
> chain I'm calling is passed up from the configuration file, so I can 
> use the same base class for most everything. [Which might sound 
> familiar :0)]
>
> When things become more complex, I'm thinking that a reference to the 
> Catalog (or Catalogs) can be stored in the Context, along with 
> everything else. So the presentation layer factory (or independent 
> test case) can include a reference to the Catalog when it assembles 
> the rest of the Context. If a Command needs a reference to the 
> Catalog, it can get it from the Context. The Catalog may be stored in 
> the servlet context, but the Command doesn't need to know that. 

The Struts request processor experiment does this (puts the Catalog at a 
well-known attribute name in the Context).

>
>
> Some applications could devolve to a Context that executes itself by 
> checking for a Command name under a default attribute and then 
> executing that Command using a Catalog stored under another default 
> attribute.
>
> Of course, another way to go would be to make the Catalog a singleton, 
> or available through some registry, but I'm thinking that going 
> through the Context may be the cleanest approach, since the Context is 
> essentially a Registry too.

I think singletons would cause name clash problems when trying to 
combine multiple sets of independently developed chains into a single 
entity.  It would also disable an interesting pattern I've been thinking 
about -- a delegating Catalog that is essentially "all the defined 
commands in my parent catalog plus some that are private to me" similar 
to some of the ideas we've been musing about in Struts for hierarchical 
sub-application modues.

>
>> This is the kind of reason why I stopped at providing you 
>> environment-independent APIs (and even using Digester to read XML 
>> files is an option -- you're perfectly free to configure the Catalog 
>> in other ways as well) to assemble your own configuration loading; 
>> tying it in to the rest of the "container" or "environment" you are 
>> running in should be the business of the client application, not the 
>> commons-chain package itself.
>
>
> Agreed. But if we are offering standard optional packages for 
> JavaServer Faces, Servlets, and Portlets, it seems like we can do the 
> same for Struts too. If the Struts JAR isn't there, the plugin package 
> wouldn't be compiled. In this way, Struts 1.1 people can start using 
> the package right away, without having to get the Struts contrib as 
> well. And if someone contributed a standard servlet implementation, 
> then Struts 1.0 people, as well as most anyone else, could also start 
> using it "out of the box".

All of the above use cases could be covered by a ChainServlet to load 
the config stuff and store it in a servlet context attribute.  That 
doesn't help the non-web case, but a default solution that uses a static 
singleton might work out ok there.

>
> -Ted 

Craig


>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] examples XML file available?

Posted by Ted Husted <hu...@apache.org>.
Craig R. McClanahan wrote:
> Once ChainServlet has assembled the Catalog, how are you planning to 
> make it available to the rest of the application?  Storing it as a 
> servet context attribute still ties you to the servlet API, and that's 
> (IMHO) too restrictive for a configuration mechanism inside 
> commons-chain itself, which should be perfectly usable in a non-web 
> environment.

Right now, the Commands I have in place are quite simple and don't need 
to refer back to the Catalog. (Just simple calls to a DAO layer designed 
to that share the same Context.) So, I just bootstrap the call from the 
presentation layer controller (e.g. Action class). The chain I'm calling 
is passed up from the configuration file, so I can use the same base 
class for most everything. [Which might sound familiar :0)]

When things become more complex, I'm thinking that a reference to the 
Catalog (or Catalogs) can be stored in the Context, along with 
everything else. So the presentation layer factory (or independent test 
case) can include a reference to the Catalog when it assembles the rest 
of the Context. If a Command needs a reference to the Catalog, it can 
get it from the Context. The Catalog may be stored in the servlet 
context, but the Command doesn't need to know that.

Some applications could devolve to a Context that executes itself by 
checking for a Command name under a default attribute and then executing 
that Command using a Catalog stored under another default attribute.

Of course, another way to go would be to make the Catalog a singleton, 
or available through some registry, but I'm thinking that going through 
the Context may be the cleanest approach, since the Context is 
essentially a Registry too.


> This is the kind of reason why I stopped at providing you 
> environment-independent APIs (and even using Digester to read XML files 
> is an option -- you're perfectly free to configure the Catalog in other 
> ways as well) to assemble your own configuration loading; tying it in to 
> the rest of the "container" or "environment" you are running in should 
> be the business of the client application, not the commons-chain package 
> itself.

Agreed. But if we are offering standard optional packages for JavaServer 
Faces, Servlets, and Portlets, it seems like we can do the same for 
Struts too. If the Struts JAR isn't there, the plugin package wouldn't 
be compiled. In this way, Struts 1.1 people can start using the package 
right away, without having to get the Struts contrib as well. And if 
someone contributed a standard servlet implementation, then Struts 1.0 
people, as well as most anyone else, could also start using it "out of 
the box".

-Ted



Re: [Chain] examples XML file available?

Posted by Ted Husted <hu...@apache.org>.
Craig R. McClanahan wrote:
> Once ChainServlet has assembled the Catalog, how are you planning to 
> make it available to the rest of the application?  Storing it as a 
> servet context attribute still ties you to the servlet API, and that's 
> (IMHO) too restrictive for a configuration mechanism inside 
> commons-chain itself, which should be perfectly usable in a non-web 
> environment.

Right now, the Commands I have in place are quite simple and don't need 
to refer back to the Catalog. (Just simple calls to a DAO layer designed 
to that share the same Context.) So, I just bootstrap the call from the 
presentation layer controller (e.g. Action class). The chain I'm calling 
is passed up from the configuration file, so I can use the same base 
class for most everything. [Which might sound familiar :0)]

When things become more complex, I'm thinking that a reference to the 
Catalog (or Catalogs) can be stored in the Context, along with 
everything else. So the presentation layer factory (or independent test 
case) can include a reference to the Catalog when it assembles the rest 
of the Context. If a Command needs a reference to the Catalog, it can 
get it from the Context. The Catalog may be stored in the servlet 
context, but the Command doesn't need to know that.

Some applications could devolve to a Context that executes itself by 
checking for a Command name under a default attribute and then executing 
that Command using a Catalog stored under another default attribute.

Of course, another way to go would be to make the Catalog a singleton, 
or available through some registry, but I'm thinking that going through 
the Context may be the cleanest approach, since the Context is 
essentially a Registry too.


> This is the kind of reason why I stopped at providing you 
> environment-independent APIs (and even using Digester to read XML files 
> is an option -- you're perfectly free to configure the Catalog in other 
> ways as well) to assemble your own configuration loading; tying it in to 
> the rest of the "container" or "environment" you are running in should 
> be the business of the client application, not the commons-chain package 
> itself.

Agreed. But if we are offering standard optional packages for JavaServer 
Faces, Servlets, and Portlets, it seems like we can do the same for 
Struts too. If the Struts JAR isn't there, the plugin package wouldn't 
be compiled. In this way, Struts 1.1 people can start using the package 
right away, without having to get the Struts contrib as well. And if 
someone contributed a standard servlet implementation, then Struts 1.0 
people, as well as most anyone else, could also start using it "out of 
the box".

-Ted



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] examples XML file available?

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Sgarlata Matt wrote:

>Thanks for the test cases Ted!  More comments below...
>----- Original Message ----- 
>From: "Ted Husted" <hu...@apache.org>
>To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
>Sent: Sunday, September 21, 2003 10:32 PM
>Subject: Re: [Chain] examples XML file available?
>
>
>  
>
>> > If I play with the package some more and like it, I could provide a
>> > DTD for the XML file and documentation for it.  That should save Craig
>> > and Ted from some boring work :)
>>
>>What might be helpful is a standalone ChainServlet that would load the
>>configuration file, like the sample PlugIn does. (A HiveMind service
>>might also be very cool.)
>>    
>>
>
>I can write the ChainServlet this week, borrowing relevant code from the
>CatalogConfiguratorPlugIn :)  HiveMind looks cool, but I'm not ready to
>invest time in learning it yet.
>
>  
>
>>Right now, I'm loading it as a Struts PlugIn (and imagine Craig is too),
>>but that wouldn't work for everyone.
>>    
>>
Of course I am :-).  After all, I'm loading the configuration for a 
"request processor" that has to tie in to the rest of the Struts 
infrastructure, so I know that it's all going to be there.

>>
>>Craig R. McClanahan wrote:
>>    
>>
>>>There's another example in the CVS HEAD sources of Struts, where we are
>>>experimenting with building a replacement for the current
>>>      
>>>
>RequestProcessor
>  
>
>>>class to assemble the request processing pipeline:
>>>
>>>  contrib/struts-chain/src/conf/chain-config.xml
>>>      
>>>
>>Also in the Struts Contrib CVS is a PlugIn class. Problem is, other
>>parts of that distribution are coupled to the Struts Nightly Build and
>>won't compile under Struts 1.1 (namely the Constants.MODULE_CONFIG_KEY).
>>    
>>
That particular issue can be addressed with a temporary workaround for 1.1.

>>I'd like to move the Struts CatalogConfiguratorPlugIn to the Commons
>>Chain distro and make it an optional compile, like JSF et al. That way,
>>people could start using Chain with Struts 1.1 "out of the box".
>>
>>Even if we could decouple the Contrib package from the Nightly Build,
>>I'm thinking if we have these other optional packages here, we can also
>>have one for Struts. So, the ComposableRequestProcessor would stay
>>there, but the CatalogConfiguratorPlugIn would move here.
>>
>>Does this sound all right?
>>    
>>
>
>Actually, if we write a ChainServlet then do we need a Struts PlugIn at all?
>If the ChainServlet is set to load before the ActionServlet and the
>ChainServlet stores its catalog in a known location, Struts users should be
>able to use the ChainServlet without using a PlugIn at all.  I do agree with
>your reasoning that the CatalogConfiguratorPlugIn should live in Chain
>instead of Struts, but I don't see a need for a PlugIn at all.
>  
>
Once ChainServlet has assembled the Catalog, how are you planning to 
make it available to the rest of the application?  Storing it as a 
servet context attribute still ties you to the servlet API, and that's 
(IMHO) too restrictive for a configuration mechanism inside 
commons-chain itself, which should be perfectly usable in a non-web 
environment.

This is the kind of reason why I stopped at providing you 
environment-independent APIs (and even using Digester to read XML files 
is an option -- you're perfectly free to configure the Catalog in other 
ways as well) to assemble your own configuration loading; tying it in to 
the rest of the "container" or "environment" you are running in should 
be the business of the client application, not the commons-chain package 
itself.

>  
>
>>-Ted.
>>    
>>
>
>Matt
>  
>
Craig

>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>  
>



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] examples XML file available?

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Sgarlata Matt wrote:

>Thanks for the test cases Ted!  More comments below...
>----- Original Message ----- 
>From: "Ted Husted" <hu...@apache.org>
>To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
>Sent: Sunday, September 21, 2003 10:32 PM
>Subject: Re: [Chain] examples XML file available?
>
>
>  
>
>> > If I play with the package some more and like it, I could provide a
>> > DTD for the XML file and documentation for it.  That should save Craig
>> > and Ted from some boring work :)
>>
>>What might be helpful is a standalone ChainServlet that would load the
>>configuration file, like the sample PlugIn does. (A HiveMind service
>>might also be very cool.)
>>    
>>
>
>I can write the ChainServlet this week, borrowing relevant code from the
>CatalogConfiguratorPlugIn :)  HiveMind looks cool, but I'm not ready to
>invest time in learning it yet.
>
>  
>
>>Right now, I'm loading it as a Struts PlugIn (and imagine Craig is too),
>>but that wouldn't work for everyone.
>>    
>>
Of course I am :-).  After all, I'm loading the configuration for a 
"request processor" that has to tie in to the rest of the Struts 
infrastructure, so I know that it's all going to be there.

>>
>>Craig R. McClanahan wrote:
>>    
>>
>>>There's another example in the CVS HEAD sources of Struts, where we are
>>>experimenting with building a replacement for the current
>>>      
>>>
>RequestProcessor
>  
>
>>>class to assemble the request processing pipeline:
>>>
>>>  contrib/struts-chain/src/conf/chain-config.xml
>>>      
>>>
>>Also in the Struts Contrib CVS is a PlugIn class. Problem is, other
>>parts of that distribution are coupled to the Struts Nightly Build and
>>won't compile under Struts 1.1 (namely the Constants.MODULE_CONFIG_KEY).
>>    
>>
That particular issue can be addressed with a temporary workaround for 1.1.

>>I'd like to move the Struts CatalogConfiguratorPlugIn to the Commons
>>Chain distro and make it an optional compile, like JSF et al. That way,
>>people could start using Chain with Struts 1.1 "out of the box".
>>
>>Even if we could decouple the Contrib package from the Nightly Build,
>>I'm thinking if we have these other optional packages here, we can also
>>have one for Struts. So, the ComposableRequestProcessor would stay
>>there, but the CatalogConfiguratorPlugIn would move here.
>>
>>Does this sound all right?
>>    
>>
>
>Actually, if we write a ChainServlet then do we need a Struts PlugIn at all?
>If the ChainServlet is set to load before the ActionServlet and the
>ChainServlet stores its catalog in a known location, Struts users should be
>able to use the ChainServlet without using a PlugIn at all.  I do agree with
>your reasoning that the CatalogConfiguratorPlugIn should live in Chain
>instead of Struts, but I don't see a need for a PlugIn at all.
>  
>
Once ChainServlet has assembled the Catalog, how are you planning to 
make it available to the rest of the application?  Storing it as a 
servet context attribute still ties you to the servlet API, and that's 
(IMHO) too restrictive for a configuration mechanism inside 
commons-chain itself, which should be perfectly usable in a non-web 
environment.

This is the kind of reason why I stopped at providing you 
environment-independent APIs (and even using Digester to read XML files 
is an option -- you're perfectly free to configure the Catalog in other 
ways as well) to assemble your own configuration loading; tying it in to 
the rest of the "container" or "environment" you are running in should 
be the business of the client application, not the commons-chain package 
itself.

>  
>
>>-Ted.
>>    
>>
>
>Matt
>  
>
Craig

>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>  
>



Re: [Chain] examples XML file available?

Posted by Sgarlata Matt <sg...@bah.com>.
Thanks for the test cases Ted!  More comments below...
----- Original Message ----- 
From: "Ted Husted" <hu...@apache.org>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
Sent: Sunday, September 21, 2003 10:32 PM
Subject: Re: [Chain] examples XML file available?


>  > If I play with the package some more and like it, I could provide a
>  > DTD for the XML file and documentation for it.  That should save Craig
>  > and Ted from some boring work :)
>
> What might be helpful is a standalone ChainServlet that would load the
> configuration file, like the sample PlugIn does. (A HiveMind service
> might also be very cool.)

I can write the ChainServlet this week, borrowing relevant code from the
CatalogConfiguratorPlugIn :)  HiveMind looks cool, but I'm not ready to
invest time in learning it yet.

> Right now, I'm loading it as a Struts PlugIn (and imagine Craig is too),
> but that wouldn't work for everyone.
>
>
> Craig R. McClanahan wrote:
> > There's another example in the CVS HEAD sources of Struts, where we are
> > experimenting with building a replacement for the current
RequestProcessor
> > class to assemble the request processing pipeline:
> >
> >   contrib/struts-chain/src/conf/chain-config.xml
>
> Also in the Struts Contrib CVS is a PlugIn class. Problem is, other
> parts of that distribution are coupled to the Struts Nightly Build and
> won't compile under Struts 1.1 (namely the Constants.MODULE_CONFIG_KEY).
>
> I'd like to move the Struts CatalogConfiguratorPlugIn to the Commons
> Chain distro and make it an optional compile, like JSF et al. That way,
> people could start using Chain with Struts 1.1 "out of the box".
>
> Even if we could decouple the Contrib package from the Nightly Build,
> I'm thinking if we have these other optional packages here, we can also
> have one for Struts. So, the ComposableRequestProcessor would stay
> there, but the CatalogConfiguratorPlugIn would move here.
>
> Does this sound all right?

Actually, if we write a ChainServlet then do we need a Struts PlugIn at all?
If the ChainServlet is set to load before the ActionServlet and the
ChainServlet stores its catalog in a known location, Struts users should be
able to use the ChainServlet without using a PlugIn at all.  I do agree with
your reasoning that the CatalogConfiguratorPlugIn should live in Chain
instead of Struts, but I don't see a need for a PlugIn at all.

> -Ted.

Matt


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] examples XML file available?

Posted by Sgarlata Matt <sg...@bah.com>.
Thanks for the test cases Ted!  More comments below...
----- Original Message ----- 
From: "Ted Husted" <hu...@apache.org>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
Sent: Sunday, September 21, 2003 10:32 PM
Subject: Re: [Chain] examples XML file available?


>  > If I play with the package some more and like it, I could provide a
>  > DTD for the XML file and documentation for it.  That should save Craig
>  > and Ted from some boring work :)
>
> What might be helpful is a standalone ChainServlet that would load the
> configuration file, like the sample PlugIn does. (A HiveMind service
> might also be very cool.)

I can write the ChainServlet this week, borrowing relevant code from the
CatalogConfiguratorPlugIn :)  HiveMind looks cool, but I'm not ready to
invest time in learning it yet.

> Right now, I'm loading it as a Struts PlugIn (and imagine Craig is too),
> but that wouldn't work for everyone.
>
>
> Craig R. McClanahan wrote:
> > There's another example in the CVS HEAD sources of Struts, where we are
> > experimenting with building a replacement for the current
RequestProcessor
> > class to assemble the request processing pipeline:
> >
> >   contrib/struts-chain/src/conf/chain-config.xml
>
> Also in the Struts Contrib CVS is a PlugIn class. Problem is, other
> parts of that distribution are coupled to the Struts Nightly Build and
> won't compile under Struts 1.1 (namely the Constants.MODULE_CONFIG_KEY).
>
> I'd like to move the Struts CatalogConfiguratorPlugIn to the Commons
> Chain distro and make it an optional compile, like JSF et al. That way,
> people could start using Chain with Struts 1.1 "out of the box".
>
> Even if we could decouple the Contrib package from the Nightly Build,
> I'm thinking if we have these other optional packages here, we can also
> have one for Struts. So, the ComposableRequestProcessor would stay
> there, but the CatalogConfiguratorPlugIn would move here.
>
> Does this sound all right?

Actually, if we write a ChainServlet then do we need a Struts PlugIn at all?
If the ChainServlet is set to load before the ActionServlet and the
ChainServlet stores its catalog in a known location, Struts users should be
able to use the ChainServlet without using a PlugIn at all.  I do agree with
your reasoning that the CatalogConfiguratorPlugIn should live in Chain
instead of Struts, but I don't see a need for a PlugIn at all.

> -Ted.

Matt


Re: [Chain] examples XML file available?

Posted by Ted Husted <hu...@apache.org>.
Sgarlata Matt wrote:
 > I'm interested in possibly using the Chain package in some of my
 > projects and I was hoping I could get an example XML file to feed to
 > the Digester?  I don't need the Command classes associated with the
 > that, I'd just like to see an example so I don't have to file or
 > anything like reverse-engineer its structure from the ConfigRuleSet.

If you're looking for a simple test case, try this:

----

<?xml version="1.0" ?>
<chains>

     <command
         name="MyCommand"
         className="myApp.MyCommand" />

</chains>


----

package us_ok_deq_wqdata.command;

import org.apache.commons.chain.Context;
import org.apache.commons.chain.Command;

public class MyCommand implements Command {

     public MyCommand () {
         ;
     }

     public boolean execute(Context context) throws Exception {

         return true;

     }

}

----

If you're testing it from a servlet, from any method that has access to 
the request, you can try

Catalog catalog = 
request.getSession().getServletContext().getAttribute(Constants.CATALOG_ATTR);

to get a handle on the default catalog, and then

Context context = new BaseContext();
Command command = catalog.getCommand("MyCommand");
boolean result = command.execute(context);

to run the request.

 > If I play with the package some more and like it, I could provide a
 > DTD for the XML file and documentation for it.  That should save Craig
 > and Ted from some boring work :)

What might be helpful is a standalone ChainServlet that would load the 
configuration file, like the sample PlugIn does. (A HiveMind service 
might also be very cool.)

Right now, I'm loading it as a Struts PlugIn (and imagine Craig is too), 
but that wouldn't work for everyone.


Craig R. McClanahan wrote:
> There's another example in the CVS HEAD sources of Struts, where we are
> experimenting with building a replacement for the current RequestProcessor
> class to assemble the request processing pipeline:
> 
>   contrib/struts-chain/src/conf/chain-config.xml

Also in the Struts Contrib CVS is a PlugIn class. Problem is, other 
parts of that distribution are coupled to the Struts Nightly Build and 
won't compile under Struts 1.1 (namely the Constants.MODULE_CONFIG_KEY).

I'd like to move the Struts CatalogConfiguratorPlugIn to the Commons 
Chain distro and make it an optional compile, like JSF et al. That way, 
people could start using Chain with Struts 1.1 "out of the box".

Even if we could decouple the Contrib package from the Nightly Build, 
I'm thinking if we have these other optional packages here, we can also 
have one for Struts. So, the ComposableRequestProcessor would stay 
there, but the CatalogConfiguratorPlugIn would move here.

Does this sound all right?

-Ted.




---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] examples XML file available?

Posted by Ted Husted <hu...@apache.org>.
Sgarlata Matt wrote:
 > I'm interested in possibly using the Chain package in some of my
 > projects and I was hoping I could get an example XML file to feed to
 > the Digester?  I don't need the Command classes associated with the
 > that, I'd just like to see an example so I don't have to file or
 > anything like reverse-engineer its structure from the ConfigRuleSet.

If you're looking for a simple test case, try this:

----

<?xml version="1.0" ?>
<chains>

     <command
         name="MyCommand"
         className="myApp.MyCommand" />

</chains>


----

package us_ok_deq_wqdata.command;

import org.apache.commons.chain.Context;
import org.apache.commons.chain.Command;

public class MyCommand implements Command {

     public MyCommand () {
         ;
     }

     public boolean execute(Context context) throws Exception {

         return true;

     }

}

----

If you're testing it from a servlet, from any method that has access to 
the request, you can try

Catalog catalog = 
request.getSession().getServletContext().getAttribute(Constants.CATALOG_ATTR);

to get a handle on the default catalog, and then

Context context = new BaseContext();
Command command = catalog.getCommand("MyCommand");
boolean result = command.execute(context);

to run the request.

 > If I play with the package some more and like it, I could provide a
 > DTD for the XML file and documentation for it.  That should save Craig
 > and Ted from some boring work :)

What might be helpful is a standalone ChainServlet that would load the 
configuration file, like the sample PlugIn does. (A HiveMind service 
might also be very cool.)

Right now, I'm loading it as a Struts PlugIn (and imagine Craig is too), 
but that wouldn't work for everyone.


Craig R. McClanahan wrote:
> There's another example in the CVS HEAD sources of Struts, where we are
> experimenting with building a replacement for the current RequestProcessor
> class to assemble the request processing pipeline:
> 
>   contrib/struts-chain/src/conf/chain-config.xml

Also in the Struts Contrib CVS is a PlugIn class. Problem is, other 
parts of that distribution are coupled to the Struts Nightly Build and 
won't compile under Struts 1.1 (namely the Constants.MODULE_CONFIG_KEY).

I'd like to move the Struts CatalogConfiguratorPlugIn to the Commons 
Chain distro and make it an optional compile, like JSF et al. That way, 
people could start using Chain with Struts 1.1 "out of the box".

Even if we could decouple the Contrib package from the Nightly Build, 
I'm thinking if we have these other optional packages here, we can also 
have one for Struts. So, the ComposableRequestProcessor would stay 
there, but the CatalogConfiguratorPlugIn would move here.

Does this sound all right?

-Ted.




Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Greg Reddin <gr...@fnf.com>.
Sgarlata Matt wrote:
> Related to this, how come
> Command.execute returns boolean instead of returning Command?  If it
> returned Command this would basically eliminate the need for a Chain
> interface altogether.  Chain would become a concrete implementation of
> Command that repeatedly executed Commands until the last command executed
> returned null (which would be the new value to indicate the end of a chain).

If Command returned a Command reference, each Command would have to know 
what the next Command in the chain is, which, IMO, would introduce too 
tight coupling between Commands.  Why use configurable chains if you're 
going to programatically hardwire the next step in the process.  The 
Chain interface exists to signify separately from the Commands 
themselves the set of commands that are to be run in a process.  The 
Command returns boolean so that you can "break" execution at any point 
in the chain.  Look at the current RequestProcessor interface in Struts. 
  Some of the processing methods return boolean to indicate that 
processing should not continue to the next "link."

If the interface was changed from what it is now, I'd prefer an approach 
that looks more like Servlet Filters where you call doNextCommand() 
without regard to what the next command is over an approach where you 
determine what the next command is, but I'm cool with the interface the 
way it exists now as well.

Greg



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Ted Husted <hu...@apache.org>.
 > As I've thought more about the package, I don't understand why some
 > design decisions were made.  First let me say that I think of Chains
 > as being an OO way to simulate procedural logic.  Many of my comments
 > will basically be concerning why some of the standard control flow
 > abilities (if/then statements, loops, exception handling, etc) in Java
 > aren't more easily done/simulated using the Chain package.

Have you reviewed the pattern descriptions for Chain of Responsibility, 
Composite, and Command from the Design Patterns book? I believe the 
scope of this package is provide a flexible, concrete implementation of 
these patterns. The alternatives you mentioned are certainly doable, but 
  don't seem to be in line with the patterns this package is meant to 
realize.

As for the second point, it's certainly possible that we will see a need 
for a catchException method, but I'd suggest we put some more use-cases 
on the table first. Once an extension point is added to the interface 
it's very difficult to take it back, so it can be better to let usage 
steer the implementation.

-Ted.


Sgarlata Matt wrote:
> The conversation threads are getting kind of crazy, so I'm going to skip
> inline quotes for parts of this.
> 
> Craig, now I do see your point about using the ConfigRuleSet to digest a
> portion of
> an arbitrary XML file.  That is very cool, and now I understand why the
> names of the XML elements are configurable.  I always understood the value
> of letting attributes to the <command> element (and other elements).  This
> is a much slicker approach than creating nested <set-property> elements.
> Still, I think it could be useful to have a DTD for the *default* behavior
> of the ConfigRuleSet.  I think in general users will start off using the
> default behavior, and then may at a later date decide to fold their commands
> into some other file, so a DTD will be nice to get people started with the
> Chain package.  I agree with most your points about the constraints I placed
> in the DTD being inappropriate, and will explicitly address each if we ever
> decide to make a DTD.
> 
> As I've thought more about the package, I don't understand why some design
> decisions were made.  First let me say that I think of Chains as being an OO
> way to simulate procedural logic.  Many of my comments will basically be
> concerning why some of the standard control flow abilities (if/then
> statements, loops, exception handling, etc) in Java aren't more easily
> done/simulated using the Chain package.  So, here I go with questions:
> 1) How come Chains have a static structure?  Related to this, how come
> Command.execute returns boolean instead of returning Command?  If it
> returned Command this would basically eliminate the need for a Chain
> interface altogether.  Chain would become a concrete implementation of
> Command that repeatedly executed Commands until the last command executed
> returned null (which would be the new value to indicate the end of a chain).
> Static chains (such as those configured using an XML file) would easily be
> supported by another concrete implementation of Command which executed a
> series of commands in order, completely ignoring their return values.
> 2) How come Filters have a postprocess method but no catchexception method?
> The postprocess block can deal with exceptions, but it seems to me like it
> would be more natural for exceptions to be dealt with in a catchexception
> block and for postprocess to be strictly for freeing resources that the
> Command acquired when its execute method was called.





---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Ted Husted <hu...@apache.org>.
 > As I've thought more about the package, I don't understand why some
 > design decisions were made.  First let me say that I think of Chains
 > as being an OO way to simulate procedural logic.  Many of my comments
 > will basically be concerning why some of the standard control flow
 > abilities (if/then statements, loops, exception handling, etc) in Java
 > aren't more easily done/simulated using the Chain package.

Have you reviewed the pattern descriptions for Chain of Responsibility, 
Composite, and Command from the Design Patterns book? I believe the 
scope of this package is provide a flexible, concrete implementation of 
these patterns. The alternatives you mentioned are certainly doable, but 
  don't seem to be in line with the patterns this package is meant to 
realize.

As for the second point, it's certainly possible that we will see a need 
for a catchException method, but I'd suggest we put some more use-cases 
on the table first. Once an extension point is added to the interface 
it's very difficult to take it back, so it can be better to let usage 
steer the implementation.

-Ted.


Sgarlata Matt wrote:
> The conversation threads are getting kind of crazy, so I'm going to skip
> inline quotes for parts of this.
> 
> Craig, now I do see your point about using the ConfigRuleSet to digest a
> portion of
> an arbitrary XML file.  That is very cool, and now I understand why the
> names of the XML elements are configurable.  I always understood the value
> of letting attributes to the <command> element (and other elements).  This
> is a much slicker approach than creating nested <set-property> elements.
> Still, I think it could be useful to have a DTD for the *default* behavior
> of the ConfigRuleSet.  I think in general users will start off using the
> default behavior, and then may at a later date decide to fold their commands
> into some other file, so a DTD will be nice to get people started with the
> Chain package.  I agree with most your points about the constraints I placed
> in the DTD being inappropriate, and will explicitly address each if we ever
> decide to make a DTD.
> 
> As I've thought more about the package, I don't understand why some design
> decisions were made.  First let me say that I think of Chains as being an OO
> way to simulate procedural logic.  Many of my comments will basically be
> concerning why some of the standard control flow abilities (if/then
> statements, loops, exception handling, etc) in Java aren't more easily
> done/simulated using the Chain package.  So, here I go with questions:
> 1) How come Chains have a static structure?  Related to this, how come
> Command.execute returns boolean instead of returning Command?  If it
> returned Command this would basically eliminate the need for a Chain
> interface altogether.  Chain would become a concrete implementation of
> Command that repeatedly executed Commands until the last command executed
> returned null (which would be the new value to indicate the end of a chain).
> Static chains (such as those configured using an XML file) would easily be
> supported by another concrete implementation of Command which executed a
> series of commands in order, completely ignoring their return values.
> 2) How come Filters have a postprocess method but no catchexception method?
> The postprocess block can deal with exceptions, but it seems to me like it
> would be more natural for exceptions to be dealt with in a catchexception
> block and for postprocess to be strictly for freeing resources that the
> Command acquired when its execute method was called.





Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Ted Husted wrote:

> Craig R. McClanahan wrote:
>
>>  - If a user attempts to remove() the key corresponding to a property,
>>    throw IllegalArgumentException.
>
>
> Can we make this an optional behavior?

Only if we make attribute-property transparency optional.  That's what 
the contract for org.apache.commons.chain.Context still says right now, 
but I'm currently believing that this is needlessly complicated.  If we 
want to keep it, though, we'll probably want two base classes -- one 
without transparency and a second one (built on top) with transparency, 
rather than a switchable behavior.  There are ***lots*** more 
transparency issues than just this one.

>
> The contact for Map.get and Map.remove says that they will return null 
> if the entry is not present or if the value is null. This implies an 
> alternate way to fulfill the Map.remove contract would be to set a 
> local property to null. 

The contract also says you can do things like unmodifiable Maps, in 
which case you're supposed to return UnsupportedOperationException.

>
>
>         // Case 2 -- this is a local property
>         if (key != null) {
> +            if (removeLocal) {
> +               return put(key,null);
> +            }
> +            } else {
>                 PropertyDescriptor descriptor =
>                     (PropertyDescriptor) descriptors.get(key);
>
> I'd like to apply this and add constructors that can be used to set 
> "removeLocal". The default could be false, which provices the original 
> behavior, and throws the exception.
>
> I do have a use-case for this involving a working component that does 
> try to use remove.
>
> IMHO, part of our API contract for BaseContext should be that the 
> local properties can be made transparent to a caller of the Map, and 
> that a context should be able to use entries or fields with 
> zero-changes to callers.

As above, if we're going to have two supported behaviors, I'd rather do 
it with two base classes.  My preference would be that we don't make it 
optional, though, on the following grounds:

* It's simpler to just explain one behavior, than two.

* If you turn off transparency, why does Context exist
  at all?  Why not just use a Map directly?

>
>
> -Ted. 

Craig



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Ted Husted wrote:

> Craig R. McClanahan wrote:
>
>>  - If a user attempts to remove() the key corresponding to a property,
>>    throw IllegalArgumentException.
>
>
> Can we make this an optional behavior?

Only if we make attribute-property transparency optional.  That's what 
the contract for org.apache.commons.chain.Context still says right now, 
but I'm currently believing that this is needlessly complicated.  If we 
want to keep it, though, we'll probably want two base classes -- one 
without transparency and a second one (built on top) with transparency, 
rather than a switchable behavior.  There are ***lots*** more 
transparency issues than just this one.

>
> The contact for Map.get and Map.remove says that they will return null 
> if the entry is not present or if the value is null. This implies an 
> alternate way to fulfill the Map.remove contract would be to set a 
> local property to null. 

The contract also says you can do things like unmodifiable Maps, in 
which case you're supposed to return UnsupportedOperationException.

>
>
>         // Case 2 -- this is a local property
>         if (key != null) {
> +            if (removeLocal) {
> +               return put(key,null);
> +            }
> +            } else {
>                 PropertyDescriptor descriptor =
>                     (PropertyDescriptor) descriptors.get(key);
>
> I'd like to apply this and add constructors that can be used to set 
> "removeLocal". The default could be false, which provices the original 
> behavior, and throws the exception.
>
> I do have a use-case for this involving a working component that does 
> try to use remove.
>
> IMHO, part of our API contract for BaseContext should be that the 
> local properties can be made transparent to a caller of the Map, and 
> that a context should be able to use entries or fields with 
> zero-changes to callers.

As above, if we're going to have two supported behaviors, I'd rather do 
it with two base classes.  My preference would be that we don't make it 
optional, though, on the following grounds:

* It's simpler to just explain one behavior, than two.

* If you turn off transparency, why does Context exist
  at all?  Why not just use a Map directly?

>
>
> -Ted. 

Craig



Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Ted Husted <hu...@apache.org>.
Craig R. McClanahan wrote:
>  - If a user attempts to remove() the key corresponding to a property,
>    throw IllegalArgumentException.

Can we make this an optional behavior?

The contact for Map.get and Map.remove says that they will return null 
if the entry is not present or if the value is null. This implies an 
alternate way to fulfill the Map.remove contract would be to set a local 
property to null.

         // Case 2 -- this is a local property
         if (key != null) {
+            if (removeLocal) {
+               return put(key,null);
+            }
+            } else {
                 PropertyDescriptor descriptor =
                     (PropertyDescriptor) descriptors.get(key);

I'd like to apply this and add constructors that can be used to set 
"removeLocal". The default could be false, which provices the original 
behavior, and throws the exception.

I do have a use-case for this involving a working component that does 
try to use remove.

IMHO, part of our API contract for BaseContext should be that the local 
properties can be made transparent to a caller of the Map, and that a 
context should be able to use entries or fields with zero-changes to 
callers.


-Ted.



Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Ted Husted <hu...@apache.org>.
Craig R. McClanahan wrote:
>  - If a user attempts to remove() the key corresponding to a property,
>    throw IllegalArgumentException.

Can we make this an optional behavior?

The contact for Map.get and Map.remove says that they will return null 
if the entry is not present or if the value is null. This implies an 
alternate way to fulfill the Map.remove contract would be to set a local 
property to null.

         // Case 2 -- this is a local property
         if (key != null) {
+            if (removeLocal) {
+               return put(key,null);
+            }
+            } else {
                 PropertyDescriptor descriptor =
                     (PropertyDescriptor) descriptors.get(key);

I'd like to apply this and add constructors that can be used to set 
"removeLocal". The default could be false, which provices the original 
behavior, and throws the exception.

I do have a use-case for this involving a working component that does 
try to use remove.

IMHO, part of our API contract for BaseContext should be that the local 
properties can be made transparent to a caller of the Map, and that a 
context should be able to use entries or fields with zero-changes to 
callers.


-Ted.



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Sgarlata Matt wrote:

>I like the way this discussion is going.  My 2 cents would be we should test
>this approach with tools like Velocity, the JSTL EL, and BeanUtils to make
>sure these tools don't get confused by the Context object being both a map
>and having real getters/setters for the same property.  Do you foresee any
>problems with this?
>  
>
For the properties of the Context implementation class, it will not 
matter whether a library considers them to be a JavaBean or a Map -- 
they'll get the same results either way.

For attributes that are not JavaBean properties:

* BeanUtils will always treat it as a Map, so things will work as expected

* For JSTL and JSP 2.0 expressions, the expression evaluation rules
  require checking for Map-ness before checking for JavaBean properties,
  so things will work as expected.

* For any other library, you'll have to check it yourself, but I would be
  surprised if there were any cases where you'd want to check for
  JavaBeans properties before doing an "instanceof Map" check.


Craig

>Matt
>----- Original Message ----- 
>From: "Craig R. McClanahan" <cr...@apache.org>
>To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
>Sent: Saturday, September 27, 2003 2:37 PM
>Subject: Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain]
>examples XML file available?)
>
>
>  
>
>>Ted Husted wrote:
>>
>>    
>>
>>>Craig R. McClanahan wrote:
>>>
>>>      
>>>
>>>>We haven't released anything yet ... why not just check it in to the
>>>>o.a.c.c.impl package so we can all take a look.  We need to
>>>>completely fulfill the Map contracts if we go this way, and I have
>>>>some concerns about that.
>>>>        
>>>>
>>>It's there. This one just delegates the Map methods to getAttributes,
>>>so the Context object can be used in places that already expect a Map.
>>>      
>>>
>>OK, I can buy into Context is-a Map.  Here's one way to approach making
>>this change:
>>
>>* Context becomes a marker interface:
>>
>>    public interface Context extends Map { }
>>
>>  The getAttributes() method is removed.
>>
>>* In order to fulfill the Map contract for things like equals() and
>>hashCode()
>>  more directly, ContextBase can extend HashMap instead of implement Map
>>  with a delegated-to HashMap instance variable like ContextBaseAttributes
>>  does now.
>>
>>* For the property transparency thing:
>>
>>  - In the ContextBase constructor, introspect the list of properties,
>>    and add key-value pairs for all of them to the superclass Map.
>>    The values in this case are actually irrelevant, because they won't
>>    be used -- all the accessors will need to know to call the
>>    underlying property getter/setter.
>>
>>  - get() and put() call the right getter or setter, which can be
>>implemented
>>    however they want (I don't see any reason they should want to store
>>    the values in the superclass HashMap, but they could by just calling
>>    super.get() and super.put()).
>>
>>  - If a user attempts to remove() the key corresponding to a property,
>>    throw IllegalArgumentException.
>>
>>Doing things this way means we don't need getField()/putField() to
>>accomplish your desire to (optionally) keep all the values in the
>>internal map.
>>
>>Does this sound like a reasonable strategy?
>>
>>    
>>
>>>-T.
>>>      
>>>
>>Craig
>>
>>
>>
>>---------------------------------------------------------------------
>>To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
>>For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>>
>>    
>>
>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>  
>


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Sgarlata Matt <sg...@bah.com>.
I like the way this discussion is going.  My 2 cents would be we should test
this approach with tools like Velocity, the JSTL EL, and BeanUtils to make
sure these tools don't get confused by the Context object being both a map
and having real getters/setters for the same property.  Do you foresee any
problems with this?

Matt
----- Original Message ----- 
From: "Craig R. McClanahan" <cr...@apache.org>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
Sent: Saturday, September 27, 2003 2:37 PM
Subject: Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain]
examples XML file available?)


> Ted Husted wrote:
>
> > Craig R. McClanahan wrote:
> >
> >> We haven't released anything yet ... why not just check it in to the
> >> o.a.c.c.impl package so we can all take a look.  We need to
> >> completely fulfill the Map contracts if we go this way, and I have
> >> some concerns about that.
> >
> >
> > It's there. This one just delegates the Map methods to getAttributes,
> > so the Context object can be used in places that already expect a Map.
>
> OK, I can buy into Context is-a Map.  Here's one way to approach making
> this change:
>
> * Context becomes a marker interface:
>
>     public interface Context extends Map { }
>
>   The getAttributes() method is removed.
>
> * In order to fulfill the Map contract for things like equals() and
> hashCode()
>   more directly, ContextBase can extend HashMap instead of implement Map
>   with a delegated-to HashMap instance variable like ContextBaseAttributes
>   does now.
>
> * For the property transparency thing:
>
>   - In the ContextBase constructor, introspect the list of properties,
>     and add key-value pairs for all of them to the superclass Map.
>     The values in this case are actually irrelevant, because they won't
>     be used -- all the accessors will need to know to call the
>     underlying property getter/setter.
>
>   - get() and put() call the right getter or setter, which can be
> implemented
>     however they want (I don't see any reason they should want to store
>     the values in the superclass HashMap, but they could by just calling
>     super.get() and super.put()).
>
>   - If a user attempts to remove() the key corresponding to a property,
>     throw IllegalArgumentException.
>
> Doing things this way means we don't need getField()/putField() to
> accomplish your desire to (optionally) keep all the values in the
> internal map.
>
> Does this sound like a reasonable strategy?
>
> >
> > -T.
>
> Craig
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Sgarlata Matt <sg...@bah.com>.
I like the way this discussion is going.  My 2 cents would be we should test
this approach with tools like Velocity, the JSTL EL, and BeanUtils to make
sure these tools don't get confused by the Context object being both a map
and having real getters/setters for the same property.  Do you foresee any
problems with this?

Matt
----- Original Message ----- 
From: "Craig R. McClanahan" <cr...@apache.org>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
Sent: Saturday, September 27, 2003 2:37 PM
Subject: Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain]
examples XML file available?)


> Ted Husted wrote:
>
> > Craig R. McClanahan wrote:
> >
> >> We haven't released anything yet ... why not just check it in to the
> >> o.a.c.c.impl package so we can all take a look.  We need to
> >> completely fulfill the Map contracts if we go this way, and I have
> >> some concerns about that.
> >
> >
> > It's there. This one just delegates the Map methods to getAttributes,
> > so the Context object can be used in places that already expect a Map.
>
> OK, I can buy into Context is-a Map.  Here's one way to approach making
> this change:
>
> * Context becomes a marker interface:
>
>     public interface Context extends Map { }
>
>   The getAttributes() method is removed.
>
> * In order to fulfill the Map contract for things like equals() and
> hashCode()
>   more directly, ContextBase can extend HashMap instead of implement Map
>   with a delegated-to HashMap instance variable like ContextBaseAttributes
>   does now.
>
> * For the property transparency thing:
>
>   - In the ContextBase constructor, introspect the list of properties,
>     and add key-value pairs for all of them to the superclass Map.
>     The values in this case are actually irrelevant, because they won't
>     be used -- all the accessors will need to know to call the
>     underlying property getter/setter.
>
>   - get() and put() call the right getter or setter, which can be
> implemented
>     however they want (I don't see any reason they should want to store
>     the values in the superclass HashMap, but they could by just calling
>     super.get() and super.put()).
>
>   - If a user attempts to remove() the key corresponding to a property,
>     throw IllegalArgumentException.
>
> Doing things this way means we don't need getField()/putField() to
> accomplish your desire to (optionally) keep all the values in the
> internal map.
>
> Does this sound like a reasonable strategy?
>
> >
> > -T.
>
> Craig
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Ted Husted wrote:

> Craig R. McClanahan wrote:
>
>> We haven't released anything yet ... why not just check it in to the 
>> o.a.c.c.impl package so we can all take a look.  We need to 
>> completely fulfill the Map contracts if we go this way, and I have 
>> some concerns about that.
>
>
> It's there. This one just delegates the Map methods to getAttributes, 
> so the Context object can be used in places that already expect a Map.

OK, I can buy into Context is-a Map.  Here's one way to approach making 
this change:

* Context becomes a marker interface:

    public interface Context extends Map { }

  The getAttributes() method is removed.

* In order to fulfill the Map contract for things like equals() and 
hashCode()
  more directly, ContextBase can extend HashMap instead of implement Map
  with a delegated-to HashMap instance variable like ContextBaseAttributes
  does now.

* For the property transparency thing:

  - In the ContextBase constructor, introspect the list of properties,
    and add key-value pairs for all of them to the superclass Map.
    The values in this case are actually irrelevant, because they won't
    be used -- all the accessors will need to know to call the
    underlying property getter/setter.

  - get() and put() call the right getter or setter, which can be 
implemented
    however they want (I don't see any reason they should want to store
    the values in the superclass HashMap, but they could by just calling
    super.get() and super.put()).

  - If a user attempts to remove() the key corresponding to a property,
    throw IllegalArgumentException.

Doing things this way means we don't need getField()/putField() to 
accomplish your desire to (optionally) keep all the values in the 
internal map.

Does this sound like a reasonable strategy?

>
> -T.

Craig



Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Ted Husted wrote:

> Craig R. McClanahan wrote:
>
>> We haven't released anything yet ... why not just check it in to the 
>> o.a.c.c.impl package so we can all take a look.  We need to 
>> completely fulfill the Map contracts if we go this way, and I have 
>> some concerns about that.
>
>
> It's there. This one just delegates the Map methods to getAttributes, 
> so the Context object can be used in places that already expect a Map.

OK, I can buy into Context is-a Map.  Here's one way to approach making 
this change:

* Context becomes a marker interface:

    public interface Context extends Map { }

  The getAttributes() method is removed.

* In order to fulfill the Map contract for things like equals() and 
hashCode()
  more directly, ContextBase can extend HashMap instead of implement Map
  with a delegated-to HashMap instance variable like ContextBaseAttributes
  does now.

* For the property transparency thing:

  - In the ContextBase constructor, introspect the list of properties,
    and add key-value pairs for all of them to the superclass Map.
    The values in this case are actually irrelevant, because they won't
    be used -- all the accessors will need to know to call the
    underlying property getter/setter.

  - get() and put() call the right getter or setter, which can be 
implemented
    however they want (I don't see any reason they should want to store
    the values in the superclass HashMap, but they could by just calling
    super.get() and super.put()).

  - If a user attempts to remove() the key corresponding to a property,
    throw IllegalArgumentException.

Doing things this way means we don't need getField()/putField() to 
accomplish your desire to (optionally) keep all the values in the 
internal map.

Does this sound like a reasonable strategy?

>
> -T.

Craig



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Ted Husted <hu...@apache.org>.
Craig R. McClanahan wrote:
> We haven't released anything yet ... why not just check it in to the 
> o.a.c.c.impl package so we can all take a look.  We need to completely 
> fulfill the Map contracts if we go this way, and I have some concerns 
> about that.

It's there. This one just delegates the Map methods to getAttributes, so 
the Context object can be used in places that already expect a Map.

-T.



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Ted Husted <hu...@apache.org>.
Craig R. McClanahan wrote:
> We haven't released anything yet ... why not just check it in to the 
> o.a.c.c.impl package so we can all take a look.  We need to completely 
> fulfill the Map contracts if we go this way, and I have some concerns 
> about that.

It's there. This one just delegates the Map methods to getAttributes, so 
the Context object can be used in places that already expect a Map.

-T.



Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Ted Husted wrote:

> Craig R. McClanahan wrote:
>
>> The latter lets any Command lets any Context implementation be passed 
>> in, but still provide generic access to the specialized properties 
>> without casting.  For example, if your Command is passed in a 
>> ServletWebContext you can try:
>>
>>  Map map = (Map) context.getAttributes().get("requestScope");
>>
>> without having to know what Context implementation was used.  The 
>> things that are accessed through the typesafe property getters and 
>> setters are *not* hidden; and you can program solely to the generic 
>> Context API if you want to avoid creating dependencies on external 
>> Context implementation classes that may or may not be present.
>
>
> It still doesn't seem like we're answering the question of why does 
> the context have-a-map instead of being-a-map. If Context extended 
> Map, rather than specify a Map property, could not the BaseContext 
> implement the ContextBaseAttributes code directly, instead of as a 
> property? Why is it
>
> context.getAttributes().get("attribute);
>
> instead of
>
> context.get("attribute");
>
> As you've said, we already have a standard interface for a Context ... 
> Map =:) Why are we creating another? (An object with a Map.) Are we 
> just following the example set by ServletContext? That in itself is a 
> fair-enough reason, but I wondered if there were another.
>
> (Another reason might be that isEmpty could conflict with a client 
> attribute (but, conceivably, so could getAttributes)).
>
> Of course, it's not hard to have it both ways. I've been using a 
> ContextMap class as a base, which I'll post as another experimental 
> class. It just implements the Map interface by calling getAttributes. 
> (Should we setup a "whiteboard" or "opt" package for these?)

We haven't released anything yet ... why not just check it in to the 
o.a.c.c.impl package so we can all take a look.  We need to completely 
fulfill the Map contracts if we go this way, and I have some concerns 
about that.

>
>
>> My problem with this is what it does to implementors of subclasses of 
>> such a BaseContext2.
>>
>> Lots of people can type the idiom for creating a new property on a 
>> JavaBean without even thinking about it:
>>
>>    private String foo;
>>    public String getFoo() { return this.foo; }
>>    public void setFoo(String foo) { this.foo = foo; }
>>
>> and there are lots of IDEs that will do it for you too.  
>> Unfortunately, such code won't work in a BaseContext2 subclass; you'd 
>> have to change it to:
>>
>>    public String getFoo() { return ((String) 
>> getAttributes().get("foo")); }
>>    public void setFoo(String foo) { getAttributes().put("foo", foo); }
>>
>> I can guarantee you that this kind of code doesn't roll straight off 
>> your fingertips :-).
>
>
> Either approach works with Base2. You can mix and match member fields 
> with Map entries. I definitely wouldn't suggest obviating member 
> fields, since it's such a common strategy.
>
> The code I use now to access the Map entries as property values looks 
> like this:
>
>     public String getApplicant() {
>         return (String) getField(Tokens.PN_APPLICANT);
>     }
>
>     public void setApplicant(String property) {
>         putField(Tokens.PN_APPLICANT, property);
>     }
>
> And I've the IDE programed to prompt me for the Property and Token 
> names when I need to create one of these, so it's not so hard. 
> (Though, just telling it to encapsulate a field is even easier.)
>
> As it stands, I'm not declaring properties for simple String fields, 
> but only for key fields that are often used in API class and those 
> that need type-safety. So like 80% of the attributes don't need 
> properties anyway.
>
> What I don't like is that getField and putField bypass the reflection 
> mechanism, and so become a backdoor that accesses the underlying 
> attribute map directly. At the very least, this seems to bend 
> encapsulation.
>
> I do believe that it would be better if we didn't compel people to use 
> member fields when there's a perfectly good Map sitting there, but I'm 
> still not thrilled with my implementation.
>
>
>> The other complication would be you can't do this for primitive 
>> properties, since  you can't store them in the real Map.
>
>
> I suppose the properties could store them in the wrapper classes and 
> turn them back to primitives on the way back. Since most data access 
> tools don't like primitives, I rarely use them as attributes myself.

But they are commonly used as properties ... which is what the typesafe 
attributes look like to a user of a Context.  On the other hand, if 
Context is-a Map then people will be used to using the wrapper classes 
around these things anyway.

>
> -Ted.

Craig



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Ted Husted wrote:

> Craig R. McClanahan wrote:
>
>> The latter lets any Command lets any Context implementation be passed 
>> in, but still provide generic access to the specialized properties 
>> without casting.  For example, if your Command is passed in a 
>> ServletWebContext you can try:
>>
>>  Map map = (Map) context.getAttributes().get("requestScope");
>>
>> without having to know what Context implementation was used.  The 
>> things that are accessed through the typesafe property getters and 
>> setters are *not* hidden; and you can program solely to the generic 
>> Context API if you want to avoid creating dependencies on external 
>> Context implementation classes that may or may not be present.
>
>
> It still doesn't seem like we're answering the question of why does 
> the context have-a-map instead of being-a-map. If Context extended 
> Map, rather than specify a Map property, could not the BaseContext 
> implement the ContextBaseAttributes code directly, instead of as a 
> property? Why is it
>
> context.getAttributes().get("attribute);
>
> instead of
>
> context.get("attribute");
>
> As you've said, we already have a standard interface for a Context ... 
> Map =:) Why are we creating another? (An object with a Map.) Are we 
> just following the example set by ServletContext? That in itself is a 
> fair-enough reason, but I wondered if there were another.
>
> (Another reason might be that isEmpty could conflict with a client 
> attribute (but, conceivably, so could getAttributes)).
>
> Of course, it's not hard to have it both ways. I've been using a 
> ContextMap class as a base, which I'll post as another experimental 
> class. It just implements the Map interface by calling getAttributes. 
> (Should we setup a "whiteboard" or "opt" package for these?)

We haven't released anything yet ... why not just check it in to the 
o.a.c.c.impl package so we can all take a look.  We need to completely 
fulfill the Map contracts if we go this way, and I have some concerns 
about that.

>
>
>> My problem with this is what it does to implementors of subclasses of 
>> such a BaseContext2.
>>
>> Lots of people can type the idiom for creating a new property on a 
>> JavaBean without even thinking about it:
>>
>>    private String foo;
>>    public String getFoo() { return this.foo; }
>>    public void setFoo(String foo) { this.foo = foo; }
>>
>> and there are lots of IDEs that will do it for you too.  
>> Unfortunately, such code won't work in a BaseContext2 subclass; you'd 
>> have to change it to:
>>
>>    public String getFoo() { return ((String) 
>> getAttributes().get("foo")); }
>>    public void setFoo(String foo) { getAttributes().put("foo", foo); }
>>
>> I can guarantee you that this kind of code doesn't roll straight off 
>> your fingertips :-).
>
>
> Either approach works with Base2. You can mix and match member fields 
> with Map entries. I definitely wouldn't suggest obviating member 
> fields, since it's such a common strategy.
>
> The code I use now to access the Map entries as property values looks 
> like this:
>
>     public String getApplicant() {
>         return (String) getField(Tokens.PN_APPLICANT);
>     }
>
>     public void setApplicant(String property) {
>         putField(Tokens.PN_APPLICANT, property);
>     }
>
> And I've the IDE programed to prompt me for the Property and Token 
> names when I need to create one of these, so it's not so hard. 
> (Though, just telling it to encapsulate a field is even easier.)
>
> As it stands, I'm not declaring properties for simple String fields, 
> but only for key fields that are often used in API class and those 
> that need type-safety. So like 80% of the attributes don't need 
> properties anyway.
>
> What I don't like is that getField and putField bypass the reflection 
> mechanism, and so become a backdoor that accesses the underlying 
> attribute map directly. At the very least, this seems to bend 
> encapsulation.
>
> I do believe that it would be better if we didn't compel people to use 
> member fields when there's a perfectly good Map sitting there, but I'm 
> still not thrilled with my implementation.
>
>
>> The other complication would be you can't do this for primitive 
>> properties, since  you can't store them in the real Map.
>
>
> I suppose the properties could store them in the wrapper classes and 
> turn them back to primitives on the way back. Since most data access 
> tools don't like primitives, I rarely use them as attributes myself.

But they are commonly used as properties ... which is what the typesafe 
attributes look like to a user of a Context.  On the other hand, if 
Context is-a Map then people will be used to using the wrapper classes 
around these things anyway.

>
> -Ted.

Craig



Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Ted Husted <hu...@apache.org>.
Craig R. McClanahan wrote:
> The latter lets any Command lets any Context implementation be passed 
> in, but still provide generic access to the specialized properties 
> without casting.  For example, if your Command is passed in a 
> ServletWebContext you can try:
> 
>  Map map = (Map) context.getAttributes().get("requestScope");
> 
> without having to know what Context implementation was used.  The things 
> that are accessed through the typesafe property getters and setters are 
> *not* hidden; and you can program solely to the generic Context API if 
> you want to avoid creating dependencies on external Context 
> implementation classes that may or may not be present.

It still doesn't seem like we're answering the question of why does the 
context have-a-map instead of being-a-map. If Context extended Map, 
rather than specify a Map property, could not the BaseContext implement 
the ContextBaseAttributes code directly, instead of as a property? Why is it

context.getAttributes().get("attribute);

instead of

context.get("attribute");

As you've said, we already have a standard interface for a Context ... 
Map =:) Why are we creating another? (An object with a Map.) Are we just 
following the example set by ServletContext? That in itself is a 
fair-enough reason, but I wondered if there were another.

(Another reason might be that isEmpty could conflict with a client 
attribute (but, conceivably, so could getAttributes)).

Of course, it's not hard to have it both ways. I've been using a 
ContextMap class as a base, which I'll post as another experimental 
class. It just implements the Map interface by calling getAttributes. 
(Should we setup a "whiteboard" or "opt" package for these?)


> My problem with this is what it does to implementors of subclasses of 
> such a BaseContext2.
> 
> Lots of people can type the idiom for creating a new property on a 
> JavaBean without even thinking about it:
> 
>    private String foo;
>    public String getFoo() { return this.foo; }
>    public void setFoo(String foo) { this.foo = foo; }
> 
> and there are lots of IDEs that will do it for you too.  Unfortunately, 
> such code won't work in a BaseContext2 subclass; you'd have to change it 
> to:
> 
>    public String getFoo() { return ((String) getAttributes().get("foo")); }
>    public void setFoo(String foo) { getAttributes().put("foo", foo); }
> 
> I can guarantee you that this kind of code doesn't roll straight off 
> your fingertips :-).

Either approach works with Base2. You can mix and match member fields 
with Map entries. I definitely wouldn't suggest obviating member fields, 
since it's such a common strategy.

The code I use now to access the Map entries as property values looks 
like this:

     public String getApplicant() {
         return (String) getField(Tokens.PN_APPLICANT);
     }

     public void setApplicant(String property) {
         putField(Tokens.PN_APPLICANT, property);
     }

And I've the IDE programed to prompt me for the Property and Token names 
when I need to create one of these, so it's not so hard. (Though, just 
telling it to encapsulate a field is even easier.)

As it stands, I'm not declaring properties for simple String fields, but 
only for key fields that are often used in API class and those that need 
type-safety. So like 80% of the attributes don't need properties anyway.

What I don't like is that getField and putField bypass the reflection 
mechanism, and so become a backdoor that accesses the underlying 
attribute map directly. At the very least, this seems to bend 
encapsulation.

I do believe that it would be better if we didn't compel people to use 
member fields when there's a perfectly good Map sitting there, but I'm 
still not thrilled with my implementation.


> The other complication would be you can't do this for primitive 
> properties, since  you can't store them in the real Map.

I suppose the properties could store them in the wrapper classes and 
turn them back to primitives on the way back. Since most data access 
tools don't like primitives, I rarely use them as attributes myself.

-Ted.




Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Ted Husted <hu...@apache.org>.
Craig R. McClanahan wrote:
> The latter lets any Command lets any Context implementation be passed 
> in, but still provide generic access to the specialized properties 
> without casting.  For example, if your Command is passed in a 
> ServletWebContext you can try:
> 
>  Map map = (Map) context.getAttributes().get("requestScope");
> 
> without having to know what Context implementation was used.  The things 
> that are accessed through the typesafe property getters and setters are 
> *not* hidden; and you can program solely to the generic Context API if 
> you want to avoid creating dependencies on external Context 
> implementation classes that may or may not be present.

It still doesn't seem like we're answering the question of why does the 
context have-a-map instead of being-a-map. If Context extended Map, 
rather than specify a Map property, could not the BaseContext implement 
the ContextBaseAttributes code directly, instead of as a property? Why is it

context.getAttributes().get("attribute);

instead of

context.get("attribute");

As you've said, we already have a standard interface for a Context ... 
Map =:) Why are we creating another? (An object with a Map.) Are we just 
following the example set by ServletContext? That in itself is a 
fair-enough reason, but I wondered if there were another.

(Another reason might be that isEmpty could conflict with a client 
attribute (but, conceivably, so could getAttributes)).

Of course, it's not hard to have it both ways. I've been using a 
ContextMap class as a base, which I'll post as another experimental 
class. It just implements the Map interface by calling getAttributes. 
(Should we setup a "whiteboard" or "opt" package for these?)


> My problem with this is what it does to implementors of subclasses of 
> such a BaseContext2.
> 
> Lots of people can type the idiom for creating a new property on a 
> JavaBean without even thinking about it:
> 
>    private String foo;
>    public String getFoo() { return this.foo; }
>    public void setFoo(String foo) { this.foo = foo; }
> 
> and there are lots of IDEs that will do it for you too.  Unfortunately, 
> such code won't work in a BaseContext2 subclass; you'd have to change it 
> to:
> 
>    public String getFoo() { return ((String) getAttributes().get("foo")); }
>    public void setFoo(String foo) { getAttributes().put("foo", foo); }
> 
> I can guarantee you that this kind of code doesn't roll straight off 
> your fingertips :-).

Either approach works with Base2. You can mix and match member fields 
with Map entries. I definitely wouldn't suggest obviating member fields, 
since it's such a common strategy.

The code I use now to access the Map entries as property values looks 
like this:

     public String getApplicant() {
         return (String) getField(Tokens.PN_APPLICANT);
     }

     public void setApplicant(String property) {
         putField(Tokens.PN_APPLICANT, property);
     }

And I've the IDE programed to prompt me for the Property and Token names 
when I need to create one of these, so it's not so hard. (Though, just 
telling it to encapsulate a field is even easier.)

As it stands, I'm not declaring properties for simple String fields, but 
only for key fields that are often used in API class and those that need 
type-safety. So like 80% of the attributes don't need properties anyway.

What I don't like is that getField and putField bypass the reflection 
mechanism, and so become a backdoor that accesses the underlying 
attribute map directly. At the very least, this seems to bend 
encapsulation.

I do believe that it would be better if we didn't compel people to use 
member fields when there's a perfectly good Map sitting there, but I'm 
still not thrilled with my implementation.


> The other complication would be you can't do this for primitive 
> properties, since  you can't store them in the real Map.

I suppose the properties could store them in the wrapper classes and 
turn them back to primitives on the way back. Since most data access 
tools don't like primitives, I rarely use them as attributes myself.

-Ted.




---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Ted Husted wrote:

> Craig R. McClanahan wrote:
>
>> Do you think we should make a Catalog an optional property of a 
>> Context?  A lot of use cases would like to have a default spot to go 
>> find one, and you can always have private conventions about what 
>> other attribute keys might also point at other Catalogs.
>
>
> If we are talking about the Context interface, it might be 
> problematic, since it would seem that any property we define there 
> would steal it from the application. So, they could not have a 
> "context" attribute of their own, even if they were using context in, 
> well, a different context =:)

Yep :-).

>
> But if by optional we mean a property on a base implementation, then 
> that would seem all right. Worst case, they implement their own base. 
> I like the loosely knit relationships between the three interfaces, 
> but at some point implementations do need to start to nail things down 
> for people.

Agreed.  We want the right balance of ease-of-use and flexibility.

>
> Of course, once we do that, a question someone is going to ask 
> sometime is "Why doesn't the Command just have a pointer to its 
> Catalog?" I'm not convinced it would be a good idea, but it's 
> something we should ask and answer.

Thinking out loud to get my initial answers down for posterity, I don't 
think we want to require the use of Catalogs at all.  I *certainly* 
don't think we should constrain a Command (or Chain) instance to be 
associated with a single Catalog.

>
> Another popular question will be, "Why isn't the Context itself a Map?"

Well, it is-a Map of sorts (or more precisely, it has-a Map as its data 
representation).  But what it also offers is a couple of interesting things:

* Ability to have type-safe accessors like any JavaBean.

* Attribute-property transparency (at least if you implement the Javadoc
  contracts for Context, or use ContextBase to do the hard part for you).

The latter lets any Command lets any Context implementation be passed 
in, but still provide generic access to the specialized properties 
without casting.  For example, if your Command is passed in a 
ServletWebContext you can try:

  Map map = (Map) context.getAttributes().get("requestScope");

without having to know what Context implementation was used.  The things 
that are accessed through the typesafe property getters and setters are 
*not* hidden; and you can program solely to the generic Context API if 
you want to avoid creating dependencies on external Context 
implementation classes that may or may not be present.

>
> In my own base class, I needed to make it a Map (through composition - 
> the Map methods just call back to getAttributes) so it could mesh with 
> other parts of the application. It's going to be a FAQ, so we might 
> want to deal with it now.

As pointed out in the discussion below, it's not necessarily trivial to 
do this.

>
> I think the answer is going to be extensibility, but we might consider 
> an optional implementation that provides a Map interface for people to 
> use.
>
> On a related subject, how do we feel about the BaseContext2 class that 
> allows property fields to be stored in the attribute Map? I have mixed 
> feelings about the implementation, since it bends encapsulation, but I 
> *really* like the idea of keeping all my fields and attributes together.

My problem with this is what it does to implementors of subclasses of 
such a BaseContext2.

Lots of people can type the idiom for creating a new property on a 
JavaBean without even thinking about it:

    private String foo;
    public String getFoo() { return this.foo; }
    public void setFoo(String foo) { this.foo = foo; }

and there are lots of IDEs that will do it for you too.  Unfortunately, 
such code won't work in a BaseContext2 subclass; you'd have to change it to:

    public String getFoo() { return ((String) getAttributes().get("foo")); }
    public void setFoo(String foo) { getAttributes().put("foo", foo); }

I can guarantee you that this kind of code doesn't roll straight off 
your fingertips :-).

A different approach to meet your desire might be to actually store the 
property names in the existing Map, with the values pointing back at the 
actual instance variables.  We'd probably want to make remove() throw 
IllegalArgumentException on attempts to remove them.  The other 
complication would be you can't do this for primitive properties, since 
you can't store them in the real Map.

>
> -Ted.

Craig

>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Ted Husted wrote:

> Craig R. McClanahan wrote:
>
>> Do you think we should make a Catalog an optional property of a 
>> Context?  A lot of use cases would like to have a default spot to go 
>> find one, and you can always have private conventions about what 
>> other attribute keys might also point at other Catalogs.
>
>
> If we are talking about the Context interface, it might be 
> problematic, since it would seem that any property we define there 
> would steal it from the application. So, they could not have a 
> "context" attribute of their own, even if they were using context in, 
> well, a different context =:)

Yep :-).

>
> But if by optional we mean a property on a base implementation, then 
> that would seem all right. Worst case, they implement their own base. 
> I like the loosely knit relationships between the three interfaces, 
> but at some point implementations do need to start to nail things down 
> for people.

Agreed.  We want the right balance of ease-of-use and flexibility.

>
> Of course, once we do that, a question someone is going to ask 
> sometime is "Why doesn't the Command just have a pointer to its 
> Catalog?" I'm not convinced it would be a good idea, but it's 
> something we should ask and answer.

Thinking out loud to get my initial answers down for posterity, I don't 
think we want to require the use of Catalogs at all.  I *certainly* 
don't think we should constrain a Command (or Chain) instance to be 
associated with a single Catalog.

>
> Another popular question will be, "Why isn't the Context itself a Map?"

Well, it is-a Map of sorts (or more precisely, it has-a Map as its data 
representation).  But what it also offers is a couple of interesting things:

* Ability to have type-safe accessors like any JavaBean.

* Attribute-property transparency (at least if you implement the Javadoc
  contracts for Context, or use ContextBase to do the hard part for you).

The latter lets any Command lets any Context implementation be passed 
in, but still provide generic access to the specialized properties 
without casting.  For example, if your Command is passed in a 
ServletWebContext you can try:

  Map map = (Map) context.getAttributes().get("requestScope");

without having to know what Context implementation was used.  The things 
that are accessed through the typesafe property getters and setters are 
*not* hidden; and you can program solely to the generic Context API if 
you want to avoid creating dependencies on external Context 
implementation classes that may or may not be present.

>
> In my own base class, I needed to make it a Map (through composition - 
> the Map methods just call back to getAttributes) so it could mesh with 
> other parts of the application. It's going to be a FAQ, so we might 
> want to deal with it now.

As pointed out in the discussion below, it's not necessarily trivial to 
do this.

>
> I think the answer is going to be extensibility, but we might consider 
> an optional implementation that provides a Map interface for people to 
> use.
>
> On a related subject, how do we feel about the BaseContext2 class that 
> allows property fields to be stored in the attribute Map? I have mixed 
> feelings about the implementation, since it bends encapsulation, but I 
> *really* like the idea of keeping all my fields and attributes together.

My problem with this is what it does to implementors of subclasses of 
such a BaseContext2.

Lots of people can type the idiom for creating a new property on a 
JavaBean without even thinking about it:

    private String foo;
    public String getFoo() { return this.foo; }
    public void setFoo(String foo) { this.foo = foo; }

and there are lots of IDEs that will do it for you too.  Unfortunately, 
such code won't work in a BaseContext2 subclass; you'd have to change it to:

    public String getFoo() { return ((String) getAttributes().get("foo")); }
    public void setFoo(String foo) { getAttributes().put("foo", foo); }

I can guarantee you that this kind of code doesn't roll straight off 
your fingertips :-).

A different approach to meet your desire might be to actually store the 
property names in the existing Map, with the values pointing back at the 
actual instance variables.  We'd probably want to make remove() throw 
IllegalArgumentException on attempts to remove them.  The other 
complication would be you can't do this for primitive properties, since 
you can't store them in the real Map.

>
> -Ted.

Craig

>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org




Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Ted Husted <hu...@apache.org>.
Craig R. McClanahan wrote:
> Do you think we should make a Catalog an optional property of a 
> Context?  A lot of use cases would like to have a default spot to go 
> find one, and you can always have private conventions about what other 
> attribute keys might also point at other Catalogs.

If we are talking about the Context interface, it might be problematic, 
since it would seem that any property we define there would steal it 
from the application. So, they could not have a "context" attribute of 
their own, even if they were using context in, well, a different context =:)

But if by optional we mean a property on a base implementation, then 
that would seem all right. Worst case, they implement their own base. I 
like the loosely knit relationships between the three interfaces, but at 
some point implementations do need to start to nail things down for people.

Of course, once we do that, a question someone is going to ask sometime 
is "Why doesn't the Command just have a pointer to its Catalog?" I'm not 
convinced it would be a good idea, but it's something we should ask and 
answer.

Another popular question will be, "Why isn't the Context itself a Map?"

In my own base class, I needed to make it a Map (through composition - 
the Map methods just call back to getAttributes) so it could mesh with 
other parts of the application. It's going to be a FAQ, so we might want 
to deal with it now.

I think the answer is going to be extensibility, but we might consider 
an optional implementation that provides a Map interface for people to use.

On a related subject, how do we feel about the BaseContext2 class that 
allows property fields to be stored in the attribute Map? I have mixed 
feelings about the implementation, since it bends encapsulation, but I 
*really* like the idea of keeping all my fields and attributes together.

-Ted.



Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Ted Husted <hu...@apache.org>.
Craig R. McClanahan wrote:
> Do you think we should make a Catalog an optional property of a 
> Context?  A lot of use cases would like to have a default spot to go 
> find one, and you can always have private conventions about what other 
> attribute keys might also point at other Catalogs.

If we are talking about the Context interface, it might be problematic, 
since it would seem that any property we define there would steal it 
from the application. So, they could not have a "context" attribute of 
their own, even if they were using context in, well, a different context =:)

But if by optional we mean a property on a base implementation, then 
that would seem all right. Worst case, they implement their own base. I 
like the loosely knit relationships between the three interfaces, but at 
some point implementations do need to start to nail things down for people.

Of course, once we do that, a question someone is going to ask sometime 
is "Why doesn't the Command just have a pointer to its Catalog?" I'm not 
convinced it would be a good idea, but it's something we should ask and 
answer.

Another popular question will be, "Why isn't the Context itself a Map?"

In my own base class, I needed to make it a Map (through composition - 
the Map methods just call back to getAttributes) so it could mesh with 
other parts of the application. It's going to be a FAQ, so we might want 
to deal with it now.

I think the answer is going to be extensibility, but we might consider 
an optional implementation that provides a Map interface for people to use.

On a related subject, how do we feel about the BaseContext2 class that 
allows property fields to be stored in the attribute Map? I have mixed 
feelings about the implementation, since it bends encapsulation, but I 
*really* like the idea of keeping all my fields and attributes together.

-Ted.



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Ted Husted wrote:

> Craig R. McClanahan wrote:
>
>> Far better would be to divide the procedural flow into small steps 
>> that are externally configurable.  And, let each step have its own 
>> arbitrarily complex internal structure (by virtue of the fact that it 
>> can be a Command or a Chain of its own).  Oh, by the way, the 
>> procedural steps become small enough and narrowly focused enough to 
>> write high quality unit tests for.  And, because commands interact 
>> with each other *solely* through a Context, you can easily create 
>> mock objects (like a ServletContext or an HttpSession, in a chain 
>> destined for a web applicaton) that let you thoroughly test things in 
>> a standalone environment (in case it's not obvious, I'm a *huge* fan 
>> of JUnit :-).
>
>
> Me too. =:) Right now, I've got my DAO layer (which also uses a XML 
> config) running under the JUnit applet or as an Ant task. I can't seem 
> to get Chain running that way. It's fine as an Ant task, but when I 
> try to run it under the applet, my Commands table comes up empty =:(
>
> Obviously, I need to define this better, provide a demnstration 
> environment, but I thought I'd bring this up in case anyone had a clue 
> for a quick fix. [That green bar is soooo addictive :)]

Doesn't sound familiar, but use the Ant task variant myself.  Perhaps a 
class loader problem; perhaps related to the XML parsing?

>
> Though, my unit tests for the Commands don't utilize mocks. They just 
> populate the Context directly and pass it up. Of course, there's the 
> part where the Context is created from the request paramenters, but 
> that's a separate test suite that isn't coupled to the Commands.

That's the approach I take as well.

>
> For end-to-end integration, Cannoo Webtest pulls it all together 
> nicely. Need to run the container running for that one, but it doesn't 
> involve loading Cactus or anything like that, so those run very quickly.

For web stuff in particular, I've also found HtmlUnit to be quite 
helpful -- it lets you treat the response page as a DOM and look for 
various things, without the fragility of comparisons to a static golden 
file that is sensitive to changes in whitespace that are not usually 
important.

>
>
>> Indeed, the only reason that Catalog exists is to allow chains to 
>> refer to other chains in an organized way.  One could argue that even 
>> this is out of scope; however, it's very useful to be able to write a 
>> Command that uses complex processing logic to decide which other 
>> commands (or chains, since you can't tell in the catalog what 
>> something is) should be used to actually perform a task.
>
>
> IMHO, the Catalog construct places a key role in decoupling the sender 
> from receiver, as specified by the CoR pattern. Right now, I have a 
> command-name coming up from the web tier. The presentation framework 
> requesting the command has no idea how it will be handled. It just 
> knows how to create a given Context for a given Command, according to 
> a high-level API contract. All it really knows is the logical name and 
> parameters required. The Catalog takes care of selecting the 
> Command/Chain to process, in much the same way a framework like Struts 
> takes care of selecting the Action class to execute.
>
> If an implementation exposes the Catalog to the Command/Chains, then 
> another usage is to allow Commands to call one another through the 
> Catalog. As mentioned, this allows any number of clever strategies for 
> creating "framework" chains that can be reused in different ways under 
> different circumstances. This usage can also make the Catalogs more 
> testable, since a test could substitute a "mock" Command, if such a 
> thing were desired.

Do you think we should make a Catalog an optional property of a 
Context?  A lot of use cases would like to have a default spot to go 
find one, and you can always have private conventions about what other 
attribute keys might also point at other Catalogs.

>
> But, I would argue that these benefits are still secondary to the core 
> need to cleanly decouple sender from the receiver.
>
> -Ted.
>
>
>
Craig



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Ted Husted wrote:

> Craig R. McClanahan wrote:
>
>> Far better would be to divide the procedural flow into small steps 
>> that are externally configurable.  And, let each step have its own 
>> arbitrarily complex internal structure (by virtue of the fact that it 
>> can be a Command or a Chain of its own).  Oh, by the way, the 
>> procedural steps become small enough and narrowly focused enough to 
>> write high quality unit tests for.  And, because commands interact 
>> with each other *solely* through a Context, you can easily create 
>> mock objects (like a ServletContext or an HttpSession, in a chain 
>> destined for a web applicaton) that let you thoroughly test things in 
>> a standalone environment (in case it's not obvious, I'm a *huge* fan 
>> of JUnit :-).
>
>
> Me too. =:) Right now, I've got my DAO layer (which also uses a XML 
> config) running under the JUnit applet or as an Ant task. I can't seem 
> to get Chain running that way. It's fine as an Ant task, but when I 
> try to run it under the applet, my Commands table comes up empty =:(
>
> Obviously, I need to define this better, provide a demnstration 
> environment, but I thought I'd bring this up in case anyone had a clue 
> for a quick fix. [That green bar is soooo addictive :)]

Doesn't sound familiar, but use the Ant task variant myself.  Perhaps a 
class loader problem; perhaps related to the XML parsing?

>
> Though, my unit tests for the Commands don't utilize mocks. They just 
> populate the Context directly and pass it up. Of course, there's the 
> part where the Context is created from the request paramenters, but 
> that's a separate test suite that isn't coupled to the Commands.

That's the approach I take as well.

>
> For end-to-end integration, Cannoo Webtest pulls it all together 
> nicely. Need to run the container running for that one, but it doesn't 
> involve loading Cactus or anything like that, so those run very quickly.

For web stuff in particular, I've also found HtmlUnit to be quite 
helpful -- it lets you treat the response page as a DOM and look for 
various things, without the fragility of comparisons to a static golden 
file that is sensitive to changes in whitespace that are not usually 
important.

>
>
>> Indeed, the only reason that Catalog exists is to allow chains to 
>> refer to other chains in an organized way.  One could argue that even 
>> this is out of scope; however, it's very useful to be able to write a 
>> Command that uses complex processing logic to decide which other 
>> commands (or chains, since you can't tell in the catalog what 
>> something is) should be used to actually perform a task.
>
>
> IMHO, the Catalog construct places a key role in decoupling the sender 
> from receiver, as specified by the CoR pattern. Right now, I have a 
> command-name coming up from the web tier. The presentation framework 
> requesting the command has no idea how it will be handled. It just 
> knows how to create a given Context for a given Command, according to 
> a high-level API contract. All it really knows is the logical name and 
> parameters required. The Catalog takes care of selecting the 
> Command/Chain to process, in much the same way a framework like Struts 
> takes care of selecting the Action class to execute.
>
> If an implementation exposes the Catalog to the Command/Chains, then 
> another usage is to allow Commands to call one another through the 
> Catalog. As mentioned, this allows any number of clever strategies for 
> creating "framework" chains that can be reused in different ways under 
> different circumstances. This usage can also make the Catalogs more 
> testable, since a test could substitute a "mock" Command, if such a 
> thing were desired.

Do you think we should make a Catalog an optional property of a 
Context?  A lot of use cases would like to have a default spot to go 
find one, and you can always have private conventions about what other 
attribute keys might also point at other Catalogs.

>
> But, I would argue that these benefits are still secondary to the core 
> need to cleanly decouple sender from the receiver.
>
> -Ted.
>
>
>
Craig



Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Ted Husted <hu...@apache.org>.
Craig R. McClanahan wrote:
> Far better would be to divide the procedural flow into small steps that 
> are externally configurable.  And, let each step have its own 
> arbitrarily complex internal structure (by virtue of the fact that it 
> can be a Command or a Chain of its own).  Oh, by the way, the procedural 
> steps become small enough and narrowly focused enough to write high 
> quality unit tests for.  And, because commands interact with each other 
> *solely* through a Context, you can easily create mock objects (like a 
> ServletContext or an HttpSession, in a chain destined for a web 
> applicaton) that let you thoroughly test things in a standalone 
> environment (in case it's not obvious, I'm a *huge* fan of JUnit :-).

Me too. =:) Right now, I've got my DAO layer (which also uses a XML 
config) running under the JUnit applet or as an Ant task. I can't seem 
to get Chain running that way. It's fine as an Ant task, but when I try 
to run it under the applet, my Commands table comes up empty =:(

Obviously, I need to define this better, provide a demnstration 
environment, but I thought I'd bring this up in case anyone had a clue 
for a quick fix. [That green bar is soooo addictive :)]

Though, my unit tests for the Commands don't utilize mocks. They just 
populate the Context directly and pass it up. Of course, there's the 
part where the Context is created from the request paramenters, but 
that's a separate test suite that isn't coupled to the Commands.

For end-to-end integration, Cannoo Webtest pulls it all together nicely. 
Need to run the container running for that one, but it doesn't involve 
loading Cactus or anything like that, so those run very quickly.


> Indeed, the only reason that Catalog exists is to allow chains to refer 
> to other chains in an organized way.  One could argue that even this is 
> out of scope; however, it's very useful to be able to write a Command 
> that uses complex processing logic to decide which other commands (or 
> chains, since you can't tell in the catalog what something is) should be 
> used to actually perform a task.

IMHO, the Catalog construct places a key role in decoupling the sender 
from receiver, as specified by the CoR pattern. Right now, I have a 
command-name coming up from the web tier. The presentation framework 
requesting the command has no idea how it will be handled. It just knows 
how to create a given Context for a given Command, according to a 
high-level API contract. All it really knows is the logical name and 
parameters required. The Catalog takes care of selecting the 
Command/Chain to process, in much the same way a framework like Struts 
takes care of selecting the Action class to execute.

If an implementation exposes the Catalog to the Command/Chains, then 
another usage is to allow Commands to call one another through the 
Catalog. As mentioned, this allows any number of clever strategies for 
creating "framework" chains that can be reused in different ways under 
different circumstances. This usage can also make the Catalogs more 
testable, since a test could substitute a "mock" Command, if such a 
thing were desired.

But, I would argue that these benefits are still secondary to the core 
need to cleanly decouple sender from the receiver.

-Ted.



-- 
Ted Husted,
   Junit in Action  - <http://www.manning.com/massol/>,
   Struts in Action - <http://husted.com/struts/book.html>,
   JSP Site Design  - <http://www.amazon.com/exec/obidos/ISBN=1861005512>.

"Get Ready, We're Moving Out!!" - <http://www.clark04.com>



Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Ted Husted <hu...@apache.org>.
Craig R. McClanahan wrote:
> Far better would be to divide the procedural flow into small steps that 
> are externally configurable.  And, let each step have its own 
> arbitrarily complex internal structure (by virtue of the fact that it 
> can be a Command or a Chain of its own).  Oh, by the way, the procedural 
> steps become small enough and narrowly focused enough to write high 
> quality unit tests for.  And, because commands interact with each other 
> *solely* through a Context, you can easily create mock objects (like a 
> ServletContext or an HttpSession, in a chain destined for a web 
> applicaton) that let you thoroughly test things in a standalone 
> environment (in case it's not obvious, I'm a *huge* fan of JUnit :-).

Me too. =:) Right now, I've got my DAO layer (which also uses a XML 
config) running under the JUnit applet or as an Ant task. I can't seem 
to get Chain running that way. It's fine as an Ant task, but when I try 
to run it under the applet, my Commands table comes up empty =:(

Obviously, I need to define this better, provide a demnstration 
environment, but I thought I'd bring this up in case anyone had a clue 
for a quick fix. [That green bar is soooo addictive :)]

Though, my unit tests for the Commands don't utilize mocks. They just 
populate the Context directly and pass it up. Of course, there's the 
part where the Context is created from the request paramenters, but 
that's a separate test suite that isn't coupled to the Commands.

For end-to-end integration, Cannoo Webtest pulls it all together nicely. 
Need to run the container running for that one, but it doesn't involve 
loading Cactus or anything like that, so those run very quickly.


> Indeed, the only reason that Catalog exists is to allow chains to refer 
> to other chains in an organized way.  One could argue that even this is 
> out of scope; however, it's very useful to be able to write a Command 
> that uses complex processing logic to decide which other commands (or 
> chains, since you can't tell in the catalog what something is) should be 
> used to actually perform a task.

IMHO, the Catalog construct places a key role in decoupling the sender 
from receiver, as specified by the CoR pattern. Right now, I have a 
command-name coming up from the web tier. The presentation framework 
requesting the command has no idea how it will be handled. It just knows 
how to create a given Context for a given Command, according to a 
high-level API contract. All it really knows is the logical name and 
parameters required. The Catalog takes care of selecting the 
Command/Chain to process, in much the same way a framework like Struts 
takes care of selecting the Action class to execute.

If an implementation exposes the Catalog to the Command/Chains, then 
another usage is to allow Commands to call one another through the 
Catalog. As mentioned, this allows any number of clever strategies for 
creating "framework" chains that can be reused in different ways under 
different circumstances. This usage can also make the Catalogs more 
testable, since a test could substitute a "mock" Command, if such a 
thing were desired.

But, I would argue that these benefits are still secondary to the core 
need to cleanly decouple sender from the receiver.

-Ted.



-- 
Ted Husted,
   Junit in Action  - <http://www.manning.com/massol/>,
   Struts in Action - <http://husted.com/struts/book.html>,
   JSP Site Design  - <http://www.amazon.com/exec/obidos/ISBN=1861005512>.

"Get Ready, We're Moving Out!!" - <http://www.clark04.com>



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Jelly] is this the main Jelly list ?

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Tony Pelton wrote:

>hi,
>
>new guy here.
>
>is this the Jelly list in addition to obviously being the list for a bunch of 
>other stuff ?
>
>i just wasn't sure if i had actually subscribed to the correct list.
>
>tia,
>Tony
>
>  
>
This is the list where the developers of the various jakarta-commons 
packages hang out, and that includes Jelly.  You'll find a corresponding 
list (commons-user@jakarta.apache.org) for more user-oriented questions; 
again for all of the commons packages.

You'll find a common convention is to do what you did -- decorate your 
subject like with [Jelly], or whatever other package you're interested 
in talking about.  This helps readers filter out whether they are 
interested in that particular message or not.

Craig



Re: [Jelly] is this the main Jelly list ?

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Tony Pelton wrote:

>hi,
>
>new guy here.
>
>is this the Jelly list in addition to obviously being the list for a bunch of 
>other stuff ?
>
>i just wasn't sure if i had actually subscribed to the correct list.
>
>tia,
>Tony
>
>  
>
This is the list where the developers of the various jakarta-commons 
packages hang out, and that includes Jelly.  You'll find a corresponding 
list (commons-user@jakarta.apache.org) for more user-oriented questions; 
again for all of the commons packages.

You'll find a common convention is to do what you did -- decorate your 
subject like with [Jelly], or whatever other package you're interested 
in talking about.  This helps readers filter out whether they are 
interested in that particular message or not.

Craig



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Jelly] is this the main Jelly list ?

Posted by di...@multitask.com.au.
Yep,

this is it.
--
dIon Gillard, Multitask Consulting
Blog:      http://blogs.codehaus.org/people/dion/


Tony Pelton <ja...@dsrts.com> wrote on 27/09/2003 12:29:42 AM:

> hi,
> 
> new guy here.
> 
> is this the Jelly list in addition to obviously being the list for 
abunch of 
> other stuff ?
> 
> i just wasn't sure if i had actually subscribed to the correct list.
> 
> tia,
> Tony
> 
> -- 
> ===
> "They that can give up essential liberty
> to obtain a little temporary safety deserve
>  neither liberty nor safety."
>   -- Benjamin Franklin
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> 


Re: [Jelly] is this the main Jelly list ?

Posted by di...@multitask.com.au.
Yep,

this is it.
--
dIon Gillard, Multitask Consulting
Blog:      http://blogs.codehaus.org/people/dion/


Tony Pelton <ja...@dsrts.com> wrote on 27/09/2003 12:29:42 AM:

> hi,
> 
> new guy here.
> 
> is this the Jelly list in addition to obviously being the list for 
abunch of 
> other stuff ?
> 
> i just wasn't sure if i had actually subscribed to the correct list.
> 
> tia,
> Tony
> 
> -- 
> ===
> "They that can give up essential liberty
> to obtain a little temporary safety deserve
>  neither liberty nor safety."
>   -- Benjamin Franklin
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


[Jelly] is this the main Jelly list ?

Posted by Tony Pelton <ja...@dsrts.com>.
hi,

new guy here.

is this the Jelly list in addition to obviously being the list for a bunch of 
other stuff ?

i just wasn't sure if i had actually subscribed to the correct list.

tia,
Tony

-- 
===
"They that can give up essential liberty
to obtain a little temporary safety deserve
 neither liberty nor safety."
  -- Benjamin Franklin



[Jelly] is this the main Jelly list ?

Posted by Tony Pelton <ja...@dsrts.com>.
hi,

new guy here.

is this the Jelly list in addition to obviously being the list for a bunch of 
other stuff ?

i just wasn't sure if i had actually subscribed to the correct list.

tia,
Tony

-- 
===
"They that can give up essential liberty
to obtain a little temporary safety deserve
 neither liberty nor safety."
  -- Benjamin Franklin



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Ted Husted <hu...@apache.org>.
Sgarlata Matt wrote:
> Well my goal with this idea was to make applications less dependent on the
> environment in which they run.  The servlet environment can of course handle
> everything that this Registry can, but it is in the presentation tier.  I
> think the Registry for the business tier should reside in the business tier.
> What if I want to offer a command-line interface to my application for, say,
> unit testing with JUnit (which I can currently do in my app for my DAOs but
> not for my business tier).  If I use the servlet context as a registry then
> it is harder to write these tests.

Then the command-line program might want to use a Singleton. But that's 
up to the application. The key part is you can load the same Catalog 
into your command-line program or into a web application, without 
changing anything internal to the Chain and Command classes.

Right now, Chain is nicely scoped as a business layer framework that 
sits between the Controller and the Persistence Layer. This is a sweet 
spot, and I believe we shouldn't muddy it with trying to handle state.

Making "applications less dependent on the environment in which they 
run", would be the job of an application framework ("a semi-complete 
application"). All the presentation frameworks, including Struts, are 
working in this direction now, by moving towards a Context object that 
help to decouple components from the runtime environment. When they get 
there, Chain and its Context object, will be ready to hook up.


> Hehe, I am often guilty of this in my own work.  How do we get Chain out of
> the sandbox so we can start working on Agility? :)  Should I move over to
> Struts and work on the decomposable request processor that Craig started out
> instead?  I know one area Chain needs work is documentation, and I will be
> working on this in the coming weeks.

The two aren't codependent. But, again, frameworks are best created as 
abstractions of working applications. Without more working applications, 
it's too early to work on anything like a framework. I haven't even 
finished deploying it in one application yet. =:)

One thing that might be helpful is a ChainServlet, so people can plug 
Catalog into working web applications right away. I believe Craig, Greg, 
and I are all just using the Struts plugin right now, but that's only 
one place where it can be used.

Along the same lines, I suppose there could also be something like a 
generic ChainRegistry that was designed to load the Catalog and store it 
behind an interface as a Singleton. This might be something people would 
use in command-line or test programs, and so forth. But anything like 
this should also be strongly cast as optional or example component and 
not considered part of the core API. This is where we step over the line 
from "business layer framework" to "application framework", and I don't 
think that's a line we're ready to cross right now.

-Ted.




Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Ted Husted <hu...@apache.org>.
Sgarlata Matt wrote:
> Well my goal with this idea was to make applications less dependent on the
> environment in which they run.  The servlet environment can of course handle
> everything that this Registry can, but it is in the presentation tier.  I
> think the Registry for the business tier should reside in the business tier.
> What if I want to offer a command-line interface to my application for, say,
> unit testing with JUnit (which I can currently do in my app for my DAOs but
> not for my business tier).  If I use the servlet context as a registry then
> it is harder to write these tests.

Then the command-line program might want to use a Singleton. But that's 
up to the application. The key part is you can load the same Catalog 
into your command-line program or into a web application, without 
changing anything internal to the Chain and Command classes.

Right now, Chain is nicely scoped as a business layer framework that 
sits between the Controller and the Persistence Layer. This is a sweet 
spot, and I believe we shouldn't muddy it with trying to handle state.

Making "applications less dependent on the environment in which they 
run", would be the job of an application framework ("a semi-complete 
application"). All the presentation frameworks, including Struts, are 
working in this direction now, by moving towards a Context object that 
help to decouple components from the runtime environment. When they get 
there, Chain and its Context object, will be ready to hook up.


> Hehe, I am often guilty of this in my own work.  How do we get Chain out of
> the sandbox so we can start working on Agility? :)  Should I move over to
> Struts and work on the decomposable request processor that Craig started out
> instead?  I know one area Chain needs work is documentation, and I will be
> working on this in the coming weeks.

The two aren't codependent. But, again, frameworks are best created as 
abstractions of working applications. Without more working applications, 
it's too early to work on anything like a framework. I haven't even 
finished deploying it in one application yet. =:)

One thing that might be helpful is a ChainServlet, so people can plug 
Catalog into working web applications right away. I believe Craig, Greg, 
and I are all just using the Struts plugin right now, but that's only 
one place where it can be used.

Along the same lines, I suppose there could also be something like a 
generic ChainRegistry that was designed to load the Catalog and store it 
behind an interface as a Singleton. This might be something people would 
use in command-line or test programs, and so forth. But anything like 
this should also be strongly cast as optional or example component and 
not considered part of the core API. This is where we step over the line 
from "business layer framework" to "application framework", and I don't 
think that's a line we're ready to cross right now.

-Ted.




---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Sgarlata Matt <sg...@bah.com>.
----- Original Message ----- 
From: "Ted Husted" <hu...@apache.org>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
Sent: Friday, September 26, 2003 8:10 AM
Subject: Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain]
examples XML file available?)


> Sgarlata Matt wrote:
> > I understand this difficulty which is why I was thinking that if we make
it
> > an explicit part of the API that you are supposed to store things in
> > such-and-such place that we could be in good shape.  In the example I
gave,
> > I was trying to say that even if different apps used the same singleton,
> > they would all be isolated from each other by virtue of the fact that
the
> > API tells them that they need to store everything under their own unique
> > attribute name, like com.mycompany.myprogram or org.apache.struts.  This
is
> > like how Java can't guarantee two classes have the same name, but
hopefully
> > if people follow the guidelines they are supposed to in terms of naming
> > their packages then name collisions will be less frequent.
>
> IMHO, the API should leave state to the underlying platform. We can
> provide various examples of where you might store state for this
> platform and that platform. For the most part, if Commands need to refer
> to Commands, then the application can pass the Catalog up through the
> Context. The API defines a place to store things, the Context, another
> seems redundant.
>
> Whether the Context is backed by a Singleton, the Servlet Context, or
> something else, can be left to the application.

Well my goal with this idea was to make applications less dependent on the
environment in which they run.  The servlet environment can of course handle
everything that this Registry can, but it is in the presentation tier.  I
think the Registry for the business tier should reside in the business tier.
What if I want to offer a command-line interface to my application for, say,
unit testing with JUnit (which I can currently do in my app for my DAOs but
not for my business tier).  If I use the servlet context as a registry then
it is harder to write these tests.

> > Yeah, you're right.  I read WHITEBOARD.html and got very excited about
> > Agility, and really I think this type of registry idea might find a nice
> > home in Agility.  Who is working on this?  Is anything out there yet?
I'd
> > be very interested in contributing if so.
>
> Yes, something like Agility is a place were you might define concrete
> strategies for storing catalogs within an application. Right now, I'm
> still getting a feel for where Commons Chain is going to end. Frameworks
> like this are best built from working examples, so we'd need to
> implement Chain in a few applications before we could abstract common
> functionality into a framework like Agility. Otherwise, the tail starts
> wagging the dog =:)

Hehe, I am often guilty of this in my own work.  How do we get Chain out of
the sandbox so we can start working on Agility? :)  Should I move over to
Struts and work on the decomposable request processor that Craig started out
instead?  I know one area Chain needs work is documentation, and I will be
working on this in the coming weeks.

> -Ted.

Matt


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Sgarlata Matt <sg...@bah.com>.
----- Original Message ----- 
From: "Ted Husted" <hu...@apache.org>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
Sent: Friday, September 26, 2003 8:10 AM
Subject: Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain]
examples XML file available?)


> Sgarlata Matt wrote:
> > I understand this difficulty which is why I was thinking that if we make
it
> > an explicit part of the API that you are supposed to store things in
> > such-and-such place that we could be in good shape.  In the example I
gave,
> > I was trying to say that even if different apps used the same singleton,
> > they would all be isolated from each other by virtue of the fact that
the
> > API tells them that they need to store everything under their own unique
> > attribute name, like com.mycompany.myprogram or org.apache.struts.  This
is
> > like how Java can't guarantee two classes have the same name, but
hopefully
> > if people follow the guidelines they are supposed to in terms of naming
> > their packages then name collisions will be less frequent.
>
> IMHO, the API should leave state to the underlying platform. We can
> provide various examples of where you might store state for this
> platform and that platform. For the most part, if Commands need to refer
> to Commands, then the application can pass the Catalog up through the
> Context. The API defines a place to store things, the Context, another
> seems redundant.
>
> Whether the Context is backed by a Singleton, the Servlet Context, or
> something else, can be left to the application.

Well my goal with this idea was to make applications less dependent on the
environment in which they run.  The servlet environment can of course handle
everything that this Registry can, but it is in the presentation tier.  I
think the Registry for the business tier should reside in the business tier.
What if I want to offer a command-line interface to my application for, say,
unit testing with JUnit (which I can currently do in my app for my DAOs but
not for my business tier).  If I use the servlet context as a registry then
it is harder to write these tests.

> > Yeah, you're right.  I read WHITEBOARD.html and got very excited about
> > Agility, and really I think this type of registry idea might find a nice
> > home in Agility.  Who is working on this?  Is anything out there yet?
I'd
> > be very interested in contributing if so.
>
> Yes, something like Agility is a place were you might define concrete
> strategies for storing catalogs within an application. Right now, I'm
> still getting a feel for where Commons Chain is going to end. Frameworks
> like this are best built from working examples, so we'd need to
> implement Chain in a few applications before we could abstract common
> functionality into a framework like Agility. Otherwise, the tail starts
> wagging the dog =:)

Hehe, I am often guilty of this in my own work.  How do we get Chain out of
the sandbox so we can start working on Agility? :)  Should I move over to
Struts and work on the decomposable request processor that Craig started out
instead?  I know one area Chain needs work is documentation, and I will be
working on this in the coming weeks.

> -Ted.

Matt


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Ted Husted <hu...@apache.org>.
Sgarlata Matt wrote:
> (I'm less annoying in this email I promise...)

Not to worry. If we didn't want people asking about our new clothes, we 
wouldn't wear our code on our sleeve (so to speak).


> I understand this difficulty which is why I was thinking that if we make it
> an explicit part of the API that you are supposed to store things in
> such-and-such place that we could be in good shape.  In the example I gave,
> I was trying to say that even if different apps used the same singleton,
> they would all be isolated from each other by virtue of the fact that the
> API tells them that they need to store everything under their own unique
> attribute name, like com.mycompany.myprogram or org.apache.struts.  This is
> like how Java can't guarantee two classes have the same name, but hopefully
> if people follow the guidelines they are supposed to in terms of naming
> their packages then name collisions will be less frequent.

IMHO, the API should leave state to the underlying platform. We can 
provide various examples of where you might store state for this 
platform and that platform. For the most part, if Commands need to refer 
to Commands, then the application can pass the Catalog up through the 
Context. The API defines a place to store things, the Context, another 
seems redundant.

Whether the Context is backed by a Singleton, the Servlet Context, or 
something else, can be left to the application.


> Yeah, you're right.  I read WHITEBOARD.html and got very excited about
> Agility, and really I think this type of registry idea might find a nice
> home in Agility.  Who is working on this?  Is anything out there yet?  I'd
> be very interested in contributing if so.

Yes, something like Agility is a place were you might define concrete 
strategies for storing catalogs within an application. Right now, I'm 
still getting a feel for where Commons Chain is going to end. Frameworks 
like this are best built from working examples, so we'd need to 
implement Chain in a few applications before we could abstract common 
functionality into a framework like Agility. Otherwise, the tail starts 
wagging the dog =:)

In the meantime, it isn't hard to hook Chain up to existing frameworks. 
Most do not provide direct support for the business layer, which is 
where Chain plugs in. Regardless of whether something like Agility 
exists, people are going to want to use Chain with existing frameworks, 
like JPublish, Maverick, Struts, Tapestry, Turbine, and WebWork. 
(Though, there might be some overlap with XWork in the case of WebWork, 
... but choice is good.)


>>Class libraries should be narrowly focused on as few fundamental ideas
>>as possible, and then do them there.  They should not impose onerous
>>restrictions on applications that want to use them (which is why the
>>config package that uses Digester is optional -- you can compose chains
>>any way you like).  The fundamental APIs we've defined so far (Command,
>>Chain, Context, and Filter) are the minimum needed to implement the
>>desired design patterns.  Catalog is on the edge, but useful for
>>combining chains/commands in a controlled manner.  Registry is more
>>about how catalogs would be accessed, rather than what they do.  Indeed,
>>you don't even need such a thing in many environments; for example, a
>>web app's ServletContext attributes do exactly what your registry does
>>for that particular use case.
> 
> 
> Yeah, this is a good approach that I don't have a lot of experience with.
> I'm using BeanUtils and Digester freely without worrying about having
> certain portions of my API tied to Struts, so thank you! :)

Yes, this is the key. Chain is not about Struts, or about Servlets, it's 
about a coherent approach to managing the business end of an application.

-Ted.



Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Ted Husted <hu...@apache.org>.
Sgarlata Matt wrote:
> (I'm less annoying in this email I promise...)

Not to worry. If we didn't want people asking about our new clothes, we 
wouldn't wear our code on our sleeve (so to speak).


> I understand this difficulty which is why I was thinking that if we make it
> an explicit part of the API that you are supposed to store things in
> such-and-such place that we could be in good shape.  In the example I gave,
> I was trying to say that even if different apps used the same singleton,
> they would all be isolated from each other by virtue of the fact that the
> API tells them that they need to store everything under their own unique
> attribute name, like com.mycompany.myprogram or org.apache.struts.  This is
> like how Java can't guarantee two classes have the same name, but hopefully
> if people follow the guidelines they are supposed to in terms of naming
> their packages then name collisions will be less frequent.

IMHO, the API should leave state to the underlying platform. We can 
provide various examples of where you might store state for this 
platform and that platform. For the most part, if Commands need to refer 
to Commands, then the application can pass the Catalog up through the 
Context. The API defines a place to store things, the Context, another 
seems redundant.

Whether the Context is backed by a Singleton, the Servlet Context, or 
something else, can be left to the application.


> Yeah, you're right.  I read WHITEBOARD.html and got very excited about
> Agility, and really I think this type of registry idea might find a nice
> home in Agility.  Who is working on this?  Is anything out there yet?  I'd
> be very interested in contributing if so.

Yes, something like Agility is a place were you might define concrete 
strategies for storing catalogs within an application. Right now, I'm 
still getting a feel for where Commons Chain is going to end. Frameworks 
like this are best built from working examples, so we'd need to 
implement Chain in a few applications before we could abstract common 
functionality into a framework like Agility. Otherwise, the tail starts 
wagging the dog =:)

In the meantime, it isn't hard to hook Chain up to existing frameworks. 
Most do not provide direct support for the business layer, which is 
where Chain plugs in. Regardless of whether something like Agility 
exists, people are going to want to use Chain with existing frameworks, 
like JPublish, Maverick, Struts, Tapestry, Turbine, and WebWork. 
(Though, there might be some overlap with XWork in the case of WebWork, 
... but choice is good.)


>>Class libraries should be narrowly focused on as few fundamental ideas
>>as possible, and then do them there.  They should not impose onerous
>>restrictions on applications that want to use them (which is why the
>>config package that uses Digester is optional -- you can compose chains
>>any way you like).  The fundamental APIs we've defined so far (Command,
>>Chain, Context, and Filter) are the minimum needed to implement the
>>desired design patterns.  Catalog is on the edge, but useful for
>>combining chains/commands in a controlled manner.  Registry is more
>>about how catalogs would be accessed, rather than what they do.  Indeed,
>>you don't even need such a thing in many environments; for example, a
>>web app's ServletContext attributes do exactly what your registry does
>>for that particular use case.
> 
> 
> Yeah, this is a good approach that I don't have a lot of experience with.
> I'm using BeanUtils and Digester freely without worrying about having
> certain portions of my API tied to Struts, so thank you! :)

Yes, this is the key. Chain is not about Struts, or about Servlets, it's 
about a coherent approach to managing the business end of an application.

-Ted.



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Sgarlata Matt <sg...@bah.com>.
(I'm less annoying in this email I promise...)
----- Original Message ----- 
From: "Craig R. McClanahan" <cr...@apache.org>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
Sent: Wednesday, September 24, 2003 12:59 PM
Subject: Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain]
examples XML file available?)


> Sgarlata Matt wrote:
>
> >The conversation threads are getting kind of crazy, so I'm going to skip
> >inline quotes for parts of this.
> >
> >Craig, now I do see your point about using the ConfigRuleSet to digest a
> >portion of
> >an arbitrary XML file.  That is very cool, and now I understand why the
> >names of the XML elements are configurable.  I always understood the
value
> >of letting attributes to the <command> element (and other elements).
This
> >is a much slicker approach than creating nested <set-property> elements.
> >Still, I think it could be useful to have a DTD for the *default*
behavior
> >of the ConfigRuleSet.  I think in general users will start off using the
> >default behavior, and then may at a later date decide to fold their
commands
> >into some other file, so a DTD will be nice to get people started with
the
> >Chain package.  I agree with most your points about the constraints I
placed
> >in the DTD being inappropriate, and will explicitly address each if we
ever
> >decide to make a DTD.
> >
>
> Unfortunately, none of the Command implementations I am interested in
> building into my Chains would be usable in a document parsed against
> such a DTD, for the technical reasons we discussed earlier.  Therefore,
> I'm not interested in any sort of DTD that someone would actually try to
> use in a validating parser.  If what you want is a more high level view
> of the typical structure of such a file (i.e. documentation), that's a
> different matter, and should be addressed with diagrams, examples, and
> how-to guides; minimally, to the level of detail you see in the "Package
> Description" docs for things like Digester and BeanUtils.

OK, maybe this weekend I'll submit a new package.html for review.  I give up
on the DTD ;)

> >How about making a Register class which is an implementation of Context
> >which stores only references to Catalogs?  We could make the registry
itself
> >a singleton, and write in design notes that since the registry is shared
> >between apps, each app should store its Catalog(s) in an
> >application-specific attribute like below:
> >
> >Registry
> >|
> >|---org.apache.struts
> >|---|---actions.RequestProcessor
> >|---|---somethingElse
> >|---com.bah.krm
> >|---org.apache.commons.something
> >
> >That's not explained incredibly well, but if each application component
> >reserves its own spot in the registry, we should be able to make the
> >registry a singleton everyone can share.  This keeps us from tying
ourselves
> >to the Servlet API, as was mentioned in the ChainServlet discussion
thread.
> >
> >
>
> It should be obvious that creating such a class is trivially simple, but
> you should first study how class loaders work in servlet containers, and
> then think about what happens if commons-chain were placed in a parent
> class loader (meaning that any singletons you try to create with static
> variables are shared across *all* webapps, not just the current one).
> The docs for Tomcat's class loader are specific to Tomcat, but typical
> of the architecture that most web containers offer:
>
>   http://jakarta.apache.org/tomcat/tomcat-4.1-doc/class-loader-howto.html

I understand this difficulty which is why I was thinking that if we make it
an explicit part of the API that you are supposed to store things in
such-and-such place that we could be in good shape.  In the example I gave,
I was trying to say that even if different apps used the same singleton,
they would all be isolated from each other by virtue of the fact that the
API tells them that they need to store everything under their own unique
attribute name, like com.mycompany.myprogram or org.apache.struts.  This is
like how Java can't guarantee two classes have the same name, but hopefully
if people follow the guidelines they are supposed to in terms of naming
their packages then name collisions will be less frequent.

> The other reason I didn't go here is that we're actually at the edge of
> the patterns that commons-chain was created to implement.  How it gets
> embedded into a particular application should be up to that application.
>
> Indeed, the only reason that Catalog exists is to allow chains to refer
> to other chains in an organized way.  One could argue that even this is
> out of scope; however, it's very useful to be able to write a Command
> that uses complex processing logic to decide which other commands (or
> chains, since you can't tell in the catalog what something is) should be
> used to actually perform a task.

Yeah, you're right.  I read WHITEBOARD.html and got very excited about
Agility, and really I think this type of registry idea might find a nice
home in Agility.  Who is working on this?  Is anything out there yet?  I'd
be very interested in contributing if so.

> Class libraries should be narrowly focused on as few fundamental ideas
> as possible, and then do them there.  They should not impose onerous
> restrictions on applications that want to use them (which is why the
> config package that uses Digester is optional -- you can compose chains
> any way you like).  The fundamental APIs we've defined so far (Command,
> Chain, Context, and Filter) are the minimum needed to implement the
> desired design patterns.  Catalog is on the edge, but useful for
> combining chains/commands in a controlled manner.  Registry is more
> about how catalogs would be accessed, rather than what they do.  Indeed,
> you don't even need such a thing in many environments; for example, a
> web app's ServletContext attributes do exactly what your registry does
> for that particular use case.

Yeah, this is a good approach that I don't have a lot of experience with.
I'm using BeanUtils and Digester freely without worrying about having
certain portions of my API tied to Struts, so thank you! :)

> >
> Craig
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Sgarlata Matt <sg...@bah.com>.
(I'm less annoying in this email I promise...)
----- Original Message ----- 
From: "Craig R. McClanahan" <cr...@apache.org>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
Sent: Wednesday, September 24, 2003 12:59 PM
Subject: Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain]
examples XML file available?)


> Sgarlata Matt wrote:
>
> >The conversation threads are getting kind of crazy, so I'm going to skip
> >inline quotes for parts of this.
> >
> >Craig, now I do see your point about using the ConfigRuleSet to digest a
> >portion of
> >an arbitrary XML file.  That is very cool, and now I understand why the
> >names of the XML elements are configurable.  I always understood the
value
> >of letting attributes to the <command> element (and other elements).
This
> >is a much slicker approach than creating nested <set-property> elements.
> >Still, I think it could be useful to have a DTD for the *default*
behavior
> >of the ConfigRuleSet.  I think in general users will start off using the
> >default behavior, and then may at a later date decide to fold their
commands
> >into some other file, so a DTD will be nice to get people started with
the
> >Chain package.  I agree with most your points about the constraints I
placed
> >in the DTD being inappropriate, and will explicitly address each if we
ever
> >decide to make a DTD.
> >
>
> Unfortunately, none of the Command implementations I am interested in
> building into my Chains would be usable in a document parsed against
> such a DTD, for the technical reasons we discussed earlier.  Therefore,
> I'm not interested in any sort of DTD that someone would actually try to
> use in a validating parser.  If what you want is a more high level view
> of the typical structure of such a file (i.e. documentation), that's a
> different matter, and should be addressed with diagrams, examples, and
> how-to guides; minimally, to the level of detail you see in the "Package
> Description" docs for things like Digester and BeanUtils.

OK, maybe this weekend I'll submit a new package.html for review.  I give up
on the DTD ;)

> >How about making a Register class which is an implementation of Context
> >which stores only references to Catalogs?  We could make the registry
itself
> >a singleton, and write in design notes that since the registry is shared
> >between apps, each app should store its Catalog(s) in an
> >application-specific attribute like below:
> >
> >Registry
> >|
> >|---org.apache.struts
> >|---|---actions.RequestProcessor
> >|---|---somethingElse
> >|---com.bah.krm
> >|---org.apache.commons.something
> >
> >That's not explained incredibly well, but if each application component
> >reserves its own spot in the registry, we should be able to make the
> >registry a singleton everyone can share.  This keeps us from tying
ourselves
> >to the Servlet API, as was mentioned in the ChainServlet discussion
thread.
> >
> >
>
> It should be obvious that creating such a class is trivially simple, but
> you should first study how class loaders work in servlet containers, and
> then think about what happens if commons-chain were placed in a parent
> class loader (meaning that any singletons you try to create with static
> variables are shared across *all* webapps, not just the current one).
> The docs for Tomcat's class loader are specific to Tomcat, but typical
> of the architecture that most web containers offer:
>
>   http://jakarta.apache.org/tomcat/tomcat-4.1-doc/class-loader-howto.html

I understand this difficulty which is why I was thinking that if we make it
an explicit part of the API that you are supposed to store things in
such-and-such place that we could be in good shape.  In the example I gave,
I was trying to say that even if different apps used the same singleton,
they would all be isolated from each other by virtue of the fact that the
API tells them that they need to store everything under their own unique
attribute name, like com.mycompany.myprogram or org.apache.struts.  This is
like how Java can't guarantee two classes have the same name, but hopefully
if people follow the guidelines they are supposed to in terms of naming
their packages then name collisions will be less frequent.

> The other reason I didn't go here is that we're actually at the edge of
> the patterns that commons-chain was created to implement.  How it gets
> embedded into a particular application should be up to that application.
>
> Indeed, the only reason that Catalog exists is to allow chains to refer
> to other chains in an organized way.  One could argue that even this is
> out of scope; however, it's very useful to be able to write a Command
> that uses complex processing logic to decide which other commands (or
> chains, since you can't tell in the catalog what something is) should be
> used to actually perform a task.

Yeah, you're right.  I read WHITEBOARD.html and got very excited about
Agility, and really I think this type of registry idea might find a nice
home in Agility.  Who is working on this?  Is anything out there yet?  I'd
be very interested in contributing if so.

> Class libraries should be narrowly focused on as few fundamental ideas
> as possible, and then do them there.  They should not impose onerous
> restrictions on applications that want to use them (which is why the
> config package that uses Digester is optional -- you can compose chains
> any way you like).  The fundamental APIs we've defined so far (Command,
> Chain, Context, and Filter) are the minimum needed to implement the
> desired design patterns.  Catalog is on the edge, but useful for
> combining chains/commands in a controlled manner.  Registry is more
> about how catalogs would be accessed, rather than what they do.  Indeed,
> you don't even need such a thing in many environments; for example, a
> web app's ServletContext attributes do exactly what your registry does
> for that particular use case.

Yeah, this is a good approach that I don't have a lot of experience with.
I'm using BeanUtils and Digester freely without worrying about having
certain portions of my API tied to Struts, so thank you! :)

> >
> Craig
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Sgarlata Matt wrote:

>The conversation threads are getting kind of crazy, so I'm going to skip
>inline quotes for parts of this.
>
>Craig, now I do see your point about using the ConfigRuleSet to digest a
>portion of
>an arbitrary XML file.  That is very cool, and now I understand why the
>names of the XML elements are configurable.  I always understood the value
>of letting attributes to the <command> element (and other elements).  This
>is a much slicker approach than creating nested <set-property> elements.
>Still, I think it could be useful to have a DTD for the *default* behavior
>of the ConfigRuleSet.  I think in general users will start off using the
>default behavior, and then may at a later date decide to fold their commands
>into some other file, so a DTD will be nice to get people started with the
>Chain package.  I agree with most your points about the constraints I placed
>in the DTD being inappropriate, and will explicitly address each if we ever
>decide to make a DTD.
>

Unfortunately, none of the Command implementations I am interested in 
building into my Chains would be usable in a document parsed against 
such a DTD, for the technical reasons we discussed earlier.  Therefore, 
I'm not interested in any sort of DTD that someone would actually try to 
use in a validating parser.  If what you want is a more high level view 
of the typical structure of such a file (i.e. documentation), that's a 
different matter, and should be addressed with diagrams, examples, and 
how-to guides; minimally, to the level of detail you see in the "Package 
Description" docs for things like Digester and BeanUtils.

>As I've thought more about the package, I don't understand why some design
>decisions were made.
>

Ted points out the GoF patterns this package was created to realize.  I 
discuss below some of my motivations, upon observing limitations in the 
extensibility of Struts based on the design decisions we made.

>  First let me say that I think of Chains as being an OO
>way to simulate procedural logic.
>

It is actually intended to *compose* procedural logic, not to *simulate* it.

In an O-O world, you often compose complex things out of simple things 
by encapsulating the result in a "black box" method that can be called 
by your user.  Ideally, the user doesn't have to know much about what 
happens inside the box -- they just use it.  But, sometimes, the default 
behavior is not enough and you need to specialize.  A typical approach 
to specializing in O-O languages is to subclass, and then override the 
appropriate methods.

Now, it's real easy to add some logic at the beginning, then call 
super.foo(), and perhaps add some logic at the end.  But what happens if 
you need to add a bunch of stuff in the middle?  Or replace one of the 
method calls performed inside the black box with one that does something 
slightly different.  You're often stuck with having to cut-n-paste the 
logic of the method you're specializing, then change the calls you want, 
and hope you notice whenever the class you copied has changed so that 
you can replicate those changes in your version.  Yuck.

One approach to making this work better was tried in Struts 1.1, where 
the RequestProcessor has a single public process() method to process 
each request.  In turn, the process() method called a bunch of protected 
processFoo() and processBar() methods that performed a single step.  
People who wanted to specialize only that step needed to subclass 
RequestProcessor and then just override that single step.  Because the 
steps were fairly fine-grained, this was a big improvement, and lots of 
innovative things were done to extend Struts.  However, there's two big 
areas of difficulty left:

* What happens when someone wants to insert new processing phases,
  remove old ones, or reorder the existing ones?  They have to override
  the relatively complex process() method, and hope they get all the
  details exactly right in their cut-n-paste.

* What happens when you, as an application author, want to take advantage
  of customized extensions provided by more than one library, where both
  of them have extended RequestProcessor?  Java does not support multiple
  inheritance, so you're stuck manually weaving the RequestProcessor changes
  together.  Again, yuck.

Far better would be to divide the procedural flow into small steps that 
are externally configurable.  And, let each step have its own 
arbitrarily complex internal structure (by virtue of the fact that it 
can be a Command or a Chain of its own).  Oh, by the way, the procedural 
steps become small enough and narrowly focused enough to write high 
quality unit tests for.  And, because commands interact with each other 
*solely* through a Context, you can easily create mock objects (like a 
ServletContext or an HttpSession, in a chain destined for a web 
applicaton) that let you thoroughly test things in a standalone 
environment (in case it's not obvious, I'm a *huge* fan of JUnit :-).

In an environment like this, people who extend the basic Struts request 
processing pipeline will do so by providing implementations of the 
fine-grained commands and chains that make up their extension, and an 
example of how to update the standard processing chain to include their 
functionality.  For the 80% case, we should even be able to do this 
without actually modifying the standard chain (by having the standard 
chain include a step between each actual processing step that says "if 
there is a command registered under name XYZ, process it here"; so the 
act of registering your customized chain under a particular name 
automatically customizes the standard chain).

For a beginning glimmer of this, see how the struts-chain example code 
(in the Struts sources referenced earlier) uses the generic 
LookupCommand to conditionally execute a chain named 
"servlet-complete-preprocess" if and only if it has been registered.  
Because the "optional" flag is set to true, it doesn't complain if there 
is no such chain -- it just proceeds on.

>  Many of my comments will basically be
>concerning why some of the standard control flow abilities (if/then
>statements, loops, exception handling, etc) in Java aren't more easily
>done/simulated using the Chain package.
>

For an example of "been there, done that" on trying to script control 
flows in XML, see the commons-workflow package that is also in the 
Sandbox.  For a far more complex and successful approach at scripting in 
XML, see commons-jelly (in the main jakarta-commons repository).

Fundamentally, if you feel a big need for if/then and loops, I would 
suggest you haven't decomposed your procedural logic into small enough 
pieces yet.  That sort of control flow does not itself need to be 
expressed in chains -- it can be done in the language in which you embed 
commons-chain (typically Java).

Exception handling is a slightly different story -- it was one of the 
motivations for the Filter API (see below).

>  So, here I go with questions:
>1) How come Chains have a static structure?
>

Chains are static so that you can reuse them in an application without 
any fear that they are mutating underneath you.  In addition, the static 
structure allows optimized processing in a multithread environment like 
a web application.  Nothing stops you, of course, from (inside a 
Command) building up your own custom Chain, then executing it, then 
throwing it away.

>  Related to this, how come
>Command.execute returns boolean instead of returning Command?
>

Commands should not know whether or not they have been composed into a 
chain.  Returning a Command would require that type of knowledge.  
Instead, a Command only says whether or not the computation has been 
finished.

Other approaches to this kind of thing have also been tried -- see, for 
example, how javax.servlet.Filter works in Servlet 2.3.  This adds the 
complexity of a FilterContext that has to be passed along (where the 
knowledge of the chain's constituent Commands is maintained), plus it 
creates a horrendously deep call stack.

I opted for the simplest possible APIs to make commons-chain very easy 
to understand and use.

>  If it
>returned Command this would basically eliminate the need for a Chain
>interface altogether.
>

Your approach only works for the top-level chain -- the current APIs 
allow chains to use arbitrarily complex subchains.  Essentially, you'd 
force anyone who wants subchains to re-invent what Chain already does.

>  Chain would become a concrete implementation of
>Command that repeatedly executed Commands until the last command executed
>returned null (which would be the new value to indicate the end of a chain).
>Static chains (such as those configured using an XML file) would easily be
>supported by another concrete implementation of Command which executed a
>series of commands in order, completely ignoring their return values.
>

You can already do exactly this kind of thing with the current API, 
without imposing on yourself the restrictions described above.  Your 
proposed changes would remove functionality and add complexity.

>2) How come Filters have a postprocess method but no catchexception method?
>

The postprocess method does both things, so you don't need a separate 
method.

>The postprocess block can deal with exceptions, but it seems to me like it
>would be more natural for exceptions to be dealt with in a catchexception
>block and for postprocess to be strictly for freeing resources that the
>Command acquired when its execute method was called.
>

My experience has been that the catch exception processing normally has 
to free the resources anyway, so it would end up either calling the 
postprocess method or duplicating the logic.  Either of those is tedious 
and error prone.  Far better just to have a single cleanup method no 
matter what happened.

>
>Ted Husted wrote:
>  
>
>>Of course, another way to go would be to make the Catalog a singleton,
>>or available through some registry, but I'm thinking that going through
>>the Context may be the cleanest approach, since the Context is
>>essentially a Registry too.
>>    
>>
>
>How about making a Register class which is an implementation of Context
>which stores only references to Catalogs?  We could make the registry itself
>a singleton, and write in design notes that since the registry is shared
>between apps, each app should store its Catalog(s) in an
>application-specific attribute like below:
>
>Registry
>|
>|---org.apache.struts
>|---|---actions.RequestProcessor
>|---|---somethingElse
>|---com.bah.krm
>|---org.apache.commons.something
>
>That's not explained incredibly well, but if each application component
>reserves its own spot in the registry, we should be able to make the
>registry a singleton everyone can share.  This keeps us from tying ourselves
>to the Servlet API, as was mentioned in the ChainServlet discussion thread.
>  
>

It should be obvious that creating such a class is trivially simple, but 
you should first study how class loaders work in servlet containers, and 
then think about what happens if commons-chain were placed in a parent 
class loader (meaning that any singletons you try to create with static 
variables are shared across *all* webapps, not just the current one).  
The docs for Tomcat's class loader are specific to Tomcat, but typical 
of the architecture that most web containers offer:

  http://jakarta.apache.org/tomcat/tomcat-4.1-doc/class-loader-howto.html

The other reason I didn't go here is that we're actually at the edge of 
the patterns that commons-chain was created to implement.  How it gets 
embedded into a particular application should be up to that application.

Indeed, the only reason that Catalog exists is to allow chains to refer 
to other chains in an organized way.  One could argue that even this is 
out of scope; however, it's very useful to be able to write a Command 
that uses complex processing logic to decide which other commands (or 
chains, since you can't tell in the catalog what something is) should be 
used to actually perform a task.

Class libraries should be narrowly focused on as few fundamental ideas 
as possible, and then do them there.  They should not impose onerous 
restrictions on applications that want to use them (which is why the 
config package that uses Digester is optional -- you can compose chains 
any way you like).  The fundamental APIs we've defined so far (Command, 
Chain, Context, and Filter) are the minimum needed to implement the 
desired design patterns.  Catalog is on the edge, but useful for 
combining chains/commands in a controlled manner.  Registry is more 
about how catalogs would be accessed, rather than what they do.  Indeed, 
you don't even need such a thing in many environments; for example, a 
web app's ServletContext attributes do exactly what your registry does 
for that particular use case.

>Matt
>
Craig



Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Ted Husted <hu...@apache.org>.
Sgarlata Matt wrote:
> How about making a Register class which is an implementation of Context
> which stores only references to Catalogs?  We could make the registry itself
> a singleton, and write in design notes that since the registry is shared
> between apps, each app should store its Catalog(s) in an
> application-specific attribute like below:
> 
> Registry
> |
> |---org.apache.struts
> |---|---actions.RequestProcessor
> |---|---somethingElse
> |---com.bah.krm
> |---org.apache.commons.something
> 
> That's not explained incredibly well, but if each application component
> reserves its own spot in the registry, we should be able to make the
> registry a singleton everyone can share.  This keeps us from tying ourselves
> to the Servlet API, as was mentioned in the ChainServlet discussion thread.

I was thinking that when I have a case of a Command needing to access 
another Command/Chain, I'd try adding a Catalog attribute to the 
Context. But, it might be too early to define another Registry class 
(since the Context is also a Registry), especially without a use-case to 
test it against. The big step now, I think, is migrating some 
applications to Chain so we can see what's needed in practice. I've got 
both a web and non-web on the hook for this now.

-Ted.



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Sgarlata Matt wrote:

>The conversation threads are getting kind of crazy, so I'm going to skip
>inline quotes for parts of this.
>
>Craig, now I do see your point about using the ConfigRuleSet to digest a
>portion of
>an arbitrary XML file.  That is very cool, and now I understand why the
>names of the XML elements are configurable.  I always understood the value
>of letting attributes to the <command> element (and other elements).  This
>is a much slicker approach than creating nested <set-property> elements.
>Still, I think it could be useful to have a DTD for the *default* behavior
>of the ConfigRuleSet.  I think in general users will start off using the
>default behavior, and then may at a later date decide to fold their commands
>into some other file, so a DTD will be nice to get people started with the
>Chain package.  I agree with most your points about the constraints I placed
>in the DTD being inappropriate, and will explicitly address each if we ever
>decide to make a DTD.
>

Unfortunately, none of the Command implementations I am interested in 
building into my Chains would be usable in a document parsed against 
such a DTD, for the technical reasons we discussed earlier.  Therefore, 
I'm not interested in any sort of DTD that someone would actually try to 
use in a validating parser.  If what you want is a more high level view 
of the typical structure of such a file (i.e. documentation), that's a 
different matter, and should be addressed with diagrams, examples, and 
how-to guides; minimally, to the level of detail you see in the "Package 
Description" docs for things like Digester and BeanUtils.

>As I've thought more about the package, I don't understand why some design
>decisions were made.
>

Ted points out the GoF patterns this package was created to realize.  I 
discuss below some of my motivations, upon observing limitations in the 
extensibility of Struts based on the design decisions we made.

>  First let me say that I think of Chains as being an OO
>way to simulate procedural logic.
>

It is actually intended to *compose* procedural logic, not to *simulate* it.

In an O-O world, you often compose complex things out of simple things 
by encapsulating the result in a "black box" method that can be called 
by your user.  Ideally, the user doesn't have to know much about what 
happens inside the box -- they just use it.  But, sometimes, the default 
behavior is not enough and you need to specialize.  A typical approach 
to specializing in O-O languages is to subclass, and then override the 
appropriate methods.

Now, it's real easy to add some logic at the beginning, then call 
super.foo(), and perhaps add some logic at the end.  But what happens if 
you need to add a bunch of stuff in the middle?  Or replace one of the 
method calls performed inside the black box with one that does something 
slightly different.  You're often stuck with having to cut-n-paste the 
logic of the method you're specializing, then change the calls you want, 
and hope you notice whenever the class you copied has changed so that 
you can replicate those changes in your version.  Yuck.

One approach to making this work better was tried in Struts 1.1, where 
the RequestProcessor has a single public process() method to process 
each request.  In turn, the process() method called a bunch of protected 
processFoo() and processBar() methods that performed a single step.  
People who wanted to specialize only that step needed to subclass 
RequestProcessor and then just override that single step.  Because the 
steps were fairly fine-grained, this was a big improvement, and lots of 
innovative things were done to extend Struts.  However, there's two big 
areas of difficulty left:

* What happens when someone wants to insert new processing phases,
  remove old ones, or reorder the existing ones?  They have to override
  the relatively complex process() method, and hope they get all the
  details exactly right in their cut-n-paste.

* What happens when you, as an application author, want to take advantage
  of customized extensions provided by more than one library, where both
  of them have extended RequestProcessor?  Java does not support multiple
  inheritance, so you're stuck manually weaving the RequestProcessor changes
  together.  Again, yuck.

Far better would be to divide the procedural flow into small steps that 
are externally configurable.  And, let each step have its own 
arbitrarily complex internal structure (by virtue of the fact that it 
can be a Command or a Chain of its own).  Oh, by the way, the procedural 
steps become small enough and narrowly focused enough to write high 
quality unit tests for.  And, because commands interact with each other 
*solely* through a Context, you can easily create mock objects (like a 
ServletContext or an HttpSession, in a chain destined for a web 
applicaton) that let you thoroughly test things in a standalone 
environment (in case it's not obvious, I'm a *huge* fan of JUnit :-).

In an environment like this, people who extend the basic Struts request 
processing pipeline will do so by providing implementations of the 
fine-grained commands and chains that make up their extension, and an 
example of how to update the standard processing chain to include their 
functionality.  For the 80% case, we should even be able to do this 
without actually modifying the standard chain (by having the standard 
chain include a step between each actual processing step that says "if 
there is a command registered under name XYZ, process it here"; so the 
act of registering your customized chain under a particular name 
automatically customizes the standard chain).

For a beginning glimmer of this, see how the struts-chain example code 
(in the Struts sources referenced earlier) uses the generic 
LookupCommand to conditionally execute a chain named 
"servlet-complete-preprocess" if and only if it has been registered.  
Because the "optional" flag is set to true, it doesn't complain if there 
is no such chain -- it just proceeds on.

>  Many of my comments will basically be
>concerning why some of the standard control flow abilities (if/then
>statements, loops, exception handling, etc) in Java aren't more easily
>done/simulated using the Chain package.
>

For an example of "been there, done that" on trying to script control 
flows in XML, see the commons-workflow package that is also in the 
Sandbox.  For a far more complex and successful approach at scripting in 
XML, see commons-jelly (in the main jakarta-commons repository).

Fundamentally, if you feel a big need for if/then and loops, I would 
suggest you haven't decomposed your procedural logic into small enough 
pieces yet.  That sort of control flow does not itself need to be 
expressed in chains -- it can be done in the language in which you embed 
commons-chain (typically Java).

Exception handling is a slightly different story -- it was one of the 
motivations for the Filter API (see below).

>  So, here I go with questions:
>1) How come Chains have a static structure?
>

Chains are static so that you can reuse them in an application without 
any fear that they are mutating underneath you.  In addition, the static 
structure allows optimized processing in a multithread environment like 
a web application.  Nothing stops you, of course, from (inside a 
Command) building up your own custom Chain, then executing it, then 
throwing it away.

>  Related to this, how come
>Command.execute returns boolean instead of returning Command?
>

Commands should not know whether or not they have been composed into a 
chain.  Returning a Command would require that type of knowledge.  
Instead, a Command only says whether or not the computation has been 
finished.

Other approaches to this kind of thing have also been tried -- see, for 
example, how javax.servlet.Filter works in Servlet 2.3.  This adds the 
complexity of a FilterContext that has to be passed along (where the 
knowledge of the chain's constituent Commands is maintained), plus it 
creates a horrendously deep call stack.

I opted for the simplest possible APIs to make commons-chain very easy 
to understand and use.

>  If it
>returned Command this would basically eliminate the need for a Chain
>interface altogether.
>

Your approach only works for the top-level chain -- the current APIs 
allow chains to use arbitrarily complex subchains.  Essentially, you'd 
force anyone who wants subchains to re-invent what Chain already does.

>  Chain would become a concrete implementation of
>Command that repeatedly executed Commands until the last command executed
>returned null (which would be the new value to indicate the end of a chain).
>Static chains (such as those configured using an XML file) would easily be
>supported by another concrete implementation of Command which executed a
>series of commands in order, completely ignoring their return values.
>

You can already do exactly this kind of thing with the current API, 
without imposing on yourself the restrictions described above.  Your 
proposed changes would remove functionality and add complexity.

>2) How come Filters have a postprocess method but no catchexception method?
>

The postprocess method does both things, so you don't need a separate 
method.

>The postprocess block can deal with exceptions, but it seems to me like it
>would be more natural for exceptions to be dealt with in a catchexception
>block and for postprocess to be strictly for freeing resources that the
>Command acquired when its execute method was called.
>

My experience has been that the catch exception processing normally has 
to free the resources anyway, so it would end up either calling the 
postprocess method or duplicating the logic.  Either of those is tedious 
and error prone.  Far better just to have a single cleanup method no 
matter what happened.

>
>Ted Husted wrote:
>  
>
>>Of course, another way to go would be to make the Catalog a singleton,
>>or available through some registry, but I'm thinking that going through
>>the Context may be the cleanest approach, since the Context is
>>essentially a Registry too.
>>    
>>
>
>How about making a Register class which is an implementation of Context
>which stores only references to Catalogs?  We could make the registry itself
>a singleton, and write in design notes that since the registry is shared
>between apps, each app should store its Catalog(s) in an
>application-specific attribute like below:
>
>Registry
>|
>|---org.apache.struts
>|---|---actions.RequestProcessor
>|---|---somethingElse
>|---com.bah.krm
>|---org.apache.commons.something
>
>That's not explained incredibly well, but if each application component
>reserves its own spot in the registry, we should be able to make the
>registry a singleton everyone can share.  This keeps us from tying ourselves
>to the Servlet API, as was mentioned in the ChainServlet discussion thread.
>  
>

It should be obvious that creating such a class is trivially simple, but 
you should first study how class loaders work in servlet containers, and 
then think about what happens if commons-chain were placed in a parent 
class loader (meaning that any singletons you try to create with static 
variables are shared across *all* webapps, not just the current one).  
The docs for Tomcat's class loader are specific to Tomcat, but typical 
of the architecture that most web containers offer:

  http://jakarta.apache.org/tomcat/tomcat-4.1-doc/class-loader-howto.html

The other reason I didn't go here is that we're actually at the edge of 
the patterns that commons-chain was created to implement.  How it gets 
embedded into a particular application should be up to that application.

Indeed, the only reason that Catalog exists is to allow chains to refer 
to other chains in an organized way.  One could argue that even this is 
out of scope; however, it's very useful to be able to write a Command 
that uses complex processing logic to decide which other commands (or 
chains, since you can't tell in the catalog what something is) should be 
used to actually perform a task.

Class libraries should be narrowly focused on as few fundamental ideas 
as possible, and then do them there.  They should not impose onerous 
restrictions on applications that want to use them (which is why the 
config package that uses Digester is optional -- you can compose chains 
any way you like).  The fundamental APIs we've defined so far (Command, 
Chain, Context, and Filter) are the minimum needed to implement the 
desired design patterns.  Catalog is on the edge, but useful for 
combining chains/commands in a controlled manner.  Registry is more 
about how catalogs would be accessed, rather than what they do.  Indeed, 
you don't even need such a thing in many environments; for example, a 
web app's ServletContext attributes do exactly what your registry does 
for that particular use case.

>Matt
>
Craig



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Greg Reddin <gr...@fnf.com>.
Sgarlata Matt wrote:
> Related to this, how come
> Command.execute returns boolean instead of returning Command?  If it
> returned Command this would basically eliminate the need for a Chain
> interface altogether.  Chain would become a concrete implementation of
> Command that repeatedly executed Commands until the last command executed
> returned null (which would be the new value to indicate the end of a chain).

If Command returned a Command reference, each Command would have to know 
what the next Command in the chain is, which, IMO, would introduce too 
tight coupling between Commands.  Why use configurable chains if you're 
going to programatically hardwire the next step in the process.  The 
Chain interface exists to signify separately from the Commands 
themselves the set of commands that are to be run in a process.  The 
Command returns boolean so that you can "break" execution at any point 
in the chain.  Look at the current RequestProcessor interface in Struts. 
  Some of the processing methods return boolean to indicate that 
processing should not continue to the next "link."

If the interface was changed from what it is now, I'd prefer an approach 
that looks more like Servlet Filters where you call doNextCommand() 
without regard to what the next command is over an approach where you 
determine what the next command is, but I'm cool with the interface the 
way it exists now as well.

Greg



Re: [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Ted Husted <hu...@apache.org>.
Sgarlata Matt wrote:
> How about making a Register class which is an implementation of Context
> which stores only references to Catalogs?  We could make the registry itself
> a singleton, and write in design notes that since the registry is shared
> between apps, each app should store its Catalog(s) in an
> application-specific attribute like below:
> 
> Registry
> |
> |---org.apache.struts
> |---|---actions.RequestProcessor
> |---|---somethingElse
> |---com.bah.krm
> |---org.apache.commons.something
> 
> That's not explained incredibly well, but if each application component
> reserves its own spot in the registry, we should be able to make the
> registry a singleton everyone can share.  This keeps us from tying ourselves
> to the Servlet API, as was mentioned in the ChainServlet discussion thread.

I was thinking that when I have a case of a Command needing to access 
another Command/Chain, I'd try adding a Catalog attribute to the 
Context. But, it might be too early to define another Registry class 
(since the Context is also a Registry), especially without a use-case to 
test it against. The big step now, I think, is migrating some 
applications to Chain so we can see what's needed in practice. I've got 
both a web and non-web on the hook for this now.

-Ted.



[Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Sgarlata Matt <sg...@bah.com>.
The conversation threads are getting kind of crazy, so I'm going to skip
inline quotes for parts of this.

Craig, now I do see your point about using the ConfigRuleSet to digest a
portion of
an arbitrary XML file.  That is very cool, and now I understand why the
names of the XML elements are configurable.  I always understood the value
of letting attributes to the <command> element (and other elements).  This
is a much slicker approach than creating nested <set-property> elements.
Still, I think it could be useful to have a DTD for the *default* behavior
of the ConfigRuleSet.  I think in general users will start off using the
default behavior, and then may at a later date decide to fold their commands
into some other file, so a DTD will be nice to get people started with the
Chain package.  I agree with most your points about the constraints I placed
in the DTD being inappropriate, and will explicitly address each if we ever
decide to make a DTD.

As I've thought more about the package, I don't understand why some design
decisions were made.  First let me say that I think of Chains as being an OO
way to simulate procedural logic.  Many of my comments will basically be
concerning why some of the standard control flow abilities (if/then
statements, loops, exception handling, etc) in Java aren't more easily
done/simulated using the Chain package.  So, here I go with questions:
1) How come Chains have a static structure?  Related to this, how come
Command.execute returns boolean instead of returning Command?  If it
returned Command this would basically eliminate the need for a Chain
interface altogether.  Chain would become a concrete implementation of
Command that repeatedly executed Commands until the last command executed
returned null (which would be the new value to indicate the end of a chain).
Static chains (such as those configured using an XML file) would easily be
supported by another concrete implementation of Command which executed a
series of commands in order, completely ignoring their return values.
2) How come Filters have a postprocess method but no catchexception method?
The postprocess block can deal with exceptions, but it seems to me like it
would be more natural for exceptions to be dealt with in a catchexception
block and for postprocess to be strictly for freeing resources that the
Command acquired when its execute method was called.

Ted Husted wrote:
> Of course, another way to go would be to make the Catalog a singleton,
> or available through some registry, but I'm thinking that going through
> the Context may be the cleanest approach, since the Context is
> essentially a Registry too.

How about making a Register class which is an implementation of Context
which stores only references to Catalogs?  We could make the registry itself
a singleton, and write in design notes that since the registry is shared
between apps, each app should store its Catalog(s) in an
application-specific attribute like below:

Registry
|
|---org.apache.struts
|---|---actions.RequestProcessor
|---|---somethingElse
|---com.bah.krm
|---org.apache.commons.something

That's not explained incredibly well, but if each application component
reserves its own spot in the registry, we should be able to make the
registry a singleton everyone can share.  This keeps us from tying ourselves
to the Servlet API, as was mentioned in the ChainServlet discussion thread.

Matt
----- Original Message ----- 
From: "Craig R. McClanahan" <cr...@apache.org>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
Sent: Monday, September 22, 2003 9:33 PM
Subject: Re: [Chain] examples XML file available?


> Sgarlata Matt wrote:
>
> >Comments below...
> >----- Original Message ----- 
> >From: "Craig R. McClanahan" <cr...@apache.org>
> >To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
> >Sent: Sunday, September 21, 2003 5:53 PM
> >Subject: Re: [Chain] examples XML file available?
> >
> >
> >
> >
> >>On Sun, 21 Sep 2003, Sgarlata Matt wrote:
> >>
> >>
> >>
> >>>Date: Sun, 21 Sep 2003 13:45:37 -0400
> >>>From: Sgarlata Matt <sg...@bah.com>
> >>>Reply-To: Jakarta Commons Developers List
> >>>
> >>>
> ><co...@jakarta.apache.org>
> >
> >
> >>>To: commons-dev@jakarta.apache.org
> >>>Subject: [Chain] examples XML file available?
> >>>
> >>>I'm interested in possibly using the Chain package in some of my
> >>>
> >>>
> >projects
> >
> >
> >>>and I was hoping I could get an example XML file to feed to the
> >>>
> >>>
> >Digester?  I
> >
> >
> >>>don't need the Command classes associated with the file or anything
like
> >>>that, I'd just like to see an example so I don't have to
> >>>
> >>>
> >reverse-engineer
> >
> >
> >>>its structure from the ConfigRuleSet.
> >>>
> >>>
> >>>
> >>There's an example in the unit tests of the source module
> >>
> >>  src/test/org/apache/commons/chain/config/test-config.xml
> >>
> >>although, in truth, this is only a test of the default rules -- you
> >>actually get to configure what element and attribute names are
recognized
> >>by setting properties on your own copy of ConfigRuleSet instead of using
> >>the default one (unit tests for this would be definitely appreciated
:-).
> >>
> >>
> >
> >Wow, that is a very cool how you set that up :)  Is there a use-case you
had
> >in mind where this type of functionality would be useful?  To be honest,
I
> >think that it might be better to make the ConfigRuleSet a little less
> >powerful and expect a set DTD.  More comments on how this would work
> >below...
> >
> >
> The use case goes like this:
>
> * Each command should be a JavaBean (i.e. has a zero-args constructor and
>   is configured with property setters).
>
> * The set of properties each command class is interested in will be unique
>   to that command class.
>
> * Users that are utilizing the Digester-based mechanism for configuring
> command chains
>   will want the most concise mechanism for configuring commands as
possible.
>
> Experience with processing both Tomcat and Struts configuration files
> (both of which use Digester) make it pretty clear this use case is
> common -- and it is exactly the use case that Digester was designed for.
>
> >
> >
> >>>If I play with the package some more and like it, I could provide a DTD
> >>>
> >>>
> >for
> >
> >
> >>>the XML file and documentation for it.  That should save Craig and Ted
> >>>
> >>>
> >from
> >
> >
> >>>some boring work :)
> >>>
> >>>
> >>While we definitely appreciate the help :-), I don't think a DTD (or a
> >>schema) that captures all of the possible functionality of the XML based
> >>configuration.  Consider one of the examples in the unit test:
> >>
> >>    <!-- Configurable command with settable properties -->
> >>    <command   name="Configurable"
> >>          className="org.apache.commons.chain.config.TestCommand"
> >>                foo="Foo Value"
> >>                bar="Bar Value"/>
> >>
> >>Besides actually instantiating TestCommand and inserting it into the
> >>parent Catalog, this leverages Digester's "Set Properties Rule" ability
to
> >>match attributes to writeable propertes and configure them.  The entry
> >>above, then, calls setFoo() and setBar() on the instantiated bean -- but
> >>this is the same <command> element that is used to configure a different
> >>type of command, with different properties, later on:
> >>
> >>    <command      id="1"
> >>                 is2="a"
> >>           className="org.apache.commons.chain.impl.DelegatingFilter"/>
> >>
> >>I'm not a total guru on XML, but I don't see how one can define a DTD
that
> >>covers this case, since the set of possible attributes is not limited.
> >>
> >>
> >
> >Yeah, you can't have a DTD verify the attributes for commands since they
are
> >not set.  However, we can specify that the className attribute for
<command>
> >is required and that the <command> element must be empty.
> >
> Why should it be empty?  You're perfectly free to add your own rules to
> the ones returned by the ConfigRuleSet, and process the innards yourself.
>
> In addition, if you're not going to support configuring JavaBean
> properties on the command instances with arbitrary attributes, you will
> certainly want something like a <set-property> element inside to
> accomplish this goal.  So an empty command is probably not the right
answer.
>
> >  I think these are
> >two very useful things to have the digester automatically check.  It
would
> >certainly beat a random NullPointerException :)  In fact, the attached
DTD
> >can take care of the items listed below.  This would certainly avoid lots
of
> >painful debugging sessions when <command> was actually typed <Command>
and
> >other stuff like that.
> >
> >- Ensure there are 1 or more <chain> elements inside <chains>
> >
> If you want to register single-command "chains" in the catalog, you
> probably won't want this.
>
> >- Ensure there are 1 or more <command> elements inside <chain>
> >
> No "placeholder" chains for future fleshing out?
>
> >- Ensure each <chain> has a name
> >- Ensure each <command> has a className specified
> >
> >- Ensure each <command> element is empty
> >
> As above, I don't buy into this one.
>
> >- Limit the XML file to only <chains>, <chain>, and <command> elements
with
> >the proper nesting.
> >
> If a person wants to define their command chains in the same document
> that they are using for other aspects of the operation (for example, if
> Struts wanted to let you put this stuff into a struts-config.xml file),
> you'd want the ability to just pull out the elements you care about and
> ignore the rest.  That's the beauty of the rules-based matching patterns
> that Digester supports -- you specify the patterns you are interested
> in, and that's all your rules have to deal with.
>
> >
> >The attached DTD is just a first pass at a DTD.  I know it isn't pretty,
and
> >would follow the format used in struts-config_1_0.dtd before recommending
it
> >for checkin.  Before I go any further though, I would actually like to
see
> >the XML file get a little more sophisticated.  Once we settle on the
format
> >of the XML file I can update ConfigRuleSet and finish up the DTD (and
> >provide test cases for ConfigRuleSet... ugh I hate writing test cases!)
> >Here's what I was thinking:
> >
> ><chains>
> >    <global-commands>
> >        <global-command
> >            name="globalCommand1"
> >            className="something"
> >            otherAttribute1="hi"/>
> >    </global-commands>
> >    <chain name="myChain">
> >        <!-- here otherAttribute1="hi" and className="something" are
> >        implied since the command was defined earlier -->
> >        <command name="globalCommand1"/>
> >        <!-- this is a local command -->
> >        <command className="something"/>
> >    </chain>
> ></chains>
> >
> >One cool thing we can do is ensure that each <command> that is actually a
> >reference to a <global-command> has a name attribute which corresponds to
> >one of the names of a global command.  This is actually something
supported
> >directly by DTDs, so we don't have to do anything fancy to get this
> >automatic validation :)
> >
> >
> How do you propose to set individual configurable properties on the
> command classes?  My experience so far on real ones (as opposed to toy
> ones) is that this is a mission critical requirement.
>
> >Matt
> >
> >
> Craig
>
> >------------------------------------------------------------------------
> >
> ><!--
> >     DTD for the optional Chain of Responsibility Configuration File,
> > Version 1.0
> >
> >     To support validation of your configuration file, include the
following
> >     DOCTYPE element at the beginning (after the "xml" declaration):
> >
> >     <!DOCTYPE chains PUBLIC
> >       "-//Apache Software Foundation//DTD Chain Configuration 1.0//EN"
> >       "http://jakarta.apache.org/commons/chain/dtds/chains_1_0.dtd">
> >-->
> >
> ><!-- The "chains" element is the root of the configuration file
hierarchy, and
> >     contains one or more nested chain elements.
> >-->
> ><!ELEMENT chains (chain+)>
> >
> ><!-- The "chain" element represents a class which implements the
> >     org.apache.commons.chain.Chain interface.  Thus it represents a
configured
> > list of Commands that will be executed in order to perform processing on
a
> > specified Context.  If no className is specified for the chain, the
chain
> > will be an instance of the class
org.apache.commons.chain.impl.ChainBase.
> >-->
> ><!ELEMENT chain (command+)>
> ><!ATTLIST chain
> > name CDATA #REQUIRED
> >
> >
> ><!ATTLIST chain
> > className CDATA #IMPLIED
> >
> >
> ><!ELEMENT command EMPTY>
> ><!ATTLIST command
> > className CDATA #REQUIRED
> >>
> >
> >
> >
> >------------------------------------------------------------------------
> >
> >---------------------------------------------------------------------
> >To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> >For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> >
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>


[Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)

Posted by Sgarlata Matt <sg...@bah.com>.
The conversation threads are getting kind of crazy, so I'm going to skip
inline quotes for parts of this.

Craig, now I do see your point about using the ConfigRuleSet to digest a
portion of
an arbitrary XML file.  That is very cool, and now I understand why the
names of the XML elements are configurable.  I always understood the value
of letting attributes to the <command> element (and other elements).  This
is a much slicker approach than creating nested <set-property> elements.
Still, I think it could be useful to have a DTD for the *default* behavior
of the ConfigRuleSet.  I think in general users will start off using the
default behavior, and then may at a later date decide to fold their commands
into some other file, so a DTD will be nice to get people started with the
Chain package.  I agree with most your points about the constraints I placed
in the DTD being inappropriate, and will explicitly address each if we ever
decide to make a DTD.

As I've thought more about the package, I don't understand why some design
decisions were made.  First let me say that I think of Chains as being an OO
way to simulate procedural logic.  Many of my comments will basically be
concerning why some of the standard control flow abilities (if/then
statements, loops, exception handling, etc) in Java aren't more easily
done/simulated using the Chain package.  So, here I go with questions:
1) How come Chains have a static structure?  Related to this, how come
Command.execute returns boolean instead of returning Command?  If it
returned Command this would basically eliminate the need for a Chain
interface altogether.  Chain would become a concrete implementation of
Command that repeatedly executed Commands until the last command executed
returned null (which would be the new value to indicate the end of a chain).
Static chains (such as those configured using an XML file) would easily be
supported by another concrete implementation of Command which executed a
series of commands in order, completely ignoring their return values.
2) How come Filters have a postprocess method but no catchexception method?
The postprocess block can deal with exceptions, but it seems to me like it
would be more natural for exceptions to be dealt with in a catchexception
block and for postprocess to be strictly for freeing resources that the
Command acquired when its execute method was called.

Ted Husted wrote:
> Of course, another way to go would be to make the Catalog a singleton,
> or available through some registry, but I'm thinking that going through
> the Context may be the cleanest approach, since the Context is
> essentially a Registry too.

How about making a Register class which is an implementation of Context
which stores only references to Catalogs?  We could make the registry itself
a singleton, and write in design notes that since the registry is shared
between apps, each app should store its Catalog(s) in an
application-specific attribute like below:

Registry
|
|---org.apache.struts
|---|---actions.RequestProcessor
|---|---somethingElse
|---com.bah.krm
|---org.apache.commons.something

That's not explained incredibly well, but if each application component
reserves its own spot in the registry, we should be able to make the
registry a singleton everyone can share.  This keeps us from tying ourselves
to the Servlet API, as was mentioned in the ChainServlet discussion thread.

Matt
----- Original Message ----- 
From: "Craig R. McClanahan" <cr...@apache.org>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
Sent: Monday, September 22, 2003 9:33 PM
Subject: Re: [Chain] examples XML file available?


> Sgarlata Matt wrote:
>
> >Comments below...
> >----- Original Message ----- 
> >From: "Craig R. McClanahan" <cr...@apache.org>
> >To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
> >Sent: Sunday, September 21, 2003 5:53 PM
> >Subject: Re: [Chain] examples XML file available?
> >
> >
> >
> >
> >>On Sun, 21 Sep 2003, Sgarlata Matt wrote:
> >>
> >>
> >>
> >>>Date: Sun, 21 Sep 2003 13:45:37 -0400
> >>>From: Sgarlata Matt <sg...@bah.com>
> >>>Reply-To: Jakarta Commons Developers List
> >>>
> >>>
> ><co...@jakarta.apache.org>
> >
> >
> >>>To: commons-dev@jakarta.apache.org
> >>>Subject: [Chain] examples XML file available?
> >>>
> >>>I'm interested in possibly using the Chain package in some of my
> >>>
> >>>
> >projects
> >
> >
> >>>and I was hoping I could get an example XML file to feed to the
> >>>
> >>>
> >Digester?  I
> >
> >
> >>>don't need the Command classes associated with the file or anything
like
> >>>that, I'd just like to see an example so I don't have to
> >>>
> >>>
> >reverse-engineer
> >
> >
> >>>its structure from the ConfigRuleSet.
> >>>
> >>>
> >>>
> >>There's an example in the unit tests of the source module
> >>
> >>  src/test/org/apache/commons/chain/config/test-config.xml
> >>
> >>although, in truth, this is only a test of the default rules -- you
> >>actually get to configure what element and attribute names are
recognized
> >>by setting properties on your own copy of ConfigRuleSet instead of using
> >>the default one (unit tests for this would be definitely appreciated
:-).
> >>
> >>
> >
> >Wow, that is a very cool how you set that up :)  Is there a use-case you
had
> >in mind where this type of functionality would be useful?  To be honest,
I
> >think that it might be better to make the ConfigRuleSet a little less
> >powerful and expect a set DTD.  More comments on how this would work
> >below...
> >
> >
> The use case goes like this:
>
> * Each command should be a JavaBean (i.e. has a zero-args constructor and
>   is configured with property setters).
>
> * The set of properties each command class is interested in will be unique
>   to that command class.
>
> * Users that are utilizing the Digester-based mechanism for configuring
> command chains
>   will want the most concise mechanism for configuring commands as
possible.
>
> Experience with processing both Tomcat and Struts configuration files
> (both of which use Digester) make it pretty clear this use case is
> common -- and it is exactly the use case that Digester was designed for.
>
> >
> >
> >>>If I play with the package some more and like it, I could provide a DTD
> >>>
> >>>
> >for
> >
> >
> >>>the XML file and documentation for it.  That should save Craig and Ted
> >>>
> >>>
> >from
> >
> >
> >>>some boring work :)
> >>>
> >>>
> >>While we definitely appreciate the help :-), I don't think a DTD (or a
> >>schema) that captures all of the possible functionality of the XML based
> >>configuration.  Consider one of the examples in the unit test:
> >>
> >>    <!-- Configurable command with settable properties -->
> >>    <command   name="Configurable"
> >>          className="org.apache.commons.chain.config.TestCommand"
> >>                foo="Foo Value"
> >>                bar="Bar Value"/>
> >>
> >>Besides actually instantiating TestCommand and inserting it into the
> >>parent Catalog, this leverages Digester's "Set Properties Rule" ability
to
> >>match attributes to writeable propertes and configure them.  The entry
> >>above, then, calls setFoo() and setBar() on the instantiated bean -- but
> >>this is the same <command> element that is used to configure a different
> >>type of command, with different properties, later on:
> >>
> >>    <command      id="1"
> >>                 is2="a"
> >>           className="org.apache.commons.chain.impl.DelegatingFilter"/>
> >>
> >>I'm not a total guru on XML, but I don't see how one can define a DTD
that
> >>covers this case, since the set of possible attributes is not limited.
> >>
> >>
> >
> >Yeah, you can't have a DTD verify the attributes for commands since they
are
> >not set.  However, we can specify that the className attribute for
<command>
> >is required and that the <command> element must be empty.
> >
> Why should it be empty?  You're perfectly free to add your own rules to
> the ones returned by the ConfigRuleSet, and process the innards yourself.
>
> In addition, if you're not going to support configuring JavaBean
> properties on the command instances with arbitrary attributes, you will
> certainly want something like a <set-property> element inside to
> accomplish this goal.  So an empty command is probably not the right
answer.
>
> >  I think these are
> >two very useful things to have the digester automatically check.  It
would
> >certainly beat a random NullPointerException :)  In fact, the attached
DTD
> >can take care of the items listed below.  This would certainly avoid lots
of
> >painful debugging sessions when <command> was actually typed <Command>
and
> >other stuff like that.
> >
> >- Ensure there are 1 or more <chain> elements inside <chains>
> >
> If you want to register single-command "chains" in the catalog, you
> probably won't want this.
>
> >- Ensure there are 1 or more <command> elements inside <chain>
> >
> No "placeholder" chains for future fleshing out?
>
> >- Ensure each <chain> has a name
> >- Ensure each <command> has a className specified
> >
> >- Ensure each <command> element is empty
> >
> As above, I don't buy into this one.
>
> >- Limit the XML file to only <chains>, <chain>, and <command> elements
with
> >the proper nesting.
> >
> If a person wants to define their command chains in the same document
> that they are using for other aspects of the operation (for example, if
> Struts wanted to let you put this stuff into a struts-config.xml file),
> you'd want the ability to just pull out the elements you care about and
> ignore the rest.  That's the beauty of the rules-based matching patterns
> that Digester supports -- you specify the patterns you are interested
> in, and that's all your rules have to deal with.
>
> >
> >The attached DTD is just a first pass at a DTD.  I know it isn't pretty,
and
> >would follow the format used in struts-config_1_0.dtd before recommending
it
> >for checkin.  Before I go any further though, I would actually like to
see
> >the XML file get a little more sophisticated.  Once we settle on the
format
> >of the XML file I can update ConfigRuleSet and finish up the DTD (and
> >provide test cases for ConfigRuleSet... ugh I hate writing test cases!)
> >Here's what I was thinking:
> >
> ><chains>
> >    <global-commands>
> >        <global-command
> >            name="globalCommand1"
> >            className="something"
> >            otherAttribute1="hi"/>
> >    </global-commands>
> >    <chain name="myChain">
> >        <!-- here otherAttribute1="hi" and className="something" are
> >        implied since the command was defined earlier -->
> >        <command name="globalCommand1"/>
> >        <!-- this is a local command -->
> >        <command className="something"/>
> >    </chain>
> ></chains>
> >
> >One cool thing we can do is ensure that each <command> that is actually a
> >reference to a <global-command> has a name attribute which corresponds to
> >one of the names of a global command.  This is actually something
supported
> >directly by DTDs, so we don't have to do anything fancy to get this
> >automatic validation :)
> >
> >
> How do you propose to set individual configurable properties on the
> command classes?  My experience so far on real ones (as opposed to toy
> ones) is that this is a mission critical requirement.
>
> >Matt
> >
> >
> Craig
>
> >------------------------------------------------------------------------
> >
> ><!--
> >     DTD for the optional Chain of Responsibility Configuration File,
> > Version 1.0
> >
> >     To support validation of your configuration file, include the
following
> >     DOCTYPE element at the beginning (after the "xml" declaration):
> >
> >     <!DOCTYPE chains PUBLIC
> >       "-//Apache Software Foundation//DTD Chain Configuration 1.0//EN"
> >       "http://jakarta.apache.org/commons/chain/dtds/chains_1_0.dtd">
> >-->
> >
> ><!-- The "chains" element is the root of the configuration file
hierarchy, and
> >     contains one or more nested chain elements.
> >-->
> ><!ELEMENT chains (chain+)>
> >
> ><!-- The "chain" element represents a class which implements the
> >     org.apache.commons.chain.Chain interface.  Thus it represents a
configured
> > list of Commands that will be executed in order to perform processing on
a
> > specified Context.  If no className is specified for the chain, the
chain
> > will be an instance of the class
org.apache.commons.chain.impl.ChainBase.
> >-->
> ><!ELEMENT chain (command+)>
> ><!ATTLIST chain
> > name CDATA #REQUIRED
> >
> >
> ><!ATTLIST chain
> > className CDATA #IMPLIED
> >
> >
> ><!ELEMENT command EMPTY>
> ><!ATTLIST command
> > className CDATA #REQUIRED
> >>
> >
> >
> >
> >------------------------------------------------------------------------
> >
> >---------------------------------------------------------------------
> >To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> >For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> >
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] examples XML file available?

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Sgarlata Matt wrote:

>Comments below...
>----- Original Message ----- 
>From: "Craig R. McClanahan" <cr...@apache.org>
>To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
>Sent: Sunday, September 21, 2003 5:53 PM
>Subject: Re: [Chain] examples XML file available?
>
>
>  
>
>>On Sun, 21 Sep 2003, Sgarlata Matt wrote:
>>
>>    
>>
>>>Date: Sun, 21 Sep 2003 13:45:37 -0400
>>>From: Sgarlata Matt <sg...@bah.com>
>>>Reply-To: Jakarta Commons Developers List
>>>      
>>>
><co...@jakarta.apache.org>
>  
>
>>>To: commons-dev@jakarta.apache.org
>>>Subject: [Chain] examples XML file available?
>>>
>>>I'm interested in possibly using the Chain package in some of my
>>>      
>>>
>projects
>  
>
>>>and I was hoping I could get an example XML file to feed to the
>>>      
>>>
>Digester?  I
>  
>
>>>don't need the Command classes associated with the file or anything like
>>>that, I'd just like to see an example so I don't have to
>>>      
>>>
>reverse-engineer
>  
>
>>>its structure from the ConfigRuleSet.
>>>
>>>      
>>>
>>There's an example in the unit tests of the source module
>>
>>  src/test/org/apache/commons/chain/config/test-config.xml
>>
>>although, in truth, this is only a test of the default rules -- you
>>actually get to configure what element and attribute names are recognized
>>by setting properties on your own copy of ConfigRuleSet instead of using
>>the default one (unit tests for this would be definitely appreciated :-).
>>    
>>
>
>Wow, that is a very cool how you set that up :)  Is there a use-case you had
>in mind where this type of functionality would be useful?  To be honest, I
>think that it might be better to make the ConfigRuleSet a little less
>powerful and expect a set DTD.  More comments on how this would work
>below...
>  
>
The use case goes like this:

* Each command should be a JavaBean (i.e. has a zero-args constructor and
  is configured with property setters).

* The set of properties each command class is interested in will be unique
  to that command class.

* Users that are utilizing the Digester-based mechanism for configuring 
command chains
  will want the most concise mechanism for configuring commands as possible.

Experience with processing both Tomcat and Struts configuration files 
(both of which use Digester) make it pretty clear this use case is 
common -- and it is exactly the use case that Digester was designed for.

>  
>
>>>If I play with the package some more and like it, I could provide a DTD
>>>      
>>>
>for
>  
>
>>>the XML file and documentation for it.  That should save Craig and Ted
>>>      
>>>
>from
>  
>
>>>some boring work :)
>>>      
>>>
>>While we definitely appreciate the help :-), I don't think a DTD (or a
>>schema) that captures all of the possible functionality of the XML based
>>configuration.  Consider one of the examples in the unit test:
>>
>>    <!-- Configurable command with settable properties -->
>>    <command   name="Configurable"
>>          className="org.apache.commons.chain.config.TestCommand"
>>                foo="Foo Value"
>>                bar="Bar Value"/>
>>
>>Besides actually instantiating TestCommand and inserting it into the
>>parent Catalog, this leverages Digester's "Set Properties Rule" ability to
>>match attributes to writeable propertes and configure them.  The entry
>>above, then, calls setFoo() and setBar() on the instantiated bean -- but
>>this is the same <command> element that is used to configure a different
>>type of command, with different properties, later on:
>>
>>    <command      id="1"
>>                 is2="a"
>>           className="org.apache.commons.chain.impl.DelegatingFilter"/>
>>
>>I'm not a total guru on XML, but I don't see how one can define a DTD that
>>covers this case, since the set of possible attributes is not limited.
>>    
>>
>
>Yeah, you can't have a DTD verify the attributes for commands since they are
>not set.  However, we can specify that the className attribute for <command>
>is required and that the <command> element must be empty.
>
Why should it be empty?  You're perfectly free to add your own rules to 
the ones returned by the ConfigRuleSet, and process the innards yourself.

In addition, if you're not going to support configuring JavaBean 
properties on the command instances with arbitrary attributes, you will 
certainly want something like a <set-property> element inside to 
accomplish this goal.  So an empty command is probably not the right answer.

>  I think these are
>two very useful things to have the digester automatically check.  It would
>certainly beat a random NullPointerException :)  In fact, the attached DTD
>can take care of the items listed below.  This would certainly avoid lots of
>painful debugging sessions when <command> was actually typed <Command> and
>other stuff like that.
>
>- Ensure there are 1 or more <chain> elements inside <chains>
>
If you want to register single-command "chains" in the catalog, you 
probably won't want this.

>- Ensure there are 1 or more <command> elements inside <chain>
>
No "placeholder" chains for future fleshing out?

>- Ensure each <chain> has a name
>- Ensure each <command> has a className specified
>
>- Ensure each <command> element is empty
>
As above, I don't buy into this one.

>- Limit the XML file to only <chains>, <chain>, and <command> elements with
>the proper nesting.
>
If a person wants to define their command chains in the same document 
that they are using for other aspects of the operation (for example, if 
Struts wanted to let you put this stuff into a struts-config.xml file), 
you'd want the ability to just pull out the elements you care about and 
ignore the rest.  That's the beauty of the rules-based matching patterns 
that Digester supports -- you specify the patterns you are interested 
in, and that's all your rules have to deal with.

>
>The attached DTD is just a first pass at a DTD.  I know it isn't pretty, and
>would follow the format used in struts-config_1_0.dtd before recommending it
>for checkin.  Before I go any further though, I would actually like to see
>the XML file get a little more sophisticated.  Once we settle on the format
>of the XML file I can update ConfigRuleSet and finish up the DTD (and
>provide test cases for ConfigRuleSet... ugh I hate writing test cases!)
>Here's what I was thinking:
>
><chains>
>    <global-commands>
>        <global-command
>            name="globalCommand1"
>            className="something"
>            otherAttribute1="hi"/>
>    </global-commands>
>    <chain name="myChain">
>        <!-- here otherAttribute1="hi" and className="something" are
>        implied since the command was defined earlier -->
>        <command name="globalCommand1"/>
>        <!-- this is a local command -->
>        <command className="something"/>
>    </chain>
></chains>
>
>One cool thing we can do is ensure that each <command> that is actually a
>reference to a <global-command> has a name attribute which corresponds to
>one of the names of a global command.  This is actually something supported
>directly by DTDs, so we don't have to do anything fancy to get this
>automatic validation :)
>  
>
How do you propose to set individual configurable properties on the 
command classes?  My experience so far on real ones (as opposed to toy 
ones) is that this is a mission critical requirement.

>Matt
>  
>
Craig

>------------------------------------------------------------------------
>
><!--
>     DTD for the optional Chain of Responsibility Configuration File,
>	 Version 1.0
>
>     To support validation of your configuration file, include the following
>     DOCTYPE element at the beginning (after the "xml" declaration):
>
>     <!DOCTYPE chains PUBLIC
>       "-//Apache Software Foundation//DTD Chain Configuration 1.0//EN"
>       "http://jakarta.apache.org/commons/chain/dtds/chains_1_0.dtd">
>-->
>
><!-- The "chains" element is the root of the configuration file hierarchy, and
>     contains one or more nested chain elements.
>-->
><!ELEMENT chains (chain+)>
>
><!-- The "chain" element represents a class which implements the
>     org.apache.commons.chain.Chain interface.  Thus it represents a configured
>	 list of Commands that will be executed in order to perform processing on a
>	 specified Context.  If no className is specified for the chain, the chain
>	 will be an instance of the class org.apache.commons.chain.impl.ChainBase.
>-->
><!ELEMENT chain (command+)>
><!ATTLIST chain
>	name CDATA #REQUIRED
>  
>
><!ATTLIST chain
>	className CDATA #IMPLIED
>  
>
><!ELEMENT command EMPTY>
><!ATTLIST command
>	className CDATA #REQUIRED
>>
>
>  
>
>------------------------------------------------------------------------
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>



Re: [Chain] examples XML file available?

Posted by "Craig R. McClanahan" <cr...@apache.org>.
Sgarlata Matt wrote:

>Comments below...
>----- Original Message ----- 
>From: "Craig R. McClanahan" <cr...@apache.org>
>To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
>Sent: Sunday, September 21, 2003 5:53 PM
>Subject: Re: [Chain] examples XML file available?
>
>
>  
>
>>On Sun, 21 Sep 2003, Sgarlata Matt wrote:
>>
>>    
>>
>>>Date: Sun, 21 Sep 2003 13:45:37 -0400
>>>From: Sgarlata Matt <sg...@bah.com>
>>>Reply-To: Jakarta Commons Developers List
>>>      
>>>
><co...@jakarta.apache.org>
>  
>
>>>To: commons-dev@jakarta.apache.org
>>>Subject: [Chain] examples XML file available?
>>>
>>>I'm interested in possibly using the Chain package in some of my
>>>      
>>>
>projects
>  
>
>>>and I was hoping I could get an example XML file to feed to the
>>>      
>>>
>Digester?  I
>  
>
>>>don't need the Command classes associated with the file or anything like
>>>that, I'd just like to see an example so I don't have to
>>>      
>>>
>reverse-engineer
>  
>
>>>its structure from the ConfigRuleSet.
>>>
>>>      
>>>
>>There's an example in the unit tests of the source module
>>
>>  src/test/org/apache/commons/chain/config/test-config.xml
>>
>>although, in truth, this is only a test of the default rules -- you
>>actually get to configure what element and attribute names are recognized
>>by setting properties on your own copy of ConfigRuleSet instead of using
>>the default one (unit tests for this would be definitely appreciated :-).
>>    
>>
>
>Wow, that is a very cool how you set that up :)  Is there a use-case you had
>in mind where this type of functionality would be useful?  To be honest, I
>think that it might be better to make the ConfigRuleSet a little less
>powerful and expect a set DTD.  More comments on how this would work
>below...
>  
>
The use case goes like this:

* Each command should be a JavaBean (i.e. has a zero-args constructor and
  is configured with property setters).

* The set of properties each command class is interested in will be unique
  to that command class.

* Users that are utilizing the Digester-based mechanism for configuring 
command chains
  will want the most concise mechanism for configuring commands as possible.

Experience with processing both Tomcat and Struts configuration files 
(both of which use Digester) make it pretty clear this use case is 
common -- and it is exactly the use case that Digester was designed for.

>  
>
>>>If I play with the package some more and like it, I could provide a DTD
>>>      
>>>
>for
>  
>
>>>the XML file and documentation for it.  That should save Craig and Ted
>>>      
>>>
>from
>  
>
>>>some boring work :)
>>>      
>>>
>>While we definitely appreciate the help :-), I don't think a DTD (or a
>>schema) that captures all of the possible functionality of the XML based
>>configuration.  Consider one of the examples in the unit test:
>>
>>    <!-- Configurable command with settable properties -->
>>    <command   name="Configurable"
>>          className="org.apache.commons.chain.config.TestCommand"
>>                foo="Foo Value"
>>                bar="Bar Value"/>
>>
>>Besides actually instantiating TestCommand and inserting it into the
>>parent Catalog, this leverages Digester's "Set Properties Rule" ability to
>>match attributes to writeable propertes and configure them.  The entry
>>above, then, calls setFoo() and setBar() on the instantiated bean -- but
>>this is the same <command> element that is used to configure a different
>>type of command, with different properties, later on:
>>
>>    <command      id="1"
>>                 is2="a"
>>           className="org.apache.commons.chain.impl.DelegatingFilter"/>
>>
>>I'm not a total guru on XML, but I don't see how one can define a DTD that
>>covers this case, since the set of possible attributes is not limited.
>>    
>>
>
>Yeah, you can't have a DTD verify the attributes for commands since they are
>not set.  However, we can specify that the className attribute for <command>
>is required and that the <command> element must be empty.
>
Why should it be empty?  You're perfectly free to add your own rules to 
the ones returned by the ConfigRuleSet, and process the innards yourself.

In addition, if you're not going to support configuring JavaBean 
properties on the command instances with arbitrary attributes, you will 
certainly want something like a <set-property> element inside to 
accomplish this goal.  So an empty command is probably not the right answer.

>  I think these are
>two very useful things to have the digester automatically check.  It would
>certainly beat a random NullPointerException :)  In fact, the attached DTD
>can take care of the items listed below.  This would certainly avoid lots of
>painful debugging sessions when <command> was actually typed <Command> and
>other stuff like that.
>
>- Ensure there are 1 or more <chain> elements inside <chains>
>
If you want to register single-command "chains" in the catalog, you 
probably won't want this.

>- Ensure there are 1 or more <command> elements inside <chain>
>
No "placeholder" chains for future fleshing out?

>- Ensure each <chain> has a name
>- Ensure each <command> has a className specified
>
>- Ensure each <command> element is empty
>
As above, I don't buy into this one.

>- Limit the XML file to only <chains>, <chain>, and <command> elements with
>the proper nesting.
>
If a person wants to define their command chains in the same document 
that they are using for other aspects of the operation (for example, if 
Struts wanted to let you put this stuff into a struts-config.xml file), 
you'd want the ability to just pull out the elements you care about and 
ignore the rest.  That's the beauty of the rules-based matching patterns 
that Digester supports -- you specify the patterns you are interested 
in, and that's all your rules have to deal with.

>
>The attached DTD is just a first pass at a DTD.  I know it isn't pretty, and
>would follow the format used in struts-config_1_0.dtd before recommending it
>for checkin.  Before I go any further though, I would actually like to see
>the XML file get a little more sophisticated.  Once we settle on the format
>of the XML file I can update ConfigRuleSet and finish up the DTD (and
>provide test cases for ConfigRuleSet... ugh I hate writing test cases!)
>Here's what I was thinking:
>
><chains>
>    <global-commands>
>        <global-command
>            name="globalCommand1"
>            className="something"
>            otherAttribute1="hi"/>
>    </global-commands>
>    <chain name="myChain">
>        <!-- here otherAttribute1="hi" and className="something" are
>        implied since the command was defined earlier -->
>        <command name="globalCommand1"/>
>        <!-- this is a local command -->
>        <command className="something"/>
>    </chain>
></chains>
>
>One cool thing we can do is ensure that each <command> that is actually a
>reference to a <global-command> has a name attribute which corresponds to
>one of the names of a global command.  This is actually something supported
>directly by DTDs, so we don't have to do anything fancy to get this
>automatic validation :)
>  
>
How do you propose to set individual configurable properties on the 
command classes?  My experience so far on real ones (as opposed to toy 
ones) is that this is a mission critical requirement.

>Matt
>  
>
Craig

>------------------------------------------------------------------------
>
><!--
>     DTD for the optional Chain of Responsibility Configuration File,
>	 Version 1.0
>
>     To support validation of your configuration file, include the following
>     DOCTYPE element at the beginning (after the "xml" declaration):
>
>     <!DOCTYPE chains PUBLIC
>       "-//Apache Software Foundation//DTD Chain Configuration 1.0//EN"
>       "http://jakarta.apache.org/commons/chain/dtds/chains_1_0.dtd">
>-->
>
><!-- The "chains" element is the root of the configuration file hierarchy, and
>     contains one or more nested chain elements.
>-->
><!ELEMENT chains (chain+)>
>
><!-- The "chain" element represents a class which implements the
>     org.apache.commons.chain.Chain interface.  Thus it represents a configured
>	 list of Commands that will be executed in order to perform processing on a
>	 specified Context.  If no className is specified for the chain, the chain
>	 will be an instance of the class org.apache.commons.chain.impl.ChainBase.
>-->
><!ELEMENT chain (command+)>
><!ATTLIST chain
>	name CDATA #REQUIRED
>  
>
><!ATTLIST chain
>	className CDATA #IMPLIED
>  
>
><!ELEMENT command EMPTY>
><!ATTLIST command
>	className CDATA #REQUIRED
>>
>
>  
>
>------------------------------------------------------------------------
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] examples XML file available?

Posted by Sgarlata Matt <sg...@bah.com>.
Comments below...
----- Original Message ----- 
From: "Craig R. McClanahan" <cr...@apache.org>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
Sent: Sunday, September 21, 2003 5:53 PM
Subject: Re: [Chain] examples XML file available?


> On Sun, 21 Sep 2003, Sgarlata Matt wrote:
>
> > Date: Sun, 21 Sep 2003 13:45:37 -0400
> > From: Sgarlata Matt <sg...@bah.com>
> > Reply-To: Jakarta Commons Developers List
<co...@jakarta.apache.org>
> > To: commons-dev@jakarta.apache.org
> > Subject: [Chain] examples XML file available?
> >
> > I'm interested in possibly using the Chain package in some of my
projects
> > and I was hoping I could get an example XML file to feed to the
Digester?  I
> > don't need the Command classes associated with the file or anything like
> > that, I'd just like to see an example so I don't have to
reverse-engineer
> > its structure from the ConfigRuleSet.
> >
>
> There's an example in the unit tests of the source module
>
>   src/test/org/apache/commons/chain/config/test-config.xml
>
> although, in truth, this is only a test of the default rules -- you
> actually get to configure what element and attribute names are recognized
> by setting properties on your own copy of ConfigRuleSet instead of using
> the default one (unit tests for this would be definitely appreciated :-).

Wow, that is a very cool how you set that up :)  Is there a use-case you had
in mind where this type of functionality would be useful?  To be honest, I
think that it might be better to make the ConfigRuleSet a little less
powerful and expect a set DTD.  More comments on how this would work
below...

> > If I play with the package some more and like it, I could provide a DTD
for
> > the XML file and documentation for it.  That should save Craig and Ted
from
> > some boring work :)
>
> While we definitely appreciate the help :-), I don't think a DTD (or a
> schema) that captures all of the possible functionality of the XML based
> configuration.  Consider one of the examples in the unit test:
>
>     <!-- Configurable command with settable properties -->
>     <command   name="Configurable"
>           className="org.apache.commons.chain.config.TestCommand"
>                 foo="Foo Value"
>                 bar="Bar Value"/>
>
> Besides actually instantiating TestCommand and inserting it into the
> parent Catalog, this leverages Digester's "Set Properties Rule" ability to
> match attributes to writeable propertes and configure them.  The entry
> above, then, calls setFoo() and setBar() on the instantiated bean -- but
> this is the same <command> element that is used to configure a different
> type of command, with different properties, later on:
>
>     <command      id="1"
>                  is2="a"
>            className="org.apache.commons.chain.impl.DelegatingFilter"/>
>
> I'm not a total guru on XML, but I don't see how one can define a DTD that
> covers this case, since the set of possible attributes is not limited.

Yeah, you can't have a DTD verify the attributes for commands since they are
not set.  However, we can specify that the className attribute for <command>
is required and that the <command> element must be empty.  I think these are
two very useful things to have the digester automatically check.  It would
certainly beat a random NullPointerException :)  In fact, the attached DTD
can take care of the items listed below.  This would certainly avoid lots of
painful debugging sessions when <command> was actually typed <Command> and
other stuff like that.

- Ensure there are 1 or more <chain> elements inside <chains>
- Ensure there are 1 or more <command> elements inside <chain>
- Ensure each <chain> has a name
- Ensure each <command> has a className specified
- Ensure each <command> element is empty
- Limit the XML file to only <chains>, <chain>, and <command> elements with
the proper nesting.

The attached DTD is just a first pass at a DTD.  I know it isn't pretty, and
would follow the format used in struts-config_1_0.dtd before recommending it
for checkin.  Before I go any further though, I would actually like to see
the XML file get a little more sophisticated.  Once we settle on the format
of the XML file I can update ConfigRuleSet and finish up the DTD (and
provide test cases for ConfigRuleSet... ugh I hate writing test cases!)
Here's what I was thinking:

<chains>
    <global-commands>
        <global-command
            name="globalCommand1"
            className="something"
            otherAttribute1="hi"/>
    </global-commands>
    <chain name="myChain">
        <!-- here otherAttribute1="hi" and className="something" are
        implied since the command was defined earlier -->
        <command name="globalCommand1"/>
        <!-- this is a local command -->
        <command className="something"/>
    </chain>
</chains>

One cool thing we can do is ensure that each <command> that is actually a
reference to a <global-command> has a name attribute which corresponds to
one of the names of a global command.  This is actually something supported
directly by DTDs, so we don't have to do anything fancy to get this
automatic validation :)

Matt

Re: [Chain] examples XML file available?

Posted by "Craig R. McClanahan" <cr...@apache.org>.
On Sun, 21 Sep 2003, Sgarlata Matt wrote:

> Date: Sun, 21 Sep 2003 13:45:37 -0400
> From: Sgarlata Matt <sg...@bah.com>
> Reply-To: Jakarta Commons Developers List <co...@jakarta.apache.org>
> To: commons-dev@jakarta.apache.org
> Subject: [Chain] examples XML file available?
>
> I'm interested in possibly using the Chain package in some of my projects
> and I was hoping I could get an example XML file to feed to the Digester?  I
> don't need the Command classes associated with the file or anything like
> that, I'd just like to see an example so I don't have to reverse-engineer
> its structure from the ConfigRuleSet.
>

There's an example in the unit tests of the source module

  src/test/org/apache/commons/chain/config/test-config.xml

although, in truth, this is only a test of the default rules -- you
actually get to configure what element and attribute names are recognized
by setting properties on your own copy of ConfigRuleSet instead of using
the default one (unit tests for this would be definitely appreciated :-).

There's another example in the CVS HEAD sources of Struts, where we are
experimenting with building a replacement for the current RequestProcessor
class to assemble the request processing pipeline:

  contrib/struts-chain/src/conf/chain-config.xml

This is probably more typical of how chain might get used in real life.

If you don't want to download the entire source distros (or use anonymous
CVS), you can access these files individually (from the
"jakarta-commons-sandbox" and "jakarta-struts" repositories,
respectively), via ViewCVS:

  http://cvs.apache.org/viewcvs/jakarta-commons-sandbox/
  http://cvs.apache.org/viewcvs/jakarta-struts/

> If I play with the package some more and like it, I could provide a DTD for
> the XML file and documentation for it.  That should save Craig and Ted from
> some boring work :)

While we definitely appreciate the help :-), I don't think a DTD (or a
schema) that captures all of the possible functionality of the XML based
configuration.  Consider one of the examples in the unit test:

    <!-- Configurable command with settable properties -->
    <command   name="Configurable"
          className="org.apache.commons.chain.config.TestCommand"
                foo="Foo Value"
                bar="Bar Value"/>

Besides actually instantiating TestCommand and inserting it into the
parent Catalog, this leverages Digester's "Set Properties Rule" ability to
match attributes to writeable propertes and configure them.  The entry
above, then, calls setFoo() and setBar() on the instantiated bean -- but
this is the same <command> element that is used to configure a different
type of command, with different properties, later on:

    <command      id="1"
                 is2="a"
           className="org.apache.commons.chain.impl.DelegatingFilter"/>

I'm not a total guru on XML, but I don't see how one can define a DTD that
covers this case, since the set of possible attributes is not limited.

Tomcat users who are familiar with the server.xml file are undoutedly
smiling right now, because they're in pretty much the same boat, for the
same reasons.

>
> Thanks,
>
> Matt
>

Craig McClanahan

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [Chain] examples XML file available?

Posted by "Craig R. McClanahan" <cr...@apache.org>.
On Sun, 21 Sep 2003, Sgarlata Matt wrote:

> Date: Sun, 21 Sep 2003 13:45:37 -0400
> From: Sgarlata Matt <sg...@bah.com>
> Reply-To: Jakarta Commons Developers List <co...@jakarta.apache.org>
> To: commons-dev@jakarta.apache.org
> Subject: [Chain] examples XML file available?
>
> I'm interested in possibly using the Chain package in some of my projects
> and I was hoping I could get an example XML file to feed to the Digester?  I
> don't need the Command classes associated with the file or anything like
> that, I'd just like to see an example so I don't have to reverse-engineer
> its structure from the ConfigRuleSet.
>

There's an example in the unit tests of the source module

  src/test/org/apache/commons/chain/config/test-config.xml

although, in truth, this is only a test of the default rules -- you
actually get to configure what element and attribute names are recognized
by setting properties on your own copy of ConfigRuleSet instead of using
the default one (unit tests for this would be definitely appreciated :-).

There's another example in the CVS HEAD sources of Struts, where we are
experimenting with building a replacement for the current RequestProcessor
class to assemble the request processing pipeline:

  contrib/struts-chain/src/conf/chain-config.xml

This is probably more typical of how chain might get used in real life.

If you don't want to download the entire source distros (or use anonymous
CVS), you can access these files individually (from the
"jakarta-commons-sandbox" and "jakarta-struts" repositories,
respectively), via ViewCVS:

  http://cvs.apache.org/viewcvs/jakarta-commons-sandbox/
  http://cvs.apache.org/viewcvs/jakarta-struts/

> If I play with the package some more and like it, I could provide a DTD for
> the XML file and documentation for it.  That should save Craig and Ted from
> some boring work :)

While we definitely appreciate the help :-), I don't think a DTD (or a
schema) that captures all of the possible functionality of the XML based
configuration.  Consider one of the examples in the unit test:

    <!-- Configurable command with settable properties -->
    <command   name="Configurable"
          className="org.apache.commons.chain.config.TestCommand"
                foo="Foo Value"
                bar="Bar Value"/>

Besides actually instantiating TestCommand and inserting it into the
parent Catalog, this leverages Digester's "Set Properties Rule" ability to
match attributes to writeable propertes and configure them.  The entry
above, then, calls setFoo() and setBar() on the instantiated bean -- but
this is the same <command> element that is used to configure a different
type of command, with different properties, later on:

    <command      id="1"
                 is2="a"
           className="org.apache.commons.chain.impl.DelegatingFilter"/>

I'm not a total guru on XML, but I don't see how one can define a DTD that
covers this case, since the set of possible attributes is not limited.

Tomcat users who are familiar with the server.xml file are undoutedly
smiling right now, because they're in pretty much the same boat, for the
same reasons.

>
> Thanks,
>
> Matt
>

Craig McClanahan