View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.chain.config;
18  
19  
20  import java.net.URL;
21  import org.apache.commons.chain.Catalog;
22  import org.apache.commons.digester.Digester;
23  import org.apache.commons.digester.RuleSet;
24  
25  
26  /**
27   * <p>Class to parse the contents of an XML configuration file (using
28   * Commons Digester) that defines and configures commands and command chains
29   * to be registered in a {@link Catalog}.  Advanced users can configure the
30   * detailed parsing behavior by configuring the properties of an instance
31   * of this class prior to calling the <code>parse()</code> method.  It
32   * is legal to call the <code>parse()</code> method more than once, in order
33   * to parse more than one configuration document.</p>
34   *
35   * @author Craig R. McClanahan
36   * @version $Revision: 482967 $ $Date: 2006-12-06 08:43:48 +0000 (Wed, 06 Dec 2006) $
37   */
38  public class ConfigParser {
39  
40  
41      // ----------------------------------------------------- Instance Variables
42  
43  
44      /**
45       * <p>The <code>Digester</code> to be used for parsing.</p>
46       */
47      private Digester digester = null;
48  
49  
50      /**
51       * <p>The <code>RuleSet</code> to be used for configuring our Digester
52       * parsing rules.</p>
53       */
54      private RuleSet ruleSet = null;
55  
56  
57      /**
58       * <p>Should Digester use the context class loader?
59       */
60      private boolean useContextClassLoader = true;
61  
62  
63      // ------------------------------------------------------------- Properties
64  
65  
66      /**
67       * <p>Return the <code>Digester</code> instance to be used for
68       * parsing, creating one if necessary.</p>
69       * @return A Digester instance.
70       */
71      public Digester getDigester() {
72  
73          if (digester == null) {
74              digester = new Digester();
75              RuleSet ruleSet = getRuleSet();
76              digester.setNamespaceAware(ruleSet.getNamespaceURI() != null);
77              digester.setUseContextClassLoader(getUseContextClassLoader());
78              digester.setValidating(false);
79              digester.addRuleSet(ruleSet);
80          }
81          return (digester);
82  
83      }
84  
85  
86      /**
87       * <p>Return the <code>RuleSet</code> to be used for configuring
88       * our <code>Digester</code> parsing rules, creating one if necessary.</p>
89       * @return The RuleSet for configuring a Digester instance.
90       */
91      public RuleSet getRuleSet() {
92  
93          if (ruleSet == null) {
94              ruleSet = new ConfigRuleSet();
95          }
96          return (ruleSet);
97  
98      }
99  
100 
101     /**
102      * <p>Set the <code>RuleSet</code> to be used for configuring
103      * our <code>Digester</code> parsing rules.</p>
104      *
105      * @param ruleSet The new RuleSet to use
106      */
107     public void setRuleSet(RuleSet ruleSet) {
108 
109         this.digester = null;
110         this.ruleSet = ruleSet;
111 
112     }
113 
114 
115     /**
116      * <p>Return the "use context class loader" flag.  If set to
117      * <code>true</code>, Digester will attempt to instantiate new
118      * command and chain instances from the context class loader.</p>
119      * @return <code>true</code> if Digester should use the context class loader.
120      */
121     public boolean getUseContextClassLoader() {
122 
123         return (this.useContextClassLoader);
124 
125     }
126 
127 
128     /**
129      * <p>Set the "use context class loader" flag.</p>
130      *
131      * @param useContextClassLoader The new flag value
132      */
133     public void setUseContextClassLoader(boolean useContextClassLoader) {
134 
135         this.useContextClassLoader = useContextClassLoader;
136 
137     }
138 
139 
140     // --------------------------------------------------------- Public Methods
141 
142 
143     /**
144      * <p>Parse the XML document at the specified URL, using the configured
145      * <code>RuleSet</code>, registering top level commands into the specified
146      * {@link Catalog}.  Use this method <strong>only</strong> if you have
147      * <strong>NOT</strong> included any <code>factory</code> element in your
148      * configuration resource, and wish to supply the catalog explictly.</p>
149      *
150      * @param catalog {@link Catalog} into which configured chains are
151      *  to be registered
152      * @param url <code>URL</code> of the XML document to be parsed
153      *
154      * @exception Exception if a parsing error occurs
155      *
156      * @deprecated Use parse(URL) on a configuration resource with "factory"
157      *  element(s) embedded
158      */
159     public void parse(Catalog catalog, URL url) throws Exception {
160 
161         // Prepare our Digester instance
162         Digester digester = getDigester();
163         digester.clear();
164         digester.push(catalog);
165 
166         // Parse the configuration document
167         digester.parse(url);
168 
169     }
170 
171 
172     /**
173      * <p>Parse the XML document at the specified URL using the configured
174      * <code>RuleSet</code>, registering catalogs with nested chains and
175      * commands as they are encountered.  Use this method <strong>only</strong>
176      * if you have included one or more <code>factory</code> elements in your
177      * configuration resource.</p>
178      *
179      * @param url <code>URL</code> of the XML document to be parsed
180      *
181      * @exception Exception if a parsing error occurs
182      */
183     public void parse(URL url) throws Exception {
184 
185         // Prepare our Digester instance
186         Digester digester = getDigester();
187         digester.clear();
188 
189         // Parse the configuration document
190         digester.parse(url);
191 
192     }
193 
194 
195 }