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.marshall;
018
019import static org.apache.juneau.commons.utils.CollectionUtils.*;
020
021import java.lang.annotation.*;
022import java.lang.reflect.*;
023
024import org.apache.juneau.commons.*;
025import org.apache.juneau.commons.reflect.*;
026import org.apache.juneau.commons.svl.*;
027
028/**
029 * Utility classes and methods for the {@link MarshalledPropApply @MarshalledPropApply} annotation.
030 *
031 */
032public class MarshalledPropApplyAnnotation {
033
034   /**
035    * Prevents instantiation.
036    */
037   private MarshalledPropApplyAnnotation() {}
038
039   /**
040    * Applies targeted {@link MarshalledPropApply} annotations to a {@link Context.Builder}.
041    */
042   @SuppressWarnings({
043      "rawtypes" // Raw types required for reflective annotation application.
044   })
045   public static class Applier extends AnnotationApplier<MarshalledPropApply,Context.Builder> {
046
047      /**
048       * Constructor.
049       *
050       * @param vr The resolver for resolving values in annotations. Must not be <jk>null</jk>.
051       */
052      public Applier(VarResolverSession vr) {
053         super(MarshalledPropApply.class, Context.Builder.class, vr);
054      }
055
056      @Override
057      public void apply(AnnotationInfo<MarshalledPropApply> ai, Context.Builder b) {
058         MarshalledPropApply a = ai.inner();
059         if (isEmptyArray(a.on()) && isEmptyArray(a.onClass()))
060            return;
061         b.annotations(a);
062      }
063   }
064
065   /**
066    * Builder class.
067    *
068    * <h5 class='section'>See Also:</h5><ul>
069    *    <li class='jm'>{@link MarshallingContext.Builder#annotations(Annotation...)}
070    * </ul>
071    */
072   public static class Builder extends AppliedAnnotationObject.BuilderTMF {
073
074      MarshalledProp value = MarshalledPropAnnotation.DEFAULT;
075
076      /**
077       * Constructor.
078       */
079      protected Builder() {
080         super(MarshalledPropApply.class);
081      }
082
083      /**
084       * Sets the {@link MarshalledPropApply#value()} property on this annotation.
085       *
086       * @param value The new value for this property.
087       * @return This object.
088       */
089      public Builder value(MarshalledProp value) {
090         this.value = value;
091         return this;
092      }
093
094      @Override /* Overridden from AppliedAnnotationObject.Builder */
095      public Builder on(String...value) {
096         super.on(value);
097         return this;
098      }
099
100      @Override /* Overridden from AppliedAnnotationObject.BuilderT */
101      public Builder on(Class<?>...value) {
102         super.on(value);
103         return this;
104      }
105
106      @Override /* Overridden from AppliedOnClassAnnotationObject.Builder */
107      public Builder onClass(Class<?>...value) {
108         super.onClass(value);
109         return this;
110      }
111
112      @Override /* Overridden from AppliedAnnotationObject.BuilderM */
113      public Builder on(Method...value) {
114         super.on(value);
115         return this;
116      }
117
118      @Override /* Overridden from AppliedAnnotationObject.BuilderMF */
119      public Builder on(Field...value) {
120         super.on(value);
121         return this;
122      }
123
124      @Override /* Overridden from AppliedAnnotationObject.BuilderT */
125      public Builder on(ClassInfo...value) {
126         super.on(value);
127         return this;
128      }
129
130      @Override /* Overridden from AppliedAnnotationObject.BuilderT */
131      public Builder onClass(ClassInfo...value) {
132         super.onClass(value);
133         return this;
134      }
135
136      @Override /* Overridden from AppliedAnnotationObject.BuilderTMF */
137      public Builder on(FieldInfo...value) {
138         super.on(value);
139         return this;
140      }
141
142      @Override /* Overridden from AppliedAnnotationObject.BuilderTMF */
143      public Builder on(MethodInfo...value) {
144         super.on(value);
145         return this;
146      }
147
148      /**
149       * Instantiates a new {@link MarshalledPropApply @MarshalledPropApply} object initialized with this builder.
150       *
151       * @return A new {@link MarshalledPropApply} object.
152       */
153      public MarshalledPropApply build() {
154         return new Object(this);
155      }
156   }
157
158   @SuppressWarnings({
159      "java:S2160" // equals() inherited from AnnotationObject compares all annotation interface methods; subclass fields are accessed via those methods
160   })
161   private static class Object extends AppliedOnClassAnnotationObject implements MarshalledPropApply {
162
163      private final MarshalledProp value;
164
165      Object(MarshalledPropApplyAnnotation.Builder b) {
166         super(b);
167         value = b.value;
168      }
169
170      @Override /* Overridden from MarshalledPropApply */
171      public MarshalledProp value() {
172         return value;
173      }
174   }
175
176   /** Default value */
177   public static final MarshalledPropApply DEFAULT = create().build();
178
179   /**
180    * Instantiates a new builder for this class.
181    *
182    * @return A new builder object.
183    */
184   public static Builder create() {
185      return new Builder();
186   }
187
188   /**
189    * Instantiates a new builder for this class.
190    *
191    * @param on The targets this annotation applies to.
192    * @return A new builder object.
193    */
194   public static Builder create(Class<?>...on) {
195      return create().on(on);
196   }
197
198   /**
199    * Instantiates a new builder for this class.
200    *
201    * @param on The targets this annotation applies to.
202    * @return A new builder object.
203    */
204   public static Builder create(String...on) {
205      return create().on(on);
206   }
207
208   /**
209    * Returns <jk>true</jk> if the specified annotation contains all default values.
210    *
211    * @param a The annotation to check. Can be <jk>null</jk> (returns <jk>true</jk>).
212    * @return <jk>true</jk> if the specified annotation contains all default values.
213    */
214   public static boolean empty(MarshalledPropApply a) {
215      return a == null || DEFAULT.equals(a);
216   }
217}