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.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.reflect.*;
024import org.apache.juneau.svl.*;
025
026/**
027 * Utility classes and methods for the {@link Beanp @Beanp} annotation.
028 *
029 * <h5 class='section'>See Also:</h5><ul>
030 * </ul>
031 */
032public class BeanpAnnotation {
033
034   //-----------------------------------------------------------------------------------------------------------------
035   // Static
036   //-----------------------------------------------------------------------------------------------------------------
037
038   /** Default value */
039   public static final Beanp DEFAULT = create().build();
040
041   /**
042    * Instantiates a new builder for this class.
043    *
044    * @return A new builder object.
045    */
046   public static Builder create() {
047      return new Builder();
048   }
049
050   /**
051    * Instantiates a new builder for this class.
052    *
053    * @param on The targets this annotation applies to.
054    * @return A new builder object.
055    */
056   public static Builder create(String...on) {
057      return create().on(on);
058   }
059
060   /**
061    * Creates a copy of the specified annotation.
062    *
063    * @param a The annotation to copy.s
064    * @param r The var resolver for resolving any variables.
065    * @return A copy of the specified annotation.
066    */
067   public static Beanp copy(Beanp a, VarResolverSession r) {
068      return
069         create()
070         .dictionary(a.dictionary())
071         .format(r.resolve(a.format()))
072         .name(r.resolve(a.name()))
073         .on(r.resolve(a.on()))
074         .params(a.params())
075         .properties(r.resolve(a.properties()))
076         .ro(r.resolve(a.ro()))
077         .type(a.type())
078         .value(r.resolve(a.value()))
079         .wo(r.resolve(a.wo()))
080         .build();
081   }
082
083   //-----------------------------------------------------------------------------------------------------------------
084   // Builder
085   //-----------------------------------------------------------------------------------------------------------------
086
087   /**
088    * Builder class.
089    *
090    * <h5 class='section'>See Also:</h5><ul>
091    *    <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#annotations(Annotation...)}
092    * </ul>
093    */
094   public static class Builder extends TargetedAnnotationMFBuilder {
095
096      Class<?> type=void.class;
097      Class<?>[] dictionary=new Class[0], params=new Class[0];
098      String format="", name="", properties="", ro="", value="", wo="";
099
100      /**
101       * Constructor.
102       */
103      protected Builder() {
104         super(Beanp.class);
105      }
106
107      /**
108       * Instantiates a new {@link Beanp @Beanp} object initialized with this builder.
109       *
110       * @return A new {@link Beanp @Beanp} object.
111       */
112      public Beanp build() {
113         return new Impl(this);
114      }
115
116      /**
117       * Sets the {@link Beanp#dictionary()} property on this annotation.
118       *
119       * @param value The new value for this property.
120       * @return This object.
121       */
122      public Builder dictionary(Class<?>...value) {
123         this.dictionary = value;
124         return this;
125      }
126
127      /**
128       * Sets the {@link Beanp#format()} property on this annotation.
129       *
130       * @param value The new value for this property.
131       * @return This object.
132       */
133      public Builder format(String value) {
134         this.format = value;
135         return this;
136      }
137
138      /**
139       * Sets the {@link Beanp#name()} property on this annotation.
140       *
141       * @param value The new value for this property.
142       * @return This object.
143       */
144      public Builder name(String value) {
145         this.name = value;
146         return this;
147      }
148
149      /**
150       * Sets the {@link Beanp#params()} property on this annotation.
151       *
152       * @param value The new value for this property.
153       * @return This object.
154       */
155      public Builder params(Class<?>...value) {
156         this.params = value;
157         return this;
158      }
159
160      /**
161       * Sets the {@link Beanp#properties()} property on this annotation.
162       *
163       * @param value The new value for this property.
164       * @return This object.
165       */
166      public Builder properties(String value) {
167         this.properties = value;
168         return this;
169      }
170
171      /**
172       * Sets the {@link Beanp#ro()} property on this annotation.
173       *
174       * @param value The new value for this property.
175       * @return This object.
176       */
177      public Builder ro(String value) {
178         this.ro = value;
179         return this;
180      }
181
182      /**
183       * Sets the {@link Beanp#type()} property on this annotation.
184       *
185       * @param value The new value for this property.
186       * @return This object.
187       */
188      public Builder type(Class<?> value) {
189         this.type = value;
190         return this;
191      }
192
193      /**
194       * Sets the {@link Beanp#value()} property on this annotation.
195       *
196       * @param value The new value for this property.
197       * @return This object.
198       */
199      public Builder value(String value) {
200         this.value = value;
201         return this;
202      }
203
204      /**
205       * Sets the {@link Beanp#wo()} property on this annotation.
206       *
207       * @param value The new value for this property.
208       * @return This object.
209       */
210      public Builder wo(String value) {
211         this.wo = value;
212         return this;
213      }
214
215      // <FluentSetters>
216
217      @Override /* GENERATED - TargetedAnnotationBuilder */
218      public Builder on(String...values) {
219         super.on(values);
220         return this;
221      }
222
223      @Override /* GENERATED - TargetedAnnotationMFBuilder */
224      public Builder on(Field...value) {
225         super.on(value);
226         return this;
227      }
228
229      @Override /* GENERATED - TargetedAnnotationMFBuilder */
230      public Builder on(Method...value) {
231         super.on(value);
232         return this;
233      }
234
235      // </FluentSetters>
236   }
237
238   //-----------------------------------------------------------------------------------------------------------------
239   // Implementation
240   //-----------------------------------------------------------------------------------------------------------------
241
242   private static class Impl extends TargetedAnnotationImpl implements Beanp {
243
244      private final Class<?> type;
245      private final Class<?>[] params, dictionary;
246      private final String name, value, properties, format, ro, wo;
247
248      Impl(Builder b) {
249         super(b);
250         this.dictionary = copyOf(b.dictionary);
251         this.format = b.format;
252         this.name = b.name;
253         this.params = copyOf(b.params);
254         this.properties = b.properties;
255         this.ro = b.ro;
256         this.type = b.type;
257         this.value = b.value;
258         this.wo = b.wo;
259         postConstruct();
260      }
261
262      @Override /* Beanp */
263      public Class<?>[] dictionary() {
264         return dictionary;
265      }
266
267      @Override /* Beanp */
268      public String format() {
269         return format;
270      }
271
272      @Override /* Beanp */
273      public String name() {
274         return name;
275      }
276
277      @Override /* Beanp */
278      public Class<?>[] params() {
279         return params;
280      }
281
282      @Override /* Beanp */
283      public String properties() {
284         return properties;
285      }
286
287      @Override /* Beanp */
288      public String ro() {
289         return ro;
290      }
291
292      @Override /* Beanp */
293      public Class<?> type() {
294         return type;
295      }
296
297      @Override /* Beanp */
298      public String value() {
299         return value;
300      }
301
302      @Override /* Beanp */
303      public String wo() {
304         return wo;
305      }
306   }
307
308   //-----------------------------------------------------------------------------------------------------------------
309   // Appliers
310   //-----------------------------------------------------------------------------------------------------------------
311
312   /**
313    * Applies targeted {@link Beanp} annotations to a {@link org.apache.juneau.BeanContext.Builder}.
314    */
315   public static class Applier extends AnnotationApplier<Beanp,BeanContext.Builder> {
316
317      /**
318       * Constructor.
319       *
320       * @param vr The resolver for resolving values in annotations.
321       */
322      public Applier(VarResolverSession vr) {
323         super(Beanp.class, BeanContext.Builder.class, vr);
324      }
325
326      @Override
327      public void apply(AnnotationInfo<Beanp> ai, BeanContext.Builder b) {
328         Beanp a = ai.inner();
329         if (isEmptyArray(a.on()))
330            return;
331         b.annotations(copy(a, vr()));
332      }
333   }
334
335   //-----------------------------------------------------------------------------------------------------------------
336   // Other
337   //-----------------------------------------------------------------------------------------------------------------
338
339   /**
340    * A collection of {@link Beanp @Beanp annotations}.
341    */
342   @Documented
343   @Target({METHOD,TYPE})
344   @Retention(RUNTIME)
345   @Inherited
346   public static @interface Array {
347
348      /**
349       * The child annotations.
350       *
351       * @return The annotation value.
352       */
353      Beanp[] value();
354   }
355}