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