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