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 RestPut @RestPut} 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 RestPutAnnotation {
042
043   //-----------------------------------------------------------------------------------------------------------------
044   // Static
045   //-----------------------------------------------------------------------------------------------------------------
046
047   /** Default value */
048   public static final RestPut 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(RestPut.class);
088      }
089
090      /**
091       * Instantiates a new {@link RestPut @RestPut} object initialized with this builder.
092       *
093       * @return A new {@link RestPut @RestPut} object.
094       */
095      public RestPut build() {
096         return new Impl(this);
097      }
098
099      /**
100       * Sets the {@link RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut#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 RestPut {
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 /* RestPut */
450      public String clientVersion() {
451         return clientVersion;
452      }
453
454      @Override /* RestPut */
455      public String[] consumes() {
456         return consumes;
457      }
458
459      @Override /* RestPut */
460      public Class<? extends RestConverter>[] converters() {
461         return converters;
462      }
463
464      @Override /* RestPut */
465      public String debug() {
466         return debug;
467      }
468
469      @Override /* RestPut */
470      public String defaultAccept() {
471         return defaultAccept;
472      }
473
474      @Override /* RestPut */
475      public String defaultCharset() {
476         return defaultCharset;
477      }
478
479      @Override /* RestPut */
480      public String defaultContentType() {
481         return defaultContentType;
482      }
483
484      @Override /* RestPut */
485      public String[] defaultRequestFormData() {
486         return defaultRequestFormData;
487      }
488
489      @Override /* RestPut */
490      public String[] defaultRequestQueryData() {
491         return defaultRequestQueryData;
492      }
493
494      @Override /* RestPut */
495      public String[] defaultRequestAttributes() {
496         return defaultRequestAttributes;
497      }
498
499      @Override /* RestPut */
500      public String[] defaultRequestHeaders() {
501         return defaultRequestHeaders;
502      }
503
504      @Override /* RestPut */
505      public String[] defaultResponseHeaders() {
506         return defaultResponseHeaders;
507      }
508
509      @Override /* RestPut */
510      public String[] description() {
511         return description;
512      }
513
514      @Override /* RestPut */
515      public Class<? extends Encoder>[] encoders() {
516         return encoders;
517      }
518
519      @Override /* RestPut */
520      public Class<? extends RestGuard>[] guards() {
521         return guards;
522      }
523
524      @Override /* RestPut */
525      public Class<? extends RestMatcher>[] matchers() {
526         return matchers;
527      }
528
529      @Override /* RestPut */
530      public String maxInput() {
531         return maxInput;
532      }
533
534      @Override /* RestPut */
535      public Class<?>[] parsers() {
536         return parsers;
537      }
538
539      @Override /* RestPut */
540      public String[] path() {
541         return path;
542      }
543
544      @Override /* RestPut */
545      public String[] produces() {
546         return produces;
547      }
548
549      @Override /* RestPut */
550      public String roleGuard() {
551         return roleGuard;
552      }
553
554      @Override /* RestPut */
555      public String rolesDeclared() {
556         return rolesDeclared;
557      }
558
559      @Override /* RestPut */
560      public Class<? extends Serializer>[] serializers() {
561         return serializers;
562      }
563
564      @Override /* RestPut */
565      public String summary() {
566         return summary;
567      }
568
569      @Override /* RestPut */
570      public OpSwagger swagger() {
571         return swagger;
572      }
573
574      @Override /* RestPut */
575      public String value() {
576         return value;
577      }
578   }
579
580   //-----------------------------------------------------------------------------------------------------------------
581   // Appliers
582   //-----------------------------------------------------------------------------------------------------------------
583
584   /**
585    * Applies {@link RestPut} annotations to a {@link org.apache.juneau.rest.RestOpContext.Builder}.
586    */
587   public static class RestOpContextApply extends AnnotationApplier<RestPut,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(RestPut.class, RestOpContext.Builder.class, vr);
596      }
597
598      @Override
599      public void apply(AnnotationInfo<RestPut> ai, RestOpContext.Builder b) {
600         RestPut a = ai.inner();
601
602         b.httpMethod("put");
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}