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