001/*
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2015-2017 Oracle and/or its affiliates. All rights reserved.
005 *
006 * The contents of this file are subject to the terms of either the GNU
007 * General Public License Version 2 only ("GPL") or the Common Development
008 * and Distribution License("CDDL") (collectively, the "License").  You
009 * may not use this file except in compliance with the License.  You can
010 * obtain a copy of the License at
011 * https://oss.oracle.com/licenses/CDDL+GPL-1.1
012 * or LICENSE.txt.  See the License for the specific
013 * language governing permissions and limitations under the License.
014 *
015 * When distributing the software, include this License Header Notice in each
016 * file and include the License file at LICENSE.txt.
017 *
018 * GPL Classpath Exception:
019 * Oracle designates this particular file as subject to the "Classpath"
020 * exception as provided by Oracle in the GPL Version 2 section of the License
021 * file that accompanied this code.
022 *
023 * Modifications:
024 * If applicable, add the following below the License Header, with the fields
025 * enclosed by brackets [] replaced by your own identifying information:
026 * "Portions Copyright [year] [name of copyright owner]"
027 *
028 * Contributor(s):
029 * If you wish your version of this file to be governed by only the CDDL or
030 * only the GPL Version 2, indicate your decision by adding "[Contributor]
031 * elects to include this software in this distribution under the [CDDL or GPL
032 * Version 2] license."  If you don't indicate a single choice of license, a
033 * recipient has the option to distribute your version of this file under
034 * either the CDDL, the GPL Version 2 or to extend the choice of license to
035 * its licensees as provided above.  However, if you add GPL Version 2 code
036 * and therefore, elected the GPL Version 2 license, then the option applies
037 * only if the new code is made subject to such option by the copyright
038 * holder.
039 */
040
041package javax.json;
042
043/**
044 * This interface represents an immutable implementation of a JSON Patch
045 * as defined by
046 * <a target=_blank href="http://tools.ietf.org/html/rfc6902">RFC 6902</a>.
047 *
048 * <EMBED CLASS='external-html' DATA-FILE-ID=LICENSE DATA-CIETName=JsonPatch>
049 * 
050 * <BR /><BR />A {@code JsonPatch} can be instantiated with {@link Json#createPatch(JsonArray)}
051 * by specifying the patch operations in a JSON Patch. Alternately, it
052 * can also be constructed with a {@link JsonPatchBuilder}.
053 *
054 * <BR /><BR />The following illustrates both approaches.
055 * 
056 * <BR /><BR />1. Construct a JsonPatch with a JSON Patch.
057 * 
058 * <BR /><DIV CLASS=SNIP>{@code
059 *   JsonArray contacts     = ...       // The target to be patched
060 *   JsonArray patch        = ...  ;    // JSON Patch
061 *   JsonPatch jsonpatch    = Json.createPatch(patch);
062 *   JsonArray result       = jsonpatch.apply(contacts);
063 * }</DIV>
064 * 
065 * <BR /><BR />2. Construct a JsonPatch with JsonPatchBuilder.
066 * 
067 * <BR /><DIV CLASS=SNIP>{@code
068 * JsonPatchBuilder builder = Json.createPatchBuilder();
069 * 
070 * JsonArray result = builder
071 *      .add("/John/phones/office", "1234-567")
072 *      .remove("/Amy/age")
073 *      .build()
074 *      .apply(contacts);
075 * }</DIV>
076 *
077 * @see <a target=_blank href="http://tools.ietf.org/html/rfc6902">RFC 6902</a>
078 *
079 * @since 1.1
080 */
081public interface JsonPatch {
082
083    /**
084     * This enum represents the list of valid JSON Patch operations
085     * as defined by
086     * <a target=_blank href="http://tools.ietf.org/html/rfc6902">RFC 6902</a>.
087     *
088     * @see <a target=_blank href="http://tools.ietf.org/html/rfc6902">RFC 6902</a>
089     */
090    enum Operation {
091
092        /**
093         * "add" operation.
094         */
095        ADD("add"),
096
097        /**
098         * "remove" operation.
099         */
100        REMOVE("remove"),
101
102        /**
103         * "remove" operation.
104         */
105        REPLACE("replace"),
106
107        /**
108         * "move" operation.
109         */
110        MOVE("move"),
111
112        /**
113         * "copy" operation.
114         */
115        COPY("copy"),
116
117        /**
118         * "test" operation.
119         */
120        TEST("test");
121
122        private final String operationName;
123
124        private Operation(String operationName) {
125            this.operationName = operationName;
126        }
127
128        /**
129         * Returns enum constant name as lower case string.
130         *
131         * @return lower case name of the enum constant
132         */
133        public String operationName() {
134            return operationName;
135        }
136
137        /**
138         * Returns the enum constant with the specified name.
139         *
140         * @param operationName {@code operationName} to convert to the enum constant.
141         * @return the enum constant for given {@code operationName}
142         * @throws JsonException if given {@code operationName} is not recognized
143         */
144        public static Operation fromOperationName(String operationName) {
145            for (Operation op : values()) {
146                if (op.operationName().equalsIgnoreCase(operationName)) {
147                    return op;
148                }
149            }
150            throw new JsonException("Illegal value for the operationName of the JSON patch operation: " + operationName);
151        }
152    }
153
154    /**
155     * Applies the patch operations to the specified {@code target}.
156     * The target is not modified by the patch.
157     *
158     * @param <T> the target type, must be a subtype of {@link JsonStructure}
159     * @param target the target to apply the patch operations
160     * @return the transformed target after the patch
161     * @throws JsonException if the supplied JSON Patch is malformed or if
162     *    it contains references to non-existing members
163     */
164    <T extends JsonStructure> T apply(T target);
165
166    /**
167     * Returns the {@code JsonPatch} as {@code JsonArray}.
168     *
169     * @return this {@code JsonPatch} as {@code JsonArray}
170     */
171    JsonArray toJsonArray();
172
173}