com.unboundid.util.json.JSONString Maven / Gradle / Ivy
                 Go to download
                
        
                    Show more of this group  Show more artifacts with this name
Show all versions of unboundid-ldapsdk-commercial-edition Show documentation
                Show all versions of unboundid-ldapsdk-commercial-edition Show documentation
      The UnboundID LDAP SDK for Java is a fast, comprehensive, and easy-to-use
      Java API for communicating with LDAP directory servers and performing
      related tasks like reading and writing LDIF, encoding and decoding data
      using base64 and ASN.1 BER, and performing secure communication.  This
      package contains the Commercial Edition of the LDAP SDK, which includes
      all of the general-purpose functionality contained in the Standard
      Edition, plus additional functionality specific to UnboundID server
      products.
    
                
            /*
 * Copyright 2015-2016 UnboundID Corp.
 * All Rights Reserved.
 */
/*
 * Copyright (C) 2015-2016 UnboundID Corp.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License (GPLv2 only)
 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
 * as published by the Free Software Foundation.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see .
 */
package com.unboundid.util.json;
import com.unboundid.util.NotMutable;
import com.unboundid.util.StaticUtils;
import com.unboundid.util.ThreadSafety;
import com.unboundid.util.ThreadSafetyLevel;
/**
 * This class provides an implementation of a JSON value that represents a
 * string of Unicode characters.  The string representation of a JSON string
 * must start and end with the double quotation mark character, and a Unicode
 * (preferably UTF-8) representation of the string between the quotes.  The
 * following special characters must be escaped:
 * 
 *   - 
 *     The double quotation mark (Unicode character U+0022) must be escaped as
 *     either {@code \"} or {@code \}{@code u0022}.
 *   
 
 *   - 
 *     The backslash (Unicode character U+005C) must be escaped as either
 *     {@code \\} or {@code \}{@code u005C}.
 *   
 
 *   - 
 *     All ASCII control characters (Unicode characters U+0000 through U+001F)
 *     must be escaped.  They can all be escaped by prefixing the
 *     four-hexadecimal-digit Unicode character code with {@code \}{@code u},
 *     like {@code \}{@code u0000} to represent the ASCII null character U+0000.
 *     For certain characters, a more user-friendly escape sequence is also
 *     defined:
 *     
 *       - 
 *         The horizontal tab character can be escaped as either {@code \t} or
 *         {@code \}{@code u0009}.
 *       
 
 *       - 
 *         The newline character can be escaped as either {@code \n} or
 *         {@code \}{@code u000A}.
 *       
 
 *       - 
 *         The formfeed character can be escaped as either {@code \f} or
 *         {@code \}{@code u000C}.
 *       
 
 *       - 
 *         The carriage return character can be escaped as either {@code \r} or
 *         {@code \}{@code u000D}.
 *       
 
 *     
 *    
 * 
 * In addition, any other character may optionally be escaped by placing the
 * {@code \}{@code u} prefix in front of each four-hexadecimal digit sequence in
 * the UTF-16 representation of that character.  For example, the "LATIN SMALL
 * LETTER N WITH TILDE" character U+00F1 may be escaped as
 * {@code \}{@code u00F1}, while the "MUSICAL SYMBOL G CLEF" character U+1D11E
 * may be escaped as {@code \}{@code uD834}{@code \}{@code uDD1E}.  And while
 * the forward slash character is not required to be escaped in JSON strings, it
 * can be escaped using {@code \/} as a more human-readable alternative to
 * {@code \}{@code u002F}.
 * 
 * The string provided to the {@link #JSONString(String)} constructor should not
 * have any escaping performed, and the string returned by the
 * {@link #stringValue()} method will not have any escaping performed.  These
 * methods work with the Java string that is represented by the JSON string.
 * 
 * If this JSON string was parsed from the string representation of a JSON
 * object, then the value returned by the {@link #toString()} method (or
 * appended to the buffer provided to the {@link #toString(StringBuilder)}
 * method) will be the string representation used in the JSON object that was
 * parsed.  Otherwise, this class will generate an appropriate string
 * representation, which will be surrounded by quotation marks and will have the
 * minimal required encoding applied.
 * 
 * The string returned by the {@link #toNormalizedString()} method (or appended
 * to the buffer provided to the {@link #toNormalizedString(StringBuilder)}
 * method) will be generated by converting it to lowercase, surrounding it with
 * quotation marks, and using the {@code \}{@code u}-style escaping for all
 * characters other than the following (as contained in the LDAP printable
 * character set defined in RFC
 * 4517 section 3.2, and indicated by the
 * {@link StaticUtils#isPrintable(char)} method):
 * 
 *   - All uppercase ASCII alphabetic letters (U+0041 through U+005A).
 
 *   - All lowercase ASCII alphabetic letters (U+0061 through U+007A).
 
 *   - All ASCII numeric digits (U+0030 through U+0039).
 
 *   - The ASCII space character U+0020.
 
 *   - The ASCII single quote (aka apostrophe) character U+0027.
 
 *   - The ASCII left parenthesis character U+0028.
 
 *   - The ASCII right parenthesis character U+0029.
 
 *   - The ASCII plus sign character U+002B.
 
 *   - The ASCII comma character U+002C.
 
 *   - The ASCII minus sign (aka hyphen) character U+002D.
 
 *   - The ASCII period character U+002E.
 
 *   - The ASCII forward slash character U+002F.
 
 *   - The ASCII colon character U+003A.
 
 *   - The ASCII equals sign character U+003D.
 
 *   - The ASCII question mark character U+003F.
 
 * 
 */
