View Javadoc

1   package org.apache.commons.digester3;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.xml.sax.Attributes;
23  
24  /**
25   * Concrete implementations of this class implement actions to be taken when a
26   * corresponding nested pattern of XML elements has been matched.
27   * <p>
28   * Writing a custom Rule is considered perfectly normal when using Digester, and
29   * is encouraged whenever the default set of Rule classes don't meet your
30   * requirements; the digester framework can help process xml even when the
31   * built-in rules aren't quite what is needed. Creating a custom Rule is just as
32   * easy as subclassing javax.servlet.http.HttpServlet for webapps, or
33   * javax.swing.Action for GUI applications.
34   * <p>
35   * If a rule wishes to manipulate a digester stack (the default object stack, a
36   * named stack, or the parameter stack) then it should only ever push objects in
37   * the rule's begin method and always pop exactly the same number of objects off
38   * the stack during the rule's end method. Of course peeking at the objects on
39   * the stacks can be done from anywhere.
40   * <p>
41   * Rule objects should limit their state data to the digester object stack and
42   * named stacks. Storing state in instance fields (other than digester) during
43   * the parsing process will cause problems if invoked in a "nested" manner; this
44   * can happen if the same instance is added to digester multiple times or if a
45   * wildcard pattern is used which can match both an element and a child of the
46   * same element.
47   * <p>
48   * Rule objects are not thread-safe when each thread creates a new digester, as
49   * is commonly the case. In a multithreaded context you should create new Rule
50   * instances for every digester or synchronize read/write access to the digester
51   * within the Rule.
52   */public abstract class Rule
53  {
54  
55      // ----------------------------------------------------- Instance Variables
56  
57      /**
58       * The Digester with which this Rule is associated.
59       */
60      private Digester digester = null;
61  
62      /**
63       * The namespace URI for which this Rule is relevant, if any.
64       */
65      private String namespaceURI = null;
66  
67      // ------------------------------------------------------------- Properties
68  
69      /**
70       * Return the Digester with which this Rule is associated.
71       *
72       * @return the Digester with which this Rule is associated
73       */
74      public Digester getDigester()
75      {
76          return ( this.digester );
77      }
78  
79      /**
80       * Set the <code>Digester</code> with which this <code>Rule</code> is associated.
81       *
82       * @param digester the <code>Digester</code> with which this <code>Rule</code> is associated
83       */
84      public void setDigester( Digester digester )
85      {
86          this.digester = digester;
87      }
88  
89      /**
90       * Return the namespace URI for which this Rule is relevant, if any.
91       *
92       * @return the namespace URI for which this Rule is relevant, if any
93       */
94      public String getNamespaceURI()
95      {
96          return ( this.namespaceURI );
97      }
98  
99      /**
100      * Set the namespace URI for which this Rule is relevant, if any.
101      *
102      * @param namespaceURI Namespace URI for which this Rule is relevant, or <code>null</code> to match independent of
103      *            namespace.
104      */
105     public void setNamespaceURI( String namespaceURI )
106     {
107         this.namespaceURI = namespaceURI;
108     }
109 
110     // --------------------------------------------------------- Public Methods
111 
112     /**
113      * This method is called when the beginning of a matching XML element is encountered.
114      *
115      * @param namespace the namespace URI of the matching element, or an empty string if the parser is not namespace
116      *            aware or the element has no namespace
117      * @param name the local name if the parser is namespace aware, or just the element name otherwise
118      * @param attributes The attribute list of this element
119      * @throws Exception if any error occurs
120      * @since Digester 1.4
121      */
122     public void begin( String namespace, String name, Attributes attributes )
123         throws Exception
124     {
125         // The default implementation does nothing
126     }
127 
128     /**
129      * This method is called when the body of a matching XML element is encountered. If the element has no body, this
130      * method is called with an empty string as the body text.
131      *
132      * @param namespace the namespace URI of the matching element, or an empty string if the parser is not namespace
133      *            aware or the element has no namespace
134      * @param name the local name if the parser is namespace aware, or just the element name otherwise
135      * @param text The text of the body of this element
136      * @throws Exception if any error occurs
137      * @since Digester 1.4
138      */
139     public void body( String namespace, String name, String text )
140         throws Exception
141     {
142         // The default implementation does nothing
143     }
144 
145     /**
146      * This method is called when the end of a matching XML element is encountered.
147      *
148      * @param namespace the namespace URI of the matching element, or an empty string if the parser is not namespace
149      *            aware or the element has no namespace
150      * @param name the local name if the parser is namespace aware, or just the element name otherwise
151      * @throws Exception if any error occurs
152      * @since Digester 1.4
153      */
154     public void end( String namespace, String name )
155         throws Exception
156     {
157         // The default implementation does nothing
158     }
159 
160     /**
161      * This method is called after all parsing methods have been called, to allow Rules to remove temporary data.
162      *
163      * @throws Exception if any error occurs
164      */
165     public void finish()
166         throws Exception
167     {
168         // The default implementation does nothing
169     }
170 
171 }