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