001 /* $Id: FromXmlRuleSet.java 471661 2006-11-06 08:09:25Z skitching $ 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 public void addRuleInstances(org.apache.commons.digester.Digester digester) throws XmlLoadException { 141 addRuleInstances(digester, null); 142 } 143 144 /** 145 * Adds to the digester the set of Rule instances defined in the 146 * XML file for this rule set. 147 * <p> 148 * Note that this method doesn't have a matching one on the DigesterLoader 149 * class, because it is not expected to be widely used, and DigesterLoader's 150 * load method is already heavily overloaded. 151 * 152 * @param digester is the digester that rules will be added to. 153 * @param basePath is a path that will be prefixed to every 154 * pattern string defined in the xmlrules input file. 155 * 156 * @see org.apache.commons.digester.RuleSetBase 157 * @since 1.6 158 */ 159 public void addRuleInstances( 160 org.apache.commons.digester.Digester digester, 161 String basePath) 162 throws XmlLoadException { 163 164 URL dtdURL = getClass().getClassLoader().getResource(DIGESTER_DTD_PATH); 165 if (dtdURL == null) { 166 throw new XmlLoadException("Cannot find resource \"" + 167 DIGESTER_DTD_PATH + "\""); 168 } 169 parser.setDigesterRulesDTD(dtdURL.toString()); 170 parser.setTarget(digester); 171 parser.setBasePath(basePath); 172 173 rulesDigester.addRuleSet(parser); 174 rulesDigester.push(parser); 175 176 rulesLoader.loadRules(); 177 } 178 179 /** 180 * Worker class encapsulates loading mechanisms. 181 * Private until some reason is found to make it public. 182 */ 183 private abstract static class XMLRulesLoader { 184 /** Load rules now */ 185 public abstract void loadRules() throws XmlLoadException; 186 } 187 188 /** Loads XMLRules from an URL */ 189 private class URLXMLRulesLoader extends XMLRulesLoader { 190 private URL url; 191 public URLXMLRulesLoader(URL url) { 192 this.url = url; 193 } 194 195 public void loadRules() throws XmlLoadException { 196 try { 197 rulesDigester.parse(url.openStream()); 198 } catch (Exception ex) { 199 throw new XmlLoadException(ex); 200 } 201 } 202 } 203 204 /** Loads XMLRules from an InputSource */ 205 private class InputSourceXMLRulesLoader extends XMLRulesLoader { 206 private InputSource inputSource; 207 public InputSourceXMLRulesLoader(InputSource inputSource) { 208 this.inputSource = inputSource; 209 } 210 211 public void loadRules() throws XmlLoadException { 212 try { 213 rulesDigester.parse(inputSource); 214 } catch (Exception ex) { 215 throw new XmlLoadException(ex); 216 } 217 } 218 } 219 } 220