001package org.apache.commons.digester3;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.xml.sax.Attributes;
023
024/**
025 * Concrete implementations of this class implement actions to be taken when a
026 * corresponding nested pattern of XML elements has been matched.
027 * <p>
028 * Writing a custom Rule is considered perfectly normal when using Digester, and
029 * is encouraged whenever the default set of Rule classes don't meet your
030 * requirements; the digester framework can help process xml even when the
031 * built-in rules aren't quite what is needed. Creating a custom Rule is just as
032 * easy as subclassing javax.servlet.http.HttpServlet for webapps, or
033 * javax.swing.Action for GUI applications.
034 * <p>
035 * If a rule wishes to manipulate a digester stack (the default object stack, a
036 * named stack, or the parameter stack) then it should only ever push objects in
037 * the rule's begin method and always pop exactly the same number of objects off
038 * the stack during the rule's end method. Of course peeking at the objects on
039 * the stacks can be done from anywhere.
040 * <p>
041 * Rule objects should limit their state data to the digester object stack and
042 * named stacks. Storing state in instance fields (other than digester) during
043 * the parsing process will cause problems if invoked in a "nested" manner; this
044 * can happen if the same instance is added to digester multiple times or if a
045 * wildcard pattern is used which can match both an element and a child of the
046 * same element.
047 * <p>
048 * Rule objects are not thread-safe when each thread creates a new digester, as
049 * is commonly the case. In a multithreaded context you should create new Rule
050 * instances for every digester or synchronize read/write access to the digester
051 * within the Rule.
052 */public abstract class Rule
053{
054
055    // ----------------------------------------------------- Instance Variables
056
057    /**
058     * The Digester with which this Rule is associated.
059     */
060    private Digester digester = null;
061
062    /**
063     * The namespace URI for which this Rule is relevant, if any.
064     */
065    private String namespaceURI = null;
066
067    // ------------------------------------------------------------- Properties
068
069    /**
070     * Return the Digester with which this Rule is associated.
071     *
072     * @return the Digester with which this Rule is associated
073     */
074    public Digester getDigester()
075    {
076        return ( this.digester );
077    }
078
079    /**
080     * Set the <code>Digester</code> with which this <code>Rule</code> is associated.
081     *
082     * @param digester the <code>Digester</code> with which this <code>Rule</code> is associated
083     */
084    public void setDigester( Digester digester )
085    {
086        this.digester = digester;
087    }
088
089    /**
090     * Return the namespace URI for which this Rule is relevant, if any.
091     *
092     * @return the namespace URI for which this Rule is relevant, if any
093     */
094    public String getNamespaceURI()
095    {
096        return ( this.namespaceURI );
097    }
098
099    /**
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}