    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.5 2008/09/10 09:20:16 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         * @throws XmlReaderException ?
    152         */
    153        protected void startParsing(final Attributes attrs)
    154            throws SAXException, XmlReaderException {
    155            // nothing required
    156        }
    157
    158        /**
    159         * Done parsing.
    160         *
    161         * @throws SAXException if there is a parsing error.
    162         * @throws XmlReaderException if there is a reader error.
    163         */
    164        protected void doneParsing() throws SAXException, XmlReaderException {
    165            // nothing required
    166        }
    167
    168        /**
    169         * Returns the handler for a child element.
    170         *
    171         * @param tagName  the tag name.
    172         * @param atts  the attributes.
    173         *
    174         * @return the handler or null, if the tagname is invalid.
    175         *
    176         * @throws SAXException  if there is a parsing error.
    177         * @throws XmlReaderException if there is a reader error.
    178         */
    179        protected XmlReadHandler getHandlerForChild(final String tagName, final Attributes atts)
    180            throws XmlReaderException, SAXException {
    181            return null;
    182        }
    183
    184        /**
    185         * Returns the tag name.
    186         *
    187         * @return the tag name.
    188         */
    189        public String getTagName() {
    190            return this.tagName;
    191        }
    192
    193        /**
    194         * Returns the root handler for the parsing.
    195         *
    196         * @return the root handler.
    197         */
    198        public RootXmlReadHandler getRootHandler() {
    199            return this.rootHandler;
    200        }
    201
    202    }
    203