001    /* ========================================================================
002     * JCommon : a free general purpose class library for the Java(tm) platform
003     * ========================================================================
004     *
005     * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
006     * 
007     * Project Info:  http://www.jfree.org/jcommon/index.html
008     *
009     * This library is free software; you can redistribute it and/or modify it 
010     * under the terms of the GNU Lesser General Public License as published by 
011     * the Free Software Foundation; either version 2.1 of the License, or 
012     * (at your option) any later version.
013     *
014     * This library is distributed in the hope that it will be useful, but 
015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
017     * License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this library; if not, write to the Free Software
021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
022     * USA.  
023     *
024     * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
025     * in the United States and other countries.]
026     * 
027     * ---------------------------
028     * AbstractXmlReadHandler.java
029     * ---------------------------
030     * (C)opyright 2003, 2004, by Thomas Morgner and Contributors.
031     *
032     * Original Author:  Thomas Morgner;
033     * Contributor(s):   David Gilbert (for Object Refinery Limited);
034     *
035     * $Id: AbstractXmlReadHandler.java,v 1.4 2005/10/18 13:32:52 mungady Exp $
036     *
037     * Changes (from 25-Nov-2003)
038     * --------------------------
039     * 25-Nov-2003 : Added Javadocs (DG);
040     *
041     */
042    package org.jfree.xml.parser;
043    
044    import org.xml.sax.Attributes;
045    import org.xml.sax.SAXException;
046    import org.jfree.util.Log;
047    
048    /**
049     * A base class for implementing an {@link XmlReadHandler}.
050     */
051    public abstract class AbstractXmlReadHandler implements XmlReadHandler {
052        /** The root handler. */
053        private RootXmlReadHandler rootHandler;
054    
055        /** The tag name. */
056        private String tagName;
057    
058        /** A flag indicating the first call. */
059        private boolean firstCall = true;
060    
061        /**
062         * Creates a new handler.
063         */
064        public AbstractXmlReadHandler() {
065        }
066    
067        /**
068         * Initialises the handler.
069         * 
070         * @param rootHandler  the root handler.
071         * @param tagName  the tag name.
072         */
073        public void init(final RootXmlReadHandler rootHandler, final String tagName) {
074            if (rootHandler == null) {
075                throw new NullPointerException("Root handler must not be null");
076            }
077            if (tagName == null) {
078                throw new NullPointerException("Tag name must not be null");
079            }
080            this.rootHandler = rootHandler;
081            this.tagName = tagName;
082        }
083    
084        /**
085         * This method is called at the start of an element.
086         *
087         * @param tagName  the tag name.
088         * @param attrs  the attributes.
089         *
090         * @throws SAXException if there is a parsing error.
091         * @throws XmlReaderException if there is a reader error.
092         */
093        public final void startElement(final String tagName, final Attributes attrs)
094            throws XmlReaderException, SAXException {
095            if (this.firstCall) {
096                if (!this.tagName.equals(tagName)) {
097                    throw new SAXException("Expected <" + this.tagName + ">, found <" + tagName + ">");
098                }
099                this.firstCall = false;
100                startParsing(attrs);
101            }
102            else {
103                final XmlReadHandler childHandler = getHandlerForChild(tagName, attrs);
104                if (childHandler == null) {
105                    Log.warn ("Unknown tag <" + tagName + ">");
106                    return;
107                }
108                childHandler.init(getRootHandler(), tagName);
109                this.rootHandler.recurse(childHandler, tagName, attrs);
110            }
111        }
112    
113        /**
114         * This method is called to process the character data between element tags.
115         *
116         * @param ch  the character buffer.
117         * @param start  the start index.
118         * @param length  the length.
119         *
120         * @throws SAXException if there is a parsing error.
121         */
122        public void characters(final char[] ch, final int start, final int length) throws SAXException {
123            // nothing required
124        }
125    
126        /**
127         * This method is called at the end of an element.
128         *
129         * @param tagName  the tag name.
130         *
131         * @throws SAXException if there is a parsing error.
132         */
133        public final void endElement(final String tagName) throws SAXException {
134            if (this.tagName.equals(tagName)) {
135                try {
136                    doneParsing();
137                    this.rootHandler.unwind(tagName);
138                }
139                catch (XmlReaderException xre) {
140                    throw new SAXException(xre);
141                }
142            }
143        }
144    
145        /**
146         * Starts parsing.
147         *
148         * @param attrs  the attributes.
149         *
150         * @throws SAXException if there is a parsing error.
151         */
152        protected void startParsing(final Attributes attrs) throws SAXException, XmlReaderException {
153            // nothing required
154        }
155    
156        /**
157         * Done parsing.
158         *
159         * @throws SAXException if there is a parsing error.
160         * @throws XmlReaderException if there is a reader error.
161         */
162        protected void doneParsing() throws SAXException, XmlReaderException {
163            // nothing required
164        }
165    
166        /**
167         * Returns the handler for a child element.
168         *
169         * @param tagName  the tag name.
170         * @param atts  the attributes.
171         *
172         * @return the handler or null, if the tagname is invalid.
173         *
174         * @throws SAXException  if there is a parsing error.
175         * @throws XmlReaderException if there is a reader error.
176         */
177        protected XmlReadHandler getHandlerForChild(final String tagName, final Attributes atts)
178            throws XmlReaderException, SAXException {
179            return null;
180        }
181    
182        /**
183         * Returns the tag name.
184         *
185         * @return the tag name.
186         */
187        public String getTagName() {
188            return this.tagName;
189        }
190    
191        /**
192         * Returns the root handler for the parsing.
193         *
194         * @return the root handler.
195         */
196        public RootXmlReadHandler getRootHandler() {
197            return this.rootHandler;
198        }
199        
200    }
201