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 java.io.Serializable; 041 042import com.unboundid.util.NotExtensible; 043import com.unboundid.util.NotNull; 044import com.unboundid.util.Nullable; 045import com.unboundid.util.ThreadSafety; 046import com.unboundid.util.ThreadSafetyLevel; 047 048 049 050/** 051 * This class provides the base class for data types that can be used as values 052 * in JSON objects and as elements in JSON arrays. The types of values defined 053 * in the ECMA-404 specification are: 054 * <UL> 055 * <LI> 056 * The {@code null} value, as implemented in the {@link JSONNull} class. 057 * </LI> 058 * <LI> 059 * The Boolean {@code true} and {@code false} values, as implemented in the 060 * {@link JSONBoolean} class. 061 * </LI> 062 * <LI> 063 * Numeric values, as implemented in the {@link JSONNumber} class. 064 * </LI> 065 * <LI> 066 * String values, as implemented in the {@link JSONString} class. 067 * </LI> 068 * <LI> 069 * Object values (consisting of zero or more name-value pairs), as 070 * implemented in the {@link JSONObject} class. 071 * </LI> 072 * <LI> 073 * Arrays of JSON values, as implemented in the {@link JSONArray} class. 074 * </LI> 075 * </UL> 076 */ 077@NotExtensible() 078@ThreadSafety(level=ThreadSafetyLevel.INTERFACE_THREADSAFE) 079public abstract class JSONValue 080 implements Serializable, Comparable<JSONValue> 081{ 082 /** 083 * A serial version UID for this serializable class. 084 */ 085 private static final long serialVersionUID = -4446120225858980451L; 086 087 088 089 /** 090 * Retrieves a hash code for this JSON value. 091 * 092 * @return The hash code for this JSON value. 093 */ 094 public abstract int hashCode(); 095 096 097 098 /** 099 * Indicates whether the provided object is equal to this JSON value. 100 * 101 * @param o The object to compare against this JSON value. 102 * 103 * @return {@code true} if the provided object is considered equal to this 104 * JSON value, or {@code false} if not. 105 */ 106 public abstract boolean equals(@Nullable Object o); 107 108 109 110 /** 111 * Indicates whether this JSON value is considered equal to the provided JSON 112 * value, subject to the specified constraints. Note that not all constraints 113 * will apply to all data types. 114 * 115 * @param v The JSON value for which to make the 116 * determination. It must not be {@code null}. 117 * @param ignoreFieldNameCase Indicates whether to ignore differences in the 118 * capitalization of JSON field names. 119 * @param ignoreValueCase Indicates whether to ignore differences in 120 * the capitalization of JSON values that 121 * represent strings. 122 * @param ignoreArrayOrder Indicates whether to ignore differences in the 123 * order of elements in JSON arrays. 124 * 125 * @return {@code true} if this JSON value is considered equal to the 126 * provided JSON value (subject to the specified constraints), or 127 * {@code false} if not. 128 */ 129 public abstract boolean equals(@NotNull JSONValue v, 130 boolean ignoreFieldNameCase, 131 boolean ignoreValueCase, 132 boolean ignoreArrayOrder); 133 134 135 136 /** 137 * Retrieves a string representation of this value as it should appear in a 138 * JSON object, including any necessary quoting, escaping, etc. If the object 139 * containing this value was decoded from a string, then this method will use 140 * the same string representation as in that original object. Otherwise, the 141 * string representation will be constructed. 142 * 143 * @return A string representation of this value as it should appear in a 144 * JSON object. 145 */ 146 @NotNull() 147 public abstract String toString(); 148 149 150 151 /** 152 * Appends a string representation of this value (as it should appear in a 153 * JSON object, including any necessary quoting, escaping, etc.) to the 154 * provided buffer. If the object containing this value was decoded from a 155 * string, then this method will use the same string representation as in that 156 * original object. Otherwise, the string representation will be constructed. 157 * 158 * @param buffer The buffer to which the information should be appended. 159 */ 160 public abstract void toString(@NotNull StringBuilder buffer); 161 162 163 164 /** 165 * Retrieves a single-line string representation of this value as it should 166 * appear in a JSON object, including any necessary quoting, escaping, etc. 167 * 168 * @return A string representation of this value as it should appear in a 169 * JSON object. 170 */ 171 @NotNull() 172 public abstract String toSingleLineString(); 173 174 175 176 /** 177 * Appends a single-line string representation of this value (as it should 178 * appear in a JSON object, including any necessary quoting, escaping, etc.) 179 * to the provided buffer. 180 * 181 * @param buffer The buffer to which the information should be appended. 182 */ 183 public abstract void toSingleLineString(@NotNull StringBuilder buffer); 184 185 186 187 /** 188 * Retrieves a normalized string representation of this value. All equivalent 189 * JSON values must have equivalent normalized representations, even if there 190 * are other legal representations for the value. 191 * 192 * @return A normalized string representation of this value. 193 */ 194 @NotNull() 195 public abstract String toNormalizedString(); 196 197 198 199 /** 200 * Appends a normalized string representation of this value to the provided 201 * buffer. All equivalent JSON values must have equivalent normalized 202 * representations, even if there are other legal representations for the 203 * value. 204 * 205 * @param buffer The buffer to which the information should be appended. 206 */ 207 public abstract void toNormalizedString(@NotNull StringBuilder buffer); 208 209 210 211 /** 212 * Retrieves a normalized string representation of this value using the 213 * provided settings. 214 * 215 * @param ignoreFieldNameCase Indicates whether field names should be 216 * treated in a case-sensitive (if {@code false}) 217 * or case-insensitive (if {@code true}) manner. 218 * @param ignoreValueCase Indicates whether string field values should 219 * be treated in a case-sensitive (if 220 * {@code false}) or case-insensitive (if 221 * {@code true}) manner. 222 * @param ignoreArrayOrder Indicates whether the order of elements in an 223 * array should be considered significant (if 224 * {@code false}) or insignificant (if 225 * {@code true}). 226 * 227 * @return A normalized string representation of this value. 228 */ 229 @NotNull() 230 public abstract String toNormalizedString(boolean ignoreFieldNameCase, 231 boolean ignoreValueCase, 232 boolean ignoreArrayOrder); 233 234 235 236 /** 237 * Appends a normalized string representation of this value to the provided 238 * buffer using the provided settings. 239 * 240 * @param buffer The buffer to which the information should be 241 * appended. 242 * @param ignoreFieldNameCase Indicates whether field names should be 243 * treated in a case-sensitive (if {@code false}) 244 * or case-insensitive (if {@code true}) manner. 245 * @param ignoreValueCase Indicates whether string field values should 246 * be treated in a case-sensitive (if 247 * {@code false}) or case-insensitive (if 248 * {@code true}) manner. 249 * @param ignoreArrayOrder Indicates whether the order of elements in an 250 * array should be considered significant (if 251 * {@code false}) or insignificant (if 252 * {@code true}). 253 */ 254 public abstract void toNormalizedString(@NotNull StringBuilder buffer, 255 boolean ignoreFieldNameCase, 256 boolean ignoreValueCase, 257 boolean ignoreArrayOrder); 258 259 260 261 /** 262 * Retrieves a normalized representation of this value using the provided 263 * settings. 264 * 265 * @param ignoreFieldNameCase Indicates whether field names should be 266 * treated in a case-sensitive (if {@code false}) 267 * or case-insensitive (if {@code true}) manner. 268 * @param ignoreValueCase Indicates whether string field values should 269 * be treated in a case-sensitive (if 270 * {@code false}) or case-insensitive (if 271 * {@code true}) manner. 272 * @param ignoreArrayOrder Indicates whether the order of elements in an 273 * array should be considered significant (if 274 * {@code false}) or insignificant (if 275 * {@code true}). 276 * 277 * @return A normalized representation of this value using the provided 278 * settings. 279 */ 280 @NotNull() 281 public abstract JSONValue toNormalizedValue(boolean ignoreFieldNameCase, 282 boolean ignoreValueCase, 283 boolean ignoreArrayOrder); 284 285 286 287 /** 288 * Appends this value to the provided JSON buffer. This will not include a 289 * field name, so it should only be used for Boolean value elements in an 290 * array. 291 * 292 * @param buffer The JSON buffer to which this value should be appended. 293 */ 294 public abstract void appendToJSONBuffer(@NotNull JSONBuffer buffer); 295 296 297 298 /** 299 * Appends a field with the given name and this value to the provided JSON 300 * buffer. 301 * 302 * @param fieldName The name to use for the field. 303 * @param buffer The JSON buffer to which this value should be appended. 304 */ 305 public abstract void appendToJSONBuffer(@NotNull String fieldName, 306 @NotNull JSONBuffer buffer); 307 308 309 310 /** 311 * Compares the provided value to this value to determine their relative order 312 * in a sorted list. The comparison will be based purely on a lexicographic 313 * comparison of the normalized representations of the values. 314 * 315 * @param value The value to compare to this value. It must not be 316 * {@code null}. 317 * 318 * @return A negative integer if this value should come before the provided 319 * value in a sorted list, a positive integer if this value should 320 * come after the provided value in a sorted list, or zero if the 321 * provided value can be considered equal to this value. 322 */ 323 @Override() 324 public final int compareTo(@NotNull final JSONValue value) 325 { 326 final String thisNormalizedRepresentation = 327 toNormalizedString(false, true, false); 328 final String providedNormalizedRepresentation = 329 value.toNormalizedString(false, true, false); 330 return thisNormalizedRepresentation.compareTo( 331 providedNormalizedRepresentation); 332 } 333}