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