001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.bean.jsonpatch;
018
019import org.apache.juneau.marshall.*;
020import org.apache.juneau.marshall.marshaller.*;
021
022/**
023 * Abstract base for a JSON Patch operation per
024 * <a href="https://datatracker.ietf.org/doc/html/rfc6902">RFC 6902</a>.
025 *
026 * <p>
027 * Polymorphic dispatch is wired here via
028 * {@code @Marshalled(typePropertyName="op", dictionary={...})}: on read, the parser inspects the {@code op}
029 * member and instantiates the matching concrete subclass; on write, the serializer emits {@code op} as the
030 * discriminator and the operation's own members alongside.
031 *
032 * <p>
033 * <b>Not</b> declared {@code sealed} - keeping it open lets downstream callers add their own ops if needed
034 * (e.g. JSON Patch extensions or vendor-specific test operators) by adding the new subclass to a custom
035 * dictionary.
036 *
037 * <h5 class='section'>See Also:</h5><ul>
038 *   <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanJsonPatch">juneau-bean-jsonpatch</a>
039 * </ul>
040 */
041@Marshalled(
042   typePropertyName = "op",
043   dictionary = { AddOp.class, RemoveOp.class, ReplaceOp.class, MoveOp.class, CopyOp.class, TestOp.class }
044)
045public abstract class JsonPatchOperation {
046
047   private String path;
048
049   /**
050    * Default constructor.
051    */
052   protected JsonPatchOperation() {}
053
054   /**
055    * Convenience constructor.
056    *
057    * @param path The JSON Pointer target of the operation.  Can be <jk>null</jk> to leave the property unset.
058    */
059   protected JsonPatchOperation(String path) {
060      this.path = path;
061   }
062
063   /**
064    * Bean property getter:  <property>path</property>.
065    *
066    * <p>
067    * The target JSON Pointer (RFC 6901) of this operation.
068    *
069    * @return The value of the <property>path</property> property, or <jk>null</jk> if it is not set.
070    */
071   public String getPath() { return path; }
072
073   /**
074    * Bean property setter:  <property>path</property>.
075    *
076    * @param value The new value for this property.  Can be <jk>null</jk> to unset the property.
077    * @return This object.
078    */
079   public JsonPatchOperation setPath(String value) {
080      path = value;
081      return this;
082   }
083
084   @Override /* Overridden from Object */
085   public String toString() {
086      return Json.of(this);
087   }
088}