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.swagger;
018
019import static org.apache.juneau.commons.utils.CollectionUtils.*;
020import static org.apache.juneau.bean.swagger.SwaggerCopyUtils.*;
021import static org.apache.juneau.commons.utils.Shorts.*;
022import static org.apache.juneau.marshall.internal.ConverterUtils.*;
023
024import java.util.*;
025
026import org.apache.juneau.commons.collections.*;
027import org.apache.juneau.commons.http.*;
028
029/**
030 * Describes a single API operation on a path.
031 *
032 * <p>
033 * The Operation Object describes a single operation (such as GET, POST, PUT, DELETE) that can be performed on a path
034 * in Swagger 2.0. Operations define what actions can be taken, what parameters they accept, what they consume/produce,
035 * and what responses they return.
036 *
037 * <h5 class='section'>Swagger Specification:</h5>
038 * <p>
039 * The Operation Object is composed of the following fields:
040 * <ul class='spaced-list'>
041 *    <li><c>tags</c> (array of string) - A list of tags for API documentation control
042 *    <li><c>summary</c> (string) - A short summary of what the operation does
043 *    <li><c>description</c> (string) - A verbose explanation of the operation behavior
044 *    <li><c>externalDocs</c> ({@link ExternalDocumentation}) - Additional external documentation for this operation
045 *    <li><c>operationId</c> (string) - Unique string used to identify the operation
046 *    <li><c>consumes</c> (array of string) - A list of MIME types the operation can consume
047 *    <li><c>produces</c> (array of string) - A list of MIME types the operation can produce
048 *    <li><c>parameters</c> (array of {@link ParameterInfo}) - A list of parameters that are applicable for this operation
049 *    <li><c>responses</c> (map of {@link ResponseInfo}, REQUIRED) - The list of possible responses as they are returned from executing this operation
050 *    <li><c>schemes</c> (array of string) - The transfer protocol for the operation (overrides the Swagger-level schemes)
051 *    <li><c>deprecated</c> (boolean) - Declares this operation to be deprecated
052 *    <li><c>security</c> (array of map) - A declaration of which security schemes are applied for this operation
053 * </ul>
054 *
055 * <h5 class='section'>Example:</h5>
056 * <p class='bjava'>
057 *    <jc>// Construct using SwaggerBuilder.</jc>
058 *    Operation <jv>operation</jv> = <jsm>operation</jsm>()
059 *       .tags(<js>"pet"</js>)
060 *       .summary(<js>"Updates a pet in the store with form data"</js>)
061 *       .description(<js>""</js>)
062 *       .operationId(<js>"updatePetWithForm"</js>)
063 *       .consumes(<js>"application/x-www-form-urlencoded"</js>)
064 *       .produces(<js>"application/json"</js>, <js>"application/xml"</js>)
065 *       .parameters(
066 *          <jsm>parameter</jsm>()
067 *             .name(<js>"petId"</js>)
068 *             .in(<js>"path"</js>)
069 *             .description(<js>"ID of pet that needs to be updated"</js>)
070 *             .required(<jk>true</jk>)
071 *             .type(<js>"string"</js>),
072 *          <jsm>parameter</jsm>()
073 *             .name(<js>"name"</js>)
074 *             .in(<js>"formData"</js>)
075 *             .description(<js>"Updated name of the pet"</js>)
076 *             .required(<jk>false</jk>)
077 *             .type(<js>"string"</js>),
078 *          <jsm>parameter</jsm>()
079 *             .name(<js>"status"</js>)
080 *             .in(<js>"formData"</js>)
081 *             .description(<js>"Updated status of the pet"</js>)
082 *             .required(<jk>false</jk>)
083 *             .type(<js>"string"</js>)
084 *       )
085 *       .response(200, <jsm>responseInfo</jsm>(<js>"Pet updated."</js>))
086 *       .response(405, <jsm>responseInfo</jsm>(<js>"Invalid input."</js>))
087 *       .security(<js>"petstore_auth"</js>, <js>"write:pets"</js>, <js>"read:pets"</js>);
088 *
089 *    <jc>// Serialize using JsonSerializer.</jc>
090 *    String <jv>json</jv> = Json.<jsm>from</jsm>(<jv>operation</jv>);
091 *
092 *    <jc>// Or just use toString() which does the same as above.</jc>
093 *    <jv>json</jv> = <jv>operation</jv>.toString();
094 * </p>
095 * <p class='bjson'>
096 *    <jc>// Output</jc>
097 *    {
098 *       <js>"tags"</js>: [
099 *          <js>"pet"</js>
100 *       ],
101 *       <js>"summary"</js>: <js>"Updates a pet in the store with form data"</js>,
102 *       <js>"description"</js>: <js>""</js>,
103 *       <js>"operationId"</js>: <js>"updatePetWithForm"</js>,
104 *       <js>"consumes"</js>: [
105 *          <js>"application/x-www-form-urlencoded"</js>
106 *       ],
107 *       <js>"produces"</js>: [
108 *          <js>"application/json"</js>,
109 *          <js>"application/xml"</js>
110 *       ],
111 *       <js>"parameters"</js>: [
112 *          {
113 *             <js>"name"</js>: <js>"petId"</js>,
114 *             <js>"in"</js>: <js>"path"</js>,
115 *             <js>"description"</js>: <js>"ID of pet that needs to be updated"</js>,
116 *             <js>"required"</js>: <jk>true</jk>,
117 *             <js>"type"</js>: <js>"string"</js>
118 *          },
119 *          {
120 *             <js>"name"</js>: <js>"name"</js>,
121 *             <js>"in"</js>: <js>"formData"</js>,
122 *             <js>"description"</js>: <js>"Updated name of the pet"</js>,
123 *             <js>"required"</js>: <jk>false</jk>,
124 *             <js>"type"</js>: <js>"string"</js>
125 *          },
126 *          {
127 *             <js>"name"</js>: <js>"status"</js>,
128 *             <js>"in"</js>: <js>"formData"</js>,
129 *             <js>"description"</js>: <js>"Updated status of the pet"</js>,
130 *             <js>"required"</js>: <jk>false</jk>,
131 *             <js>"type"</js>: <js>"string"</js>
132 *          }
133 *       ],
134 *       <js>"responses"</js>: {
135 *          <js>"200"</js>: {
136 *             <js>"description"</js>: <js>"Pet updated."</js>
137 *          },
138 *          <js>"405"</js>: {
139 *             <js>"description"</js>: <js>"Invalid input"</js>
140 *          }
141 *       },
142 *       <js>"security"</js>: [
143 *          {
144 *             <js>"petstore_auth"</js>: [
145 *                <js>"write:pets"</js>,
146 *                <js>"read:pets"</js>
147 *             ]
148 *          }
149 *       ]
150 *    }
151 * </p>
152 *
153 * <h5 class='section'>See Also:</h5><ul>
154 *    <li class='link'><a class="doclink" href="https://swagger.io/specification/v2/#operation-object">Swagger 2.0 Specification &gt; Operation Object</a>
155 *    <li class='link'><a class="doclink" href="https://swagger.io/docs/specification/2-0/paths-and-operations/">Swagger Paths and Operations</a>
156 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanSwagger2">juneau-bean-swagger-v2</a>
157 * </ul>
158 */
159@SuppressWarnings({
160   "java:S1192" // Duplicated literals (argument/property names) read more clearly inline than as constants
161})
162public class Operation extends SwaggerElement {
163
164   private interface MapStringList extends Map<String,List<String>> {}
165
166   private String summary;
167   private String description;
168   private String operationId;
169   private Boolean deprecated;
170   private ExternalDocumentation externalDocs;
171   private final Set<String> tags = st();
172   private final Set<String> schemes = st();
173   private final Set<MediaType> consumes = st();
174   private final Set<MediaType> produces = st();
175   private List<ParameterInfo> parameters = list();
176   private List<Map<String,List<String>>> security = list();
177
178   private final Map<String,ResponseInfo> responses = map();
179
180   /**
181    * Default constructor.
182    */
183   public Operation() {}
184
185   /**
186    * Copy constructor.
187    *
188    * @param copyFrom The object to copy.
189    */
190   public Operation(Operation copyFrom) {
191      super(copyFrom);
192
193      this.consumes.addAll(copyOf(copyFrom.consumes));
194      this.deprecated = copyFrom.deprecated;
195      this.description = copyFrom.description;
196      this.externalDocs = copyOf(copyFrom.externalDocs);
197      this.operationId = copyFrom.operationId;
198      this.produces.addAll(copyOf(copyFrom.produces));
199      this.schemes.addAll(copyOf(copyFrom.schemes));
200      this.summary = copyFrom.summary;
201      this.tags.addAll(copyOf(copyFrom.tags));
202
203      parameters.addAll(copyOf(copyFrom.parameters, ParameterInfo::copy));
204
205      copyFrom.responses.forEach((k, v) -> responses.put(k, v.copy()));
206
207      copyFrom.security.forEach(x -> {
208         Map<String,List<String>> m2 = map();
209         x.forEach((k, v) -> m2.put(k, copyOf(v)));
210         security.add(m2);
211      });
212   }
213
214   /**
215    * Bean property appender:  <property>consumes</property>.
216    *
217    * <p>
218    * A list of MIME types the operation can consume.
219    *
220    * @param values
221    *    The values to add to this property.
222    *    <br>Ignored if <jk>null</jk>.
223    * @return This object.
224    */
225   public Operation addConsumes(Collection<MediaType> values) {
226      if (nn(values))
227         consumes.addAll(values);
228      return this;
229   }
230
231   /**
232    * Bean property fluent setter:  <property>consumes</property>.
233    *
234    * <p>
235    * A list of MIME types the operation can consume.
236    *
237    * @param value
238    *    The new value for this property.
239    * @return This object.
240    */
241   public Operation addConsumes(MediaType...value) {
242      addAllNn(consumes, value);
243      return this;
244   }
245
246   /**
247    * Bean property fluent setter:  <property>parameters</property>.
248    *
249    * <p>
250    * The parameters needed to send a valid API call.
251    *
252    * @param values
253    *    The values to add to this property.
254    *    <br>Ignored if <jk>null</jk>.
255    * @return This object.
256    */
257   public Operation addParameters(Collection<ParameterInfo> values) {
258      if (nn(values))
259         parameters.addAll(values);
260      return this;
261   }
262
263   /**
264    * Bean property fluent setter:  <property>parameters</property>.
265    *
266    * <p>
267    * A list of parameters that are applicable for this operation.
268    *
269    * @param value
270    *    The new value for this property.
271    * @return This object.
272    */
273   public Operation addParameters(ParameterInfo...value) {
274      addAllNn(parameters, value);
275      return this;
276   }
277
278   /**
279    * Bean property setter:  <property>produces</property>.
280    *
281    * <p>
282    * A list of MIME types the operation can produce.
283    *
284    * @param values
285    *    The values to add to this property.
286    *    <br>Ignored if <jk>null</jk>.
287    * @return This object.
288    */
289   public Operation addProduces(Collection<MediaType> values) {
290      if (nn(values))
291         produces.addAll(values);
292      return this;
293   }
294
295   /**
296    * Bean property fluent setter:  <property>produces</property>.
297    *
298    * <p>
299    * A list of MIME types the operation can produce.
300    *
301    * @param value
302    *    The new value for this property.
303    * @return This object.
304    */
305   public Operation addProduces(MediaType...value) {
306      addAllNn(produces, value);
307      return this;
308   }
309
310   /**
311    * Adds a single value to the <property>responses</property> property.
312    *
313    * @param statusCode The HTTP status code.  Must not be <jk>null</jk>, or an {@link IllegalArgumentException} is thrown.
314    * @param response The response description.  Must not be <jk>null</jk>, or an {@link IllegalArgumentException} is thrown.
315    * @return This object.
316    */
317   public Operation addResponse(String statusCode, ResponseInfo response) {
318      reqnn("statusCode", statusCode);
319      reqnn("response", response);
320      responses.put(statusCode, response);
321      return this;
322   }
323
324   /**
325    * Bean property setter:  <property>schemes</property>.
326    *
327    * <p>
328    * The transfer protocol for the operation.
329    *
330    * @param values
331    *    The values to add to this property.
332    *    <br>Ignored if <jk>null</jk>.
333    * @return This object.
334    */
335   public Operation addSchemes(Collection<String> values) {
336      if (nn(values))
337         schemes.addAll(values);
338      return this;
339   }
340
341   /**
342    * Bean property fluent setter:  <property>schemes</property>.
343    *
344    * <p>
345    * The transfer protocol for the operation.
346    *
347    * @param value
348    *    The new value for this property.
349    *    <br>String values can also be JSON arrays.
350    * @return This object.
351    */
352   public Operation addSchemes(String...value) {
353      addAllNn(schemes, value);
354      return this;
355   }
356
357   /**
358    * Bean property adder:  <property>security</property>.
359    *
360    * <p>
361    * A declaration of which security schemes are applied for this operation.
362    *
363    * @param value
364    *    The values to add to this property.
365    *    <br>Must not be <jk>null</jk>, or an {@link IllegalArgumentException} is thrown.
366    * @return This object.
367    */
368   public Operation addSecurity(Collection<Map<String,List<String>>> value) {
369      reqnn("value", value);
370      security.addAll(value);
371      return this;
372   }
373
374   /**
375    * Same as {@link #addSecurity(String, String...)}.
376    *
377    * @param scheme
378    *    The scheme name.
379    *    <br>Must not be <jk>null</jk>, or an {@link IllegalArgumentException} is thrown.
380    * @param alternatives
381    *    The list of values describes alternative security schemes that can be used (that is, there is a logical OR
382    *    between the security requirements).
383    * @return This object.
384    */
385   public Operation addSecurity(String scheme, String...alternatives) {
386      reqnn("scheme", scheme);
387      Map<String,List<String>> m = map();
388      m.put(scheme, l(alternatives));
389      security.add(m);
390      return this;
391   }
392
393   /**
394    * Bean property appender:  <property>tags</property>.
395    *
396    * <p>
397    * A list of tags for API documentation control.
398    *
399    * @param values
400    *    The values to add to this property.
401    *    <br>Ignored if <jk>null</jk>.
402    * @return This object.
403    */
404   public Operation addTags(Collection<String> values) {
405      if (nn(values))
406         tags.addAll(values);
407      return this;
408   }
409
410   /**
411    * Bean property fluent adder:  <property>tags</property>.
412    *
413    * <p>
414    * A list of tags for API documentation control.
415    * <br>Tags can be used for logical grouping of operations by resources or any other qualifier.
416    *
417    * @param value
418    *    The values to add to this property.
419    * @return This object.
420    */
421   public Operation addTags(String...value) {
422      addAllNn(tags, value);
423      return this;
424   }
425
426   /**
427    * Make a deep copy of this object.
428    *
429    * @return A deep copy of this object.
430    */
431   public Operation copy() {
432      return new Operation(this);
433   }
434
435   @Override /* Overridden from SwaggerElement */
436   public <T> T get(String property, Class<T> type) {
437      reqnn("property", property);
438      return switch (property) {
439         case "consumes" -> toType(getConsumes(), type);
440         case "deprecated" -> toType(getDeprecated(), type);
441         case "description" -> toType(getDescription(), type);
442         case "externalDocs" -> toType(getExternalDocs(), type);
443         case "operationId" -> toType(getOperationId(), type);
444         case "parameters" -> toType(getParameters(), type);
445         case "produces" -> toType(getProduces(), type);
446         case "responses" -> toType(getResponses(), type);
447         case "schemes" -> toType(getSchemes(), type);
448         case "security" -> toType(getSecurity(), type);
449         case "summary" -> toType(getSummary(), type);
450         case "tags" -> toType(getTags(), type);
451         default -> super.get(property, type);
452      };
453   }
454
455   /**
456    * Bean property getter:  <property>consumes</property>.
457    *
458    * <p>
459    * A list of MIME types the operation can consume.
460    *
461    * @return The property value, or <jk>null</jk> if it is not set.
462    */
463   public Set<MediaType> getConsumes() { return nie(consumes); }
464
465   /**
466    * Bean property getter:  <property>deprecated</property>.
467    *
468    * <p>
469    * Declares this operation to be deprecated.
470    *
471    * @return The property value, or <jk>null</jk> if it is not set.
472    */
473   public Boolean getDeprecated() { return deprecated; }
474
475   /**
476    * Bean property getter:  <property>description</property>.
477    *
478    * <p>
479    * A verbose explanation of the operation behavior.
480    *
481    * @return The property value, or <jk>null</jk> if it is not set.
482    */
483   public String getDescription() { return description; }
484
485   /**
486    * Bean property getter:  <property>externalDocs</property>.
487    *
488    * <p>
489    * Additional external documentation for this operation.
490    *
491    * @return The property value, or <jk>null</jk> if it is not set.
492    */
493   public ExternalDocumentation getExternalDocs() { return externalDocs; }
494
495   /**
496    * Bean property getter:  <property>operationId</property>.
497    *
498    * <p>
499    * Unique string used to identify the operation.
500    *
501    * @return The property value, or <jk>null</jk> if it is not set.
502    */
503   public String getOperationId() { return operationId; }
504
505   /**
506    * Returns the parameter with the specified type and name.
507    *
508    * @param in The parameter in.  Must not be <jk>null</jk>, or an {@link IllegalArgumentException} is thrown.
509    * @param name The parameter name.  Can be <jk>null</jk> for parameter type <c>body</c>.
510    * @return The matching parameter info, or <jk>null</jk> if not found.
511    */
512   public ParameterInfo getParameter(String in, String name) {
513      reqnn("in", in);
514      // Note: name can be null for "body" parameters
515      for (var pi : parameters)
516         if (eq(pi.getIn(), in) && (eq(pi.getName(), name) || eq(pi.getIn(), "body")))
517            return pi;
518      return null;
519   }
520
521   /**
522    * Bean property getter:  <property>parameters</property>.
523    *
524    * <p>
525    * A list of parameters that are applicable for this operation.
526    *
527    * <h5 class='section'>Notes:</h5><ul>
528    *    <li class='note'>
529    *       If a parameter is already defined at the <a class="doclink" href="https://swagger.io/specification#pathItemObject">Path Item</a>,
530    *       the new definition will override it, but can never remove it.
531    *    <li class='note'>
532    *       The list MUST NOT include duplicated parameters.
533    *    <li class='note'>
534    *       A unique parameter is defined by a combination of a <c>name</c> and <c>location</c>.
535    *    <li class='note'>
536    *       The list can use the <a class="doclink" href="https://swagger.io/specification#referenceObject">Swagger Reference Object</a>
537    *       to link to parameters that are defined at the <a class='doclink' href='https://swagger.io/specification/v2#parameterObject'>Swagger Object's parameters</a>.
538    *    <li class='note'>
539    *       There can be one <js>"body"</js> parameter at most.
540    * </ul>
541    *
542    * @return The property value, or <jk>null</jk> if it is not set.
543    */
544   public List<ParameterInfo> getParameters() { return nie(parameters); }
545
546   /**
547    * Bean property getter:  <property>produces</property>.
548    *
549    * <p>
550    * A list of MIME types the operation can produce.
551    *
552    * @return The property value, or <jk>null</jk> if it is not set.
553    */
554   public Set<MediaType> getProduces() { return nie(produces); }
555
556   /**
557    * Returns the response info with the given status code.
558    *
559    * @param status The HTTP status code.
560    * @return The response info, or <jk>null</jk> if not found.
561    */
562   public ResponseInfo getResponse(int status) {
563      return getResponse(String.valueOf(status));
564   }
565
566   /**
567    * Returns the response info with the given status code.
568    *
569    * @param status The HTTP status code.  Must not be <jk>null</jk>, or an {@link IllegalArgumentException} is thrown.
570    * @return The response info, or <jk>null</jk> if not found.
571    */
572   public ResponseInfo getResponse(String status) {
573      reqnn("status", status);
574      return responses.get(status);
575   }
576
577   /**
578    * Bean property getter:  <property>responses</property>.
579    *
580    * <p>
581    * The list of possible responses as they are returned from executing this operation.
582    *
583    * @return The property value, or <jk>null</jk> if it is not set.
584    */
585   public Map<String,ResponseInfo> getResponses() { return nie(responses); }
586
587   /**
588    * Bean property getter:  <property>schemes</property>.
589    *
590    * <p>
591    * The transfer protocol for the operation.
592    *
593    * @return The property value, or <jk>null</jk> if it is not set.
594    */
595   public Set<String> getSchemes() { return nie(schemes); }
596
597   /**
598    * Bean property getter:  <property>security</property>.
599    *
600    * <p>
601    * A declaration of which security schemes are applied for this operation.
602    *
603    * @return The property value, or <jk>null</jk> if it is not set.
604    */
605   public List<Map<String,List<String>>> getSecurity() { return nie(security); }
606
607   /**
608    * Bean property getter:  <property>summary</property>.
609    *
610    * <p>
611    * A short summary of what the operation does.
612    *
613    * @return The property value, or <jk>null</jk> if it is not set.
614    */
615   public String getSummary() { return summary; }
616
617   /**
618    * Bean property getter:  <property>tags</property>.
619    *
620    * <p>
621    * A list of tags for API documentation control.
622    * <br>Tags can be used for logical grouping of operations by resources or any other qualifier.
623    *
624    * @return The property value, or <jk>null</jk> if it is not set.
625    */
626   public Set<String> getTags() { return nie(tags); }
627
628   /**
629    * Bean property getter:  <property>deprecated</property>.
630    *
631    * <p>
632    * Declares this operation to be deprecated.
633    *
634    * @return The property value, or <jk>false</jk> if it is not set.
635    */
636   public boolean isDeprecated() { return nn(deprecated) && deprecated; }
637
638   @Override /* Overridden from SwaggerElement */
639   public Set<String> keySet() {
640      // @formatter:off
641      var s = stb(String.class)
642         .addIf(ine(consumes), "consumes")
643         .addIf(nn(deprecated), "deprecated")
644         .addIf(nn(description), "description")
645         .addIf(nn(externalDocs), "externalDocs")
646         .addIf(nn(operationId), "operationId")
647         .addIf(ine(parameters), "parameters")
648         .addIf(ine(produces), "produces")
649         .addIf(ine(responses), "responses")
650         .addIf(ine(schemes), "schemes")
651         .addIf(ine(security), "security")
652         .addIf(nn(summary), "summary")
653         .addIf(ine(tags), "tags")
654         .build();
655      // @formatter:on
656      return new MultiSet<>(s, super.keySet());
657   }
658
659   @SuppressWarnings({
660      "rawtypes", // Raw types necessary for generic type handling
661      "unchecked" // Type erasure requires unchecked casts in generic type conversions
662   })
663   @Override /* Overridden from SwaggerElement */
664   public Operation set(String property, Object value) {
665      reqnn("property", property);
666      return switch (property) {
667         case "consumes" -> setConsumes(toListBuilder(value, MediaType.class).sparse().build());
668         case "deprecated" -> setDeprecated(toBoolean(value));
669         case "description" -> setDescription(s(value));
670         case "externalDocs" -> setExternalDocs(toType(value, ExternalDocumentation.class));
671         case "operationId" -> setOperationId(s(value));
672         case "parameters" -> setParameters(toListBuilder(value, ParameterInfo.class).sparse().build());
673         case "produces" -> setProduces(toListBuilder(value, MediaType.class).sparse().build());
674         case "responses" -> setResponses(toMapBuilder(value, String.class, ResponseInfo.class).sparse().build());
675         case "schemes" -> setSchemes(toListBuilder(value, String.class).sparse().addAny(value).build());
676         case "security" -> setSecurity((List)toListBuilder(value, MapStringList.class).sparse().build());
677         case "summary" -> setSummary(s(value));
678         case "tags" -> setTags(toListBuilder(value, String.class).sparse().build());
679         default -> {
680            super.set(property, value);
681            yield this;
682         }
683      };
684   }
685
686   /**
687    * Bean property setter:  <property>consumes</property>.
688    *
689    * <p>
690    * A list of MIME types the operation can consume.
691    *
692    * @param value
693    *    The new value for this property.
694    *    <br>Values MUST be as described under <a class="doclink" href="https://swagger.io/specification#mimeTypes">Swagger Mime Types</a>.
695    *    <br>Can be <jk>null</jk> to unset the property.
696    * @return This object.
697    */
698   public Operation setConsumes(Collection<MediaType> value) {
699      consumes.clear();
700      if (nn(value))
701         consumes.addAll(value);
702      return this;
703   }
704
705   /**
706    * Bean property setter:  <property>consumes</property>.
707    *
708    * <p>
709    * A list of MIME types the operation can consume.
710    *
711    * @param value
712    *    The new value for this property.
713    *    <br>Values MUST be as described under <a class="doclink" href="https://swagger.io/specification#mimeTypes">Swagger Mime Types</a>.
714    *    <br>Can be <jk>null</jk> to unset the property.
715    * @return This object.
716    */
717   public Operation setConsumes(MediaType...value) {
718      return setConsumes(l(value));
719   }
720
721   /**
722    * Bean property setter:  <property>deprecated</property>.
723    *
724    * <p>
725    * Declares this operation to be deprecated.
726    *
727    * @param value The new value for this property.
728    *    <br>Can be <jk>null</jk> to unset the property.
729    * @return This object.
730    */
731   public Operation setDeprecated(Boolean value) {
732      deprecated = value;
733      return this;
734   }
735
736   /**
737    * Bean property setter:  <property>description</property>.
738    *
739    * <p>
740    * A verbose explanation of the operation behavior.
741    *
742    * @param value
743    *    The new value for this property.
744    *    <br><a class="doclink" href="https://help.github.com/articles/github-flavored-markdown">GFM syntax</a> can be used for rich text representation.
745    *    <br>Can be <jk>null</jk> to unset the property.
746    * @return This object.
747    */
748   public Operation setDescription(String value) {
749      description = value;
750      return this;
751   }
752
753   /**
754    * Bean property setter:  <property>externalDocs</property>.
755    *
756    * <p>
757    * Additional external documentation for this operation.
758    *
759    * @param value
760    *    The values to add to this property.
761    *    <br>Can be <jk>null</jk> to unset the property.
762    * @return This object.
763    */
764   public Operation setExternalDocs(ExternalDocumentation value) {
765      externalDocs = value;
766      return this;
767   }
768
769   /**
770    * Bean property setter:  <property>operationId</property>.
771    *
772    * <p>
773    * Unique string used to identify the operation.
774    *
775    * @param value
776    *    The new value for this property.
777    *    <br>The id MUST be unique among all operations described in the API.
778    *    <br>Tools and libraries MAY use the operationId to uniquely identify an operation, therefore, it is recommended to
779    *    follow common programming naming conventions.
780    *    <br>Can be <jk>null</jk> to unset the property.
781    * @return This object.
782    */
783   public Operation setOperationId(String value) {
784      operationId = value;
785      return this;
786   }
787
788   /**
789    * Bean property setter:  <property>parameters</property>.
790    *
791    * <p>
792    * A list of parameters that are applicable for this operation.
793    *
794    * @param value
795    *    The new value for this property.
796    *    <br>Can be <jk>null</jk> to unset the property.
797    * @return This object.
798    */
799   public Operation setParameters(Collection<ParameterInfo> value) {
800      parameters = toList(value);
801      return this;
802   }
803
804   /**
805    * Bean property setter:  <property>parameters</property>.
806    *
807    * <p>
808    * A list of parameters that are applicable for this operation.
809    *
810    * @param value
811    *    The new value for this property.
812    *    <br>Can be <jk>null</jk> to unset the property.
813    * @return This object.
814    */
815   public Operation setParameters(ParameterInfo...value) {
816      return setParameters(l(value));
817   }
818
819   /**
820    * Bean property setter:  <property>produces</property>.
821    *
822    * <p>
823    * A list of MIME types the operation can produce.
824    *
825    * @param value
826    *    The new value for this property.
827    *    <br>Value MUST be as described under <a class="doclink" href="https://swagger.io/specification#mimeTypes">Swagger Mime Types</a>.
828    *    <br>Can be <jk>null</jk> to unset the property.
829    * @return This object.
830    */
831   public Operation setProduces(Collection<MediaType> value) {
832      produces.clear();
833      if (nn(value))
834         produces.addAll(value);
835      return this;
836   }
837
838   /**
839    * Bean property setter:  <property>produces</property>.
840    *
841    * <p>
842    * A list of MIME types the operation can produce.
843    *
844    * @param value
845    *    The new value for this property.
846    *    <br>Value MUST be as described under <a class="doclink" href="https://swagger.io/specification#mimeTypes">Swagger Mime Types</a>.
847    *    <br>Can be <jk>null</jk> to unset the property.
848    * @return This object.
849    */
850   public Operation setProduces(MediaType...value) {
851      return setProduces(l(value));
852   }
853
854   /**
855    * Bean property setter:  <property>responses</property>.
856    *
857    * <p>
858    * The list of possible responses as they are returned from executing this operation.
859    *
860    * @param value
861    *    The new value for this property.
862    *    <br>Property value is required.
863    *    <br>Can be <jk>null</jk> to unset the property.
864    * @return This object.
865    */
866   public Operation setResponses(Map<String,ResponseInfo> value) {
867      responses.clear();
868      if (nn(value))
869         responses.putAll(value);
870      return this;
871   }
872
873   /**
874    * Bean property setter:  <property>schemes</property>.
875    *
876    * <p>
877    * The transfer protocol for the operation.
878    *
879    * @param value
880    *    The new value for this property.
881    *    <br>Valid values:
882    *    <ul>
883    *       <li><js>"http"</js>
884    *       <li><js>"https"</js>
885    *       <li><js>"ws"</js>
886    *       <li><js>"wss"</js>
887    *    </ul>
888    *    <br>Can be <jk>null</jk> to unset the property.
889    * @return This object.
890    */
891   public Operation setSchemes(Collection<String> value) {
892      schemes.clear();
893      if (nn(value))
894         schemes.addAll(value);
895      return this;
896   }
897
898   /**
899    * Bean property setter:  <property>schemes</property>.
900    *
901    * <p>
902    * The transfer protocol for the operation.
903    *
904    * @param value
905    *    The new value for this property.
906    *    <br>Can be <jk>null</jk> to unset the property.
907    * @return This object.
908    */
909   public Operation setSchemes(String...value) {
910      setSchemes(stb(String.class).sparse().add(value).build());
911      return this;
912   }
913
914   /**
915    * Bean property setter:  <property>security</property>.
916    *
917    * <p>
918    * A declaration of which security schemes are applied for this operation.
919    *
920    * @param value
921    *    The new value for this property.
922    *    <br>Can be <jk>null</jk> to unset the property.
923    * @return This object.
924    */
925   public Operation setSecurity(Collection<Map<String,List<String>>> value) {
926      security = toList(value);
927      return this;
928   }
929
930   /**
931    * Bean property setter:  <property>security</property>.
932    *
933    * <p>
934    * A declaration of which security schemes are applied for this operation.
935    *
936    * @param value
937    *    The new value for this property.
938    *    <br>Can be <jk>null</jk> to unset the property.
939    * @return This object.
940    */
941   @SafeVarargs
942   public final Operation setSecurity(Map<String,List<String>>...value) {
943      security = l(value);
944      return this;
945   }
946
947   /**
948    * Bean property setter:  <property>summary</property>.
949    *
950    * <p>
951    * A short summary of what the operation does.
952    *
953    * @param value
954    *    The new value for this property.
955    *    <br>Can be <jk>null</jk> to unset the property.
956    * @return This object.
957    */
958   public Operation setSummary(String value) {
959      summary = value;
960      return this;
961   }
962
963   /**
964    * Bean property setter:  <property>tags</property>.
965    *
966    * <p>
967    * A list of tags for API documentation control.
968    * <br>Tags can be used for logical grouping of operations by resources or any other qualifier.
969    *
970    * @param value
971    *    The new value for this property.
972    *    <br>Can be <jk>null</jk> to unset the property.
973    * @return This object.
974    */
975   public Operation setTags(Collection<String> value) {
976      tags.clear();
977      if (nn(value))
978         tags.addAll(value);
979      return this;
980   }
981
982   /**
983    * Bean property fluent setter:  <property>tags</property>.
984    *
985    * <p>
986    * A list of tags for API documentation control.
987    * <br>Tags can be used for logical grouping of operations by resources or any other qualifier.
988    *
989    * @param value
990    *    The new value for this property.
991    * @return This object.
992    */
993   public Operation setTags(String...value) {
994      setTags(stb(String.class).sparse().add(value).build());
995      return this;
996   }
997
998   /**
999    * Sets strict mode on this bean.
1000    *
1001    * @return This object.
1002    */
1003   @Override
1004   public Operation strict() {
1005      super.strict();
1006      return this;
1007   }
1008
1009   /**
1010    * Sets strict mode on this bean.
1011    *
1012    * @param value
1013    *    The new value for this property.
1014    *    <br>Non-boolean values will be converted to boolean using <code>Boolean.<jsm>valueOf</jsm>(value.toString())</code>.
1015    *    <br>Can be <jk>null</jk> (interpreted as <jk>false</jk>).
1016    * @return This object.
1017    */
1018   @Override
1019   public Operation strict(Object value) {
1020      super.strict(value);
1021      return this;
1022   }
1023}