001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.chain.config; 018 019 020 import java.net.URL; 021 import org.apache.commons.chain.Catalog; 022 import org.apache.commons.digester.Digester; 023 import org.apache.commons.digester.RuleSet; 024 025 026 /** 027 * <p>Class to parse the contents of an XML configuration file (using 028 * Commons Digester) that defines and configures commands and command chains 029 * to be registered in a {@link Catalog}. Advanced users can configure the 030 * detailed parsing behavior by configuring the properties of an instance 031 * of this class prior to calling the <code>parse()</code> method. It 032 * is legal to call the <code>parse()</code> method more than once, in order 033 * to parse more than one configuration document.</p> 034 * 035 * @author Craig R. McClanahan 036 * @version $Revision: 482967 $ $Date: 2006-12-06 08:43:48 +0000 (Wed, 06 Dec 2006) $ 037 */ 038 public class ConfigParser { 039 040 041 // ----------------------------------------------------- Instance Variables 042 043 044 /** 045 * <p>The <code>Digester</code> to be used for parsing.</p> 046 */ 047 private Digester digester = null; 048 049 050 /** 051 * <p>The <code>RuleSet</code> to be used for configuring our Digester 052 * parsing rules.</p> 053 */ 054 private RuleSet ruleSet = null; 055 056 057 /** 058 * <p>Should Digester use the context class loader? 059 */ 060 private boolean useContextClassLoader = true; 061 062 063 // ------------------------------------------------------------- Properties 064 065 066 /** 067 * <p>Return the <code>Digester</code> instance to be used for 068 * parsing, creating one if necessary.</p> 069 * @return A Digester instance. 070 */ 071 public Digester getDigester() { 072 073 if (digester == null) { 074 digester = new Digester(); 075 RuleSet ruleSet = getRuleSet(); 076 digester.setNamespaceAware(ruleSet.getNamespaceURI() != null); 077 digester.setUseContextClassLoader(getUseContextClassLoader()); 078 digester.setValidating(false); 079 digester.addRuleSet(ruleSet); 080 } 081 return (digester); 082 083 } 084 085 086 /** 087 * <p>Return the <code>RuleSet</code> to be used for configuring 088 * our <code>Digester</code> parsing rules, creating one if necessary.</p> 089 * @return The RuleSet for configuring a Digester instance. 090 */ 091 public RuleSet getRuleSet() { 092 093 if (ruleSet == null) { 094 ruleSet = new ConfigRuleSet(); 095 } 096 return (ruleSet); 097 098 } 099 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 }