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}