| <?xml version="1.0" encoding="UTF-8"?> |
| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| <document xmlns="http://maven.apache.org/XDOC/2.0" |
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd"> |
| <properties> |
| <title>Apache Commons Digester | Guide | XML Rules</title> |
| <author email="dev@commons.apache.org">Commons Documentation Team</author> |
| </properties> |
| <body> |
| <section name="Documentation for org.apache.commons.digester3.xmlrules"> |
| <p>The <code>xmlrules</code> package provides for XML-based definition of |
| rules for <code>Digester</code>. This improves maintainability of Java code, |
| as rules are now defined in XML and read into <code>Digester</code> at run-time. |
| </p> |
| |
| <subsection name="Introduction"> |
| <p>This is a brief overview of the digester-rules-in-XML feature. Briefly, |
| this feature lets you define Digester rules in XML, instead of |
| creating and initializing the Rules objects programmatically, which can become |
| tedious. In addition, it allows for including of one XML rules file within |
| another, inclusion of programmatically created rule sets within an XML file |
| (via reflection), and recursively nested matching pattern specifications. |
| </p> |
| </subsection> |
| |
| <subsection name="Overview of digester-rules.dtd"> |
| <p>A DTD, named <code>digester-rules.dtd</code> has been defined to help in the |
| understanding of how the loader operates. |
| </p> |
| <p> |
| The DTD is distributed in the <code>commons-digester3-3.0.jar</code>. It can be found at |
| <code>org/apache/commons/digester3/xmlrules/digester-rules.dtd</code>. |
| </p> |
| |
| <p>Digester input documents wishing to cite this DTD should include the |
| following DOCTYPE declaration:</p> |
| <source> |
| <!DOCTYPE digester-rules PUBLIC |
| "-//Apache Commons //DTD digester-rules XML V1.0//EN" |
| "http://commons.apache.org/digester/dtds/digester-rules-3.0.dtd"> |
| </source> |
| </subsection> |
| |
| <subsection name="Rule elements"> |
| <p>The DTD defines an element type corresponding to each predefined Digester |
| rule. Each rule element type includes attributes for values needed to |
| initialize the rule, and an optional <code>pattern</code> attribute |
| specifying the pattern to associate with the rule.</p> |
| <p>The <code>DigesterLoader</code> adds the rules to the digester in the order in |
| which they occur in the XML.</p> |
| <p>The use of each rule element type should be self-explanatory, if you compare |
| them to the API documentation for the <code>Digester</code> rules classes. |
| </p> |
| </subsection> |
| |
| <subsection name="Defining matching patterns"> |
| <p>The matching pattern is a simple, xpath-like string which the |
| <code>Digester</code> uses to determine which elements to apply each rule to. |
| See the <code>Digester</code> <a href="./core.html">documentation</a> for |
| more details.</p> |
| <p> |
| There are two methods for associating patterns to rules in the XML file. One |
| is for each rule element to directly define its pattern in a |
| <code>pattern</code> attribute. An example would like something like:</p> |
| <source> |
| <digester-rules> |
| <object-create-rule pattern="*/foo" classname="Foo" /> |
| <set-properties-rule pattern="*/foo" /> |
| </digester-rules> |
| </source> |
| <p> |
| In the above example, an <code>ObjectCreateRule</code> is created and |
| associated with the pattern "*/foo"; then a <code>SetPropertiesRule</code> is |
| created and associated with the pattern "*/foo".</p> |
| <p>The other method is to nest rules elements inside a |
| <code><pattern></code> element. In this way, the same pattern can be |
| defined for a group of rules. The following example has the same effect as the |
| previous example:</p> |
| <source> |
| <digester-rules> |
| <pattern value="*/foo"> |
| <object-create-rule classname="Foo" /> |
| <set-properties-rule /> |
| </pattern> |
| </digester-rules> |
| </source> |
| <p>Pattern elements can be recursively nested. If patterns are nested, the pattern |
| string is formed by concatenating all the patterns together. Example:</p> |
| <source> |
| <digester-rules> |
| <pattern value="*/foo"> |
| <pattern value="bar"> |
| <object-create-rule classname="Foobar" /> |
| <set-properties-rule /> |
| </pattern> |
| </pattern> |
| </digester-rules> |
| </source> |
| <p> |
| In the above example, an <code>ObjectCreateRule</code> and a |
| <code>SetPropertiesRule</code> are associated with the matching pattern |
| "*/foo/bar".</p> |
| <p>The use of pattern elements and the use of the pattern attribute inside rules |
| elements can be freely mixed. The next example has the same effect as the |
| previous example:</p> |
| <source> |
| <digester-rules> |
| <pattern value="*/foo"> |
| <object-create-rule pattern="bar" classname="Foobar" /> |
| <set-properties-rule pattern="bar" /> |
| </pattern> |
| </digester-rules> |
| </source> |
| </subsection> |
| |
| <subsection name="Including rules XML files within other rules XML files"> |
| <p> |
| The <code><include></code> element lets you include one rules file within |
| another. With respect to pattern concatenation, the <code>DigesterLoader</code> |
| behaves as if the include file was 'macro-expanded'. Example:</p> |
| <source> |
| File rules1.xml: |
| |
| <?xml version="1.0"?> |
| <!DOCTYPE digester-rules PUBLIC |
| "-//Apache Commons //DTD digester-rules XML V1.0//EN" |
| "http://commons.apache.org/digester/dtds/digester-rules-3.0.dtd"> |
| <digester-rules> |
| <pattern value="root/foo"> |
| <object-create-rule classname="Foo" /> |
| |
| <include url="classpath:/rules2.xml" /> |
| </pattern> |
| </digester-rules> |
| |
| |
| |
| File rules2.xml: |
| |
| <?xml version="1.0"?> |
| <!DOCTYPE digester-rules PUBLIC |
| "-//Apache Commons //DTD digester-rules XML V1.0//EN" |
| "http://commons.apache.org/digester/dtds/digester-rules-3.0.dtd"> |
| <digester-rules> |
| <pattern value="bar"> |
| <object-create-rule classname="Bar" /> |
| </pattern> |
| </digester-rules> |
| </source> |
| <p>Note that the <i>url</i> attribute accepts any valid <code>URL</code>, plus the the meta <code>classpath</code> URL, |
| that points to a any valid resource present in the ClassPath; the <code>ClassLoader</code> used to load the resources |
| is the same users set to resolve classes during the parse-time.</p> |
| |
| <p> |
| Parsing <code>rule1.xml</code> would result in a <code>Digester</code> initialized with these |
| pattern/rule pairs:</p> |
| <source> |
| root/foo -> ObjectCreateRule(Foo) |
| |
| root/foo/bar -> ObjectCreateRule(Bar) |
| </source> |
| <p>Note that the pattern for the <code>bar</code> rule has been prepended with the <code>root/foo</code> |
| pattern. If <code>rule2.xml</code> was parsed by itself, it would yield a <code>Digester</code> |
| initialized with this pattern/rule:</p> |
| <source> |
| bar -> ObjectCreateRule(Bar) |
| </source> |
| </subsection> |
| |
| <subsection name="Including programmatically-created rules"> |
| <p>Sometimes rules cannot be easily defined via XML. Rule sets that are created |
| programmatically can still be included within a digester-rules XML file. This |
| is done by using an <code><include></code> element with a |
| <code>class</code> attribute, containing the name of a class that implements |
| <code>org.apache.commons.digester3.binder.RulesModule</code>. |
| The pattern concatenation works exactly as if the rules had been included from an XML file, |
| i.e.:</p> |
| <source> |
| File rules3.xml: |
| |
| <?xml version="1.0"?> |
| <!DOCTYPE digester-rules PUBLIC |
| "-//Apache Commons //DTD digester-rules XML V1.0//EN" |
| "http://commons.apache.org/digester/dtds/digester-rules-3.0.dtd"> |
| <digester-rules> |
| <pattern value="root/foo"> |
| <object-create-rule classname="Foo" /> |
| |
| <include class="BarRuleModule" /> |
| </pattern> |
| </digester-rules> |
| </source> |
| <p>BarRuleCreator class definition:</p> |
| <source> |
| public class BarRuleModule |
| extends AbstractRulesModule |
| { |
| |
| @Override |
| public void configure() |
| { |
| forPattern( "bar" ).objectCreate().ofType( Bar.class ); |
| } |
| |
| } |
| </source> |
| <p> |
| Parsing <code>rules3.xml</code> yields the same results as <code>rules1.xml</code> above: |
| </p> |
| <source> |
| root/foo -> ObjectCreateRule(Foo) |
| |
| root/foo/bar -> ObjectCreateRule(Bar) |
| </source> |
| </subsection> |
| |
| <subsection name="Creating a digester from XML"> |
| <p><a href="../apidocs/org/apache/commons/digester3/xmlrules/FromXmlRulesModule.html"> |
| <code>FromXmlRulesModule</code></a> is a <code>RulesModule</code> implementation that |
| initializes its <code>Digester</code> from rules defined in one or more XML files. The |
| path to the XML files are passed in the <code>configure()</code> method, i.e.</p> |
| |
| <source> |
| public class MyRulesModule |
| extends FromXmlRulesModule |
| { |
| |
| @Override |
| protected void loadRules() |
| { |
| loadXMLRules( new URL( "http://www.acme.com/shared/config/digester-rules.xml" ) ); |
| loadXMLRules( new File( "/etc/digester-rules.xml" ) ); |
| } |
| |
| } |
| </source> |
| <p>The <code>MyRulesModule</code> can be reused now by the <code>DigesterLoader</code> |
| to create <code>Digester</code> instances:</p> |
| |
| <source>import static org.apache.commons.digester3.binder.DigesterLoader.newLoader; |
| |
| import org.apache.commons.digester3.Digester; |
| import org.apache.commons.digester3.binder.DigesterLoader; |
| ... |
| DigesterLoader loader = newLoader( new MyRulesModule() ); |
| ... |
| Digester digester= loader.newDigester(); |
| </source> |
| </subsection> |
| </section> |
| </body> |
| </document> |