001/* ===========================================================
002 * JFreeChart : a free chart library for the Java(tm) platform
003 * ===========================================================
004 *
005 * (C) Copyright 2000-present, by David Gilbert and Contributors.
006 *
007 * Project Info:  http://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 * JSONUtils.java
029 * --------------
030 * (C) Copyright 2014-present, by David Gilbert.
031 *
032 * Original Author:  David Gilbert;
033 * Contributor(s):   -;
034 *
035 */
036
037package org.jfree.data.json;
038
039import java.io.IOException;
040import java.io.StringWriter;
041import java.io.Writer;
042import java.util.Iterator;
043import java.util.List;
044import org.jfree.chart.util.Args;
045import org.jfree.data.KeyedValues;
046import org.jfree.data.KeyedValues2D;
047import org.jfree.data.category.CategoryDataset;
048import org.jfree.data.general.PieDataset;
049import org.jfree.data.json.impl.JSONValue;
050
051/**
052 * A utility class that can read and write data in specific JSON formats.
053 */
054public class JSONUtils {
055
056    /**
057     * Returns a string containing the data in JSON format.  The format is
058     * an array of arrays, where each sub-array represents one data value.
059     * The sub-array should contain two items, first the item key as a string
060     * and second the item value as a number.  For example:
061     * {@code [["Key A", 1.0], ["Key B", 2.0]]}
062     * <br><br>
063     * Note that this method can be used with instances of {@link PieDataset}.
064     * 
065     * @param data  the data ({@code null} not permitted).
066     * 
067     * @return A string in JSON format. 
068     */
069    public static String writeKeyedValues(KeyedValues data) {
070        Args.nullNotPermitted(data, "data");
071        StringWriter sw = new StringWriter();
072        try {
073            writeKeyedValues(data, sw);
074        } catch (IOException ex) {
075            throw new RuntimeException(ex);
076        }
077        return sw.toString();
078    }
079
080    /**
081     * Writes the data in JSON format to the supplied writer.
082     * <br><br>
083     * Note that this method can be used with instances of {@link PieDataset}.
084     * 
085     * @param data  the data ({@code null} not permitted).
086     * @param writer  the writer ({@code null} not permitted).
087     * 
088     * @throws IOException if there is an I/O problem.
089     */
090    public static void writeKeyedValues(KeyedValues data, Writer writer) 
091            throws IOException {
092        Args.nullNotPermitted(data, "data");
093        Args.nullNotPermitted(writer, "writer");
094        writer.write("[");
095        boolean first = true;
096        Iterator iterator = data.getKeys().iterator();
097        while (iterator.hasNext()) {
098            Comparable key = (Comparable) iterator.next();
099            if (!first) {
100                writer.write(", ");
101            } else {
102                first = false;
103            }
104            writer.write("[");
105            writer.write(JSONValue.toJSONString(key.toString()));
106            writer.write(", ");
107            writer.write(JSONValue.toJSONString(data.getValue(key)));
108            writer.write("]");
109        }
110        writer.write("]");
111    }
112    
113    /**
114     * Returns a string containing the data in JSON format.  The format is...
115     * <br><br>
116     * Note that this method can be used with instances of 
117     * {@link CategoryDataset}.
118     * 
119     * @param data  the data ({@code null} not permitted).
120     * 
121     * @return A string in JSON format. 
122     */
123    public static String writeKeyedValues2D(KeyedValues2D data) {
124        Args.nullNotPermitted(data, "data");
125        StringWriter sw = new StringWriter();
126        try {
127            writeKeyedValues2D(data, sw);
128        } catch (IOException ex) {
129            throw new RuntimeException(ex);
130        }
131        return sw.toString();
132    }
133
134    /**
135     * Writes the data in JSON format to the supplied writer.
136     * <br><br>
137     * Note that this method can be used with instances of 
138     * {@link CategoryDataset}.
139     * 
140     * @param data  the data ({@code null} not permitted).
141     * @param writer  the writer ({@code null} not permitted).
142     * 
143     * @throws IOException if there is an I/O problem.
144     */
145    public static void writeKeyedValues2D(KeyedValues2D data, Writer writer) 
146            throws IOException {
147        Args.nullNotPermitted(data, "data");
148        Args.nullNotPermitted(writer, "writer");
149        List<Comparable<?>> columnKeys = data.getColumnKeys();
150        List<Comparable<?>> rowKeys = data.getRowKeys();
151        writer.write("{");
152        if (!columnKeys.isEmpty()) {
153            writer.write("\"columnKeys\": [");
154            boolean first = true;
155            for (Comparable<?> columnKey : columnKeys) {
156                if (!first) {
157                    writer.write(", ");
158                } else {
159                    first = false;
160                }
161                writer.write(JSONValue.toJSONString(columnKey.toString()));
162            }
163            writer.write("]");
164        }
165        if (!rowKeys.isEmpty()) {
166            writer.write(", \"rows\": [");
167            boolean firstRow = true;
168            for (Comparable<?> rowKey : rowKeys) {   
169                if (!firstRow) {
170                    writer.write(", [");
171                } else {
172                    writer.write("[");
173                    firstRow = false;
174                }
175                // write the row data 
176                writer.write(JSONValue.toJSONString(rowKey.toString()));
177                writer.write(", [");
178                boolean first = true;
179                for (Comparable<?> columnKey : columnKeys) {
180                    if (!first) {
181                        writer.write(", ");
182                    } else {
183                        first = false;
184                    }
185                    writer.write(JSONValue.toJSONString(data.getValue(rowKey, 
186                            columnKey)));
187                }
188                writer.write("]]");
189            }
190            writer.write("]");
191        }
192        writer.write("}");    
193    }
194    
195}