/* * This library is part of OpenCms - * the Open Source Content Management System * * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * For further information about Alkacon Software GmbH, please see the * company website: http://www.alkacon.com * * For further information about OpenCms, please see the * project website: http://www.opencms.org * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * This file is based on: * org.json.CDL * from the JSON in Java implementation. * * Copyright (c) 2002 JSON.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * The Software shall be used for Good, not Evil. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package org.opencms.json; /** * This provides static methods to convert comma delimited text into a * JSONArray, and to covert a JSONArray into comma delimited text. Comma * delimited text is a very popular format for data interchange. It is * understood by most database, spreadsheet, and organizer programs. * <p> * Each row of text represents a row in a table or a data record. Each row * ends with a NEWLINE character. Each row contains one or more values. * Values are separated by commas. A value can contain any character except * for comma, unless is is wrapped in single quotes or double quotes. * <p> * The first row usually contains the names of the columns. * <p> * A comma delimited list can be converted into a JSONArray of JSONObjects. * The names for the elements in the JSONObjects can be taken from the names * in the first row.<p> * */ public final class CDL { private CDL() { // hidden constructor } /** * Produce a JSONArray of strings from a row of comma delimited values.<p> * * @param x A JSONTokener of the source text * @return A JSONArray of strings * @throws JSONException if something goes wrong */ public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException { JSONArray ja = new JSONArray(); for (;;) { String value = getValue(x); if (value == null || (ja.length() == 0 && value.length() == 0)) { return null; } ja.put(value); for (;;) { char c = x.next(); if (c == ',') { break; } if (c != ' ') { if (c == '\n' || c == '\r' || c == 0) { return ja; } throw x.syntaxError("Bad character '" + c + "' (" + (int)c + ")."); } } } } /** * Produce a JSONObject from a row of comma delimited text, using a * parallel JSONArray of strings to provides the names of the elements.<p> * * @param names A JSONArray of names. This is commonly obtained from the * first row of a comma delimited text file using the rowToJSONArray * method * @param x A JSONTokener of the source text * @return A JSONObject combining the names and values * @throws JSONException if something goes wrong */ public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x) throws JSONException { JSONArray ja = rowToJSONArray(x); return ja != null ? ja.toJSONObject(names) : null; } /** * Produce a comma delimited text row from a JSONArray. Values containing * the comma character will be quoted.<p> * * @param ja A JSONArray of strings * @return A string ending in NEWLINE */ public static String rowToString(JSONArray ja) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < ja.length(); i += 1) { if (i > 0) { sb.append(','); } Object o = ja.opt(i); if (o != null) { String s = o.toString(); if (s.indexOf(',') >= 0) { if (s.indexOf('"') >= 0) { sb.append('\''); sb.append(s); sb.append('\''); } else { sb.append('"'); sb.append(s); sb.append('"'); } } else { sb.append(s); } } } sb.append('\n'); return sb.toString(); } /** * Produce a JSONArray of JSONObjects from a comma delimited text string * using a supplied JSONArray as the source of element names.<p> * * @param names A JSONArray of strings * @param x A JSONTokener of the source text * @return A JSONArray of JSONObjects * @throws JSONException if something goes wrong */ public static JSONArray toJSONArray(JSONArray names, JSONTokener x) throws JSONException { if (names == null || names.length() == 0) { return null; } JSONArray ja = new JSONArray(); for (;;) { JSONObject jo = rowToJSONObject(names, x); if (jo == null) { break; } ja.put(jo); } if (ja.length() == 0) { return null; } return ja; } /** * Produce a JSONArray of JSONObjects from a comma delimited text string * using a supplied JSONArray as the source of element names.<p> * * @param names A JSONArray of strings. * @param string The comma delimited text * @return A JSONArray of JSONObjects * @throws JSONException if something goes wrong */ public static JSONArray toJSONArray(JSONArray names, String string) throws JSONException { return toJSONArray(names, new JSONTokener(string)); } /** * Produce a JSONArray of JSONObjects from a comma delimited text string, * using the first row as a source of names.<p> * * @param x The JSONTokener containing the comma delimited text * @return A JSONArray of JSONObjects * @throws JSONException if something goes wrong */ public static JSONArray toJSONArray(JSONTokener x) throws JSONException { return toJSONArray(rowToJSONArray(x), x); } /** * Produce a JSONArray of JSONObjects from a comma delimited text string, * using the first row as a source of names.<p> * * @param string The comma delimited text * @return A JSONArray of JSONObjects * @throws JSONException if something goes wrong */ public static JSONArray toJSONArray(String string) throws JSONException { return toJSONArray(new JSONTokener(string)); } /** * Produce a comma delimited text from a JSONArray of JSONObjects. The * first row will be a list of names obtained by inspecting the first * JSONObject.<p> * * @param ja A JSONArray of JSONObjects * @return A comma delimited text * @throws JSONException if something goes wrong */ public static String toString(JSONArray ja) throws JSONException { JSONObject jo = ja.optJSONObject(0); if (jo != null) { JSONArray names = jo.names(); if (names != null) { return rowToString(names) + toString(names, ja); } } return null; } /** * Produce a comma delimited text from a JSONArray of JSONObjects using * a provided list of names. The list of names is not included in the * output.<p> * * @param names A JSONArray of strings * @param ja A JSONArray of JSONObjects * @return A comma delimited text * @throws JSONException if something goes wrong */ public static String toString(JSONArray names, JSONArray ja) throws JSONException { if (names == null || names.length() == 0) { return null; } StringBuffer sb = new StringBuffer(); for (int i = 0; i < ja.length(); i += 1) { JSONObject jo = ja.optJSONObject(i); if (jo != null) { sb.append(rowToString(jo.toJSONArray(names))); } } return sb.toString(); } /** * Get the next value. The value can be wrapped in quotes. The value can * be empty.<p> * * @param x A JSONTokener of the source text * @return The value string, or null if empty * @throws JSONException if the quoted string is badly formed */ private static String getValue(JSONTokener x) throws JSONException { char c; do { c = x.next(); } while (c == ' ' || c == '\t'); switch (c) { case 0: return null; case '"': case '\'': return x.nextString(c); case ',': x.back(); return ""; default: x.back(); return x.nextTo(','); } } }