001package org.apache.commons.digester3;002003/*004 * Licensed to the Apache Software Foundation (ASF) under one005 * or more contributor license agreements. See the NOTICE file006 * distributed with this work for additional information007 * regarding copyright ownership. The ASF licenses this file008 * to you under the Apache License, Version 2.0 (the009 * "License"); you may not use this file except in compliance010 * with the License. You may obtain a copy of the License at011 *012 * http://www.apache.org/licenses/LICENSE-2.0013 *014 * Unless required by applicable law or agreed to in writing,015 * software distributed under the License is distributed on an016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY017 * KIND, either express or implied. See the License for the018 * specific language governing permissions and limitations019 * under the License.020 */021022import org.xml.sax.Attributes;023024/**025 * Concrete implementations of this class implement actions to be taken when a026 * corresponding nested pattern of XML elements has been matched.027 * <p>028 * Writing a custom Rule is considered perfectly normal when using Digester, and029 * is encouraged whenever the default set of Rule classes don't meet your030 * requirements; the digester framework can help process xml even when the031 * built-in rules aren't quite what is needed. Creating a custom Rule is just as032 * easy as subclassing javax.servlet.http.HttpServlet for webapps, or033 * javax.swing.Action for GUI applications.034 * <p>035 * If a rule wishes to manipulate a digester stack (the default object stack, a036 * named stack, or the parameter stack) then it should only ever push objects in037 * the rule's begin method and always pop exactly the same number of objects off038 * the stack during the rule's end method. Of course peeking at the objects on039 * the stacks can be done from anywhere.040 * <p>041 * Rule objects should limit their state data to the digester object stack and042 * named stacks. Storing state in instance fields (other than digester) during043 * the parsing process will cause problems if invoked in a "nested" manner; this044 * can happen if the same instance is added to digester multiple times or if a045 * wildcard pattern is used which can match both an element and a child of the046 * same element.047 * <p>048 * Rule objects are not thread-safe when each thread creates a new digester, as049 * is commonly the case. In a multithreaded context you should create new Rule050 * instances for every digester or synchronize read/write access to the digester051 * within the Rule.052 */public abstract class Rule053{054055 // ----------------------------------------------------- Instance Variables056057 /**058 * The Digester with which this Rule is associated.059 */060 private Digester digester = null;061062 /**063 * The namespace URI for which this Rule is relevant, if any.064 */065 private String namespaceURI = null;066067 // ------------------------------------------------------------- Properties068069 /**070 * Return the Digester with which this Rule is associated.071 *072 * @return the Digester with which this Rule is associated073 */074 public Digester getDigester()075 {076 return ( this.digester );077 }078079 /**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 associated083 */084 public void setDigester( Digester digester )085 {086 this.digester = digester;087 }088089 /**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 any093 */094 public String getNamespaceURI()095 {096 return ( this.namespaceURI );097 }098099 /**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 of103 * namespace.104 */105 public void setNamespaceURI( String namespaceURI )106 {107 this.namespaceURI = namespaceURI;108 }109110 // --------------------------------------------------------- Public Methods111112 /**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 namespace116 * aware or the element has no namespace117 * @param name the local name if the parser is namespace aware, or just the element name otherwise118 * @param attributes The attribute list of this element119 * @throws Exception if any error occurs120 * @since Digester 1.4121 */122 public void begin( String namespace, String name, Attributes attributes )123 throws Exception124 {125 // The default implementation does nothing126 }127128 /**129 * This method is called when the body of a matching XML element is encountered. If the element has no body, this130 * 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 namespace133 * aware or the element has no namespace134 * @param name the local name if the parser is namespace aware, or just the element name otherwise135 * @param text The text of the body of this element136 * @throws Exception if any error occurs137 * @since Digester 1.4138 */139 public void body( String namespace, String name, String text )140 throws Exception141 {142 // The default implementation does nothing143 }144145 /**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 namespace149 * aware or the element has no namespace150 * @param name the local name if the parser is namespace aware, or just the element name otherwise151 * @throws Exception if any error occurs152 * @since Digester 1.4153 */154 public void end( String namespace, String name )155 throws Exception156 {157 // The default implementation does nothing158 }159160 /**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 occurs164 */165 public void finish()166 throws Exception167 {168 // The default implementation does nothing169 }170171}