com.hfg.javascript.JSONUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com_hfg Show documentation
Show all versions of com_hfg Show documentation
com.hfg xml, html, svg, and bioinformatics utility library
package com.hfg.javascript;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import com.hfg.util.FileUtil;
import com.hfg.util.StringUtil;
import com.hfg.util.io.StreamUtil;
//------------------------------------------------------------------------------
/**
JSON (serialized Javascript) utilities.
@author J. Alex Taylor, hairyfatguy.com
*/
//------------------------------------------------------------------------------
// com.hfg Library
//
// 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.
//
// 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
//
// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
// [email protected]
//------------------------------------------------------------------------------
public class JSONUtil
{
//###########################################################################
// PUBLIC FUNCTIONS
//###########################################################################
//--------------------------------------------------------------------------
/**
* Converts a JSON file back into objects.
*/
public static JsCollection toJsonObj(File inJsonFile)
throws IOException
{
if (! inJsonFile.exists())
{
throw new IOException("The specified JSON file " + StringUtil.singleQuote(inJsonFile.getPath()) + " doesn't exist!");
}
else if (! inJsonFile.canRead())
{
throw new IOException("No read permissions for the specified JSON file " + StringUtil.singleQuote(inJsonFile.getPath()) + "!");
}
return toJsonObj(FileUtil.read(inJsonFile));
}
//--------------------------------------------------------------------------
/**
* Converts a JSON Reader into objects.
*/
public static JsCollection toJsonObj(Reader inJson)
throws IOException
{
return toJsonObj(StreamUtil.readerToString(inJson));
}
//--------------------------------------------------------------------------
/**
* Converts a JSON stream back into objects.
*/
public static JsCollection toJsonObj(InputStream inJson)
throws IOException
{
return toJsonObj(StreamUtil.inputStreamToString(inJson));
}
//--------------------------------------------------------------------------
/**
* Converts a JSON string back into objects.
*/
public static JsCollection toJsonObj(CharSequence inJSON)
{
JsCollection obj = null;
if (inJSON != null)
{
CharSequence json = stripLineComments(inJSON);
if (json.toString().trim().startsWith("["))
{
obj = new JsArray(json);
}
else if (json.toString().trim().startsWith("{"))
{
obj = new JsObjMap(json);
}
else
{
throw new RuntimeException("The JSON string must be enclosed in [] or {}.");
}
}
return obj;
}
//--------------------------------------------------------------------------
/**
* Escapes JSON string values according to RFC 4627.
* @param inValue the String to be escaped
* @return the escaped String value
*/
public static String escapeString(String inValue)
{
String escapedValue = null;
if (inValue != null)
{
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < inValue.length(); i++)
{
char theChar = inValue.charAt(i);
switch (theChar)
{
case '"':
// Prepend quotes with an escape (if one isn't already present)
// buffer.append((0 == buffer.length() || buffer.charAt(buffer.length() - 1) != '\\' ? "\\" : "") + "\"");
buffer.append("\\\"");
break;
case '\\':
/* if (i < inValue.length() - 1
&& inValue.charAt(i + 1) == '\'') // No need to escape single quotes in a double quoted string
{
// Do nothing.
}
else
*/ {
buffer.append("\\\\");
// buffer.append("\\");
}
break;
case '\r':
buffer.append("\\r");
break;
case '\n':
buffer.append("\\n");
break;
case '\t':
buffer.append("\\t");
break;
default:
// A less common control character?
if(theChar >='\u0000'
&& theChar <='\u001F')
{
String hexString = Integer.toHexString(theChar);
buffer.append("\\u");
// Prepend with the correct number of zeros
for(int j = 0; j < 4 - hexString.length(); j++)
{
buffer.append('0');
}
buffer.append(hexString.toUpperCase());
}
else
{
// No escaping necessary
buffer.append(theChar);
}
}
}
escapedValue = buffer.toString();
}
return escapedValue;
}
//--------------------------------------------------------------------------
/**
* Un-escapes JSON string values according to RFC 4627.
* @param inValue the String to be unescaped
* @return the unescaped String value
*/
public static String unescapeString(String inValue)
{
String unescapedString = null;
if (inValue != null)
{
unescapedString = inValue.replace("\\\"", "\"");
unescapedString = unescapedString.replace("\\\'", "'");
unescapedString = unescapedString.replace("\\r", "\r");
unescapedString = unescapedString.replace("\\n", "\n");
unescapedString = unescapedString.replace("\\t", "\t");
unescapedString = unescapedString.replace("\\\\", "\\");
unescapedString = unescapedString.replace("\\/", "/");
//TODO: isocontrol characters
}
return unescapedString;
}
//--------------------------------------------------------------------------
/**
* This function strips any line comments from the JSON since they are not valid JSON syntax.
* @param inJSON the JSON string to be cleansed of line comments
* @return the cleansed JSON string value
*/
public static CharSequence stripLineComments(CharSequence inJSON)
{
String[] lines = StringUtil.lines(inJSON);
boolean commentsRemoved = false;
for (int lineIndex = 0; lineIndex < lines.length; lineIndex++)
{
String line = lines[lineIndex];
int startingIndex = 0;
int index;
boolean inQuotes = false;
while (startingIndex < line.length()
&& (index = line.indexOf("//", startingIndex)) >= 0)
{
// We can't simply truncate from the '//' because they could be contained within quotes.
char prevChar = ' ';
for (int i = startingIndex; i < index; i++)
{
char theChar = line.charAt(i);
if (line.charAt(i) == '"'
&& prevChar != '\\') // Make sure it isn't an escaped quote
{
inQuotes = !inQuotes;
}
prevChar = theChar;
}
if (! inQuotes)
{
lines[lineIndex] = line.substring(0, index);
commentsRemoved = true;
break;
}
startingIndex = index + 2;
}
}
return commentsRemoved ? StringUtil.join(lines, "\n") : inJSON;
}
//--------------------------------------------------------------------------
protected static Object convertStringValueToObject(String inStringValue)
{
Object valueObj;
try
{
if (inStringValue.equals("null")
|| inStringValue.equals("undefined")) // Coming from javascript, it may be 'undefined'
{
valueObj = null;
}
else if (inStringValue.equals("true"))
{
valueObj = Boolean.TRUE;
}
else if (inStringValue.equals("false"))
{
valueObj = Boolean.FALSE;
}
else if (inStringValue.indexOf(".") > 0)
{
valueObj = Double.parseDouble(inStringValue);
}
else
{
valueObj = Integer.parseInt(inStringValue);
}
}
catch (Exception e)
{
valueObj = inStringValue;
}
return valueObj;
}
}