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