@NotMutable()
@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
public final class JSONString
       extends JSONValue
{
  /**
   * The serial version UID for this serializable class.
   */
  private static final long serialVersionUID = -4677194657299153890L;
  // The JSON-formatted string representation for this JSON string.  It will be
  // surrounded by quotation marks and any necessary escaping will have been
  // performed.
  private String jsonStringRepresentation;
  // The string value for this object.
  private final String value;
  /**
   * Creates a new JSON string.
   *
   * @param  value  The string to represent in this JSON value.  It must not be
   *                {@code null}.
   */
  public JSONString(final String value)
  {
    this.value = value;
    jsonStringRepresentation = null;
  }
  /**
   * Creates a new JSON string.  This method should be used for strings parsed
   * from the string representation of a JSON object.
   *
   * @param  javaString  The Java string to represent.
   * @param  jsonString  The JSON string representation to use for the Java
   *                     string.
   */
  JSONString(final String javaString, final String jsonString)
  {
    value = javaString;
    jsonStringRepresentation = jsonString;
  }
  /**
   * Retrieves the string value for this object.  This will be the interpreted
   * value, without the surrounding quotation marks or escaping.
   *
   * @return  The string value for this object.
   */
  public String stringValue()
  {
    return value;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public int hashCode()
  {
    return stringValue().hashCode();
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean equals(final Object o)
  {
    if (o == this)
    {
      return true;
    }
    if (o instanceof JSONString)
    {
      final JSONString s = (JSONString) o;
      return value.equals(s.value);
    }
    return false;
  }
  /**
   * Indicates whether the value of this JSON string matches that of the
   * provided string, optionally ignoring differences in capitalization.
   *
   * @param  s           The JSON string to compare against this JSON string.
   *                     It must not be {@code null}.
   * @param  ignoreCase  Indicates whether to ignore differences in
   *                     capitalization.
   *
   * @return  {@code true} if the value of this JSON string matches the value of
   *          the provided string (optionally ignoring differences in
   *          capitalization), or {@code false} if not.
   */
  public boolean equals(final JSONString s, final boolean ignoreCase)
  {
    if (ignoreCase)
    {
      return value.equalsIgnoreCase(s.value);
    }
    else
    {
      return value.equals(s.value);
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public boolean equals(final JSONValue v, final boolean ignoreFieldNameCase,
                        final boolean ignoreValueCase,
                        final boolean ignoreArrayOrder)
  {
    return ((v instanceof JSONString) &&
         equals((JSONString) v, ignoreValueCase));
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public String toString()
  {
    if (jsonStringRepresentation == null)
    {
      final StringBuilder buffer = new StringBuilder();
      toString(buffer);
      jsonStringRepresentation = buffer.toString();
    }
    return jsonStringRepresentation;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void toString(final StringBuilder buffer)
  {
    if (jsonStringRepresentation != null)
    {
      buffer.append(jsonStringRepresentation);
    }
    else
    {
      final boolean emptyBufferProvided = (buffer.length() == 0);
      encodeString(value, buffer);
      if (emptyBufferProvided)
      {
        jsonStringRepresentation = buffer.toString();
      }
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public String toSingleLineString()
  {
    return toString();
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void toSingleLineString(final StringBuilder buffer)
  {
    toString(buffer);
  }
  /**
   * Appends a minimally-escaped JSON representation of the provided string to
   * the given buffer.  When escaping is required, the most user-friendly form
   * of escaping will be used.
   *
   * @param  s       The string to be encoded.
   * @param  buffer  The buffer to which the encoded representation should be
   *                 appended.
   */
  static void encodeString(final String s, final StringBuilder buffer)
  {
    buffer.append('"');
    for (final char c : s.toCharArray())
    {
      switch (c)
      {
        case '"':
          buffer.append("\\\"");
          break;
        case '\\':
          buffer.append("\\\\");
          break;
        case '\b': // backspace
          buffer.append("\\b");
          break;
        case '\f': // formfeed
          buffer.append("\\f");
          break;
        case '\n': // newline
          buffer.append("\\n");
          break;
        case '\r': // carriage return
          buffer.append("\\r");
          break;
        case '\t': // horizontal tab
          buffer.append("\\t");
          break;
        default:
          if (c <= '\u001F')
          {
            buffer.append("\\u");
            buffer.append(String.format("%04X", (int) c));
          }
          else
          {
            buffer.append(c);
          }
          break;
      }
    }
    buffer.append('"');
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public String toNormalizedString()
  {
    final StringBuilder buffer = new StringBuilder();
    toNormalizedString(buffer);
    return buffer.toString();
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void toNormalizedString(final StringBuilder buffer)
  {
    buffer.append('"');
    for (final char c : value.toLowerCase().toCharArray())
    {
      if (StaticUtils.isPrintable(c))
      {
        buffer.append(c);
      }
      else
      {
        buffer.append("\\u");
        buffer.append(String.format("%04X", (int) c));
      }
    }
    buffer.append('"');
  }
}
     © 2015 - 2025 Weber Informatics LLC | Privacy Policy