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