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 }