1. /* $Id: FromXmlRuleSet.java,v 1.15 2004/05/10 06:30:08 skitching Exp $
  2. *
  3. * Copyright 2001-2004 The Apache Software Foundation.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * 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.digester.xmlrules;
  18. import java.net.URL;
  19. import org.apache.commons.digester.Digester;
  20. import org.apache.commons.digester.RuleSetBase;
  21. import org.xml.sax.InputSource;
  22. /**
  23. * A Digester rule set where the rules come from an XML file.
  24. *
  25. * @since 1.2
  26. */
  27. public class FromXmlRuleSet extends RuleSetBase {
  28. public static final String DIGESTER_DTD_PATH = "org/apache/commons/digester/xmlrules/digester-rules.dtd";
  29. /**
  30. * The file containing the Digester rules, in XML.
  31. */
  32. private XMLRulesLoader rulesLoader;
  33. /**
  34. * The rule set for parsing the Digester rules
  35. */
  36. private DigesterRuleParser parser;
  37. /**
  38. * The digester for loading the rules xml.
  39. */
  40. private Digester rulesDigester;
  41. /**
  42. * Constructs a FromXmlRuleSet using the default DigesterRuleParser and
  43. * rulesDigester.
  44. * @param rulesXml the path to the XML document defining the Digester rules
  45. */
  46. public FromXmlRuleSet(URL rulesXml) {
  47. this(rulesXml, new DigesterRuleParser(), new Digester());
  48. }
  49. /**
  50. * Constructs a FromXmlRuleSet using the default DigesterRuleParser and
  51. * a ruleDigester for loading the rules xml.
  52. * @param rulesXml the path to the XML document defining the Digester rules
  53. * @param rulesDigester the digester to read the rules xml.
  54. */
  55. public FromXmlRuleSet(URL rulesXml, Digester rulesDigester) {
  56. this(rulesXml, new DigesterRuleParser(), rulesDigester);
  57. }
  58. /**
  59. * @param rulesXml the path to the XML document defining the Digester rules
  60. * @param parser an instance of DigesterRuleParser, for parsing the rules from XML
  61. */
  62. public FromXmlRuleSet(URL rulesXml, DigesterRuleParser parser) {
  63. this(rulesXml, parser, new Digester());
  64. }
  65. /**
  66. * @param rulesXml the path to the XML document defining the Digester rules
  67. * @param parser an instance of DigesterRuleParser, for parsing the rules from XML
  68. * @param rulesDigester the digester used to load the Xml rules.
  69. */
  70. public FromXmlRuleSet(URL rulesXml, DigesterRuleParser parser, Digester rulesDigester) {
  71. init(new URLXMLRulesLoader(rulesXml), parser, rulesDigester);
  72. }
  73. /**
  74. * Constructs a FromXmlRuleSet using the default DigesterRuleParser and
  75. * rulesDigester.
  76. * @param inputSource load the xml rules from this InputSource
  77. */
  78. public FromXmlRuleSet(InputSource inputSource) {
  79. this(inputSource, new DigesterRuleParser(), new Digester());
  80. }
  81. /**
  82. * Constructs a FromXmlRuleSet using the default DigesterRuleParser and
  83. * a ruleDigester for loading the rules xml.
  84. * @param inputSource load the xml rules from this InputSource
  85. * @param rulesDigester the digester to read the rules xml.
  86. */
  87. public FromXmlRuleSet(InputSource inputSource, Digester rulesDigester) {
  88. this(inputSource, new DigesterRuleParser(), rulesDigester);
  89. }
  90. /**
  91. * @param inputSource load the xml rules from this InputSource
  92. * @param parser an instance of DigesterRuleParser, for parsing the rules from XML
  93. */
  94. public FromXmlRuleSet(InputSource inputSource, DigesterRuleParser parser) {
  95. this(inputSource, parser, new Digester());
  96. }
  97. /**
  98. * @param inputSource load the xml rules from this InputSource
  99. * @param parser an instance of DigesterRuleParser, for parsing the rules from XML
  100. * @param rulesDigester the digester used to load the Xml rules.
  101. */
  102. public FromXmlRuleSet(InputSource inputSource, DigesterRuleParser parser, Digester rulesDigester) {
  103. init(new InputSourceXMLRulesLoader(inputSource), parser, rulesDigester);
  104. }
  105. /**
  106. * Base constructor
  107. */
  108. private void init(XMLRulesLoader rulesLoader, DigesterRuleParser parser, Digester rulesDigester) {
  109. this.rulesLoader = rulesLoader;
  110. this.parser = parser;
  111. this.rulesDigester = rulesDigester;
  112. }
  113. /**
  114. * Adds to the digester the set of Rule instances defined in the
  115. * XML file for this rule set.
  116. * @see org.apache.commons.digester.RuleSetBase
  117. */
  118. public void addRuleInstances(org.apache.commons.digester.Digester digester) throws XmlLoadException {
  119. addRuleInstances(digester, null);
  120. }
  121. /**
  122. * Adds to the digester the set of Rule instances defined in the
  123. * XML file for this rule set.
  124. * <p>
  125. * Note that this method doesn't have a matching one on the DigesterLoader
  126. * class, because it is not expected to be widely used, and DigesterLoader's
  127. * load method is already heavily overloaded.
  128. *
  129. * @param digester is the digester that rules will be added to.
  130. * @param basePath is a path that will be prefixed to every
  131. * pattern string defined in the xmlrules input file.
  132. *
  133. * @see org.apache.commons.digester.RuleSetBase
  134. * @since 1.6
  135. */
  136. public void addRuleInstances(
  137. org.apache.commons.digester.Digester digester,
  138. String basePath)
  139. throws XmlLoadException {
  140. URL dtdURL = getClass().getClassLoader().getResource(DIGESTER_DTD_PATH);
  141. if (dtdURL == null) {
  142. throw new XmlLoadException("Cannot find resource \"" +
  143. DIGESTER_DTD_PATH + "\"");
  144. }
  145. parser.setDigesterRulesDTD(dtdURL.toString());
  146. parser.setTarget(digester);
  147. parser.setBasePath(basePath);
  148. rulesDigester.addRuleSet(parser);
  149. rulesDigester.push(parser);
  150. rulesLoader.loadRules();
  151. }
  152. /**
  153. * Worker class encapsulates loading mechanisms.
  154. * Private until some reason is found to make it public.
  155. */
  156. private abstract static class XMLRulesLoader {
  157. /** Load rules now */
  158. public abstract void loadRules() throws XmlLoadException;
  159. }
  160. /** Loads XMLRules from an URL */
  161. private class URLXMLRulesLoader extends XMLRulesLoader {
  162. private URL url;
  163. public URLXMLRulesLoader(URL url) {
  164. this.url = url;
  165. }
  166. public void loadRules() throws XmlLoadException {
  167. try {
  168. rulesDigester.parse(url.openStream());
  169. } catch (Exception ex) {
  170. throw new XmlLoadException(ex);
  171. }
  172. }
  173. }
  174. /** Loads XMLRules from an InputSource */
  175. private class InputSourceXMLRulesLoader extends XMLRulesLoader {
  176. private InputSource inputSource;
  177. public InputSourceXMLRulesLoader(InputSource inputSource) {
  178. this.inputSource = inputSource;
  179. }
  180. public void loadRules() throws XmlLoadException {
  181. try {
  182. rulesDigester.parse(inputSource);
  183. } catch (Exception ex) {
  184. throw new XmlLoadException(ex);
  185. }
  186. }
  187. }
  188. }