-
Notifications
You must be signed in to change notification settings - Fork 55
/
XmlConfigParser.java
168 lines (149 loc) · 6.35 KB
/
XmlConfigParser.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*
* 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.
*/
package org.apache.commons.chain2.config.xml;
import org.apache.commons.chain2.CatalogFactory;
import org.apache.commons.chain2.config.ChainConfigurationException;
import org.apache.commons.chain2.config.ConfigParser;
import org.apache.commons.chain2.impl.CatalogFactoryBase;
import org.apache.commons.digester3.Digester;
import org.apache.commons.digester3.RuleSet;
import java.net.URL;
import java.util.Map;
/**
* <p>Class to parse the contents of an XML configuration file (using
* Commons Digester) that defines and configures commands and command chains
* to be registered in a {@link org.apache.commons.chain2.Catalog}. Advanced users can configure the
* detailed parsing behavior by configuring the properties of an instance
* of this class prior to calling the <code>parse()</code> method. It
* is legal to call the <code>parse()</code> method more than once, in order
* to parse more than one configuration document.</p>
*
* @version $Id: ConfigParser.java 1364104 2012-07-21 14:25:54Z elijah $
*/
public class XmlConfigParser implements ConfigParser {
// ----------------------------------------------------- Instance Variables
/**
* <p>The <code>RuleSet</code> to be used for configuring our Digester
* parsing rules.</p>
*/
private RuleSet ruleSet = new ConfigRuleSet();
/**
* <p>Should Digester use the context class loader?
*/
private boolean useContextClassLoader = true;
// ------------------------------------------------------------- Constructor
public XmlConfigParser() {
}
public XmlConfigParser(String ruleSet, ClassLoader loader) {
if (ruleSet == null) {
throw new IllegalArgumentException("ConfigParser can't be " +
"instantiated with a null ruleSet class name");
}
if (loader == null) {
throw new IllegalArgumentException("ConfigParser can't be " +
"instantiated with a null class loader reference");
}
try {
Class<?> clazz = loader.loadClass(ruleSet);
setRuleSet((RuleSet) clazz.newInstance());
} catch (Exception e) {
throw new RuntimeException("Exception initializing RuleSet '"
+ ruleSet + "' instance: "
+ e.getMessage());
}
}
// ------------------------------------------------------------- Properties
/**
* <p>Return the <code>Digester</code> instance to be used for
* parsing, creating one if necessary.</p>
* @return A Digester instance.
*/
public Digester getDigester() {
Digester digester = new Digester();
RuleSet ruleSet = getRuleSet();
digester.setNamespaceAware(ruleSet.getNamespaceURI() != null);
digester.setUseContextClassLoader(getUseContextClassLoader());
digester.setValidating(false);
digester.addRuleSet(ruleSet);
return digester;
}
/**
* <p>Return the <code>RuleSet</code> to be used for configuring
* our <code>Digester</code> parsing rules, creating one if necessary.</p>
* @return The RuleSet for configuring a Digester instance.
*/
public RuleSet getRuleSet() {
return ruleSet;
}
/**
* <p>Set the <code>RuleSet</code> to be used for configuring
* our <code>Digester</code> parsing rules.</p>
*
* @param ruleSet The new RuleSet to use
*/
public void setRuleSet(RuleSet ruleSet) {
this.ruleSet = ruleSet;
}
/**
* <p>Return the "use context class loader" flag. If set to
* <code>true</code>, Digester will attempt to instantiate new
* command and chain instances from the context class loader.</p>
* @return <code>true</code> if Digester should use the context class loader.
*/
public boolean getUseContextClassLoader() {
return this.useContextClassLoader;
}
/**
* <p>Set the "use context class loader" flag.</p>
*
* @param useContextClassLoader The new flag value
*/
public void setUseContextClassLoader(boolean useContextClassLoader) {
this.useContextClassLoader = useContextClassLoader;
}
// --------------------------------------------------------- Public Methods
/**
* <p>Parse the XML document at the specified URL using the configured
* <code>RuleSet</code>, registering catalogs with nested chains and
* commands as they are encountered. Use this method <strong>only</strong>
* if you have included one or more <code>factory</code> elements in your
* configuration resource.</p>
*
* @param <K> the type of keys maintained by the context associated with this command
* @param <V> the type of mapped values
* @param <C> Type of the context associated with this command
* @param url <code>URL</code> of the XML document to be parsed
* @return a CatalogFactory instance parsed from the given location
* @throws ChainConfigurationException if a parsing error occurs
*/
public <K, V, C extends Map<K, V>> CatalogFactory<K, V, C> parse(URL url) {
// Prepare our Digester instance
Digester digester = getDigester();
digester.clear();
// Parse the configuration document
try {
digester.parse(url);
} catch (Exception e) {
String msg = String.format(
"Error parsing digester configuration at url: %s",
url);
throw new ChainConfigurationException(msg, e);
}
// FIXME get rid of singleton pattern and create a new instance here
return CatalogFactoryBase.getInstance();
}
}