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 * 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 > 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 * Creates a copy of this object. 118 * 119 * @return A copy of this object. 120 */ 121 public PathItem copy() { 122 return new PathItem(this); 123 } 124 125 @Override /* Overridden from OpenApiElement */ 126 public <T> T get(String property, Class<T> type) { 127 assertArgNotNull("property", property); 128 return switch (property) { 129 case "summary" -> toType(getSummary(), type); 130 case "description" -> toType(getDescription(), type); 131 case "get" -> toType(getGet(), type); 132 case "put" -> toType(getPut(), type); 133 case "post" -> toType(getPost(), type); 134 case "delete" -> toType(getDelete(), type); 135 case "options" -> toType(getOptions(), type); 136 case "head" -> toType(getHead(), type); 137 case "patch" -> toType(getPatch(), type); 138 case "trace" -> toType(getTrace(), type); 139 case "servers" -> toType(getServers(), type); 140 case "parameters" -> toType(getParameters(), type); 141 default -> super.get(property, type); 142 }; 143 } 144 145 /** 146 * Returns the DELETE operation. 147 * 148 * @return The DELETE operation. 149 */ 150 public Operation getDelete() { return delete; } 151 152 /** 153 * Returns the description. 154 * 155 * @return The description. 156 */ 157 public String getDescription() { return description; } 158 159 /** 160 * Returns the GET operation. 161 * 162 * @return The GET operation. 163 */ 164 public Operation getGet() { return get; } 165 166 /** 167 * Returns the HEAD operation. 168 * 169 * @return The HEAD operation. 170 */ 171 public Operation getHead() { return head; } 172 173 /** 174 * Returns the OPTIONS operation. 175 * 176 * @return The OPTIONS operation. 177 */ 178 public Operation getOptions() { return options; } 179 180 /** 181 * Returns the parameters list. 182 * 183 * @return The parameters list. 184 */ 185 public List<Parameter> getParameters() { return parameters; } 186 187 /** 188 * Returns the PATCH operation. 189 * 190 * @return The PATCH operation. 191 */ 192 public Operation getPatch() { return patch; } 193 194 /** 195 * Returns the POST operation. 196 * 197 * @return The POST operation. 198 */ 199 public Operation getPost() { return post; } 200 201 /** 202 * Returns the PUT operation. 203 * 204 * @return The PUT operation. 205 */ 206 public Operation getPut() { return put; } 207 208 /** 209 * Returns the servers list. 210 * 211 * @return The servers list. 212 */ 213 public List<Server> getServers() { return servers; } 214 215 /** 216 * Returns the summary. 217 * 218 * @return The summary. 219 */ 220 public String getSummary() { return summary; } 221 222 /** 223 * Returns the TRACE operation. 224 * 225 * @return The TRACE operation. 226 */ 227 public Operation getTrace() { return trace; } 228 229 @Override /* Overridden from OpenApiElement */ 230 public Set<String> keySet() { 231 // @formatter:off 232 var s = setb(String.class) 233 .addIf(nn(delete), "delete") 234 .addIf(nn(description), "description") 235 .addIf(nn(get), "get") 236 .addIf(nn(head), "head") 237 .addIf(nn(options), "options") 238 .addIf(nn(parameters), "parameters") 239 .addIf(nn(patch), "patch") 240 .addIf(nn(post), "post") 241 .addIf(nn(put), "put") 242 .addIf(nn(servers), "servers") 243 .addIf(nn(summary), "summary") 244 .addIf(nn(trace), "trace") 245 .build(); 246 // @formatter:on 247 return new MultiSet<>(s, super.keySet()); 248 } 249 250 @Override /* Overridden from OpenApiElement */ 251 public PathItem set(String property, Object value) { 252 assertArgNotNull("property", property); 253 return switch (property) { 254 case "delete" -> setDelete(toType(value, Operation.class)); 255 case "description" -> setDescription(s(value)); 256 case "get" -> setGet(toType(value, Operation.class)); 257 case "head" -> setHead(toType(value, Operation.class)); 258 case "options" -> setOptions(toType(value, Operation.class)); 259 case "patch" -> setPatch(toType(value, Operation.class)); 260 case "parameters" -> setParameters(listb(Parameter.class).addAny(value).sparse().build()); 261 case "post" -> setPost(toType(value, Operation.class)); 262 case "put" -> setPut(toType(value, Operation.class)); 263 case "servers" -> setServers(listb(Server.class).addAny(value).sparse().build()); 264 case "summary" -> setSummary(s(value)); 265 case "trace" -> setTrace(toType(value, Operation.class)); 266 default -> { 267 super.set(property, value); 268 yield this; 269 } 270 }; 271 } 272 273 /** 274 * Sets the DELETE operation. 275 * 276 * @param value The new value for this property. 277 * @return This object. 278 */ 279 public PathItem setDelete(Operation value) { 280 delete = value; 281 return this; 282 } 283 284 /** 285 * Sets the description. 286 * 287 * @param value The new value for this property. 288 * @return This object. 289 */ 290 public PathItem setDescription(String value) { 291 description = value; 292 return this; 293 } 294 295 /** 296 * Sets the GET operation. 297 * 298 * @param value The new value for this property. 299 * @return This object. 300 */ 301 public PathItem setGet(Operation value) { 302 get = value; 303 return this; 304 } 305 306 /** 307 * Sets the HEAD operation. 308 * 309 * @param value The new value for this property. 310 * @return This object. 311 */ 312 public PathItem setHead(Operation value) { 313 head = value; 314 return this; 315 } 316 317 /** 318 * Sets the OPTIONS operation. 319 * 320 * @param value The new value for this property. 321 * @return This object. 322 */ 323 public PathItem setOptions(Operation value) { 324 options = value; 325 return this; 326 } 327 328 /** 329 * Sets the parameters list. 330 * 331 * @param value The new value for this property. 332 * @return This object. 333 */ 334 public PathItem setParameters(List<Parameter> value) { 335 parameters = value; 336 return this; 337 } 338 339 /** 340 * Sets the PATCH operation. 341 * 342 * @param value The new value for this property. 343 * @return This object. 344 */ 345 public PathItem setPatch(Operation value) { 346 patch = value; 347 return this; 348 } 349 350 /** 351 * Sets the POST operation. 352 * 353 * @param value The new value for this property. 354 * @return This object. 355 */ 356 public PathItem setPost(Operation value) { 357 post = value; 358 return this; 359 } 360 361 /** 362 * Sets the PUT operation. 363 * 364 * @param value The new value for this property. 365 * @return This object. 366 */ 367 public PathItem setPut(Operation value) { 368 put = value; 369 return this; 370 } 371 372 /** 373 * Sets the servers list. 374 * 375 * @param value The new value for this property. 376 * @return This object. 377 */ 378 public PathItem setServers(List<Server> value) { 379 servers = value; 380 return this; 381 } 382 383 /** 384 * Sets the summary. 385 * 386 * @param value The new value for this property. 387 * @return This object. 388 */ 389 public PathItem setSummary(String value) { 390 summary = value; 391 return this; 392 } 393 394 /** 395 * Sets the TRACE operation. 396 * 397 * @param value The new value for this property. 398 * @return This object. 399 */ 400 public PathItem setTrace(Operation value) { 401 trace = value; 402 return this; 403 } 404 405 @Override /* Overridden from OpenApiElement */ 406 public PathItem strict() { 407 super.strict(); 408 return this; 409 } 410 411 @Override /* Overridden from OpenApiElement */ 412 public PathItem strict(Object value) { 413 super.strict(value); 414 return this; 415 } 416}