001 /* $Id: FromXmlRuleSet.java 992060 2010-09-02 19:09:47Z simonetripodi $
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements. See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019
020 package org.apache.commons.digester.xmlrules;
021
022
023 import java.net.URL;
024
025 import org.apache.commons.digester.Digester;
026 import org.apache.commons.digester.RuleSetBase;
027
028 import org.xml.sax.InputSource;
029
030 /**
031 * A Digester rule set where the rules come from an XML file.
032 *
033 * @since 1.2
034 */
035 public class FromXmlRuleSet extends RuleSetBase {
036
037 public static final String DIGESTER_DTD_PATH = "org/apache/commons/digester/xmlrules/digester-rules.dtd";
038
039 /**
040 * The file containing the Digester rules, in XML.
041 */
042 private XMLRulesLoader rulesLoader;
043
044 /**
045 * The rule set for parsing the Digester rules
046 */
047 private DigesterRuleParser parser;
048
049 /**
050 * The digester for loading the rules xml.
051 */
052 private Digester rulesDigester;
053
054 /**
055 * Constructs a FromXmlRuleSet using the default DigesterRuleParser and
056 * rulesDigester.
057 * @param rulesXml the path to the XML document defining the Digester rules
058 */
059 public FromXmlRuleSet(URL rulesXml) {
060 this(rulesXml, new DigesterRuleParser(), new Digester());
061 }
062
063 /**
064 * Constructs a FromXmlRuleSet using the default DigesterRuleParser and
065 * a ruleDigester for loading the rules xml.
066 * @param rulesXml the path to the XML document defining the Digester rules
067 * @param rulesDigester the digester to read the rules xml.
068 */
069 public FromXmlRuleSet(URL rulesXml, Digester rulesDigester) {
070 this(rulesXml, new DigesterRuleParser(), rulesDigester);
071 }
072
073 /**
074 * @param rulesXml the path to the XML document defining the Digester rules
075 * @param parser an instance of DigesterRuleParser, for parsing the rules from XML
076 */
077 public FromXmlRuleSet(URL rulesXml, DigesterRuleParser parser) {
078 this(rulesXml, parser, new Digester());
079 }
080
081 /**
082 * @param rulesXml the path to the XML document defining the Digester rules
083 * @param parser an instance of DigesterRuleParser, for parsing the rules from XML
084 * @param rulesDigester the digester used to load the Xml rules.
085 */
086 public FromXmlRuleSet(URL rulesXml, DigesterRuleParser parser, Digester rulesDigester) {
087 init(new URLXMLRulesLoader(rulesXml), parser, rulesDigester);
088 }
089
090 /**
091 * Constructs a FromXmlRuleSet using the default DigesterRuleParser and
092 * rulesDigester.
093 * @param inputSource load the xml rules from this InputSource
094 */
095 public FromXmlRuleSet(InputSource inputSource) {
096 this(inputSource, new DigesterRuleParser(), new Digester());
097 }
098
099 /**
100 * Constructs a FromXmlRuleSet using the default DigesterRuleParser and
101 * a ruleDigester for loading the rules xml.
102 * @param inputSource load the xml rules from this InputSource
103 * @param rulesDigester the digester to read the rules xml.
104 */
105 public FromXmlRuleSet(InputSource inputSource, Digester rulesDigester) {
106 this(inputSource, new DigesterRuleParser(), rulesDigester);
107 }
108
109 /**
110 * @param inputSource load the xml rules from this InputSource
111 * @param parser an instance of DigesterRuleParser, for parsing the rules from XML
112 */
113 public FromXmlRuleSet(InputSource inputSource, DigesterRuleParser parser) {
114 this(inputSource, parser, new Digester());
115 }
116
117 /**
118 * @param inputSource load the xml rules from this InputSource
119 * @param parser an instance of DigesterRuleParser, for parsing the rules from XML
120 * @param rulesDigester the digester used to load the Xml rules.
121 */
122 public FromXmlRuleSet(InputSource inputSource, DigesterRuleParser parser, Digester rulesDigester) {
123 init(new InputSourceXMLRulesLoader(inputSource), parser, rulesDigester);
124 }
125
126 /**
127 * Base constructor
128 */
129 private void init(XMLRulesLoader rulesLoader, DigesterRuleParser parser, Digester rulesDigester) {
130 this.rulesLoader = rulesLoader;
131 this.parser = parser;
132 this.rulesDigester = rulesDigester;
133 }
134
135 /**
136 * Adds to the digester the set of Rule instances defined in the
137 * XML file for this rule set.
138 * @see org.apache.commons.digester.RuleSetBase
139 */
140 @Override
141 public void addRuleInstances(org.apache.commons.digester.Digester digester) throws XmlLoadException {
142 addRuleInstances(digester, null);
143 }
144
145 /**
146 * Adds to the digester the set of Rule instances defined in the
147 * XML file for this rule set.
148 * <p>
149 * Note that this method doesn't have a matching one on the DigesterLoader
150 * class, because it is not expected to be widely used, and DigesterLoader's
151 * load method is already heavily overloaded.
152 *
153 * @param digester is the digester that rules will be added to.
154 * @param basePath is a path that will be prefixed to every
155 * pattern string defined in the xmlrules input file.
156 *
157 * @see org.apache.commons.digester.RuleSetBase
158 * @since 1.6
159 */
160 public void addRuleInstances(
161 org.apache.commons.digester.Digester digester,
162 String basePath)
163 throws XmlLoadException {
164
165 URL dtdURL = getClass().getClassLoader().getResource(DIGESTER_DTD_PATH);
166 if (dtdURL == null) {
167 throw new XmlLoadException("Cannot find resource \"" +
168 DIGESTER_DTD_PATH + "\"");
169 }
170 parser.setDigesterRulesDTD(dtdURL.toString());
171 parser.setTarget(digester);
172 parser.setBasePath(basePath);
173
174 rulesDigester.addRuleSet(parser);
175 rulesDigester.push(parser);
176
177 rulesLoader.loadRules();
178 }
179
180 /**
181 * Worker class encapsulates loading mechanisms.
182 * Private until some reason is found to make it public.
183 */
184 private abstract static class XMLRulesLoader {
185 /** Load rules now */
186 public abstract void loadRules() throws XmlLoadException;
187 }
188
189 /** Loads XMLRules from an URL */
190 private class URLXMLRulesLoader extends XMLRulesLoader {
191 private URL url;
192 public URLXMLRulesLoader(URL url) {
193 this.url = url;
194 }
195
196 @Override
197 public void loadRules() throws XmlLoadException {
198 try {
199 rulesDigester.parse(url.openStream());
200 } catch (Exception ex) {
201 throw new XmlLoadException(ex);
202 }
203 }
204 }
205
206 /** Loads XMLRules from an InputSource */
207 private class InputSourceXMLRulesLoader extends XMLRulesLoader {
208 private InputSource inputSource;
209 public InputSourceXMLRulesLoader(InputSource inputSource) {
210 this.inputSource = inputSource;
211 }
212
213 @Override
214 public void loadRules() throws XmlLoadException {
215 try {
216 rulesDigester.parse(inputSource);
217 } catch (Exception ex) {
218 throw new XmlLoadException(ex);
219 }
220 }
221 }
222 }
223