    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 */
    042package org.jfree.xml.parser;
    043
    044import org.xml.sax.Attributes;
    045import org.xml.sax.SAXException;
    046import org.jfree.util.Log;
    047
    048/**
    049 * A base class for implementing an {@link XmlReadHandler}.
    050 */
    051public 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