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

com.azure.core.models.JsonPatchDocument Maven / Gradle / Ivy

There is a newer version: 1.54.1
Show newest version
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.core.models;

import com.azure.core.implementation.Option;
import com.azure.core.util.serializer.JacksonAdapter;
import com.azure.core.util.serializer.JsonSerializer;
import com.azure.core.util.serializer.JsonSerializerProviders;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonValue;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Represents a JSON Patch document.
 */
public final class JsonPatchDocument {
    private static final Object SERIALIZER_INSTANTIATION_SYNCHRONIZER = new Object();
    private static volatile JsonSerializer defaultSerializer;

    @JsonIgnore
    private final JsonSerializer serializer;

    @JsonValue
    private final List operations;

    /**
     * Creates a new JSON Patch document.
     */
    public JsonPatchDocument() {
        this(null);
    }

    /**
     * Creates a new JSON Patch document.
     * 

* If {@code serializer} isn't specified {@link JacksonAdapter} will be used. * * @param serializer The {@link JsonSerializer} that will be used to serialize patch operation values. */ public JsonPatchDocument(JsonSerializer serializer) { this.operations = new ArrayList<>(); this.serializer = serializer; } /** * Gets a representation of the {@link JsonPatchOperation JSON patch operations} in this JSON patch document. *

* Modifications to the returned list won't mutate the operations in the document. * * @return The JSON patch operations in this JSON patch document. */ List getOperations() { return new ArrayList<>(operations); } /** * Appends an "add" operation to this JSON Patch document. *

* If the {@code path} doesn't exist a new member is added to the object. If the {@code path} does exist the * previous value is replaced. If the {@code path} specifies an array index the value is inserted at the specified. *

* See JSON Patch Add for more information. * *

Code Samples

* * *
     * /*
     *  * Add an object member to the JSON document { "foo" : "bar" } to get the JSON document
     *  * { "bar": "foo", "foo": "bar" }.
     *  */
     * jsonPatchDocument.appendAdd("/bar", "foo");
     *
     * /*
     *  * Add an array element to the JSON document { "foo": [ "fizz", "fizzbuzz" ] } to get the JSON document
     *  * { "foo": [ "fizz", "buzz", "fizzbuzz" ] }.
     *  */
     * jsonPatchDocument.appendAdd("/foo/1", "buzz");
     *
     * /*
     *  * Add a nested member to the JSON document { "foo": "bar" } to get the JSON document
     *  * { "foo": "bar", "child": { "grandchild": { } } }.
     *  */
     * jsonPatchDocument.appendAdd("/child", Collections.singletonMap("grandchild", Collections.emptyMap()));
     *
     * /*
     *  * Add an array element to the JSON document { "foo": [ "fizz", "buzz" ] } to get the JSON document
     *  * { "foo": [ "fizz", "buzz", "fizzbuzz" ] }.
     *  */
     * jsonPatchDocument.appendAdd("/foo/-", "fizzbuzz");
     * 
* * * @param path The path to apply the addition. * @param value The value that will be serialized and added to the path. * @return The updated JsonPatchDocument object. * @throws NullPointerException If {@code path} is null. */ public JsonPatchDocument appendAdd(String path, Object value) { return appendAddInternal(path, serializeValue(value)); } /** * Appends an "add" operation to this JSON Patch document. *

* If the {@code path} doesn't exist a new member is added to the object. If the {@code path} does exist the * previous value is replaced. If the {@code path} specifies an array index the value is inserted at the specified. *

* See JSON Patch Add for more information. * *

Code Samples

* * *
     * /*
     *  * Add an object member to the JSON document { "foo" : "bar" } to get the JSON document
     *  * { "bar": "foo", "foo": "bar" }.
     *  */
     * jsonPatchDocument.appendAddRaw("/bar", "\"foo\"");
     *
     * /*
     *  * Add an array element to the JSON document { "foo": [ "fizz", "fizzbuzz" ] } to get the JSON document
     *  * { "foo": [ "fizz", "buzz", "fizzbuzz" ] }.
     *  */
     * jsonPatchDocument.appendAddRaw("/foo/1", "\"buzz\"");
     *
     * /*
     *  * Add a nested member to the JSON document { "foo": "bar" } to get the JSON document
     *  * { "foo": "bar", "child": { "grandchild": { } } }.
     *  */
     * jsonPatchDocument.appendAddRaw("/child", "\"child\": { \"grandchild\": { } }");
     *
     * /*
     *  * Add an array element to the JSON document { "foo": [ "fizz", "buzz" ] } to get the JSON document
     *  * { "foo": [ "fizz", "buzz", "fizzbuzz" ] }.
     *  */
     * jsonPatchDocument.appendAddRaw("/foo/-", "\"fizzbuzz\"");
     * 
* * * @param path The path to apply the addition. * @param rawJson The raw JSON value that will be added to the path. * @return The updated JsonPatchDocument object. * @throws NullPointerException If {@code path} is null. */ public JsonPatchDocument appendAddRaw(String path, String rawJson) { return appendAddInternal(path, Option.of(rawJson)); } private JsonPatchDocument appendAddInternal(String path, Option rawJsonOption) { Objects.requireNonNull(path, "'path' cannot be null."); return appendOperation(JsonPatchOperationKind.ADD, null, path, rawJsonOption); } /** * Appends a "replace" operation to this JSON Patch document. *

* See JSON Patch replace for more information. * *

Code Samples

* * *
     * /*
     *  * Replace an object member in the JSON document { "bar": "qux", "foo": "bar" } to get the JSON document
     *  * { "bar": "foo", "foo": "bar" }.
     *  */
     * jsonPatchDocument.appendReplace("/bar", "foo");
     *
     * /*
     *  * Replace an object member in the JSON document { "foo": "fizz" } to get the JSON document
     *  * { "foo": [ "fizz", "buzz", "fizzbuzz" ]  }.
     *  */
     * jsonPatchDocument.appendReplace("/foo", new String[] {"fizz", "buzz", "fizzbuzz"});
     *
     * /*
     *  * Given the JSON document { "foo": "bar" } the following is an example of an invalid replace operation as the
     *  * target path doesn't exist in the document.
     *  */
     * jsonPatchDocument.appendReplace("/baz", "foo");
     * 
* * * @param path The path to replace. * @param value The value will be serialized and used as the replacement. * @return The updated JsonPatchDocument object. * @throws NullPointerException If {@code path} is null. */ public JsonPatchDocument appendReplace(String path, Object value) { return appendReplaceInternal(path, serializeValue(value)); } /** * Appends a "replace" operation to this JSON Patch document. *

* See JSON Patch replace for more information. * *

Code Samples

* * *
     * /*
     *  * Replace an object member in the JSON document { "bar": "qux", "foo": "bar" } to get the JSON document
     *  * { "bar": "foo", "foo": "bar" }.
     *  */
     * jsonPatchDocument.appendReplaceRaw("/bar", "\"foo\"");
     *
     * /*
     *  * Replace an object member in the JSON document { "foo": "fizz" } to get the JSON document
     *  * { "foo": [ "fizz", "buzz", "fizzbuzz" ]  }.
     *  */
     * jsonPatchDocument.appendReplaceRaw("/foo", "[ \"fizz\", \"buzz\", \"fizzbuzz\" ]");
     *
     * /*
     *  * Given the JSON document { "foo": "bar" } the following is an example of an invalid replace operation as the
     *  * target path doesn't exist in the document.
     *  */
     * jsonPatchDocument.appendReplaceRaw("/baz", "\"foo\"");
     * 
* * * @param path The path to replace. * @param rawJson The raw JSON value that will be used as the replacement. * @return The updated JsonPatchDocument object. * @throws NullPointerException If {@code path} is null. */ public JsonPatchDocument appendReplaceRaw(String path, String rawJson) { return appendReplaceInternal(path, Option.of(rawJson)); } private JsonPatchDocument appendReplaceInternal(String path, Option rawJsonOption) { Objects.requireNonNull(path, "'path' cannot be null."); return appendOperation(JsonPatchOperationKind.REPLACE, null, path, rawJsonOption); } /** * Appends a "copy" operation to this JSON Patch document. *

* See JSON Patch copy for more information. * *

Code Samples

* * *
     * /*
     *  * Copy an object member in the JSON document { "foo": "bar" } to get the JSON document
     *  * { "foo": "bar", "copy": "bar" }.
     *  */
     * jsonPatchDocument.appendCopy("/foo", "/copy");
     *
     * /*
     *  * Copy an object member in the JSON document { "foo": { "bar": "baz" } } to get the JSON document
     *  * { "foo": { "bar": "baz" }, "bar": "baz" }.
     *  */
     * jsonPatchDocument.appendCopy("/foo/bar", "/bar");
     *
     * /*
     *  * Given the JSON document { "foo": "bar" } the following is an example of an invalid copy operation as the
     *  * target from doesn't exist in the document.
     *  */
     * jsonPatchDocument.appendCopy("/baz", "/fizz");
     * 
* * * @param from The path to copy from. * @param path The path to copy to. * @return The updated JsonPatchDocument object. * @throws NullPointerException If {@code from} or {@code path} is null. */ public JsonPatchDocument appendCopy(String from, String path) { Objects.requireNonNull(from, "'from' cannot be null."); Objects.requireNonNull(path, "'path' cannot be null."); return appendOperation(JsonPatchOperationKind.COPY, from, path, Option.uninitialized()); } /** * Appends a "move" operation to this JSON Patch document. *

* For the operation to be successful {@code path} cannot be a child node of {@code from}. *

* See JSON Patch move for more information. * *

Code Samples

* * *
     * /*
     *  * Move an object member in the JSON document { "foo": "bar", "bar": "foo" } to get the JSON document
     *  * { "bar": "bar" }.
     *  */
     * jsonPatchDocument.appendMove("/foo", "/bar");
     *
     * /*
     *  * Move an object member in the JSON document { "foo": { "bar": "baz" } } to get the JSON document
     *  * { "foo": "baz" }.
     *  */
     * jsonPatchDocument.appendMove("/foo/bar", "/foo");
     *
     * /*
     *  * Given the JSON document { "foo": { "bar": "baz" } } the following is an example of an invalid move operation
     *  * as the target path is a child of the target from.
     *  */
     * jsonPatchDocument.appendMove("/foo", "/foo/bar");
     *
     * /*
     *  * Given the JSON document { "foo": "bar" } the following is an example of an invalid move operation as the
     *  * target from doesn't exist in the document.
     *  */
     * jsonPatchDocument.appendMove("/baz", "/fizz");
     * 
* * * @param from The path to move from. * @param path The path to move to. * @return The updated JsonPatchDocument object. * @throws NullPointerException If {@code from} or {@code path} is null. */ public JsonPatchDocument appendMove(String from, String path) { Objects.requireNonNull(from, "'from' cannot be null."); Objects.requireNonNull(path, "'path' cannot be null."); return appendOperation(JsonPatchOperationKind.MOVE, from, path, Option.uninitialized()); } /** * Appends a "remove" operation to this JSON Patch document. *

* See JSON Patch remove for more information. * *

Code Samples

* * *
     * /*
     *  * Remove an object member in the JSON document { "foo": "bar", "bar": "foo" } to get the JSON document
     *  * { "foo": "bar" }.
     *  */
     * jsonPatchDocument.appendRemove("/bar");
     *
     * /*
     *  * Remove an object member in the JSON document { "foo": { "bar": "baz" } } to get the JSON document
     *  * { "foo": { } }.
     *  */
     * jsonPatchDocument.appendRemove("/foo/bar");
     *
     * /*
     *  * Given the JSON document { "foo": "bar" } the following is an example of an invalid remove operation as the
     *  * target from doesn't exist in the document.
     *  */
     * jsonPatchDocument.appendRemove("/baz");
     * 
* * * @param path The path to remove. * @return The updated JsonPatchDocument object. * @throws NullPointerException If {@code path} is null. */ public JsonPatchDocument appendRemove(String path) { Objects.requireNonNull(path, "'path' cannot be null."); return appendOperation(JsonPatchOperationKind.REMOVE, null, path, Option.uninitialized()); } /** * Appends a "test" operation to this JSON Patch document. *

* See JSON Patch test for more information. * *

Code Samples

* * *
     * /*
     *  * Test an object member in the JSON document { "foo": "bar" } to get a successful operation.
     *  */
     * jsonPatchDocument.appendTest("/foo", "bar");
     *
     * /*
     *  * Test an object member in the JSON document { "foo": "bar" } to get a unsuccessful operation.
     *  */
     * jsonPatchDocument.appendTest("/foo", 42);
     *
     * /*
     *  * Given the JSON document { "foo": "bar" } the following is an example of an unsuccessful test operation as
     *  * the target path doesn't exist in the document.
     *  */
     * jsonPatchDocument.appendTest("/baz", "bar");
     * 
* * * @param path The path to test. * @param value The value that will be serialized and used to test against. * @return The updated JsonPatchDocument object. * @throws NullPointerException If {@code path} is null. */ public JsonPatchDocument appendTest(String path, Object value) { return appendTestInternal(path, serializeValue(value)); } /** * Appends a "test" operation to this JSON Patch document. *

* See JSON Patch test for more information. * *

Code Samples

* * *
     * /*
     *  * Test an object member in the JSON document { "foo": "bar" } to get a successful operation.
     *  */
     * jsonPatchDocument.appendTestRaw("/foo", "\"bar\"");
     *
     * /*
     *  * Test an object member in the JSON document { "foo": "bar" } to get a unsuccessful operation.
     *  */
     * jsonPatchDocument.appendTestRaw("/foo", "42");
     *
     * /*
     *  * Given the JSON document { "foo": "bar" } the following is an example of an unsuccessful test operation as
     *  * the target path doesn't exist in the document.
     *  */
     * jsonPatchDocument.appendTestRaw("/baz", "\"bar\"");
     * 
* * * @param path The path to test. * @param rawJson The raw JSON value that will be used to test against. * @return The updated JsonPatchDocument object. * @throws NullPointerException If {@code path} is null. */ public JsonPatchDocument appendTestRaw(String path, String rawJson) { return appendTestInternal(path, Option.of(rawJson)); } private JsonPatchDocument appendTestInternal(String path, Option rawJsonOption) { Objects.requireNonNull(path, "'path' cannot be null."); return appendOperation(JsonPatchOperationKind.TEST, null, path, rawJsonOption); } private Option serializeValue(Object value) { if (value == null) { return Option.empty(); } byte[] bytes; if (serializer == null) { if (defaultSerializer == null) { synchronized (SERIALIZER_INSTANTIATION_SYNCHRONIZER) { if (defaultSerializer == null) { defaultSerializer = JsonSerializerProviders.createInstance(); } } } bytes = defaultSerializer.serializeToBytes(value); } else { bytes = serializer.serializeToBytes(value); } return Option.of(new String(bytes, StandardCharsets.UTF_8)); } private JsonPatchDocument appendOperation(JsonPatchOperationKind operationKind, String from, String path, Option optionalValue) { operations.add(new JsonPatchOperation(operationKind, from, path, optionalValue)); return this; } /** * Gets a formatted JSON string representation of this JSON Patch document. * * @return The formatted JSON String representing this JSON Patch document. */ @Override public String toString() { StringBuilder builder = new StringBuilder("["); for (int i = 0; i < operations.size(); i++) { if (i > 0) { builder.append(","); } operations.get(i).buildString(builder); } return builder.append("]").toString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy