1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. 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.chain.config; 18 19 20 import java.net.URL; 21 import org.apache.commons.chain.Catalog; 22 import org.apache.commons.digester.Digester; 23 import org.apache.commons.digester.RuleSet; 24 25 26 /** 27 * <p>Class to parse the contents of an XML configuration file (using 28 * Commons Digester) that defines and configures commands and command chains 29 * to be registered in a {@link Catalog}. Advanced users can configure the 30 * detailed parsing behavior by configuring the properties of an instance 31 * of this class prior to calling the <code>parse()</code> method. It 32 * is legal to call the <code>parse()</code> method more than once, in order 33 * to parse more than one configuration document.</p> 34 * 35 * @author Craig R. McClanahan 36 * @version $Revision: 482967 $ $Date: 2006-12-06 08:43:48 +0000 (Wed, 06 Dec 2006) $ 37 */ 38 public class ConfigParser { 39 40 41 // ----------------------------------------------------- Instance Variables 42 43 44 /** 45 * <p>The <code>Digester</code> to be used for parsing.</p> 46 */ 47 private Digester digester = null; 48 49 50 /** 51 * <p>The <code>RuleSet</code> to be used for configuring our Digester 52 * parsing rules.</p> 53 */ 54 private RuleSet ruleSet = null; 55 56 57 /** 58 * <p>Should Digester use the context class loader? 59 */ 60 private boolean useContextClassLoader = true; 61 62 63 // ------------------------------------------------------------- Properties 64 65 66 /** 67 * <p>Return the <code>Digester</code> instance to be used for 68 * parsing, creating one if necessary.</p> 69 * @return A Digester instance. 70 */ 71 public Digester getDigester() { 72 73 if (digester == null) { 74 digester = new Digester(); 75 RuleSet ruleSet = getRuleSet(); 76 digester.setNamespaceAware(ruleSet.getNamespaceURI() != null); 77 digester.setUseContextClassLoader(getUseContextClassLoader()); 78 digester.setValidating(false); 79 digester.addRuleSet(ruleSet); 80 } 81 return (digester); 82 83 } 84 85 86 /** 87 * <p>Return the <code>RuleSet</code> to be used for configuring 88 * our <code>Digester</code> parsing rules, creating one if necessary.</p> 89 * @return The RuleSet for configuring a Digester instance. 90 */ 91 public RuleSet getRuleSet() { 92 93 if (ruleSet == null) { 94 ruleSet = new ConfigRuleSet(); 95 } 96 return (ruleSet); 97 98 } 99 100 101 /** 102 * <p>Set the <code>RuleSet</code> to be used for configuring 103 * our <code>Digester</code> parsing rules.</p> 104 * 105 * @param ruleSet The new RuleSet to use 106 */ 107 public void setRuleSet(RuleSet ruleSet) { 108 109 this.digester = null; 110 this.ruleSet = ruleSet; 111 112 } 113 114 115 /** 116 * <p>Return the "use context class loader" flag. If set to 117 * <code>true</code>, Digester will attempt to instantiate new 118 * command and chain instances from the context class loader.</p> 119 * @return <code>true</code> if Digester should use the context class loader. 120 */ 121 public boolean getUseContextClassLoader() { 122 123 return (this.useContextClassLoader); 124 125 } 126 127 128 /** 129 * <p>Set the "use context class loader" flag.</p> 130 * 131 * @param useContextClassLoader The new flag value 132 */ 133 public void setUseContextClassLoader(boolean useContextClassLoader) { 134 135 this.useContextClassLoader = useContextClassLoader; 136 137 } 138 139 140 // --------------------------------------------------------- Public Methods 141 142 143 /** 144 * <p>Parse the XML document at the specified URL, using the configured 145 * <code>RuleSet</code>, registering top level commands into the specified 146 * {@link Catalog}. Use this method <strong>only</strong> if you have 147 * <strong>NOT</strong> included any <code>factory</code> element in your 148 * configuration resource, and wish to supply the catalog explictly.</p> 149 * 150 * @param catalog {@link Catalog} into which configured chains are 151 * to be registered 152 * @param url <code>URL</code> of the XML document to be parsed 153 * 154 * @exception Exception if a parsing error occurs 155 * 156 * @deprecated Use parse(URL) on a configuration resource with "factory" 157 * element(s) embedded 158 */ 159 public void parse(Catalog catalog, URL url) throws Exception { 160 161 // Prepare our Digester instance 162 Digester digester = getDigester(); 163 digester.clear(); 164 digester.push(catalog); 165 166 // Parse the configuration document 167 digester.parse(url); 168 169 } 170 171 172 /** 173 * <p>Parse the XML document at the specified URL using the configured 174 * <code>RuleSet</code>, registering catalogs with nested chains and 175 * commands as they are encountered. Use this method <strong>only</strong> 176 * if you have included one or more <code>factory</code> elements in your 177 * configuration resource.</p> 178 * 179 * @param url <code>URL</code> of the XML document to be parsed 180 * 181 * @exception Exception if a parsing error occurs 182 */ 183 public void parse(URL url) throws Exception { 184 185 // Prepare our Digester instance 186 Digester digester = getDigester(); 187 digester.clear(); 188 189 // Parse the configuration document 190 digester.parse(url); 191 192 } 193 194 195 }