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 * Allows configuration of the supported OAuth Flows.
029 *
030 * <p>
031 * The OAuthFlows Object allows configuration of the supported OAuth Flows. This object contains the configuration 
032 * for different OAuth 2.0 flows that can be used to secure the API. Each flow type has its own specific configuration 
033 * requirements and use cases.
034 *
035 * <h5 class='section'>OpenAPI Specification:</h5>
036 * <p>
037 * The OAuthFlows Object is composed of the following fields:
038 * <ul class='spaced-list'>
039 *    <li><c>implicit</c> ({@link OAuthFlow}) - Configuration for the OAuth Implicit flow
040 *    <li><c>password</c> ({@link OAuthFlow}) - Configuration for the OAuth Resource Owner Password flow
041 *    <li><c>clientCredentials</c> ({@link OAuthFlow}) - Configuration for the OAuth Client Credentials flow
042 *    <li><c>authorizationCode</c> ({@link OAuthFlow}) - Configuration for the OAuth Authorization Code flow
043 * </ul>
044 *
045 * <h5 class='section'>Example:</h5>
046 * <p class='bcode'>
047 *    <jc>// Construct using SwaggerBuilder.</jc>
048 *    OAuthFlows <jv>x</jv> = <jsm>oauthFlows</jsm>()
049 *       .setAuthorizationCode(<jsm>oauthFlow</jsm>()
050 *          .setAuthorizationUrl(<js>"https://example.com/oauth/authorize"</js>)
051 *          .setTokenUrl(<js>"https://example.com/oauth/token"</js>));
052 *
053 *    <jc>// Serialize using JsonSerializer.</jc>
054 *    String <jv>json</jv> = Json.<jsm>from</jsm>(<jv>x</jv>);
055 *
056 *    <jc>// Or just use toString() which does the same as above.</jc>
057 *    <jv>json</jv> = <jv>x</jv>.toString();
058 * </p>
059 * <p class='bcode'>
060 *    <jc>// Output</jc>
061 *    {
062 *       <js>"authorizationCode"</js>: {
063 *          <js>"authorizationUrl"</js>: <js>"https://example.com/oauth/authorize"</js>,
064 *          <js>"tokenUrl"</js>: <js>"https://example.com/oauth/token"</js>
065 *       }
066 *    }
067 * </p>
068 *
069 * <h5 class='section'>See Also:</h5><ul>
070 *    <li class='link'><a class="doclink" href="https://spec.openapis.org/oas/v3.0.0#oauth-flows-object">OpenAPI Specification &gt; OAuth Flows Object</a>
071 *    <li class='link'><a class="doclink" href="https://swagger.io/docs/specification/authentication/oauth2/">OpenAPI OAuth2 Authentication</a>
072 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanOpenApi3">juneau-bean-openapi-v3</a>
073 * </ul>
074 */
075public class OAuthFlows extends OpenApiElement {
076
077   private OAuthFlow implicit,
078         password,
079         clientCredentials,
080         authorizationCode;
081
082   /**
083    * Default constructor.
084    */
085   public OAuthFlows() {}
086
087   /**
088    * Copy constructor.
089    *
090    * @param copyFrom The object to copy.
091    */
092   public OAuthFlows(OAuthFlows copyFrom) {
093      super(copyFrom);
094
095      this.implicit = copyFrom.implicit;
096      this.password = copyFrom.password;
097      this.clientCredentials = copyFrom.clientCredentials;
098      this.authorizationCode = copyFrom.authorizationCode;
099   }
100
101   /**
102    * Make a deep copy of this object.
103    *
104    * @return A deep copy of this object.
105    */
106   public OAuthFlows copy() {
107      return new OAuthFlows(this);
108   }
109
110   @Override /* SwaggerElement */
111   protected OAuthFlows strict() {
112      super.strict();
113      return this;
114   }
115
116   @Override /* Overridden from OpenApiElement */
117   public OAuthFlows strict(Object value) {
118      super.strict(value);
119      return this;
120   }
121
122   /**
123    * Bean property getter:  <property>implicit</property>.
124    *
125    * <p>
126    * Describes the type of items in the array.
127    *
128    * @return The property value, or <jk>null</jk> if it is not set.
129    */
130   public OAuthFlow getImplicit() {
131      return implicit;
132   }
133
134   /**
135    * Bean property setter:  <property>items</property>.
136    *
137    * <p>
138    * Describes the type of items in the array.
139    *
140    * @param value
141    *    The new value for this property.
142    *    <br>Property value is required if <code>type</code> is <js>"array"</js>.
143    *    <br>Can be <jk>null</jk> to unset the property.
144    * @return This object
145    */
146   public OAuthFlows setImplicit(OAuthFlow value) {
147      implicit = value;
148      return this;
149   }
150
151   /**
152    * Bean property getter:  <property>password</property>.
153    *
154    * <p>
155    * Describes the type of items in the array.
156    *
157    * @return The property value, or <jk>null</jk> if it is not set.
158    */
159   public OAuthFlow getPassword() {
160      return password;
161   }
162
163   /**
164    * Bean property setter:  <property>items</property>.
165    *
166    * <p>
167    * Describes the type of items in the array.
168    *
169    * @param value
170    *    The new value for this property.
171    *    <br>Property value is required if <code>type</code> is <js>"array"</js>.
172    *    <br>Can be <jk>null</jk> to unset the property.
173    * @return This object
174    */
175   public OAuthFlows setPassword(OAuthFlow value) {
176      password = value;
177      return this;
178   }
179
180   /**
181    * Bean property getter:  <property>clientCredentials</property>.
182    *
183    * <p>
184    * Describes the type of items in the array.
185    *
186    * @return The property value, or <jk>null</jk> if it is not set.
187    */
188   public OAuthFlow getClientCredentials() {
189      return clientCredentials;
190   }
191
192   /**
193    * Bean property setter:  <property>items</property>.
194    *
195    * <p>
196    * Describes the type of items in the array.
197    *
198    * @param value
199    *    The new value for this property.
200    *    <br>Property value is required if <code>type</code> is <js>"array"</js>.
201    *    <br>Can be <jk>null</jk> to unset the property.
202    * @return This object
203    */
204   public OAuthFlows setClientCredentials(OAuthFlow value) {
205      clientCredentials = value;
206      return this;
207   }
208
209   /**
210    * Bean property getter:  <property>authorizationCode</property>.
211    *
212    * <p>
213    * Describes the type of items in the array.
214    *
215    * @return The property value, or <jk>null</jk> if it is not set.
216    */
217   public OAuthFlow getAuthorizationCode() {
218      return authorizationCode;
219   }
220
221   /**
222    * Bean property setter:  <property>authorizationCode</property>.
223    *
224    * <p>
225    * Describes the type of items in the array.
226    *
227    * @param value
228    *    The new value for this property.
229    *    <br>Property value is required if <code>type</code> is <js>"array"</js>.
230    *    <br>Can be <jk>null</jk> to unset the property.
231    * @return This object
232    */
233   public OAuthFlows setAuthorizationCode(OAuthFlow value) {
234      authorizationCode = value;
235      return this;
236   }
237
238   @Override /* SwaggerElement */
239   public <T> T get(String property, Class<T> type) {
240      assertArgNotNull("property", property);
241      return switch (property) {
242         case "implicit" -> toType(getImplicit(), type);
243         case "password" -> toType(getPassword(), type);
244         case "clientCredentials" -> toType(getClientCredentials(), type);
245         case "authorizationCode" -> toType(getAuthorizationCode(), type);
246         default -> super.get(property, type);
247      };
248   }
249
250   @Override /* SwaggerElement */
251   public OAuthFlows set(String property, Object value) {
252      assertArgNotNull("property", property);
253      return switch (property) {
254         case "authorizationCode" -> setAuthorizationCode(toType(value, OAuthFlow.class));
255         case "clientCredentials" -> setClientCredentials(toType(value, OAuthFlow.class));
256         case "implicit" -> setImplicit(toType(value, OAuthFlow.class));
257         case "password" -> setPassword(toType(value, OAuthFlow.class));
258         default -> {
259            super.set(property, value);
260            yield this;
261         }
262      };
263   }
264
265   @Override /* SwaggerElement */
266   public Set<String> keySet() {
267      var s = setBuilder(String.class)
268         .addIf(authorizationCode != null, "authorizationCode")
269         .addIf(clientCredentials != null, "clientCredentials")
270         .addIf(implicit != null, "implicit")
271         .addIf(password != null, "password")
272         .build();
273      return new MultiSet<>(s, super.keySet());
274   }
275}