001 /* $Id: Rule.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; 021 022 023 import org.xml.sax.Attributes; 024 025 026 /** 027 * Concrete implementations of this class implement actions to be taken when 028 * a corresponding nested pattern of XML elements has been matched. 029 * <p> 030 * Writing a custom Rule is considered perfectly normal when using Digester, 031 * and is encouraged whenever the default set of Rule classes don't meet your 032 * requirements; the digester framework can help process xml even when the 033 * built-in rules aren't quite what is needed. Creating a custom Rule is 034 * just as easy as subclassing javax.servlet.http.HttpServlet for webapps, 035 * or javax.swing.Action for GUI applications. 036 * <p> 037 * If a rule wishes to manipulate a digester stack (the default object stack, 038 * a named stack, or the parameter stack) then it should only ever push 039 * objects in the rule's begin method and always pop exactly the same 040 * number of objects off the stack during the rule's end method. Of course 041 * peeking at the objects on the stacks can be done from anywhere. 042 * <p> 043 * Rule objects should be stateless, ie they should not update any instance 044 * member during the parsing process. A rule instance that changes state 045 * will encounter problems if invoked in a "nested" manner; this can happen 046 * if the same instance is added to digester multiple times or if a 047 * wildcard pattern is used which can match both an element and a child of the 048 * same element. The digester object stack and named stacks should be used to 049 * store any state that a rule requires, making the rule class safe under all 050 * possible uses. 051 */ 052 053 public abstract class Rule { 054 055 056 // ----------------------------------------------------------- Constructors 057 058 059 /** 060 * Constructor sets the associated Digester. 061 * 062 * @param digester The digester with which this rule is associated 063 * @deprecated The digester instance is now set in the {@link Digester#addRule} method. Use {@link #Rule()} instead. 064 */ 065 @Deprecated 066 public Rule(Digester digester) { 067 068 super(); 069 setDigester(digester); 070 071 } 072 073 /** 074 * <p>Base constructor. 075 * Now the digester will be set when the rule is added.</p> 076 */ 077 public Rule() {} 078 079 080 // ----------------------------------------------------- Instance Variables 081 082 083 /** 084 * The Digester with which this Rule is associated. 085 */ 086 protected Digester digester = null; 087 088 089 /** 090 * The namespace URI for which this Rule is relevant, if any. 091 */ 092 protected String namespaceURI = null; 093 094 095 // ------------------------------------------------------------- Properties 096 097 098 /** 099 * Return the Digester with which this Rule is associated. 100 */ 101 public Digester getDigester() { 102 103 return (this.digester); 104 105 } 106 107 /** 108 * Set the <code>Digester</code> with which this <code>Rule</code> is associated. 109 */ 110 public void setDigester(Digester digester) { 111 112 this.digester = digester; 113 114 } 115 116 /** 117 * Return the namespace URI for which this Rule is relevant, if any. 118 */ 119 public String getNamespaceURI() { 120 121 return (this.namespaceURI); 122 123 } 124 125 126 /** 127 * Set the namespace URI for which this Rule is relevant, if any. 128 * 129 * @param namespaceURI Namespace URI for which this Rule is relevant, 130 * or <code>null</code> to match independent of namespace. 131 */ 132 public void setNamespaceURI(String namespaceURI) { 133 134 this.namespaceURI = namespaceURI; 135 136 } 137 138 139 // --------------------------------------------------------- Public Methods 140 141 142 /** 143 * This method is called when the beginning of a matching XML element 144 * is encountered. 145 * 146 * @param attributes The attribute list of this element 147 * @deprecated Use the {@link #begin(String,String,Attributes) begin} 148 * method with <code>namespace</code> and <code>name</code> 149 * parameters instead. 150 */ 151 @Deprecated 152 public void begin(Attributes attributes) throws Exception { 153 154 // The default implementation does nothing 155 156 } 157 158 159 /** 160 * This method is called when the beginning of a matching XML element 161 * is encountered. The default implementation delegates to the deprecated 162 * method {@link #begin(Attributes) begin} without the 163 * <code>namespace</code> and <code>name</code> parameters, to retain 164 * backwards compatibility. 165 * 166 * @param namespace the namespace URI of the matching element, or an 167 * empty string if the parser is not namespace aware or the element has 168 * no namespace 169 * @param name the local name if the parser is namespace aware, or just 170 * the element name otherwise 171 * @param attributes The attribute list of this element 172 * @since Digester 1.4 173 */ 174 public void begin(String namespace, String name, Attributes attributes) 175 throws Exception { 176 177 begin(attributes); 178 179 } 180 181 182 /** 183 * This method is called when the body of a matching XML element 184 * is encountered. If the element has no body, this method is 185 * called with an empty string as the body text. 186 * 187 * @param text The text of the body of this element 188 * @deprecated Use the {@link #body(String,String,String) body} method 189 * with <code>namespace</code> and <code>name</code> parameters 190 * instead. 191 */ 192 @Deprecated 193 public void body(String text) throws Exception { 194 195 // The default implementation does nothing 196 197 } 198 199 200 /** 201 * This method is called when the body of a matching XML element is 202 * encountered. If the element has no body, this method is 203 * called with an empty string as the body text. 204 * <p> 205 * The default implementation delegates to the deprecated method 206 * {@link #body(String) body} without the <code>namespace</code> and 207 * <code>name</code> parameters, to retain backwards compatibility. 208 * 209 * @param namespace the namespace URI of the matching element, or an 210 * empty string if the parser is not namespace aware or the element has 211 * no namespace 212 * @param name the local name if the parser is namespace aware, or just 213 * the element name otherwise 214 * @param text The text of the body of this element 215 * @since Digester 1.4 216 */ 217 public void body(String namespace, String name, String text) 218 throws Exception { 219 220 body(text); 221 222 } 223 224 225 /** 226 * This method is called when the end of a matching XML element 227 * is encountered. 228 * 229 * @deprecated Use the {@link #end(String,String) end} method with 230 * <code>namespace</code> and <code>name</code> parameters instead. 231 */ 232 @Deprecated 233 public void end() throws Exception { 234 235 // The default implementation does nothing 236 237 } 238 239 240 /** 241 * This method is called when the end of a matching XML element 242 * is encountered. The default implementation delegates to the deprecated 243 * method {@link #end end} without the 244 * <code>namespace</code> and <code>name</code> parameters, to retain 245 * backwards compatibility. 246 * 247 * @param namespace the namespace URI of the matching element, or an 248 * empty string if the parser is not namespace aware or the element has 249 * no namespace 250 * @param name the local name if the parser is namespace aware, or just 251 * the element name otherwise 252 * @since Digester 1.4 253 */ 254 public void end(String namespace, String name) 255 throws Exception { 256 257 end(); 258 259 } 260 261 262 /** 263 * This method is called after all parsing methods have been 264 * called, to allow Rules to remove temporary data. 265 */ 266 public void finish() throws Exception { 267 268 // The default implementation does nothing 269 270 } 271 272 273 }