001/* ======================================================
002 * JFreeChart : a chart library for the Java(tm) platform
003 * ======================================================
004 *
005 * (C) Copyright 2000-present, by David Gilbert and Contributors.
006 *
007 * Project Info:  https://www.jfree.org/jfreechart/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 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 
025 * Other names may be trademarks of their respective owners.]
026 *
027 * ------------------
028 * DatasetReader.java
029 * ------------------
030 * (C) Copyright 2002-present, by David Gilbert.
031 *
032 * Original Author:  David Gilbert;
033 * Contributor(s):   -;
034 *
035 */
036
037package org.jfree.data.xml;
038
039import java.io.File;
040import java.io.FileInputStream;
041import java.io.IOException;
042import java.io.InputStream;
043
044import javax.xml.XMLConstants;
045import javax.xml.parsers.ParserConfigurationException;
046import javax.xml.parsers.SAXParser;
047import javax.xml.parsers.SAXParserFactory;
048
049import org.jfree.chart.util.Args;
050import org.jfree.data.category.CategoryDataset;
051import org.jfree.data.general.PieDataset;
052import org.xml.sax.SAXException;
053import org.xml.sax.SAXNotRecognizedException;
054import org.xml.sax.SAXNotSupportedException;
055
056/**
057 * A utility class for reading datasets from XML.
058 */
059public class DatasetReader {
060
061    /** A factory for creating new parser instances. */
062    static SAXParserFactory factory;
063
064    private DatasetReader() {
065        // no requirement to instantiate
066    }
067
068    /**
069     * Returns the {@link SAXParserFactory} used to create {@link SAXParser} instances.
070     * 
071     * @return The {@link SAXParserFactory} (never {@code null}).
072     */
073    public static SAXParserFactory getSAXParserFactory() {
074        if (factory == null) {
075            SAXParserFactory f = SAXParserFactory.newInstance();
076            try {
077                f.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
078                f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
079                f.setFeature("http://xml.org/sax/features/external-general-entities", false);
080                factory = f;
081            } catch (SAXNotRecognizedException | SAXNotSupportedException | ParserConfigurationException e) {
082                throw new RuntimeException(e);
083            }
084        }
085        return factory;
086    }
087    
088    /**
089     * Sets the SAXParserFactory that will be used to create SAXParser instances.  
090     * You would only call this method if you wish to configure a new factory because
091     * the default does not meet requirements.
092     * 
093     * @param f  the new factory ({@code null} not permitted).
094     */
095    public static void setSAXParserFactory(SAXParserFactory f) {
096        Args.nullNotPermitted(f, "f");
097        factory = f;
098    }
099
100    /**
101     * Reads a {@link PieDataset} from an XML file.
102     *
103     * @param file  the file ({@code null} not permitted).
104     *
105     * @return A dataset.
106     *
107     * @throws IOException if there is a problem reading the file.
108     */
109    public static PieDataset readPieDatasetFromXML(File file)
110        throws IOException {
111        InputStream in = new FileInputStream(file);
112        return readPieDatasetFromXML(in);
113    }
114
115    /**
116     * Reads a {@link PieDataset} from a stream.
117     *
118     * @param in  the input stream.
119     *
120     * @return A dataset.
121     *
122     * @throws IOException if there is an I/O error.
123     */
124    public static PieDataset readPieDatasetFromXML(InputStream in)
125            throws IOException {
126        PieDataset result = null;
127        try {
128            SAXParser parser = getSAXParserFactory().newSAXParser();
129            PieDatasetHandler handler = new PieDatasetHandler();
130            parser.parse(in, handler);
131            result = handler.getDataset();
132        }
133        catch (SAXException | ParserConfigurationException e) {
134            throw new RuntimeException(e);
135        }
136        return result;
137    }
138
139    /**
140     * Reads a {@link CategoryDataset} from a file.
141     *
142     * @param file  the file.
143     *
144     * @return A dataset.
145     *
146     * @throws IOException if there is a problem reading the file.
147     */
148    public static CategoryDataset readCategoryDatasetFromXML(File file)
149            throws IOException {
150        InputStream in = new FileInputStream(file);
151        return readCategoryDatasetFromXML(in);
152    }
153
154    /**
155     * Reads a {@link CategoryDataset} from a stream.
156     *
157     * @param in  the stream.
158     *
159     * @return A dataset.
160     *
161     * @throws IOException if there is a problem reading the file.
162     */
163    public static CategoryDataset readCategoryDatasetFromXML(InputStream in)
164            throws IOException {
165        CategoryDataset result = null;
166        try {
167            SAXParser parser = getSAXParserFactory().newSAXParser();
168            CategoryDatasetHandler handler = new CategoryDatasetHandler();
169            parser.parse(in, handler);
170            result = handler.getDataset();
171        }
172        catch (SAXException | ParserConfigurationException e) {
173            throw new RuntimeException(e);
174        }
175        return result;
176    }
177
178}