All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hfg.javascript.JSONUtil Maven / Gradle / Ivy

There is a newer version: 20240423
Show newest version
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;
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy