commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Sgarlata Matt" <sgarlata_m...@bah.com>
Subject [Chain] DTD, Design Considerations, etc. (was Re: [Chain] examples XML file available?)
Date Wed, 24 Sep 2003 12:39:05 GMT
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" <craigmcc@apache.org>
To: "Jakarta Commons Developers List" <commons-dev@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" <craigmcc@apache.org>
> >To: "Jakarta Commons Developers List" <commons-dev@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 <sgarlata_matt@bah.com>
> >>>Reply-To: Jakarta Commons Developers List
> >>>
> >>>
> ><commons-dev@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
>


Mime
View raw message