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}