001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.rest.annotation; 014 015import static org.apache.juneau.internal.ArrayUtils.*; 016import java.lang.annotation.*; 017import java.nio.charset.*; 018 019import org.apache.juneau.*; 020import org.apache.juneau.annotation.*; 021import org.apache.juneau.encoders.*; 022import org.apache.juneau.http.HttpHeaders; 023import org.apache.juneau.http.HttpParts; 024import org.apache.juneau.reflect.*; 025import org.apache.juneau.rest.*; 026import org.apache.juneau.rest.converter.*; 027import org.apache.juneau.rest.guard.*; 028import org.apache.juneau.rest.httppart.*; 029import org.apache.juneau.rest.matcher.*; 030import org.apache.juneau.serializer.*; 031import org.apache.juneau.svl.*; 032 033/** 034 * Utility classes and methods for the {@link RestPost @RestPost} annotation. 035 * 036 * <h5 class='section'>See Also:</h5><ul> 037 * <li class='link'><a class="doclink" href="../../../../../index.html#jrs.RestOpAnnotatedMethods">@RestOp-Annotated Methods</a> 038 * </ul> 039 */ 040public class RestPostAnnotation { 041 042 //----------------------------------------------------------------------------------------------------------------- 043 // Static 044 //----------------------------------------------------------------------------------------------------------------- 045 046 /** Default value */ 047 public static final RestPost DEFAULT = create().build(); 048 049 /** 050 * Instantiates a new builder for this class. 051 * 052 * @return A new builder object. 053 */ 054 public static Builder create() { 055 return new Builder(); 056 } 057 058 //----------------------------------------------------------------------------------------------------------------- 059 // Builder 060 //----------------------------------------------------------------------------------------------------------------- 061 062 /** 063 * Builder class. 064 * 065 * <h5 class='section'>See Also:</h5><ul> 066 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#annotations(Annotation...)} 067 * </ul> 068 */ 069 @SuppressWarnings("unchecked") 070 public static class Builder extends TargetedAnnotationMBuilder { 071 072 Class<? extends RestConverter>[] converters = new Class[0]; 073 Class<? extends RestGuard>[] guards = new Class[0]; 074 Class<? extends RestMatcher>[] matchers = new Class[0]; 075 Class<? extends Encoder>[] encoders = new Class[0]; 076 Class<? extends Serializer>[] serializers = new Class[0]; 077 Class<?>[] parsers={}; 078 OpSwagger swagger = OpSwaggerAnnotation.DEFAULT; 079 String clientVersion="", debug="", defaultAccept="", defaultCharset="", defaultContentType="", maxInput="", rolesDeclared="", roleGuard="", summary="", value=""; 080 String[] consumes={}, defaultRequestFormData={}, defaultRequestQueryData={}, defaultRequestAttributes={}, defaultRequestHeaders={}, defaultResponseHeaders={}, description={}, path={}, produces={}; 081 082 /** 083 * Constructor. 084 */ 085 protected Builder() { 086 super(RestPost.class); 087 } 088 089 /** 090 * Instantiates a new {@link RestPost @RestPost} object initialized with this builder. 091 * 092 * @return A new {@link RestPost @RestPost} object. 093 */ 094 public RestPost build() { 095 return new Impl(this); 096 } 097 098 /** 099 * Sets the {@link RestPost#clientVersion()} property on this annotation. 100 * 101 * @param value The new value for this property. 102 * @return This object. 103 */ 104 public Builder clientVersion(String value) { 105 this.clientVersion = value; 106 return this; 107 } 108 109 /** 110 * Sets the {@link RestPost#consumes()} property on this annotation. 111 * 112 * @param value The new value for this property. 113 * @return This object. 114 */ 115 public Builder consumes(String...value) { 116 this.consumes = value; 117 return this; 118 } 119 120 /** 121 * Sets the {@link RestPost#converters()} property on this annotation. 122 * 123 * @param value The new value for this property. 124 * @return This object. 125 */ 126 public Builder converters(Class<? extends RestConverter>...value) { 127 this.converters = value; 128 return this; 129 } 130 131 /** 132 * Sets the {@link RestPost#debug()} property on this annotation. 133 * 134 * @param value The new value for this property. 135 * @return This object. 136 */ 137 public Builder debug(String value) { 138 this.debug = value; 139 return this; 140 } 141 142 /** 143 * Sets the {@link RestPost#defaultAccept()} property on this annotation. 144 * 145 * @param value The new value for this property. 146 * @return This object. 147 */ 148 public Builder defaultAccept(String value) { 149 this.defaultAccept = value; 150 return this; 151 } 152 153 /** 154 * Sets the {@link RestPost#defaultCharset()} property on this annotation. 155 * 156 * @param value The new value for this property. 157 * @return This object. 158 */ 159 public Builder defaultCharset(String value) { 160 this.defaultCharset = value; 161 return this; 162 } 163 164 /** 165 * Sets the {@link RestPost#defaultContentType()} property on this annotation. 166 * 167 * @param value The new value for this property. 168 * @return This object. 169 */ 170 public Builder defaultContentType(String value) { 171 this.defaultContentType = value; 172 return this; 173 } 174 175 /** 176 * Sets the {@link RestPost#defaultRequestFormData()} property on this annotation. 177 * 178 * @param value The new value for this property. 179 * @return This object. 180 */ 181 public Builder defaultRequestFormData(String...value) { 182 this.defaultRequestFormData = value; 183 return this; 184 } 185 186 /** 187 * Sets the {@link RestPost#defaultRequestQueryData()} property on this annotation. 188 * 189 * @param value The new value for this property. 190 * @return This object. 191 */ 192 public Builder defaultRequestQueryData(String...value) { 193 this.defaultRequestQueryData = value; 194 return this; 195 } 196 197 /** 198 * Sets the {@link RestPost#defaultRequestAttributes()} property on this annotation. 199 * 200 * @param value The new value for this property. 201 * @return This object. 202 */ 203 public Builder defaultRequestAttributes(String...value) { 204 this.defaultRequestAttributes = value; 205 return this; 206 } 207 208 /** 209 * Sets the {@link RestPost#defaultRequestHeaders()} property on this annotation. 210 * 211 * @param value The new value for this property. 212 * @return This object. 213 */ 214 public Builder defaultRequestHeaders(String...value) { 215 this.defaultRequestHeaders = value; 216 return this; 217 } 218 219 /** 220 * Sets the {@link RestPost#defaultResponseHeaders()} property on this annotation. 221 * 222 * @param value The new value for this property. 223 * @return This object. 224 */ 225 public Builder defaultResponseHeaders(String...value) { 226 this.defaultResponseHeaders = value; 227 return this; 228 } 229 230 /** 231 * Sets the {@link RestPost#description()} property on this annotation. 232 * 233 * @param value The new value for this property. 234 * @return This object. 235 */ 236 public Builder description(String...value) { 237 this.description = value; 238 return this; 239 } 240 241 /** 242 * Sets the {@link RestPost#encoders()} property on this annotation. 243 * 244 * @param value The new value for this property. 245 * @return This object. 246 */ 247 public Builder encoders(Class<? extends Encoder>...value) { 248 this.encoders = value; 249 return this; 250 } 251 252 /** 253 * Sets the {@link RestPost#guards()} property on this annotation. 254 * 255 * @param value The new value for this property. 256 * @return This object. 257 */ 258 public Builder guards(Class<? extends RestGuard>...value) { 259 this.guards = value; 260 return this; 261 } 262 263 /** 264 * Sets the {@link RestPost#matchers()} property on this annotation. 265 * 266 * @param value The new value for this property. 267 * @return This object. 268 */ 269 public Builder matchers(Class<? extends RestMatcher>...value) { 270 this.matchers = value; 271 return this; 272 } 273 274 /** 275 * Sets the {@link RestPost#maxInput()} property on this annotation. 276 * 277 * @param value The new value for this property. 278 * @return This object. 279 */ 280 public Builder maxInput(String value) { 281 this.maxInput = value; 282 return this; 283 } 284 285 /** 286 * Sets the {@link RestPost#parsers()} property on this annotation. 287 * 288 * @param value The new value for this property. 289 * @return This object. 290 */ 291 public Builder parsers(Class<?>...value) { 292 this.parsers = value; 293 return this; 294 } 295 296 /** 297 * Sets the {@link RestPost#path()} property on this annotation. 298 * 299 * @param value The new value for this property. 300 * @return This object. 301 */ 302 public Builder path(String...value) { 303 this.path = value; 304 return this; 305 } 306 307 /** 308 * Sets the {@link RestPost#produces()} property on this annotation. 309 * 310 * @param value The new value for this property. 311 * @return This object. 312 */ 313 public Builder produces(String...value) { 314 this.produces = value; 315 return this; 316 } 317 318 /** 319 * Sets the {@link RestPost#roleGuard()} property on this annotation. 320 * 321 * @param value The new value for this property. 322 * @return This object. 323 */ 324 public Builder roleGuard(String value) { 325 this.roleGuard = value; 326 return this; 327 } 328 329 /** 330 * Sets the {@link RestPost#rolesDeclared()} property on this annotation. 331 * 332 * @param value The new value for this property. 333 * @return This object. 334 */ 335 public Builder rolesDeclared(String value) { 336 this.rolesDeclared = value; 337 return this; 338 } 339 340 /** 341 * Sets the {@link RestPost#serializers()} property on this annotation. 342 * 343 * @param value The new value for this property. 344 * @return This object. 345 */ 346 public Builder serializers(Class<? extends Serializer>...value) { 347 this.serializers = value; 348 return this; 349 } 350 351 /** 352 * Sets the {@link RestPost#summary()} property on this annotation. 353 * 354 * @param value The new value for this property. 355 * @return This object. 356 */ 357 public Builder summary(String value) { 358 this.summary = value; 359 return this; 360 } 361 362 /** 363 * Sets the {@link RestPost#swagger()} property on this annotation. 364 * 365 * @param value The new value for this property. 366 * @return This object. 367 */ 368 public Builder swagger(OpSwagger value) { 369 this.swagger = value; 370 return this; 371 } 372 373 /** 374 * Sets the {@link RestPost#value()} property on this annotation. 375 * 376 * @param value The new value for this property. 377 * @return This object. 378 */ 379 public Builder value(String value) { 380 this.value = value; 381 return this; 382 } 383 384 // <FluentSetters> 385 386 @Override /* GENERATED - TargetedAnnotationBuilder */ 387 public Builder on(String...values) { 388 super.on(values); 389 return this; 390 } 391 392 @Override /* GENERATED - TargetedAnnotationTMBuilder */ 393 public Builder on(java.lang.reflect.Method...value) { 394 super.on(value); 395 return this; 396 } 397 398 // </FluentSetters> 399 } 400 401 //----------------------------------------------------------------------------------------------------------------- 402 // Implementation 403 //----------------------------------------------------------------------------------------------------------------- 404 405 private static class Impl extends TargetedAnnotationImpl implements RestPost { 406 407 private final Class<? extends RestConverter>[] converters; 408 private final Class<? extends RestGuard>[] guards; 409 private final Class<? extends RestMatcher>[] matchers; 410 private final Class<? extends Encoder>[] encoders; 411 private final Class<? extends Serializer>[] serializers; 412 private final Class<?>[] parsers; 413 private final OpSwagger swagger; 414 private final String clientVersion, debug, defaultAccept, defaultCharset, defaultContentType, maxInput, rolesDeclared, roleGuard, summary, value; 415 private final String[] consumes, defaultRequestFormData, defaultRequestQueryData, defaultRequestAttributes, defaultRequestHeaders, defaultResponseHeaders, description, path, produces; 416 417 Impl(Builder b) { 418 super(b); 419 this.clientVersion = b.clientVersion; 420 this.consumes = copyOf(b.consumes); 421 this.converters = copyOf(b.converters); 422 this.debug = b.debug; 423 this.defaultAccept = b.defaultAccept; 424 this.defaultCharset = b.defaultCharset; 425 this.defaultContentType = b.defaultContentType; 426 this.defaultRequestFormData = copyOf(b.defaultRequestFormData); 427 this.defaultRequestQueryData = copyOf(b.defaultRequestQueryData); 428 this.defaultRequestAttributes = copyOf(b.defaultRequestAttributes); 429 this.defaultRequestHeaders = copyOf(b.defaultRequestHeaders); 430 this.defaultResponseHeaders = copyOf(b.defaultResponseHeaders); 431 this.description = copyOf(b.description); 432 this.encoders = copyOf(b.encoders); 433 this.guards = copyOf(b.guards); 434 this.matchers = copyOf(b.matchers); 435 this.maxInput = b.maxInput; 436 this.parsers = copyOf(b.parsers); 437 this.path = copyOf(b.path); 438 this.produces = copyOf(b.produces); 439 this.roleGuard = b.roleGuard; 440 this.rolesDeclared = b.rolesDeclared; 441 this.serializers = copyOf(b.serializers); 442 this.summary = b.summary; 443 this.swagger = b.swagger; 444 this.value = b.value; 445 postConstruct(); 446 } 447 448 @Override /* RestPost */ 449 public String clientVersion() { 450 return clientVersion; 451 } 452 453 @Override /* RestPost */ 454 public String[] consumes() { 455 return consumes; 456 } 457 458 @Override /* RestPost */ 459 public Class<? extends RestConverter>[] converters() { 460 return converters; 461 } 462 463 @Override /* RestPost */ 464 public String debug() { 465 return debug; 466 } 467 468 @Override /* RestPost */ 469 public String defaultAccept() { 470 return defaultAccept; 471 } 472 473 @Override /* RestPost */ 474 public String defaultCharset() { 475 return defaultCharset; 476 } 477 478 @Override /* RestPost */ 479 public String defaultContentType() { 480 return defaultContentType; 481 } 482 483 @Override /* RestPost */ 484 public String[] defaultRequestFormData() { 485 return defaultRequestFormData; 486 } 487 488 @Override /* RestPost */ 489 public String[] defaultRequestQueryData() { 490 return defaultRequestQueryData; 491 } 492 493 @Override /* RestPost */ 494 public String[] defaultRequestAttributes() { 495 return defaultRequestAttributes; 496 } 497 498 @Override /* RestPost */ 499 public String[] defaultRequestHeaders() { 500 return defaultRequestHeaders; 501 } 502 503 @Override /* RestPost */ 504 public String[] defaultResponseHeaders() { 505 return defaultResponseHeaders; 506 } 507 508 @Override /* RestPost */ 509 public String[] description() { 510 return description; 511 } 512 513 @Override /* RestPost */ 514 public Class<? extends Encoder>[] encoders() { 515 return encoders; 516 } 517 518 @Override /* RestPost */ 519 public Class<? extends RestGuard>[] guards() { 520 return guards; 521 } 522 523 @Override /* RestPost */ 524 public Class<? extends RestMatcher>[] matchers() { 525 return matchers; 526 } 527 528 @Override /* RestPost */ 529 public String maxInput() { 530 return maxInput; 531 } 532 533 @Override /* RestPost */ 534 public Class<?>[] parsers() { 535 return parsers; 536 } 537 538 @Override /* RestPost */ 539 public String[] path() { 540 return path; 541 } 542 543 @Override /* RestPost */ 544 public String[] produces() { 545 return produces; 546 } 547 548 @Override /* RestPost */ 549 public String roleGuard() { 550 return roleGuard; 551 } 552 553 @Override /* RestPost */ 554 public String rolesDeclared() { 555 return rolesDeclared; 556 } 557 558 @Override /* RestPost */ 559 public Class<? extends Serializer>[] serializers() { 560 return serializers; 561 } 562 563 @Override /* RestPost */ 564 public String summary() { 565 return summary; 566 } 567 568 @Override /* RestPost */ 569 public OpSwagger swagger() { 570 return swagger; 571 } 572 573 @Override /* RestPost */ 574 public String value() { 575 return value; 576 } 577 } 578 579 //----------------------------------------------------------------------------------------------------------------- 580 // Appliers 581 //----------------------------------------------------------------------------------------------------------------- 582 583 /** 584 * Applies {@link RestPost} annotations to a {@link org.apache.juneau.rest.RestOpContext.Builder}. 585 */ 586 public static class RestOpContextApply extends AnnotationApplier<RestPost,RestOpContext.Builder> { 587 588 /** 589 * Constructor. 590 * 591 * @param vr The resolver for resolving values in annotations. 592 */ 593 public RestOpContextApply(VarResolverSession vr) { 594 super(RestPost.class, RestOpContext.Builder.class, vr); 595 } 596 597 @Override 598 public void apply(AnnotationInfo<RestPost> ai, RestOpContext.Builder b) { 599 RestPost a = ai.inner(); 600 601 b.httpMethod("post"); 602 603 classes(a.serializers()).ifPresent(x -> b.serializers().set(x)); 604 classes(a.parsers()).ifPresent(x -> b.parsers().set(x)); 605 classes(a.encoders()).ifPresent(x -> b.encoders().set(x)); 606 stream(a.produces()).map(MediaType::of).forEach(x -> b.produces(x)); 607 stream(a.consumes()).map(MediaType::of).forEach(x -> b.consumes(x)); 608 stream(a.defaultRequestHeaders()).map(HttpHeaders::stringHeader).forEach(x -> b.defaultRequestHeaders().setDefault(x)); 609 stream(a.defaultResponseHeaders()).map(HttpHeaders::stringHeader).forEach(x -> b.defaultResponseHeaders().setDefault(x)); 610 stream(a.defaultRequestAttributes()).map(BasicNamedAttribute::ofPair).forEach(x -> b.defaultRequestAttributes().add(x)); 611 stream(a.defaultRequestQueryData()).map(HttpParts::basicPart).forEach(x -> b.defaultRequestQueryData().setDefault(x)); 612 stream(a.defaultRequestFormData()).map(HttpParts::basicPart).forEach(x -> b.defaultRequestFormData().setDefault(x)); 613 string(a.defaultAccept()).map(HttpHeaders::accept).ifPresent(x -> b.defaultRequestHeaders().setDefault(x)); 614 string(a.defaultContentType()).map(HttpHeaders::contentType).ifPresent(x -> b.defaultRequestHeaders().setDefault(x)); 615 b.converters().append(a.converters()); 616 b.guards().append(a.guards()); 617 b.matchers().append(a.matchers()); 618 string(a.clientVersion()).ifPresent(x -> b.clientVersion(x)); 619 string(a.defaultCharset()).map(Charset::forName).ifPresent(x -> b.defaultCharset(x)); 620 string(a.maxInput()).ifPresent(x -> b.maxInput(x)); 621 stream(a.path()).forEach(x -> b.path(x)); 622 string(a.value()).ifPresent(x -> b.path(x)); 623 cdl(a.rolesDeclared()).forEach(x -> b.rolesDeclared(x)); 624 string(a.roleGuard()).ifPresent(x -> b.roleGuard(x)); 625 string(a.debug()).map(Enablement::fromString).ifPresent(x -> b.debug(x)); 626 } 627 } 628}