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