001/*
002 * Copyright 2015-2024 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2015-2024 Ping Identity Corporation
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *    http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020/*
021 * Copyright (C) 2015-2024 Ping Identity Corporation
022 *
023 * This program is free software; you can redistribute it and/or modify
024 * it under the terms of the GNU General Public License (GPLv2 only)
025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
026 * as published by the Free Software Foundation.
027 *
028 * This program is distributed in the hope that it will be useful,
029 * but WITHOUT ANY WARRANTY; without even the implied warranty of
030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
031 * GNU General Public License for more details.
032 *
033 * You should have received a copy of the GNU General Public License
034 * along with this program; if not, see <http://www.gnu.org/licenses>.
035 */
036package com.unboundid.util.json;
037
038
039
040import com.unboundid.util.ByteStringBuffer;
041import com.unboundid.util.NotMutable;
042import com.unboundid.util.NotNull;
043import com.unboundid.util.Nullable;
044import com.unboundid.util.StaticUtils;
045import com.unboundid.util.ThreadSafety;
046import com.unboundid.util.ThreadSafetyLevel;
047
048
049
050/**
051 * This class provides an implementation of a JSON value that represents a
052 * string of Unicode characters.  The string representation of a JSON string
053 * must start and end with the double quotation mark character, and a Unicode
054 * (preferably UTF-8) representation of the string between the quotes.  The
055 * following special characters must be escaped:
056 * <UL>
057 *   <LI>
058 *     The double quotation mark (Unicode character U+0022) must be escaped as
059 *     either {@code \"} or {@code \}{@code u0022}.
060 *   </LI>
061 *   <LI>
062 *     The backslash (Unicode character U+005C) must be escaped as either
063 *     {@code \\} or {@code \}{@code u005C}.
064 *   </LI>
065 *   <LI>
066 *     All ASCII control characters (Unicode characters U+0000 through U+001F)
067 *     must be escaped.  They can all be escaped by prefixing the
068 *     four-hexadecimal-digit Unicode character code with {@code \}{@code u},
069 *     like {@code \}{@code u0000} to represent the ASCII null character U+0000.
070 *     For certain characters, a more user-friendly escape sequence is also
071 *     defined:
072 *     <UL>
073 *       <LI>
074 *         The horizontal tab character can be escaped as either {@code \t} or
075 *         {@code \}{@code u0009}.
076 *       </LI>
077 *       <LI>
078 *         The newline character can be escaped as either {@code \n} or
079 *         {@code \}{@code u000A}.
080 *       </LI>
081 *       <LI>
082 *         The formfeed character can be escaped as either {@code \f} or
083 *         {@code \}{@code u000C}.
084 *       </LI>
085 *       <LI>
086 *         The carriage return character can be escaped as either {@code \r} or
087 *         {@code \}{@code u000D}.
088 *       </LI>
089 *     </UL>
090 *   </LI>
091 * </UL>
092 * In addition, any other character may optionally be escaped by placing the
093 * {@code \}{@code u} prefix in front of each four-hexadecimal digit sequence in
094 * the UTF-16 representation of that character.  For example, the "LATIN SMALL
095 * LETTER N WITH TILDE" character U+00F1 may be escaped as
096 * {@code \}{@code u00F1}, while the "MUSICAL SYMBOL G CLEF" character U+1D11E
097 * may be escaped as {@code \}{@code uD834}{@code \}{@code uDD1E}.  And while
098 * the forward slash character is not required to be escaped in JSON strings, it
099 * can be escaped using {@code \/} as a more human-readable alternative to
100 * {@code \}{@code u002F}.
101 * <BR><BR>
102 * The string provided to the {@link #JSONString(String)} constructor should not
103 * have any escaping performed, and the string returned by the
104 * {@link #stringValue()} method will not have any escaping performed.  These
105 * methods work with the Java string that is represented by the JSON string.
106 * <BR><BR>
107 * If this JSON string was parsed from the string representation of a JSON
108 * object, then the value returned by the {@link #toString()} method (or
109 * appended to the buffer provided to the {@link #toString(StringBuilder)}
110 * method) will be the string representation used in the JSON object that was
111 * parsed.  Otherwise, this class will generate an appropriate string
112 * representation, which will be surrounded by quotation marks and will have the
113 * minimal required encoding applied.
114 * <BR><BR>
115 * The string returned by the {@link #toNormalizedString()} method (or appended
116 * to the buffer provided to the {@link #toNormalizedString(StringBuilder)}
117 * method) will be generated by converting it to lowercase, surrounding it with
118 * quotation marks, and using the {@code \}{@code u}-style escaping for all
119 * characters other than the following (as contained in the LDAP printable
120 * character set defined in <A HREF="http://www.ietf.org/rfc/rfc4517.txt">RFC
121 * 4517</A> section 3.2, and indicated by the
122 * {@link StaticUtils#isPrintable(char)} method):
123 * <UL>
124 *   <LI>All uppercase ASCII alphabetic letters (U+0041 through U+005A).</LI>
125 *   <LI>All lowercase ASCII alphabetic letters (U+0061 through U+007A).</LI>
126 *   <LI>All ASCII numeric digits (U+0030 through U+0039).</LI>
127 *   <LI>The ASCII space character U+0020.</LI>
128 *   <LI>The ASCII single quote (aka apostrophe) character U+0027.</LI>
129 *   <LI>The ASCII left parenthesis character U+0028.</LI>
130 *   <LI>The ASCII right parenthesis character U+0029.</LI>
131 *   <LI>The ASCII plus sign character U+002B.</LI>
132 *   <LI>The ASCII comma character U+002C.</LI>
133 *   <LI>The ASCII minus sign (aka hyphen) character U+002D.</LI>
134 *   <LI>The ASCII period character U+002E.</LI>
135 *   <LI>The ASCII forward slash character U+002F.</LI>
136 *   <LI>The ASCII colon character U+003A.</LI>
137 *   <LI>The ASCII equals sign character U+003D.</LI>
138 *   <LI>The ASCII question mark character U+003F.</LI>
139 * </UL>
140 */
141@NotMutable()
142@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
143public final class JSONString
144       extends JSONValue
145{
146  /**
147   * The serial version UID for this serializable class.
148   */
149  private static final long serialVersionUID = -4677194657299153890L;
150
151
152
153  // The JSON-formatted string representation for this JSON string.  It will be
154  // surrounded by quotation marks and any necessary escaping will have been
155  // performed.
156  @Nullable private String jsonStringRepresentation;
157
158  // The string value for this object.
159  @NotNull private final String value;
160
161
162
163  /**
164   * Creates a new JSON string.
165   *
166   * @param  value  The string to represent in this JSON value.  It must not be
167   *                {@code null}.
168   */
169  public JSONString(@NotNull final String value)
170  {
171    this.value = value;
172    jsonStringRepresentation = null;
173  }
174
175
176
177  /**
178   * Creates a new JSON string.  This method should be used for strings parsed
179   * from the string representation of a JSON object.
180   *
181   * @param  javaString  The Java string to represent.
182   * @param  jsonString  The JSON string representation to use for the Java
183   *                     string.
184   */
185  JSONString(@NotNull final String javaString, @NotNull final String jsonString)
186  {
187    value = javaString;
188    jsonStringRepresentation = jsonString;
189  }
190
191
192
193  /**
194   * Retrieves the string value for this object.  This will be the interpreted
195   * value, without the surrounding quotation marks or escaping.
196   *
197   * @return  The string value for this object.
198   */
199  @NotNull()
200  public String stringValue()
201  {
202    return value;
203  }
204
205
206
207  /**
208   * {@inheritDoc}
209   */
210  @Override()
211  public int hashCode()
212  {
213    return stringValue().hashCode();
214  }
215
216
217
218  /**
219   * {@inheritDoc}
220   */
221  @Override()
222  public boolean equals(@Nullable final Object o)
223  {
224    if (o == this)
225    {
226      return true;
227    }
228
229    if (o instanceof JSONString)
230    {
231      final JSONString s = (JSONString) o;
232      return value.equals(s.value);
233    }
234
235    return false;
236  }
237
238
239
240  /**
241   * Indicates whether the value of this JSON string matches that of the
242   * provided string, optionally ignoring differences in capitalization.
243   *
244   * @param  s           The JSON string to compare against this JSON string.
245   *                     It must not be {@code null}.
246   * @param  ignoreCase  Indicates whether to ignore differences in
247   *                     capitalization.
248   *
249   * @return  {@code true} if the value of this JSON string matches the value of
250   *          the provided string (optionally ignoring differences in
251   *          capitalization), or {@code false} if not.
252   */
253  public boolean equals(@NotNull final JSONString s, final boolean ignoreCase)
254  {
255    if (ignoreCase)
256    {
257      return value.equalsIgnoreCase(s.value);
258    }
259    else
260    {
261      return value.equals(s.value);
262    }
263  }
264
265
266
267  /**
268   * {@inheritDoc}
269   */
270  @Override()
271  public boolean equals(@NotNull final JSONValue v,
272                        final boolean ignoreFieldNameCase,
273                        final boolean ignoreValueCase,
274                        final boolean ignoreArrayOrder)
275  {
276    return ((v instanceof JSONString) &&
277         equals((JSONString) v, ignoreValueCase));
278  }
279
280
281
282  /**
283   * Retrieves a string representation of this JSON string as it should appear
284   * in a JSON object, including the surrounding quotation marks and any
285   * appropriate escaping  To obtain the string to which this value refers
286   * without the surrounding quotation marks or escaping, use the
287   * {@link #stringValue()} method.
288   * <BR><BR>
289   * If the object containing this string was decoded from a string, then this
290   * method will use the same string representation as in that original object.
291   * Otherwise, the string representation will be constructed.
292   *
293   * @return  A string representation of this value as it should appear in a
294   *          JSON object.
295   */
296  @Override()
297  @NotNull()
298  public String toString()
299  {
300    if (jsonStringRepresentation == null)
301    {
302      final StringBuilder buffer = new StringBuilder();
303      toString(buffer);
304      jsonStringRepresentation = buffer.toString();
305    }
306
307    return jsonStringRepresentation;
308  }
309
310
311
312  /**
313   * Appends a string representation of this JSON string as it should appear
314   * in a JSON object, including the surrounding quotation marks and any
315   * appropriate escaping, to the provided buffer.  To obtain the string to
316   * which this value refers without the surrounding quotation marks or
317   * escaping, use the {@link #stringValue()} method.
318   * <BR><BR>
319   * If the object containing this string was decoded from a string, then this
320   * method will use the same string representation as in that original object.
321   * Otherwise, the string representation will be constructed.
322   *
323   * @param  buffer  The buffer to which the information should be appended.
324   */
325  @Override()
326  public void toString(@NotNull final StringBuilder buffer)
327  {
328    if (jsonStringRepresentation != null)
329    {
330      buffer.append(jsonStringRepresentation);
331    }
332    else
333    {
334      final boolean emptyBufferProvided = (buffer.length() == 0);
335      encodeString(value, buffer);
336
337      if (emptyBufferProvided)
338      {
339        jsonStringRepresentation = buffer.toString();
340      }
341    }
342  }
343
344
345
346  /**
347   * Retrieves a single-line representation of this JSON string as it should
348   * appear in a JSON object, including the surrounding quotation marks and any
349   * appropriate escaping.  To obtain the string to which this value refers
350   * without the surrounding quotation marks or escaping, use the
351   * {@link #stringValue()} method.
352   *
353   * @return  A single-line representation of this value as it should appear in
354   *          a JSON object.
355   */
356  @Override()
357  @NotNull()
358  public String toSingleLineString()
359  {
360    return toString();
361  }
362
363
364
365  /**
366   * Appends a single-line string representation of this JSON string as it
367   * should appear in a JSON object, including the surrounding quotation marks
368   * and any appropriate escaping, to the provided buffer.  To obtain the string
369   * to which this value refers without the surrounding quotation marks or
370   * escaping, use the {@link #stringValue()} method.
371   *
372   * @param  buffer  The buffer to which the information should be appended.
373   */
374  @Override()
375  public void toSingleLineString(@NotNull final StringBuilder buffer)
376  {
377    toString(buffer);
378  }
379
380
381
382  /**
383   * Appends a minimally-escaped JSON representation of the provided string to
384   * the given buffer.  When escaping is required, the most user-friendly form
385   * of escaping will be used.
386   *
387   * @param  s       The string to be encoded.
388   * @param  buffer  The buffer to which the encoded representation should be
389   *                 appended.
390   */
391  static void encodeString(@NotNull final String s,
392                           @NotNull final StringBuilder buffer)
393  {
394    buffer.append('"');
395
396    for (final char c : s.toCharArray())
397    {
398      switch (c)
399      {
400        case '"':
401          buffer.append("\\\"");
402          break;
403        case '\\':
404          buffer.append("\\\\");
405          break;
406        case '\b': // backspace
407          buffer.append("\\b");
408          break;
409        case '\f': // formfeed
410          buffer.append("\\f");
411          break;
412        case '\n': // newline
413          buffer.append("\\n");
414          break;
415        case '\r': // carriage return
416          buffer.append("\\r");
417          break;
418        case '\t': // horizontal tab
419          buffer.append("\\t");
420          break;
421        default:
422          if (c <= '\u001F')
423          {
424            buffer.append("\\u");
425            buffer.append(String.format("%04X", (int) c));
426          }
427          else
428          {
429            buffer.append(c);
430          }
431          break;
432      }
433    }
434
435    buffer.append('"');
436  }
437
438
439
440  /**
441   * Appends a minimally-escaped JSON representation of the provided string to
442   * the given buffer.  When escaping is required, the most user-friendly form
443   * of escaping will be used.
444   *
445   * @param  s       The string to be encoded.
446   * @param  buffer  The buffer to which the encoded representation should be
447   *                 appended.
448   */
449  static void encodeString(@NotNull final String s,
450                           @NotNull final ByteStringBuffer buffer)
451  {
452    buffer.append('"');
453
454    for (final char c : s.toCharArray())
455    {
456      switch (c)
457      {
458        case '"':
459          buffer.append("\\\"");
460          break;
461        case '\\':
462          buffer.append("\\\\");
463          break;
464        case '\b': // backspace
465          buffer.append("\\b");
466          break;
467        case '\f': // formfeed
468          buffer.append("\\f");
469          break;
470        case '\n': // newline
471          buffer.append("\\n");
472          break;
473        case '\r': // carriage return
474          buffer.append("\\r");
475          break;
476        case '\t': // horizontal tab
477          buffer.append("\\t");
478          break;
479        default:
480          if (c <= '\u001F')
481          {
482            buffer.append("\\u");
483            buffer.append(String.format("%04X", (int) c));
484          }
485          else
486          {
487            buffer.append(c);
488          }
489          break;
490      }
491    }
492
493    buffer.append('"');
494  }
495
496
497
498  /**
499   * Retrieves a normalized representation of this JSON string as it should
500   * appear in a JSON object, including the surrounding quotes and any
501   * appropriate escaping.  The normalized representation will use the unescaped
502   * ASCII representation of all of the following characters:
503   * <UL>
504   *   <LI>The letters a through z (ASCII character codes 0x61 through
505   *       0x7A).</LI>
506   *   <LI>The digits 0 through 9 (ASCII character codes 0x30 through
507   *       0x39).</LI>
508   *   <LI>The space (ASCII character code 0x20).</LI>
509   *   <LI>The single quote (ASCII character code 0x27).</LI>
510   *   <LI>The left parenthesis (ASCII character code 0x28).</LI>
511   *   <LI>The right parenthesis (ASCII character code 0x29).</LI>
512   *   <LI>The plus sign (ASCII character code 0x2B).</LI>
513   *   <LI>The comma (ASCII character code 0x2C).</LI>
514   *   <LI>The hyphen (ASCII character code 0x2D).</LI>
515   *   <LI>The period (ASCII character code 0x2E).</LI>
516   *   <LI>The forward slash (ASCII character code 0x2F).</LI>
517   *   <LI>The colon (ASCII character code 0x3A).</LI>
518   *   <LI>The equal sign (ASCII character code 0x3D).</LI>
519   *   <LI>The question mark (ASCII character code 0x3F).</LI>
520   * </UL>
521   * All characters except those listed above will be escaped using their
522   * Unicode representation.
523   *
524   * @return  A normalized representation of this JSON string as it should
525   *          appear in a JSON object, including
526   */
527  @Override()
528  @NotNull()
529  public String toNormalizedString()
530  {
531    final StringBuilder buffer = new StringBuilder();
532    toNormalizedString(buffer);
533    return buffer.toString();
534  }
535
536
537
538  /**
539   * Appends a normalized representation of this JSON string as it should
540   * appear in a JSON object, including the surrounding quotes and any
541   * appropriate escaping, to the provided buffer.  The normalized
542   * representation will use the unescaped ASCII representation of all of the
543   * following characters:
544   * <UL>
545   *   <LI>The letters a through z (ASCII character codes 0x61 through
546   *       0x7A).</LI>
547   *   <LI>The digits 0 through 9 (ASCII character codes 0x30 through
548   *       0x39).</LI>
549   *   <LI>The space (ASCII character code 0x20).</LI>
550   *   <LI>The single quote (ASCII character code 0x27).</LI>
551   *   <LI>The left parenthesis (ASCII character code 0x28).</LI>
552   *   <LI>The right parenthesis (ASCII character code 0x29).</LI>
553   *   <LI>The plus sign (ASCII character code 0x2B).</LI>
554   *   <LI>The comma (ASCII character code 0x2C).</LI>
555   *   <LI>The hyphen (ASCII character code 0x2D).</LI>
556   *   <LI>The period (ASCII character code 0x2E).</LI>
557   *   <LI>The forward slash (ASCII character code 0x2F).</LI>
558   *   <LI>The colon (ASCII character code 0x3A).</LI>
559   *   <LI>The equal sign (ASCII character code 0x3D).</LI>
560   *   <LI>The question mark (ASCII character code 0x3F).</LI>
561   * </UL>
562   * All characters except those listed above will be escaped using their
563   * Unicode representation.
564   *
565   * @param  buffer  The buffer to which the information should be appended.
566   */
567  @Override()
568  public void toNormalizedString(@NotNull final StringBuilder buffer)
569  {
570    toNormalizedString(buffer, false, true, false);
571  }
572
573
574
575  /**
576   * Retrieves a normalized representation of this JSON string as it should
577   * appear in a JSON object, including the surrounding quotes and any
578   * appropriate escaping.  The normalized representation will use the unescaped
579   * ASCII representation of all of the following characters:
580   * <UL>
581   *   <LI>The letters a through z (ASCII character codes 0x61 through
582   *       0x7A).</LI>
583   *   <LI>The letters A through Z (ASCII character codes 0x41 through 0x5A).
584   *       These characters will only be used if {@code ignoreValueCase} is
585   *       {@code false}.</LI>
586   *   <LI>The digits 0 through 9 (ASCII character codes 0x30 through
587   *       0x39).</LI>
588   *   <LI>The space (ASCII character code 0x20).</LI>
589   *   <LI>The single quote (ASCII character code 0x27).</LI>
590   *   <LI>The left parenthesis (ASCII character code 0x28).</LI>
591   *   <LI>The right parenthesis (ASCII character code 0x29).</LI>
592   *   <LI>The plus sign (ASCII character code 0x2B).</LI>
593   *   <LI>The comma (ASCII character code 0x2C).</LI>
594   *   <LI>The hyphen (ASCII character code 0x2D).</LI>
595   *   <LI>The period (ASCII character code 0x2E).</LI>
596   *   <LI>The forward slash (ASCII character code 0x2F).</LI>
597   *   <LI>The colon (ASCII character code 0x3A).</LI>
598   *   <LI>The equal sign (ASCII character code 0x3D).</LI>
599   *   <LI>The question mark (ASCII character code 0x3F).</LI>
600   * </UL>
601   * All characters except those listed above will be escaped using their
602   * Unicode representation.
603   *
604   * @param  ignoreFieldNameCase  Indicates whether field names should be
605   *                              treated in a case-sensitive (if {@code false})
606   *                              or case-insensitive (if {@code true}) manner.
607   * @param  ignoreValueCase      Indicates whether string field values should
608   *                              be treated in a case-sensitive (if
609   *                              {@code false}) or case-insensitive (if
610   *                              {@code true}) manner.
611   * @param  ignoreArrayOrder     Indicates whether the order of elements in an
612   *                              array should be considered significant (if
613   *                              {@code false}) or insignificant (if
614   *                              {@code true}).
615   *
616   * @return  A normalized representation of this JSON string as it should
617   *          appear in a JSON object, including
618   */
619  @Override()
620  @NotNull()
621  public String toNormalizedString(final boolean ignoreFieldNameCase,
622                                   final boolean ignoreValueCase,
623                                   final boolean ignoreArrayOrder)
624  {
625    final StringBuilder buffer = new StringBuilder();
626    toNormalizedString(buffer, ignoreFieldNameCase, ignoreValueCase,
627         ignoreArrayOrder);
628    return buffer.toString();
629  }
630
631
632
633  /**
634   * Appends a normalized representation of this JSON string as it should
635   * appear in a JSON object, including the surrounding quotes and any
636   * appropriate escaping, to the provided buffer.  The normalized
637   * representation will use the unescaped ASCII representation of all of the
638   * following characters:
639   * <UL>
640   *   <LI>The letters a through z (ASCII character codes 0x61 through
641   *       0x7A).</LI>
642   *   <LI>The letters A through Z (ASCII character codes 0x41 through 0x5A).
643   *       These characters will only be used if {@code ignoreValueCase} is
644   *       {@code false}.</LI>
645   *   <LI>The digits 0 through 9 (ASCII character codes 0x30 through
646   *       0x39).</LI>
647   *   <LI>The space (ASCII character code 0x20).</LI>
648   *   <LI>The single quote (ASCII character code 0x27).</LI>
649   *   <LI>The left parenthesis (ASCII character code 0x28).</LI>
650   *   <LI>The right parenthesis (ASCII character code 0x29).</LI>
651   *   <LI>The plus sign (ASCII character code 0x2B).</LI>
652   *   <LI>The comma (ASCII character code 0x2C).</LI>
653   *   <LI>The hyphen (ASCII character code 0x2D).</LI>
654   *   <LI>The period (ASCII character code 0x2E).</LI>
655   *   <LI>The forward slash (ASCII character code 0x2F).</LI>
656   *   <LI>The colon (ASCII character code 0x3A).</LI>
657   *   <LI>The equal sign (ASCII character code 0x3D).</LI>
658   *   <LI>The question mark (ASCII character code 0x3F).</LI>
659   * </UL>
660   * All characters except those listed above will be escaped using their
661   * Unicode representation.
662   *
663   * @param  buffer               The buffer to which the information should be
664   *                              appended.
665   * @param  ignoreFieldNameCase  Indicates whether field names should be
666   *                              treated in a case-sensitive (if {@code false})
667   *                              or case-insensitive (if {@code true}) manner.
668   * @param  ignoreValueCase      Indicates whether string field values should
669   *                              be treated in a case-sensitive (if
670   *                              {@code false}) or case-insensitive (if
671   *                              {@code true}) manner.
672   * @param  ignoreArrayOrder     Indicates whether the order of elements in an
673   *                              array should be considered significant (if
674   *                              {@code false}) or insignificant (if
675   *                              {@code true}).
676   */
677  @Override()
678  public void toNormalizedString(@NotNull final StringBuilder buffer,
679                                 final boolean ignoreFieldNameCase,
680                                 final boolean ignoreValueCase,
681                                 final boolean ignoreArrayOrder)
682  {
683    buffer.append('"');
684
685    final char[] charArray;
686    if (ignoreValueCase)
687    {
688      charArray = StaticUtils.toLowerCase(value).toCharArray();
689    }
690    else
691    {
692      charArray = value.toCharArray();
693    }
694
695    for (final char c : charArray)
696    {
697      if (StaticUtils.isPrintable(c))
698      {
699        buffer.append(c);
700      }
701      else
702      {
703        buffer.append("\\u");
704        buffer.append(String.format("%04X", (int) c));
705      }
706    }
707
708    buffer.append('"');
709  }
710
711
712
713  /**
714   * {@inheritDoc}
715   */
716  @Override()
717  @NotNull()
718  public JSONString toNormalizedValue(final boolean ignoreFieldNameCase,
719                                      final boolean ignoreValueCase,
720                                      final boolean ignoreArrayOrder)
721  {
722    if (ignoreValueCase)
723    {
724      return new JSONString(StaticUtils.toLowerCase(value));
725    }
726    else
727    {
728      return this;
729    }
730  }
731
732
733
734  /**
735   * {@inheritDoc}
736   */
737  @Override()
738  public void appendToJSONBuffer(@NotNull final JSONBuffer buffer)
739  {
740    buffer.appendString(value);
741  }
742
743
744
745  /**
746   * {@inheritDoc}
747   */
748  @Override()
749  public void appendToJSONBuffer(@NotNull final String fieldName,
750                                 @NotNull final JSONBuffer buffer)
751  {
752    buffer.appendString(fieldName, value);
753  }
754}