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.openapi3;
018
019import static org.apache.juneau.common.utils.Utils.*;
020import static org.apache.juneau.internal.CollectionUtils.*;
021import static org.apache.juneau.internal.ConverterUtils.*;
022
023import java.util.*;
024
025import org.apache.juneau.internal.*;
026
027/**
028 * A map of possible out-of-band callbacks related to the parent operation.
029 *
030 * <p>
031 * The Callback Object is a map of possible out-of-band callbacks related to the parent operation. Each value in the
032 * map is a Path Item Object that describes a set of requests that may be initiated by the API provider and the expected
033 * responses. The key value used to identify the callback object is an expression, evaluated at runtime, that identifies
034 * a URL to use for the callback operation.
035 *
036 * <h5 class='section'>OpenAPI Specification:</h5>
037 * <p>
038 * The Callback Object is composed of the following fields:
039 * <ul class='spaced-list'>
040 *    <li><c>callbacks</c> (map of {@link PathItem}) - A map of possible out-of-band callbacks related to the parent operation
041 * </ul>
042 *
043 * <h5 class='section'>Example:</h5>
044 * <p class='bcode'>
045 *    <jc>// Construct using SwaggerBuilder.</jc>
046 *    Callback <jv>x</jv> = <jsm>callback</jsm>()
047 *       .setCallbacks(<jsm>map</jsm>(<js>"myCallback"</js>, <jsm>pathItem</jsm>().setPost(<jsm>operation</jsm>().setSummary(<js>"Callback"</js>))));
048 *
049 *    <jc>// Serialize using JsonSerializer.</jc>
050 *    String <jv>json</jv> = Json.<jsm>from</jsm>(<jv>x</jv>);
051 *
052 *    <jc>// Or just use toString() which does the same as above.</jc>
053 *    <jv>json</jv> = <jv>x</jv>.toString();
054 * </p>
055 * <p class='bcode'>
056 *    <jc>// Output</jc>
057 *    {
058 *       <js>"callbacks"</js>: {
059 *          <js>"myCallback"</js>: {
060 *             <js>"post"</js>: { <js>"summary"</js>: <js>"Callback"</js> }
061 *          }
062 *       }
063 *    }
064 * </p>
065 *
066 * <h5 class='section'>See Also:</h5><ul>
067 *    <li class='link'><a class="doclink" href="https://spec.openapis.org/oas/v3.0.0#callback-object">OpenAPI Specification &gt; Callback Object</a>
068 *    <li class='link'><a class="doclink" href="https://swagger.io/docs/specification/callbacks/">OpenAPI Callbacks</a>
069 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanOpenApi3">juneau-bean-openapi-v3</a>
070 * </ul>
071 */
072public class Callback extends OpenApiElement {
073
074   private Map<String,PathItem> callbacks;
075
076   /**
077    * Default constructor.
078    */
079   public Callback() {}
080
081   /**
082    * Copy constructor.
083    *
084    * @param copyFrom The object to copy.
085    */
086   public Callback(Callback copyFrom) {
087      super(copyFrom);
088      this.callbacks = copyOf(copyFrom.callbacks);
089   }
090
091   /**
092    * Returns the callbacks map.
093    *
094    * @return The callbacks map.
095    */
096   public Map<String,PathItem> getCallbacks() {
097      return callbacks;
098   }
099
100   /**
101    * Sets the callbacks map.
102    *
103    * @param value The new value for this property.
104    * @return This object.
105    */
106   public Callback setCallbacks(Map<String,PathItem> value) {
107      this.callbacks = value;
108      return this;
109   }
110
111   /**
112    * Adds a callback.
113    *
114    * @param expression The callback expression.  Must not be <jk>null</jk>.
115    * @param pathItem The path item for the callback.  Must not be <jk>null</jk>.
116    * @return This object.
117    */
118   public Callback addCallback(String expression, PathItem pathItem) {
119      assertArgNotNull("expression", expression);
120      assertArgNotNull("pathItem", pathItem);
121      if (callbacks == null)
122         callbacks = new LinkedHashMap<>();
123      callbacks.put(expression, pathItem);
124      return this;
125   }
126
127   /**
128    * Creates a copy of this object.
129    *
130    * @return A copy of this object.
131    */
132   public Callback copy() {
133      return new Callback(this);
134   }
135
136   @Override /* Overridden from OpenApiElement */
137   public <T> T get(String property, Class<T> type) {
138      assertArgNotNull("property", property);
139      return switch (property) {
140         case "callbacks" -> toType(getCallbacks(), type);
141         default -> super.get(property, type);
142      };
143   }
144
145   @Override /* Overridden from OpenApiElement */
146   public Callback set(String property, Object value) {
147      assertArgNotNull("property", property);
148      return switch (property) {
149         case "callbacks" -> setCallbacks(mapBuilder(String.class, PathItem.class).sparse().addAny(value).build());
150         default -> {
151            super.set(property, value);
152            yield this;
153         }
154      };
155   }
156
157   @Override /* Overridden from OpenApiElement */
158   public Set<String> keySet() {
159      var s = setBuilder(String.class)
160         .addIf(callbacks != null, "callbacks")
161         .build();
162      return new MultiSet<>(s, super.keySet());
163   }
164
165   @Override /* Overridden from OpenApiElement */
166   public Callback strict() {
167      super.strict();
168      return this;
169   }
170
171   @Override /* Overridden from OpenApiElement */
172   public Callback strict(Object value) {
173      super.strict(value);
174      return this;
175   }
176}