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