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