| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.johnzon.core; |
| |
| |
| import java.io.Serializable; |
| import java.util.Map; |
| |
| import jakarta.json.JsonMergePatch; |
| import jakarta.json.JsonObject; |
| import jakarta.json.JsonObjectBuilder; |
| import jakarta.json.JsonValue; |
| |
| /** |
| * @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a> |
| */ |
| public class JsonMergePatchImpl implements JsonMergePatch, Serializable { |
| private JsonValue patch; |
| private BufferStrategy.BufferProvider<char[]> bufferProvider; |
| private JsonProviderImpl provider; |
| |
| public JsonMergePatchImpl(final JsonValue patch, final BufferStrategy.BufferProvider<char[]> bufferProvider, |
| final JsonProviderImpl provider) { |
| this.patch = patch; |
| this.bufferProvider = bufferProvider; |
| this.provider = provider; |
| } |
| |
| @Override |
| public JsonValue apply(JsonValue valueToApplyPatchOn) { |
| return applyPatch(valueToApplyPatchOn, patch); |
| } |
| |
| private JsonValue applyPatch(JsonValue valueToApplyPatchOn, JsonValue patch) { |
| if (patch == null) { |
| return JsonValue.NULL; |
| } else if (patch instanceof JsonObject && valueToApplyPatchOn instanceof JsonObject) { |
| // we only apply an actual patch IF both sides are a JsonObject |
| JsonObject patchObject = patch.asJsonObject(); |
| |
| return applyJsonObjectPatch(valueToApplyPatchOn.asJsonObject(), patchObject); |
| } else { |
| // this must be a native JsonValue or JsonObject, so we just replace |
| // the whole original valueToApplyPatchOn with the new jsonValue |
| return patch; |
| } |
| } |
| |
| private JsonValue applyJsonObjectPatch(JsonObject jsonObject, JsonObject patch) { |
| JsonObjectBuilder builder = new JsonObjectBuilderImpl(jsonObject, bufferProvider, RejectDuplicateKeysMode.DEFAULT, provider); |
| |
| for (Map.Entry<String, JsonValue> patchAttrib : patch.entrySet()) { |
| String attribName = patchAttrib.getKey(); |
| if (patchAttrib.getValue().equals(JsonValue.NULL)) { |
| builder.remove(attribName); |
| } else { |
| JsonValue originalAttrib = jsonObject.get(attribName); |
| if (originalAttrib == null) { |
| builder.add(attribName, patchAttrib.getValue()); |
| } else { |
| builder.add(attribName, applyPatch(originalAttrib, patchAttrib.getValue())); |
| } |
| } |
| } |
| return builder.build(); |
| } |
| |
| @Override |
| public JsonValue toJsonValue() { |
| return patch; |
| } |
| } |