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