Sgarlata Matt wrote:

Comments below...
----- Original Message ----- From: "Craig R. McClanahan" <[EMAIL PROTECTED]>
To: "Jakarta Commons Developers List" <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
Reply-To: Jakarta Commons Developers List


<[EMAIL PROTECTED]>


To: [EMAIL PROTECTED]
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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to