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.common.utils.*;
026import org.apache.juneau.internal.*;
027
028/**
029 * Describes the operations available on a single path.
030 *
031 * <p>
032 * The PathItem Object describes the operations available on a single path. A Path Item may be empty, due to ACL 
033 * constraints. The path itself is still exposed to the documentation viewer but they will not know which operations 
034 * and parameters are available.
035 *
036 * <h5 class='section'>OpenAPI Specification:</h5>
037 * <p>
038 * The PathItem Object is composed of the following fields:
039 * <ul class='spaced-list'>
040 *    <li><c>summary</c> (string) - An optional, string summary, intended to apply to all operations in this path
041 *    <li><c>description</c> (string) - An optional, string description, intended to apply to all operations in this path
042 *    <li><c>get</c> ({@link Operation}) - A definition of a GET operation on this path
043 *    <li><c>put</c> ({@link Operation}) - A definition of a PUT operation on this path
044 *    <li><c>post</c> ({@link Operation}) - A definition of a POST operation on this path
045 *    <li><c>delete</c> ({@link Operation}) - A definition of a DELETE operation on this path
046 *    <li><c>options</c> ({@link Operation}) - A definition of an OPTIONS operation on this path
047 *    <li><c>head</c> ({@link Operation}) - A definition of a HEAD operation on this path
048 *    <li><c>patch</c> ({@link Operation}) - A definition of a PATCH operation on this path
049 *    <li><c>trace</c> ({@link Operation}) - A definition of a TRACE operation on this path
050 *    <li><c>servers</c> (array of {@link Server}) - An alternative server array to service all operations in this path
051 *    <li><c>parameters</c> (array of {@link Parameter}) - A list of parameters that are applicable for all the operations described under this path
052 * </ul>
053 *
054 * <h5 class='section'>Example:</h5>
055 * <p class='bcode'>
056 *    <jc>// Construct using SwaggerBuilder.</jc>
057 *    PathItem <jv>x</jv> = <jsm>pathItem</jsm>()
058 *       .setSummary(<js>"User management"</js>)
059 *       .setGet(<jsm>operation</jsm>().setSummary(<js>"Get users"</js>))
060 *       .setPost(<jsm>operation</jsm>().setSummary(<js>"Create user"</js>));
061 *
062 *    <jc>// Serialize using JsonSerializer.</jc>
063 *    String <jv>json</jv> = Json.<jsm>from</jsm>(<jv>x</jv>);
064 *
065 *    <jc>// Or just use toString() which does the same as above.</jc>
066 *    <jv>json</jv> = <jv>x</jv>.toString();
067 * </p>
068 * <p class='bcode'>
069 *    <jc>// Output</jc>
070 *    {
071 *       <js>"summary"</js>: <js>"User management"</js>,
072 *       <js>"get"</js>: { <js>"summary"</js>: <js>"Get users"</js> },
073 *       <js>"post"</js>: { <js>"summary"</js>: <js>"Create user"</js> }
074 *    }
075 * </p>
076 *
077 * <h5 class='section'>See Also:</h5><ul>
078 *    <li class='link'><a class="doclink" href="https://spec.openapis.org/oas/v3.0.0#path-item-object">OpenAPI Specification &gt; Path Item Object</a>
079 *    <li class='link'><a class="doclink" href="https://swagger.io/docs/specification/paths-and-operations/">OpenAPI Paths and Operations</a>
080 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanOpenApi3">juneau-bean-openapi-v3</a>
081 * </ul>
082 */
083public class PathItem extends OpenApiElement {
084
085   private String summary, description;
086   private Operation get, put, post, delete, options, head, patch, trace;
087   private List<Server> servers;
088   private List<Parameter> parameters;
089
090   /**
091    * Default constructor.
092    */
093   public PathItem() {}
094
095   /**
096    * Copy constructor.
097    *
098    * @param copyFrom The object to copy.
099    */
100   public PathItem(PathItem copyFrom) {
101      super(copyFrom);
102      this.summary = copyFrom.summary;
103      this.description = copyFrom.description;
104      this.get = copyFrom.get;
105      this.put = copyFrom.put;
106      this.post = copyFrom.post;
107      this.delete = copyFrom.delete;
108      this.options = copyFrom.options;
109      this.head = copyFrom.head;
110      this.patch = copyFrom.patch;
111      this.trace = copyFrom.trace;
112      this.servers = copyOf(copyFrom.servers);
113      this.parameters = copyOf(copyFrom.parameters);
114   }
115
116   /**
117    * Returns the summary.
118    *
119    * @return The summary.
120    */
121   public String getSummary() {
122      return summary;
123   }
124
125   /**
126    * Sets the summary.
127    *
128    * @param value The new value for this property.
129    * @return This object.
130    */
131   public PathItem setSummary(String value) {
132      this.summary = value;
133      return this;
134   }
135
136   /**
137    * Returns the description.
138    *
139    * @return The description.
140    */
141   public String getDescription() {
142      return description;
143   }
144
145   /**
146    * Sets the description.
147    *
148    * @param value The new value for this property.
149    * @return This object.
150    */
151   public PathItem setDescription(String value) {
152      this.description = value;
153      return this;
154   }
155
156   /**
157    * Returns the GET operation.
158    *
159    * @return The GET operation.
160    */
161   public Operation getGet() {
162      return get;
163   }
164
165   /**
166    * Sets the GET operation.
167    *
168    * @param value The new value for this property.
169    * @return This object.
170    */
171   public PathItem setGet(Operation value) {
172      this.get = value;
173      return this;
174   }
175
176   /**
177    * Returns the PUT operation.
178    *
179    * @return The PUT operation.
180    */
181   public Operation getPut() {
182      return put;
183   }
184
185   /**
186    * Sets the PUT operation.
187    *
188    * @param value The new value for this property.
189    * @return This object.
190    */
191   public PathItem setPut(Operation value) {
192      this.put = value;
193      return this;
194   }
195
196   /**
197    * Returns the POST operation.
198    *
199    * @return The POST operation.
200    */
201   public Operation getPost() {
202      return post;
203   }
204
205   /**
206    * Sets the POST operation.
207    *
208    * @param value The new value for this property.
209    * @return This object.
210    */
211   public PathItem setPost(Operation value) {
212      this.post = value;
213      return this;
214   }
215
216   /**
217    * Returns the DELETE operation.
218    *
219    * @return The DELETE operation.
220    */
221   public Operation getDelete() {
222      return delete;
223   }
224
225   /**
226    * Sets the DELETE operation.
227    *
228    * @param value The new value for this property.
229    * @return This object.
230    */
231   public PathItem setDelete(Operation value) {
232      this.delete = value;
233      return this;
234   }
235
236   /**
237    * Returns the OPTIONS operation.
238    *
239    * @return The OPTIONS operation.
240    */
241   public Operation getOptions() {
242      return options;
243   }
244
245   /**
246    * Sets the OPTIONS operation.
247    *
248    * @param value The new value for this property.
249    * @return This object.
250    */
251   public PathItem setOptions(Operation value) {
252      this.options = value;
253      return this;
254   }
255
256   /**
257    * Returns the HEAD operation.
258    *
259    * @return The HEAD operation.
260    */
261   public Operation getHead() {
262      return head;
263   }
264
265   /**
266    * Sets the HEAD operation.
267    *
268    * @param value The new value for this property.
269    * @return This object.
270    */
271   public PathItem setHead(Operation value) {
272      this.head = value;
273      return this;
274   }
275
276   /**
277    * Returns the PATCH operation.
278    *
279    * @return The PATCH operation.
280    */
281   public Operation getPatch() {
282      return patch;
283   }
284
285   /**
286    * Sets the PATCH operation.
287    *
288    * @param value The new value for this property.
289    * @return This object.
290    */
291   public PathItem setPatch(Operation value) {
292      this.patch = value;
293      return this;
294   }
295
296   /**
297    * Returns the TRACE operation.
298    *
299    * @return The TRACE operation.
300    */
301   public Operation getTrace() {
302      return trace;
303   }
304
305   /**
306    * Sets the TRACE operation.
307    *
308    * @param value The new value for this property.
309    * @return This object.
310    */
311   public PathItem setTrace(Operation value) {
312      this.trace = value;
313      return this;
314   }
315
316   /**
317    * Returns the servers list.
318    *
319    * @return The servers list.
320    */
321   public List<Server> getServers() {
322      return servers;
323   }
324
325   /**
326    * Sets the servers list.
327    *
328    * @param value The new value for this property.
329    * @return This object.
330    */
331   public PathItem setServers(List<Server> value) {
332      this.servers = value;
333      return this;
334   }
335
336   /**
337    * Returns the parameters list.
338    *
339    * @return The parameters list.
340    */
341   public List<Parameter> getParameters() {
342      return parameters;
343   }
344
345   /**
346    * Sets the parameters list.
347    *
348    * @param value The new value for this property.
349    * @return This object.
350    */
351   public PathItem setParameters(List<Parameter> value) {
352      this.parameters = value;
353      return this;
354   }
355
356   /**
357    * Creates a copy of this object.
358    *
359    * @return A copy of this object.
360    */
361   public PathItem copy() {
362      return new PathItem(this);
363   }
364
365   @Override /* Overridden from OpenApiElement */
366   public <T> T get(String property, Class<T> type) {
367      assertArgNotNull("property", property);
368      return switch (property) {
369         case "summary" -> toType(getSummary(), type);
370         case "description" -> toType(getDescription(), type);
371         case "get" -> toType(getGet(), type);
372         case "put" -> toType(getPut(), type);
373         case "post" -> toType(getPost(), type);
374         case "delete" -> toType(getDelete(), type);
375         case "options" -> toType(getOptions(), type);
376         case "head" -> toType(getHead(), type);
377         case "patch" -> toType(getPatch(), type);
378         case "trace" -> toType(getTrace(), type);
379         case "servers" -> toType(getServers(), type);
380         case "parameters" -> toType(getParameters(), type);
381         default -> super.get(property, type);
382      };
383   }
384
385   @Override /* Overridden from OpenApiElement */
386   public PathItem set(String property, Object value) {
387      assertArgNotNull("property", property);
388      return switch (property) {
389         case "delete" -> setDelete(toType(value, Operation.class));
390         case "description" -> setDescription(Utils.s(value));
391         case "get" -> setGet(toType(value, Operation.class));
392         case "head" -> setHead(toType(value, Operation.class));
393         case "options" -> setOptions(toType(value, Operation.class));
394         case "patch" -> setPatch(toType(value, Operation.class));
395         case "parameters" -> setParameters(listBuilder(Parameter.class).sparse().addAny(value).build());
396         case "post" -> setPost(toType(value, Operation.class));
397         case "put" -> setPut(toType(value, Operation.class));
398         case "servers" -> setServers(listBuilder(Server.class).sparse().addAny(value).build());
399         case "summary" -> setSummary(Utils.s(value));
400         case "trace" -> setTrace(toType(value, Operation.class));
401         default -> {
402            super.set(property, value);
403            yield this;
404         }
405      };
406   }
407
408   @Override /* Overridden from OpenApiElement */
409   public Set<String> keySet() {
410      var s = setBuilder(String.class)
411         .addIf(delete != null, "delete")
412         .addIf(description != null, "description")
413         .addIf(get != null, "get")
414         .addIf(head != null, "head")
415         .addIf(options != null, "options")
416         .addIf(patch != null, "patch")
417         .addIf(parameters != null, "parameters")
418         .addIf(post != null, "post")
419         .addIf(put != null, "put")
420         .addIf(servers != null, "servers")
421         .addIf(summary != null, "summary")
422         .addIf(trace != null, "trace")
423         .build();
424      return new MultiSet<>(s, super.keySet());
425   }
426
427   @Override /* Overridden from OpenApiElement */
428   public PathItem strict() {
429      super.strict();
430      return this;
431   }
432
433   @Override /* Overridden from OpenApiElement */
434   public PathItem strict(Object value) {
435      super.strict(value);
436      return this;
437   }
438
439}