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.reflect.*;
025import org.apache.juneau.svl.*;
026
027/**
028 * Utility classes and methods for the {@link Content @Content} annotation.
029 *
030 * <h5 class='section'>See Also:</h5><ul>
031 * </ul>
032 */
033public class ContentAnnotation {
034
035   //-----------------------------------------------------------------------------------------------------------------
036   // Static
037   //-----------------------------------------------------------------------------------------------------------------
038
039   /** Default value */
040   public static final Content DEFAULT = create().build();
041
042   /**
043    * Instantiates a new builder for this class.
044    *
045    * @return A new builder object.
046    */
047   public static Builder create() {
048      return new Builder();
049   }
050
051   /**
052    * Instantiates a new builder for this class.
053    *
054    * @param on The targets this annotation applies to.
055    * @return A new builder object.
056    */
057   public static Builder create(Class<?>...on) {
058      return create().on(on);
059   }
060
061   /**
062    * Instantiates a new builder for this class.
063    *
064    * @param on The targets this annotation applies to.
065    * @return A new builder object.
066    */
067   public static Builder create(String...on) {
068      return create().on(on);
069   }
070
071   /**
072    * Returns <jk>true</jk> if the specified annotation contains all default values.
073    *
074    * @param a The annotation to check.
075    * @return <jk>true</jk> if the specified annotation contains all default values.
076    */
077   public static boolean empty(Content a) {
078      return a == null || DEFAULT.equals(a);
079   }
080
081   //-----------------------------------------------------------------------------------------------------------------
082   // Builder
083   //-----------------------------------------------------------------------------------------------------------------
084
085   /**
086    * Builder class.
087    *
088    * <h5 class='section'>See Also:</h5><ul>
089    *    <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#annotations(Annotation...)}
090    * </ul>
091    */
092   public static class Builder extends TargetedAnnotationTMBuilder {
093
094      Schema schema = SchemaAnnotation.DEFAULT;
095
096      /**
097       * Constructor.
098       */
099      protected Builder() {
100         super(Content.class);
101      }
102
103      /**
104       * Instantiates a new {@link Content @Content} object initialized with this builder.
105       *
106       * @return A new {@link Content @Content} object.
107       */
108      public Content build() {
109         return new Impl(this);
110      }
111
112      /**
113       * Sets the {@link Content#schema} property on this annotation.
114       *
115       * @param value The new value for this property.
116       * @return This object.
117       */
118      public Builder schema(Schema value) {
119         this.schema = value;
120         return this;
121      }
122
123      // <FluentSetters>
124
125      @Override /* GENERATED - TargetedAnnotationBuilder */
126      public Builder on(String...values) {
127         super.on(values);
128         return this;
129      }
130
131      @Override /* GENERATED - TargetedAnnotationTBuilder */
132      public Builder on(java.lang.Class<?>...value) {
133         super.on(value);
134         return this;
135      }
136
137      @Override /* GENERATED - TargetedAnnotationTBuilder */
138      public Builder onClass(java.lang.Class<?>...value) {
139         super.onClass(value);
140         return this;
141      }
142
143      @Override /* GENERATED - TargetedAnnotationTMBuilder */
144      public Builder on(Method...value) {
145         super.on(value);
146         return this;
147      }
148
149      // </FluentSetters>
150   }
151
152   //-----------------------------------------------------------------------------------------------------------------
153   // Implementation
154   //-----------------------------------------------------------------------------------------------------------------
155
156   private static class Impl extends TargetedAnnotationTImpl implements Content {
157
158      private final Schema schema;
159
160      Impl(Builder b) {
161         super(b);
162         this.schema = b.schema;
163         postConstruct();
164      }
165
166      @Override /* Body */
167      public Schema schema() {
168         return schema;
169      }
170   }
171
172   //-----------------------------------------------------------------------------------------------------------------
173   // Appliers
174   //-----------------------------------------------------------------------------------------------------------------
175
176   /**
177    * Applies targeted {@link Content} annotations to a {@link org.apache.juneau.BeanContext.Builder}.
178    */
179   public static class Applier extends AnnotationApplier<Content,BeanContext.Builder> {
180
181      /**
182       * Constructor.
183       *
184       * @param vr The resolver for resolving values in annotations.
185       */
186      public Applier(VarResolverSession vr) {
187         super(Content.class, BeanContext.Builder.class, vr);
188      }
189
190      @Override
191      public void apply(AnnotationInfo<Content> ai, BeanContext.Builder b) {
192         Content a = ai.inner();
193         if (isEmptyArray(a.on(), a.onClass()))
194            return;
195         b.annotations(a);
196      }
197   }
198
199   //-----------------------------------------------------------------------------------------------------------------
200   // Other
201   //-----------------------------------------------------------------------------------------------------------------
202
203   /**
204    * A collection of {@link Content @Content annotations}.
205    */
206   @Documented
207   @Target({METHOD,TYPE})
208   @Retention(RUNTIME)
209   @Inherited
210   public static @interface Array {
211
212      /**
213       * The child annotations.
214       *
215       * @return The annotation value.
216       */
217      Content[] value();
218   }
219}