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.http.annotation;
014
015import static java.lang.annotation.ElementType.*;
016import static java.lang.annotation.RetentionPolicy.*;
017import static org.apache.juneau.internal.ArrayUtils.*;
018
019import java.lang.annotation.*;
020import java.lang.reflect.*;
021
022import org.apache.juneau.*;
023import org.apache.juneau.annotation.*;
024import org.apache.juneau.httppart.*;
025import org.apache.juneau.reflect.*;
026import org.apache.juneau.svl.*;
027
028/**
029 * Utility classes and methods for the {@link Response @Response} annotation.
030 *
031 * <h5 class='section'>See Also:</h5><ul>
032 * </ul>
033 */
034public class ResponseAnnotation {
035
036   //-----------------------------------------------------------------------------------------------------------------
037   // Static
038   //-----------------------------------------------------------------------------------------------------------------
039
040   /** Default value */
041   public static final Response DEFAULT = create().build();
042
043   /**
044    * Instantiates a new builder for this class.
045    *
046    * @return A new builder object.
047    */
048   public static Builder create() {
049      return new Builder();
050   }
051
052   /**
053    * Instantiates a new builder for this class.
054    *
055    * @param on The targets this annotation applies to.
056    * @return A new builder object.
057    */
058   public static Builder create(Class<?>...on) {
059      return create().on(on);
060   }
061
062   /**
063    * Instantiates a new builder for this class.
064    *
065    * @param on The targets this annotation applies to.
066    * @return A new builder object.
067    */
068   public static Builder create(String...on) {
069      return create().on(on);
070   }
071
072   /**
073    * Returns <jk>true</jk> if the specified annotation contains all default values.
074    *
075    * @param a The annotation to check.
076    * @return <jk>true</jk> if the specified annotation contains all default values.
077    */
078   public static boolean empty(Response a) {
079      return a == null || DEFAULT.equals(a);
080   }
081
082   //-----------------------------------------------------------------------------------------------------------------
083   // Builder
084   //-----------------------------------------------------------------------------------------------------------------
085
086   /**
087    * Builder class.
088    *
089    * <h5 class='section'>See Also:</h5><ul>
090    *    <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#annotations(Annotation...)}
091    * </ul>
092    */
093   public static class Builder extends TargetedAnnotationTMBuilder {
094
095      Class<? extends HttpPartParser> parser = HttpPartParser.Void.class;
096      Class<? extends HttpPartSerializer> serializer = HttpPartSerializer.Void.class;
097      Header[] headers={};
098      Schema schema = SchemaAnnotation.DEFAULT;
099      String[] examples={};
100
101      /**
102       * Constructor.
103       */
104      protected Builder() {
105         super(Response.class);
106      }
107
108      /**
109       * Instantiates a new {@link Response @Response} object initialized with this builder.
110       *
111       * @return A new {@link Response @Response} object.
112       */
113      public Response build() {
114         return new Impl(this);
115      }
116
117      /**
118       * Sets the {@link Response#examples} property on this annotation.
119       *
120       * @param value The new value for this property.
121       * @return This object.
122       */
123      public Builder examples(String...value) {
124         this.examples = value;
125         return this;
126      }
127
128      /**
129       * Sets the {@link Response#headers} property on this annotation.
130       *
131       * @param value The new value for this property.
132       * @return This object.
133       */
134      public Builder headers(Header...value) {
135         this.headers = value;
136         return this;
137      }
138
139      /**
140       * Sets the {@link Response#parser} property on this annotation.
141       *
142       * @param value The new value for this property.
143       * @return This object.
144       */
145      public Builder parser(Class<? extends HttpPartParser> value) {
146         this.parser = value;
147         return this;
148      }
149
150      /**
151       * Sets the {@link Response#schema} property on this annotation.
152       *
153       * @param value The new value for this property.
154       * @return This object.
155       */
156      public Builder schema(Schema value) {
157         this.schema = value;
158         return this;
159      }
160
161      /**
162       * Sets the {@link Response#serializer} property on this annotation.
163       *
164       * @param value The new value for this property.
165       * @return This object.
166       */
167      public Builder serializer(Class<? extends HttpPartSerializer> value) {
168         this.serializer = value;
169         return this;
170      }
171
172      // <FluentSetters>
173
174      @Override /* GENERATED - TargetedAnnotationBuilder */
175      public Builder on(String...values) {
176         super.on(values);
177         return this;
178      }
179
180      @Override /* GENERATED - TargetedAnnotationTBuilder */
181      public Builder on(java.lang.Class<?>...value) {
182         super.on(value);
183         return this;
184      }
185
186      @Override /* GENERATED - TargetedAnnotationTBuilder */
187      public Builder onClass(java.lang.Class<?>...value) {
188         super.onClass(value);
189         return this;
190      }
191
192      @Override /* GENERATED - TargetedAnnotationTMBuilder */
193      public Builder on(Method...value) {
194         super.on(value);
195         return this;
196      }
197
198      // </FluentSetters>
199   }
200
201   //-----------------------------------------------------------------------------------------------------------------
202   // Implementation
203   //-----------------------------------------------------------------------------------------------------------------
204
205   private static class Impl extends TargetedAnnotationTImpl implements Response {
206
207      private final Class<? extends HttpPartParser> parser;
208      private final Class<? extends HttpPartSerializer> serializer;
209      private final Header[] headers;
210      private final Schema schema;
211      private final String[] examples;
212
213      Impl(Builder b) {
214         super(b);
215         this.examples = copyOf(b.examples);
216         this.headers = copyOf(b.headers);
217         this.parser = b.parser;
218         this.schema = b.schema;
219         this.serializer = b.serializer;
220         postConstruct();
221      }
222
223      @Override /* Response */
224      public String[] examples() {
225         return examples;
226      }
227
228      @Override /* Response */
229      public Header[] headers() {
230         return headers;
231      }
232
233      @Override /* Response */
234      public Class<? extends HttpPartParser> parser() {
235         return parser;
236      }
237
238      @Override /* Response */
239      public Schema schema() {
240         return schema;
241      }
242
243      @Override /* Response */
244      public Class<? extends HttpPartSerializer> serializer() {
245         return serializer;
246      }
247   }
248
249   //-----------------------------------------------------------------------------------------------------------------
250   // Appliers
251   //-----------------------------------------------------------------------------------------------------------------
252
253   /**
254    * Applies targeted {@link Response} annotations to a {@link org.apache.juneau.BeanContext.Builder}.
255    */
256   public static class Applier extends AnnotationApplier<Response,BeanContext.Builder> {
257
258      /**
259       * Constructor.
260       *
261       * @param vr The resolver for resolving values in annotations.
262       */
263      public Applier(VarResolverSession vr) {
264         super(Response.class, BeanContext.Builder.class, vr);
265      }
266
267      @Override
268      public void apply(AnnotationInfo<Response> ai, BeanContext.Builder b) {
269         Response a = ai.inner();
270         if (isEmptyArray(a.on(), a.onClass()))
271            return;
272         b.annotations(a);
273      }
274   }
275
276   //-----------------------------------------------------------------------------------------------------------------
277   // Other
278   //-----------------------------------------------------------------------------------------------------------------
279
280   /**
281    * A collection of {@link Response @Response annotations}.
282    */
283   @Documented
284   @Target({METHOD,TYPE})
285   @Retention(RUNTIME)
286   @Inherited
287   public static @interface Array {
288
289      /**
290       * The child annotations.
291       *
292       * @return The annotation value.
293       */
294      Response[] value();
295   }
296}