| 1 | package com.github.dakusui.json; | |
| 2 | ||
| 3 | import com.google.gson.*; | |
| 4 | ||
| 5 | import java.util.*; | |
| 6 | import java.util.Map.Entry; | |
| 7 | ||
| 8 | import static com.github.dakusui.json.JsonSummarizer.*; | |
| 9 | import static com.github.dakusui.valid8j.Requires.require; | |
| 10 | import static com.github.dakusui.valid8j_pcond.forms.Predicates.callp; | |
| 11 | import static java.util.Objects.requireNonNull; | |
| 12 | ||
| 13 | public class JsonUtils { | |
| 14 | ||
| 15 | static final ThreadLocal<JsonParser> JSON_PARSER; | |
| 16 | ||
| 17 | static { | |
| 18 | JSON_PARSER = new ThreadLocal<>(); | |
| 19 | } | |
| 20 | ||
| 21 | public static String summarizeJsonElement(JsonElement jsonElement) { | |
| 22 |
2
1. summarizeJsonElement : negated conditional → KILLED 2. summarizeJsonElement : negated conditional → KILLED |
if (jsonElement == null || jsonElement.isJsonNull()) { |
| 23 |
1
1. summarizeJsonElement : replaced return value with "" for com/github/dakusui/json/JsonUtils::summarizeJsonElement → NO_COVERAGE |
return "null"; |
| 24 | } | |
| 25 | JsonElement compact = JsonSummarizer.compactJsonElement(jsonElement, 3, 3); | |
| 26 | ||
| 27 |
1
1. summarizeJsonElement : negated conditional → KILLED |
if (jsonElement.isJsonPrimitive()) { |
| 28 |
1
1. summarizeJsonElement : replaced return value with "" for com/github/dakusui/json/JsonUtils::summarizeJsonElement → KILLED |
return compact + " (primitive)"; |
| 29 | } | |
| 30 |
1
1. summarizeJsonElement : negated conditional → KILLED |
if (jsonElement.isJsonArray()) { |
| 31 |
1
1. summarizeJsonElement : replaced return value with "" for com/github/dakusui/json/JsonUtils::summarizeJsonElement → NO_COVERAGE |
return focusedArray((JsonArray) compact) + " (array: size=" + jsonElement.getAsJsonArray().size() + ")"; |
| 32 | } | |
| 33 |
1
1. summarizeJsonElement : negated conditional → KILLED |
if (jsonElement.isJsonObject()) { |
| 34 |
1
1. summarizeJsonElement : replaced return value with "" for com/github/dakusui/json/JsonUtils::summarizeJsonElement → KILLED |
return focusedObject((JsonObject) compact) + " (object: " + jsonElement.getAsJsonObject().entrySet().size() + " entries)"; |
| 35 | } | |
| 36 |
1
1. summarizeJsonElement : replaced return value with "" for com/github/dakusui/json/JsonUtils::summarizeJsonElement → NO_COVERAGE |
return compact + " (unknown)"; |
| 37 | } | |
| 38 | ||
| 39 | /** | |
| 40 | * Returns a string representation of a path to a JSON element {@code target} in {@code root} JSON object node. | |
| 41 | * | |
| 42 | * @param target A JSON element whose path in {@code root} is searched for. | |
| 43 | * @param root A root JSON object node where {@code target}'s path is searched. | |
| 44 | * @return A string representation of path to {@code target} in {@code root}. | |
| 45 | */ | |
| 46 | public static String findPathStringOf(JsonElement target, JsonObject root) { | |
| 47 |
1
1. findPathStringOf : replaced return value with "" for com/github/dakusui/json/JsonUtils::findPathStringOf → KILLED |
return jsonpathToString(findPathOf(target, root)); |
| 48 | } | |
| 49 | ||
| 50 | public static List<Object> findPathOf(JsonElement target, JsonObject root) { | |
| 51 |
1
1. findPathOf : replaced return value with Collections.emptyList for com/github/dakusui/json/JsonUtils::findPathOf → KILLED |
return buildPathInfo(root).get(target); |
| 52 | } | |
| 53 | ||
| 54 | @SafeVarargs | |
| 55 | public static JsonObject createSummaryJsonObjectFromPaths(JsonObject rootJsonObject, List<Object>... paths) { | |
| 56 | JsonObject ret = new JsonObject(); | |
| 57 | for (List<Object> eachPath : paths) { | |
| 58 | ret = merge(requireJsonObject(createSummaryJsonElementFromPath(rootJsonObject, eachPath)), ret); | |
| 59 | } | |
| 60 |
1
1. createSummaryJsonObjectFromPaths : replaced return value with null for com/github/dakusui/json/JsonUtils::createSummaryJsonObjectFromPaths → SURVIVED |
return ret; |
| 61 | } | |
| 62 | ||
| 63 | private static JsonElement createSummaryJsonElementFromPath(JsonObject rootJsonObject, List<Object> path) { | |
| 64 |
2
1. createSummaryJsonElementFromPath : replaced return value with null for com/github/dakusui/json/JsonUtils::createSummaryJsonElementFromPath → KILLED 2. createSummaryJsonElementFromPath : negated conditional → KILLED |
return path.isEmpty() ? |
| 65 | focusedElement(compactJsonObject(rootJsonObject, 3, 3)) : | |
| 66 |
1
1. createSummaryJsonElementFromPath : negated conditional → SURVIVED |
path.size() == 1 ? |
| 67 | summaryTopLevelElement(rootJsonObject, path.getFirst()) : | |
| 68 |
1
1. createSummaryJsonElementFromPath : Replaced integer subtraction with addition → KILLED |
summaryObject(rootJsonObject, path.subList(0, path.size() - 1), path.getLast()); |
| 69 | } | |
| 70 | ||
| 71 | private static JsonElement summaryTopLevelElement(JsonObject rootJsonObject, Object topLevelAttribute) { | |
| 72 | assert topLevelAttribute instanceof String; | |
| 73 | JsonObject ret = new JsonObject(); | |
| 74 | String topLevelAttributeName = (String) topLevelAttribute; | |
| 75 |
1
1. summaryTopLevelElement : removed call to com/google/gson/JsonObject::add → SURVIVED |
ret.add(topLevelAttributeName, focusedElement(asJsonElement(rootJsonObject, topLevelAttribute))); |
| 76 |
1
1. summaryTopLevelElement : replaced return value with null for com/github/dakusui/json/JsonUtils::summaryTopLevelElement → KILLED |
return ret; |
| 77 | } | |
| 78 | ||
| 79 | private static JsonObject requireJsonObject(JsonElement jsonElement) { | |
| 80 |
1
1. requireJsonObject : replaced return value with null for com/github/dakusui/json/JsonUtils::requireJsonObject → KILLED |
return require(jsonElement, callp("isJsonObject")).getAsJsonObject(); |
| 81 | } | |
| 82 | ||
| 83 | enum JsonTypes { | |
| 84 | OBJECT { | |
| 85 | @Override | |
| 86 | JsonObject _validate(JsonElement value) throws JsonTypeMismatchException { | |
| 87 |
1
1. _validate : negated conditional → KILLED |
if (!value.isJsonObject()) { |
| 88 | throw new JsonTypeMismatchException(value, this); | |
| 89 | } | |
| 90 |
1
1. _validate : replaced return value with null for com/github/dakusui/json/JsonUtils$JsonTypes$1::_validate → KILLED |
return value.getAsJsonObject(); |
| 91 | } | |
| 92 | }, | |
| 93 | ARRAY { | |
| 94 | @Override | |
| 95 | JsonArray _validate(JsonElement value) throws JsonTypeMismatchException { | |
| 96 |
1
1. _validate : negated conditional → KILLED |
if (!value.isJsonArray()) { |
| 97 | throw new JsonTypeMismatchException(value, this); | |
| 98 | } | |
| 99 |
1
1. _validate : replaced return value with null for com/github/dakusui/json/JsonUtils$JsonTypes$2::_validate → KILLED |
return value.getAsJsonArray(); |
| 100 | } | |
| 101 | ||
| 102 | }, | |
| 103 | PRIMITIVE { | |
| 104 | @Override | |
| 105 | JsonPrimitive _validate(JsonElement value) | |
| 106 | throws JsonTypeMismatchException { | |
| 107 |
1
1. _validate : negated conditional → KILLED |
if (!value.isJsonPrimitive()) { |
| 108 | throw new JsonTypeMismatchException(value, this); | |
| 109 | } | |
| 110 |
1
1. _validate : replaced return value with null for com/github/dakusui/json/JsonUtils$JsonTypes$3::_validate → KILLED |
return value.getAsJsonPrimitive(); |
| 111 | } | |
| 112 | }, | |
| 113 | NULL { | |
| 114 | @Override | |
| 115 | JsonNull _validate(JsonElement value) throws JsonTypeMismatchException { | |
| 116 |
1
1. _validate : negated conditional → NO_COVERAGE |
if (!value.isJsonNull()) { |
| 117 | throw new JsonTypeMismatchException(value, this); | |
| 118 | } | |
| 119 |
1
1. _validate : replaced return value with null for com/github/dakusui/json/JsonUtils$JsonTypes$4::_validate → NO_COVERAGE |
return value.getAsJsonNull(); |
| 120 | } | |
| 121 | }; | |
| 122 | ||
| 123 | abstract JsonElement _validate(JsonElement value) | |
| 124 | throws JsonTypeMismatchException; | |
| 125 | ||
| 126 | JsonElement validate(JsonElement value) throws JsonTypeMismatchException { | |
| 127 |
1
1. validate : negated conditional → KILLED |
if (value == null) { |
| 128 | return null; | |
| 129 | } | |
| 130 |
1
1. validate : replaced return value with null for com/github/dakusui/json/JsonUtils$JsonTypes::validate → KILLED |
return _validate(value); |
| 131 | } | |
| 132 | } | |
| 133 | ||
| 134 | public static JsonElement asJsonElementWithDefault(JsonElement base, JsonElement defaultValue, int from, Object[] path) | |
| 135 | throws JsonInvalidPathException { | |
| 136 | JsonElement ret = _asJsonElement(base, defaultValue, from, path); | |
| 137 | // // | |
| 138 | // TODO: To workaround test failure. Need to come up with more consistent | |
| 139 | // policy to handle JsonNull.INSTANCE. | |
| 140 |
2
1. asJsonElementWithDefault : negated conditional → KILLED 2. asJsonElementWithDefault : negated conditional → KILLED |
if (ret == null || ret == JsonNull.INSTANCE) { |
| 141 | ret = defaultValue; | |
| 142 | } | |
| 143 |
1
1. asJsonElementWithDefault : replaced return value with null for com/github/dakusui/json/JsonUtils::asJsonElementWithDefault → KILLED |
return ret; |
| 144 | } | |
| 145 | ||
| 146 | public static JsonElement asJsonElement(JsonElement base, int from, Object[] path) throws JsonInvalidPathException { | |
| 147 | JsonElement ret = _asJsonElement(base, null, from, path); | |
| 148 |
1
1. asJsonElement : negated conditional → KILLED |
if (ret == null) { |
| 149 | throw new JsonPathNotFoundException(base, path, from); | |
| 150 | } | |
| 151 |
1
1. asJsonElement : replaced return value with null for com/github/dakusui/json/JsonUtils::asJsonElement → KILLED |
return ret; |
| 152 | } | |
| 153 | ||
| 154 | private static JsonElement _asJsonElement(JsonElement base, | |
| 155 | JsonElement defaultValue, int from, Object[] path) | |
| 156 | throws JsonInvalidPathException { | |
| 157 |
2
1. _asJsonElement : negated conditional → KILLED 2. _asJsonElement : negated conditional → KILLED |
if (path.length == from || base == null) { |
| 158 |
1
1. _asJsonElement : replaced return value with null for com/github/dakusui/json/JsonUtils::_asJsonElement → KILLED |
return base; |
| 159 | } | |
| 160 | JsonElement newbase; | |
| 161 |
1
1. _asJsonElement : negated conditional → KILLED |
if (path[from] == null) { |
| 162 | throw new JsonInvalidPathException(base, path, from); // invalid path; | |
| 163 | } | |
| 164 |
1
1. _asJsonElement : negated conditional → KILLED |
if (base.isJsonObject()) { |
| 165 | newbase = base.getAsJsonObject().get(path[from].toString()); | |
| 166 | } else { | |
| 167 |
1
1. _asJsonElement : negated conditional → KILLED |
if (base.isJsonArray()) { |
| 168 | Integer index; | |
| 169 |
3
1. _asJsonElement : negated conditional → KILLED 2. _asJsonElement : negated conditional → KILLED 3. _asJsonElement : negated conditional → KILLED |
if ((path[from] instanceof Integer) || (path[from] instanceof Long) |
| 170 | || (path[from] instanceof Short)) { | |
| 171 | index = ((Number) path[from]).intValue(); | |
| 172 | } else { | |
| 173 |
1
1. _asJsonElement : negated conditional → KILLED |
if ((index = parseInt(path[from])) == null) { |
| 174 | throw new JsonInvalidPathException(base, path, from); | |
| 175 | } | |
| 176 | } | |
| 177 |
4
1. _asJsonElement : changed conditional boundary → SURVIVED 2. _asJsonElement : negated conditional → KILLED 3. _asJsonElement : negated conditional → KILLED 4. _asJsonElement : changed conditional boundary → KILLED |
if (index < 0 || index >= base.getAsJsonArray().size()) { |
| 178 | throw new JsonIndexOutOfBoundsException(base, path, from); | |
| 179 | } | |
| 180 | newbase = base.getAsJsonArray().get(index); | |
| 181 |
1
1. _asJsonElement : negated conditional → NO_COVERAGE |
} else if (base.isJsonPrimitive()) { |
| 182 | return null; | |
| 183 | } else { | |
| 184 | // JsonNull | |
| 185 | return null; | |
| 186 | } | |
| 187 | } | |
| 188 | ||
| 189 |
1
1. _asJsonElement : Replaced integer addition with subtraction → KILLED |
JsonElement ret = _asJsonElement(newbase, defaultValue, from + 1, path); |
| 190 | ||
| 191 |
1
1. _asJsonElement : negated conditional → KILLED |
if (ret == null) { |
| 192 |
1
1. _asJsonElement : negated conditional → SURVIVED |
if (defaultValue != null) { |
| 193 |
1
1. _asJsonElement : replaced return value with null for com/github/dakusui/json/JsonUtils::_asJsonElement → SURVIVED |
return defaultValue; |
| 194 | } | |
| 195 | } | |
| 196 |
1
1. _asJsonElement : replaced return value with null for com/github/dakusui/json/JsonUtils::_asJsonElement → KILLED |
return ret; |
| 197 | } | |
| 198 | ||
| 199 | private static Integer parseInt(Object object) { | |
| 200 | Integer ret = null; | |
| 201 | try { | |
| 202 | String str = object.toString(); | |
| 203 | ret = Integer.parseInt(str); | |
| 204 | } catch (NumberFormatException ignored) { | |
| 205 | } | |
| 206 | ||
| 207 |
1
1. parseInt : replaced Integer return value with 0 for com/github/dakusui/json/JsonUtils::parseInt → KILLED |
return ret; |
| 208 | } | |
| 209 | ||
| 210 | public static boolean hasPath(JsonElement base, Object... path) { | |
| 211 | try { | |
| 212 |
2
1. hasPath : negated conditional → KILLED 2. hasPath : replaced boolean return with true for com/github/dakusui/json/JsonUtils::hasPath → KILLED |
return _asJsonElement(base, null, 0, path) != null; |
| 213 | } catch (JsonInvalidPathException e) { | |
| 214 |
1
1. hasPath : replaced boolean return with true for com/github/dakusui/json/JsonUtils::hasPath → NO_COVERAGE |
return false; |
| 215 | } | |
| 216 | } | |
| 217 | ||
| 218 | public static JsonObject asJsonObjectWithDefault(JsonObject base, | |
| 219 | JsonObject defaultValue, Object... path) | |
| 220 | throws JsonTypeMismatchException, | |
| 221 | JsonInvalidPathException { | |
| 222 |
1
1. asJsonObjectWithDefault : replaced return value with null for com/github/dakusui/json/JsonUtils::asJsonObjectWithDefault → KILLED |
return (JsonObject) JsonTypes.OBJECT.validate(asJsonElementWithDefault( |
| 223 | base, defaultValue, path)); | |
| 224 | } | |
| 225 | ||
| 226 | public static JsonObject asJsonObject(JsonObject base, Object... path) | |
| 227 | throws JsonTypeMismatchException, | |
| 228 | JsonInvalidPathException { | |
| 229 |
1
1. asJsonObject : replaced return value with null for com/github/dakusui/json/JsonUtils::asJsonObject → KILLED |
return asJsonObjectWithDefault(base, null, path); |
| 230 | } | |
| 231 | ||
| 232 | public static JsonObject asJsonObjectWithPromotion(JsonElement base, | |
| 233 | String[] prioritizedKeys, Object... path) | |
| 234 | throws JsonInvalidPathException, | |
| 235 | JsonTypeMismatchException { | |
| 236 | JsonObject ret; | |
| 237 | JsonElement elem = asJsonElement(base, path); | |
| 238 |
1
1. asJsonObjectWithPromotion : negated conditional → KILLED |
if (elem.isJsonObject()) { |
| 239 | ret = elem.getAsJsonObject(); | |
| 240 | } else { | |
| 241 | JsonArray arr = asJsonArrayWithPromotion(base, path); | |
| 242 | ret = new JsonObject(); | |
| 243 | int i = 0; | |
| 244 | for (JsonElement item : arr) { | |
| 245 |
2
1. asJsonObjectWithPromotion : changed conditional boundary → SURVIVED 2. asJsonObjectWithPromotion : negated conditional → KILLED |
if (i >= prioritizedKeys.length) { |
| 246 |
1
1. asJsonObjectWithPromotion : negated conditional → NO_COVERAGE |
if (prioritizedKeys.length == 0) { |
| 247 | throw new JsonTypeMismatchException(elem, | |
| 248 | "An object or an empty array are acceptable"); | |
| 249 | } else { | |
| 250 | throw new JsonTypeMismatchException( | |
| 251 | elem, | |
| 252 | String | |
| 253 | .format( | |
| 254 | "A primitive, an array whose length is less than or equal to %d, or an object are acceptable", | |
| 255 | prioritizedKeys.length)); | |
| 256 | } | |
| 257 | } | |
| 258 | String key = prioritizedKeys[i]; | |
| 259 |
1
1. asJsonObjectWithPromotion : removed call to com/google/gson/JsonObject::add → KILLED |
ret.add(key, item); |
| 260 |
1
1. asJsonObjectWithPromotion : Changed increment from 1 to -1 → SURVIVED |
i++; |
| 261 | } | |
| 262 | } | |
| 263 |
1
1. asJsonObjectWithPromotion : replaced return value with null for com/github/dakusui/json/JsonUtils::asJsonObjectWithPromotion → KILLED |
return ret; |
| 264 | } | |
| 265 | ||
| 266 | public static JsonArray asJsonArrayWithPromotion(JsonElement base, | |
| 267 | Object... path) throws | |
| 268 | JsonInvalidPathException, JsonTypeMismatchException { | |
| 269 | JsonArray ret; | |
| 270 | JsonElement elem = asJsonElement(base, path); | |
| 271 |
1
1. asJsonArrayWithPromotion : negated conditional → KILLED |
if (elem.isJsonObject()) { |
| 272 | throw new JsonTypeMismatchException(elem, JsonTypes.ARRAY, | |
| 273 | JsonTypes.NULL, JsonTypes.PRIMITIVE); | |
| 274 | } | |
| 275 |
1
1. asJsonArrayWithPromotion : negated conditional → KILLED |
if (elem.isJsonArray()) { |
| 276 | ret = elem.getAsJsonArray(); | |
| 277 | } else { | |
| 278 | ret = new JsonArray(); | |
| 279 |
1
1. asJsonArrayWithPromotion : removed call to com/google/gson/JsonArray::add → KILLED |
ret.add(elem); |
| 280 | } | |
| 281 |
1
1. asJsonArrayWithPromotion : replaced return value with null for com/github/dakusui/json/JsonUtils::asJsonArrayWithPromotion → KILLED |
return ret; |
| 282 | } | |
| 283 | ||
| 284 | public static JsonArray asJsonArray(JsonElement base, Object... path) | |
| 285 | throws JsonException { | |
| 286 |
1
1. asJsonArray : replaced return value with null for com/github/dakusui/json/JsonUtils::asJsonArray → KILLED |
return asJsonArrayWithDefault(base, null, path); |
| 287 | } | |
| 288 | ||
| 289 | public static JsonArray asJsonArrayWithDefault(JsonElement base, | |
| 290 | JsonArray defaultValue, Object... path) throws JsonTypeMismatchException, | |
| 291 | JsonInvalidPathException { | |
| 292 |
1
1. asJsonArrayWithDefault : replaced return value with null for com/github/dakusui/json/JsonUtils::asJsonArrayWithDefault → KILLED |
return (JsonArray) JsonTypes.ARRAY.validate(asJsonElementWithDefault(base, |
| 293 | defaultValue, path)); | |
| 294 | } | |
| 295 | ||
| 296 | public static JsonElement asJsonElementWithDefault(JsonElement base, | |
| 297 | JsonElement defaultValue, Object... path) | |
| 298 | throws JsonInvalidPathException { | |
| 299 |
1
1. asJsonElementWithDefault : replaced return value with null for com/github/dakusui/json/JsonUtils::asJsonElementWithDefault → KILLED |
return asJsonElementWithDefault(base, defaultValue, 0, path); |
| 300 | } | |
| 301 | ||
| 302 | public static JsonElement asJsonElement(JsonElement base, Object... path) | |
| 303 | throws JsonInvalidPathException { | |
| 304 |
1
1. asJsonElement : replaced return value with null for com/github/dakusui/json/JsonUtils::asJsonElement → KILLED |
return asJsonElement(base, 0, path); |
| 305 | } | |
| 306 | ||
| 307 | public static String asString(JsonElement base, Object... path) | |
| 308 | throws JsonTypeMismatchException, | |
| 309 | JsonInvalidPathException { | |
| 310 | JsonPrimitive prim = (JsonPrimitive) JsonTypes.PRIMITIVE | |
| 311 | .validate(asJsonElement(base, path)); | |
| 312 |
1
1. asString : negated conditional → KILLED |
if (prim == null) { |
| 313 |
1
1. asString : replaced return value with "" for com/github/dakusui/json/JsonUtils::asString → NO_COVERAGE |
return null; |
| 314 | } | |
| 315 |
1
1. asString : replaced return value with "" for com/github/dakusui/json/JsonUtils::asString → KILLED |
return prim.getAsString(); |
| 316 | } | |
| 317 | ||
| 318 | public static String asStringWithDefault(JsonElement base, | |
| 319 | String defaultValue, Object... path) throws JsonTypeMismatchException, | |
| 320 | JsonInvalidPathException { | |
| 321 | JsonElement dv = null; | |
| 322 |
1
1. asStringWithDefault : negated conditional → KILLED |
if (defaultValue != null) { |
| 323 | dv = new JsonPrimitive(defaultValue); | |
| 324 | } | |
| 325 | JsonPrimitive prim = (JsonPrimitive) JsonTypes.PRIMITIVE | |
| 326 | .validate(asJsonElementWithDefault(base, dv, path)); | |
| 327 |
1
1. asStringWithDefault : negated conditional → KILLED |
if (prim == null) { |
| 328 |
1
1. asStringWithDefault : replaced return value with "" for com/github/dakusui/json/JsonUtils::asStringWithDefault → SURVIVED |
return null; |
| 329 | } | |
| 330 |
1
1. asStringWithDefault : replaced return value with "" for com/github/dakusui/json/JsonUtils::asStringWithDefault → KILLED |
return prim.getAsString(); |
| 331 | } | |
| 332 | ||
| 333 | public static int asInt(JsonElement base, Object... path) | |
| 334 | throws JsonTypeMismatchException, | |
| 335 | JsonFormatException, JsonInvalidPathException { | |
| 336 | try { | |
| 337 |
1
1. asInt : replaced int return with 0 for com/github/dakusui/json/JsonUtils::asInt → KILLED |
return Integer.parseInt(requireNonNull(asString(base, path))); |
| 338 | } catch (NumberFormatException e) { | |
| 339 | throw new JsonFormatException(asJsonElement(base, path)); | |
| 340 | } | |
| 341 | } | |
| 342 | ||
| 343 | public static int asIntWithDefault(JsonElement base, int defaultValue, | |
| 344 | Object... path) throws JsonTypeMismatchException, | |
| 345 | JsonFormatException, JsonInvalidPathException { | |
| 346 | try { | |
| 347 |
1
1. asIntWithDefault : replaced int return with 0 for com/github/dakusui/json/JsonUtils::asIntWithDefault → SURVIVED |
return Integer.parseInt(requireNonNull(asStringWithDefault(base, Integer.toString(defaultValue), path))); |
| 348 | } catch (NumberFormatException e) { | |
| 349 | throw new JsonFormatException(asJsonElement(base, path)); | |
| 350 | } | |
| 351 | } | |
| 352 | ||
| 353 | public static long asLong(JsonElement base, Object... path) | |
| 354 | throws JsonTypeMismatchException, | |
| 355 | JsonFormatException, JsonInvalidPathException { | |
| 356 | try { | |
| 357 |
1
1. asLong : replaced long return with 0 for com/github/dakusui/json/JsonUtils::asLong → KILLED |
return Long.parseLong(requireNonNull(asString(base, path))); |
| 358 | } catch (NumberFormatException e) { | |
| 359 | throw new JsonFormatException(asJsonElement(base, path)); | |
| 360 | } | |
| 361 | } | |
| 362 | ||
| 363 | @SuppressWarnings("UnusedDeclaration") | |
| 364 | public static long asLongWithDefault(JsonElement base, long defaultValue, | |
| 365 | Object... path) throws JsonTypeMismatchException, | |
| 366 | JsonFormatException, JsonInvalidPathException { | |
| 367 | try { | |
| 368 |
1
1. asLongWithDefault : replaced long return with 0 for com/github/dakusui/json/JsonUtils::asLongWithDefault → NO_COVERAGE |
return Long.parseLong(requireNonNull(asStringWithDefault(base, Long.toString(defaultValue), path))); |
| 369 | } catch (NumberFormatException e) { | |
| 370 | throw new JsonFormatException(asJsonElement(base, path)); | |
| 371 | } | |
| 372 | } | |
| 373 | ||
| 374 | @SuppressWarnings("UnusedDeclaration") | |
| 375 | public static float asFloat(JsonElement base, Object... path) | |
| 376 | throws JsonTypeMismatchException, | |
| 377 | JsonFormatException, JsonInvalidPathException { | |
| 378 | try { | |
| 379 |
1
1. asFloat : replaced float return with 0.0f for com/github/dakusui/json/JsonUtils::asFloat → NO_COVERAGE |
return Float.parseFloat(requireNonNull(asString(base, path))); |
| 380 | } catch (NumberFormatException e) { | |
| 381 | throw new JsonFormatException(asJsonElement(base, path)); | |
| 382 | } | |
| 383 | } | |
| 384 | ||
| 385 | @SuppressWarnings("UnusedDeclaration") | |
| 386 | public static float asFloatWithDefault(JsonElement base, float defaultValue, | |
| 387 | Object... path) throws JsonTypeMismatchException, | |
| 388 | JsonFormatException, JsonInvalidPathException { | |
| 389 | try { | |
| 390 |
1
1. asFloatWithDefault : replaced float return with 0.0f for com/github/dakusui/json/JsonUtils::asFloatWithDefault → NO_COVERAGE |
return Float.parseFloat(requireNonNull(asStringWithDefault(base, Float.toString(defaultValue), path))); |
| 391 | } catch (NumberFormatException e) { | |
| 392 | throw new JsonFormatException(asJsonElement(base, path)); | |
| 393 | } | |
| 394 | } | |
| 395 | ||
| 396 | public static double asDouble(JsonElement base, Object... path) | |
| 397 | throws JsonException { | |
| 398 | try { | |
| 399 |
1
1. asDouble : replaced double return with 0.0d for com/github/dakusui/json/JsonUtils::asDouble → KILLED |
return Double.parseDouble(requireNonNull(asString(base, path))); |
| 400 | } catch (NumberFormatException e) { | |
| 401 | throw new JsonFormatException(asJsonElement(base, path)); | |
| 402 | } | |
| 403 | } | |
| 404 | ||
| 405 | public static double asDoubleWithDefault(JsonElement base, | |
| 406 | double defaultValue, Object... path) throws JsonTypeMismatchException, | |
| 407 | JsonFormatException, JsonInvalidPathException { | |
| 408 | try { | |
| 409 |
1
1. asDoubleWithDefault : replaced double return with 0.0d for com/github/dakusui/json/JsonUtils::asDoubleWithDefault → KILLED |
return Double.parseDouble(requireNonNull(asStringWithDefault(base, Double.toString(defaultValue), path))); |
| 410 | } catch (NumberFormatException e) { | |
| 411 | throw new JsonFormatException(asJsonElement(base, path)); | |
| 412 | } | |
| 413 | } | |
| 414 | ||
| 415 | public static Map<JsonElement, List<Object>> buildPathInfo(JsonObject root) { | |
| 416 | Map<JsonElement, List<Object>> ret = new HashMap<>(); | |
| 417 | ret.put(root, List.of()); | |
| 418 | List<Object> path = new LinkedList<>(); | |
| 419 |
1
1. buildPathInfo : removed call to com/github/dakusui/json/JsonUtils::buildPathInfo → KILLED |
buildPathInfo(ret, path, root); |
| 420 |
1
1. buildPathInfo : replaced return value with Collections.emptyMap for com/github/dakusui/json/JsonUtils::buildPathInfo → KILLED |
return ret; |
| 421 | } | |
| 422 | ||
| 423 | private static void buildPathInfo(Map<JsonElement, List<Object>> map, List<Object> path, JsonElement elem) { | |
| 424 |
1
1. buildPathInfo : negated conditional → KILLED |
if (!elem.isJsonNull()) { |
| 425 |
1
1. buildPathInfo : negated conditional → KILLED |
if (elem.isJsonArray()) { |
| 426 |
1
1. buildPathInfo : removed call to com/github/dakusui/json/JsonUtils::buildPathInfo → KILLED |
buildPathInfo(map, path, elem.getAsJsonArray()); |
| 427 |
1
1. buildPathInfo : negated conditional → KILLED |
} else if (elem.isJsonObject()) { |
| 428 |
1
1. buildPathInfo : removed call to com/github/dakusui/json/JsonUtils::buildPathInfo → KILLED |
buildPathInfo(map, path, elem.getAsJsonObject()); |
| 429 | } | |
| 430 | map.put(elem, new ArrayList<>(path)); | |
| 431 | } | |
| 432 | } | |
| 433 | ||
| 434 | private static void buildPathInfo(Map<JsonElement, List<Object>> map, List<Object> path, JsonArray arr) { | |
| 435 | int len = arr.size(); | |
| 436 |
2
1. buildPathInfo : changed conditional boundary → KILLED 2. buildPathInfo : negated conditional → KILLED |
for (int i = 0; i < len; i++) { |
| 437 | path.add(i); | |
| 438 |
1
1. buildPathInfo : removed call to com/github/dakusui/json/JsonUtils::buildPathInfo → KILLED |
buildPathInfo(map, path, arr.get(i)); |
| 439 | path.removeLast(); | |
| 440 | } | |
| 441 | } | |
| 442 | ||
| 443 | private static void buildPathInfo(Map<JsonElement, List<Object>> map, List<Object> path, JsonObject obj) { | |
| 444 | for (Entry<String, JsonElement> ent : obj.entrySet()) { | |
| 445 | String k = ent.getKey(); | |
| 446 | JsonElement elem = ent.getValue(); | |
| 447 | path.add(k); | |
| 448 |
1
1. buildPathInfo : removed call to com/github/dakusui/json/JsonUtils::buildPathInfo → KILLED |
buildPathInfo(map, path, elem); |
| 449 | path.removeLast(); | |
| 450 | } | |
| 451 | } | |
| 452 | ||
| 453 | private static String jsonpathToString(List<Object> path) { | |
| 454 | StringBuilder buf = new StringBuilder(); | |
| 455 | for (Object each : path) { | |
| 456 |
1
1. jsonpathToString : negated conditional → KILLED |
if (each instanceof Number) { |
| 457 | buf.append("[").append(each).append("]"); | |
| 458 | } else { | |
| 459 | buf.append(".").append(quoteIfNonAlphanumericalIsContained(each)); | |
| 460 | } | |
| 461 | } | |
| 462 |
1
1. jsonpathToString : negated conditional → KILLED |
if (buf.isEmpty()) |
| 463 | buf.append('.'); | |
| 464 |
1
1. jsonpathToString : replaced return value with "" for com/github/dakusui/json/JsonUtils::jsonpathToString → KILLED |
return buf.toString(); |
| 465 | } | |
| 466 | ||
| 467 | private static String quoteIfNonAlphanumericalIsContained(Object obj) { | |
| 468 |
1
1. quoteIfNonAlphanumericalIsContained : negated conditional → KILLED |
if (obj instanceof String s) { |
| 469 |
2
1. quoteIfNonAlphanumericalIsContained : negated conditional → KILLED 2. quoteIfNonAlphanumericalIsContained : replaced return value with "" for com/github/dakusui/json/JsonUtils::quoteIfNonAlphanumericalIsContained → KILLED |
return s.matches("[a-zA-Z_][a-zA-Z0-9_]+") ? s : '"' + escape(s) + '"'; |
| 470 | } | |
| 471 |
1
1. quoteIfNonAlphanumericalIsContained : replaced return value with "" for com/github/dakusui/json/JsonUtils::quoteIfNonAlphanumericalIsContained → NO_COVERAGE |
return Objects.toString(obj); |
| 472 | } | |
| 473 | ||
| 474 | ||
| 475 | /** | |
| 476 | * <a href="https://stackoverflow.com/a/61628600/820227">Answer by Dan in stackoverflow.com</a> | |
| 477 | * escape() | |
| 478 | * Escape a give String to make it safe to be printed or stored. | |
| 479 | * | |
| 480 | * @param s The input String. | |
| 481 | * @return The output String. | |
| 482 | **/ | |
| 483 | private static String escape(String s) { | |
| 484 |
1
1. escape : replaced return value with "" for com/github/dakusui/json/JsonUtils::escape → KILLED |
return s.replace("\\", "\\\\") |
| 485 | .replace("\t", "\\t") | |
| 486 | .replace("\b", "\\b") | |
| 487 | .replace("\n", "\\n") | |
| 488 | .replace("\r", "\\r") | |
| 489 | .replace("\f", "\\f") | |
| 490 | .replace("\'", "\\'") // <== not necessary | |
| 491 | .replace("\"", "\\\""); | |
| 492 | } | |
| 493 | ||
| 494 | public static JsonElement toJson(String str) { | |
| 495 |
1
1. toJson : replaced return value with null for com/github/dakusui/json/JsonUtils::toJson → KILLED |
return JsonParser.parseString(str); |
| 496 | } | |
| 497 | ||
| 498 | public static Iterator<String> keyIterator(final JsonObject json) { | |
| 499 |
1
1. keyIterator : replaced return value with null for com/github/dakusui/json/JsonUtils::keyIterator → KILLED |
return new Iterator<>() { |
| 500 | final Iterator<Entry<String, JsonElement>> iEntries = json.entrySet() | |
| 501 | .iterator(); | |
| 502 | ||
| 503 | public boolean hasNext() { | |
| 504 |
2
1. hasNext : replaced boolean return with true for com/github/dakusui/json/JsonUtils$1::hasNext → KILLED 2. hasNext : replaced boolean return with false for com/github/dakusui/json/JsonUtils$1::hasNext → KILLED |
return iEntries.hasNext(); |
| 505 | } | |
| 506 | ||
| 507 | public String next() { | |
| 508 |
1
1. next : replaced return value with "" for com/github/dakusui/json/JsonUtils$1::next → KILLED |
return iEntries.next().getKey(); |
| 509 | } | |
| 510 | ||
| 511 | public void remove() { | |
| 512 |
1
1. remove : removed call to java/util/Iterator::remove → NO_COVERAGE |
iEntries.remove(); |
| 513 | } | |
| 514 | }; | |
| 515 | } | |
| 516 | ||
| 517 | public static String formatPath(Object... relPath) { | |
| 518 | StringBuilder ret = new StringBuilder(); | |
| 519 | for (Object obj : relPath) { | |
| 520 |
1
1. formatPath : negated conditional → KILLED |
if (!ret.isEmpty()) |
| 521 | ret.append("/"); | |
| 522 | ret.append(obj); | |
| 523 | } | |
| 524 |
1
1. formatPath : replaced return value with "" for com/github/dakusui/json/JsonUtils::formatPath → KILLED |
return ret.toString(); |
| 525 | } | |
| 526 | ||
| 527 | public static JsonObject merge(JsonObject left, JsonObject right) throws JsonInvalidPathException { | |
| 528 |
1
1. merge : replaced return value with null for com/github/dakusui/json/JsonUtils::merge → KILLED |
return merge(left, right, new LinkedList<>()); |
| 529 | } | |
| 530 | ||
| 531 | public static JsonObject merge(JsonObject left, JsonObject right, List<Object> relPath) throws JsonInvalidPathException { | |
| 532 | JsonObject ret = new JsonObject(); | |
| 533 | for (Entry<String, JsonElement> each : left.entrySet()) { | |
| 534 |
1
1. merge : negated conditional → KILLED |
if (right.has(each.getKey())) { |
| 535 |
2
1. merge : negated conditional → KILLED 2. merge : negated conditional → KILLED |
if (each.getValue().isJsonObject() && right.get(each.getKey()).isJsonObject()) { |
| 536 |
1
1. merge : removed call to com/google/gson/JsonObject::add → KILLED |
ret.add( |
| 537 | each.getKey(), | |
| 538 | merge(each.getValue().getAsJsonObject(), right.get(each.getKey()).getAsJsonObject()) | |
| 539 | ); | |
| 540 | } else { | |
| 541 | throw new JsonInvalidPathException(right, relPath.toArray()); | |
| 542 | } | |
| 543 | } else { | |
| 544 |
1
1. merge : removed call to com/google/gson/JsonObject::add → KILLED |
ret.add(each.getKey(), each.getValue()); |
| 545 | } | |
| 546 | } | |
| 547 | for (Entry<String, JsonElement> each : right.entrySet()) { | |
| 548 |
1
1. merge : negated conditional → KILLED |
if (!ret.has(each.getKey())) { |
| 549 |
1
1. merge : removed call to com/google/gson/JsonObject::add → KILLED |
ret.add(each.getKey(), each.getValue()); |
| 550 | } | |
| 551 | } | |
| 552 |
1
1. merge : replaced return value with null for com/github/dakusui/json/JsonUtils::merge → KILLED |
return ret; |
| 553 | } | |
| 554 | } | |
Mutations | ||
| 22 |
1.1 2.2 |
|
| 23 |
1.1 |
|
| 27 |
1.1 |
|
| 28 |
1.1 |
|
| 30 |
1.1 |
|
| 31 |
1.1 |
|
| 33 |
1.1 |
|
| 34 |
1.1 |
|
| 36 |
1.1 |
|
| 47 |
1.1 |
|
| 51 |
1.1 |
|
| 60 |
1.1 |
|
| 64 |
1.1 2.2 |
|
| 66 |
1.1 |
|
| 68 |
1.1 |
|
| 75 |
1.1 |
|
| 76 |
1.1 |
|
| 80 |
1.1 |
|
| 87 |
1.1 |
|
| 90 |
1.1 |
|
| 96 |
1.1 |
|
| 99 |
1.1 |
|
| 107 |
1.1 |
|
| 110 |
1.1 |
|
| 116 |
1.1 |
|
| 119 |
1.1 |
|
| 127 |
1.1 |
|
| 130 |
1.1 |
|
| 140 |
1.1 2.2 |
|
| 143 |
1.1 |
|
| 148 |
1.1 |
|
| 151 |
1.1 |
|
| 157 |
1.1 2.2 |
|
| 158 |
1.1 |
|
| 161 |
1.1 |
|
| 164 |
1.1 |
|
| 167 |
1.1 |
|
| 169 |
1.1 2.2 3.3 |
|
| 173 |
1.1 |
|
| 177 |
1.1 2.2 3.3 4.4 |
|
| 181 |
1.1 |
|
| 189 |
1.1 |
|
| 191 |
1.1 |
|
| 192 |
1.1 |
|
| 193 |
1.1 |
|
| 196 |
1.1 |
|
| 207 |
1.1 |
|
| 212 |
1.1 2.2 |
|
| 214 |
1.1 |
|
| 222 |
1.1 |
|
| 229 |
1.1 |
|
| 238 |
1.1 |
|
| 245 |
1.1 2.2 |
|
| 246 |
1.1 |
|
| 259 |
1.1 |
|
| 260 |
1.1 |
|
| 263 |
1.1 |
|
| 271 |
1.1 |
|
| 275 |
1.1 |
|
| 279 |
1.1 |
|
| 281 |
1.1 |
|
| 286 |
1.1 |
|
| 292 |
1.1 |
|
| 299 |
1.1 |
|
| 304 |
1.1 |
|
| 312 |
1.1 |
|
| 313 |
1.1 |
|
| 315 |
1.1 |
|
| 322 |
1.1 |
|
| 327 |
1.1 |
|
| 328 |
1.1 |
|
| 330 |
1.1 |
|
| 337 |
1.1 |
|
| 347 |
1.1 |
|
| 357 |
1.1 |
|
| 368 |
1.1 |
|
| 379 |
1.1 |
|
| 390 |
1.1 |
|
| 399 |
1.1 |
|
| 409 |
1.1 |
|
| 419 |
1.1 |
|
| 420 |
1.1 |
|
| 424 |
1.1 |
|
| 425 |
1.1 |
|
| 426 |
1.1 |
|
| 427 |
1.1 |
|
| 428 |
1.1 |
|
| 436 |
1.1 2.2 |
|
| 438 |
1.1 |
|
| 448 |
1.1 |
|
| 456 |
1.1 |
|
| 462 |
1.1 |
|
| 464 |
1.1 |
|
| 468 |
1.1 |
|
| 469 |
1.1 2.2 |
|
| 471 |
1.1 |
|
| 484 |
1.1 |
|
| 495 |
1.1 |
|
| 499 |
1.1 |
|
| 504 |
1.1 2.2 |
|
| 508 |
1.1 |
|
| 512 |
1.1 |
|
| 520 |
1.1 |
|
| 524 |
1.1 |
|
| 528 |
1.1 |
|
| 534 |
1.1 |
|
| 535 |
1.1 2.2 |
|
| 536 |
1.1 |
|
| 544 |
1.1 |
|
| 548 |
1.1 |
|
| 549 |
1.1 |
|
| 552 |
1.1 |