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.urlencoding.annotation;
018
019import static java.lang.annotation.ElementType.*;
020import static java.lang.annotation.RetentionPolicy.*;
021import static org.apache.juneau.commons.utils.CollectionUtils.*;
022
023import java.lang.annotation.*;
024import java.lang.reflect.*;
025
026import org.apache.juneau.*;
027import org.apache.juneau.commons.annotation.*;
028import org.apache.juneau.commons.reflect.*;
029import org.apache.juneau.svl.*;
030
031/**
032 * Utility classes and methods for the {@link UrlEncoding @UrlEncoding} annotation.
033 *
034 * <h5 class='section'>See Also:</h5><ul>
035 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/UrlEncodingBasics">URL-Encoding Basics</a>
036 * </ul>
037 */
038public class UrlEncodingAnnotation {
039   /**
040    * Applies targeted {@link UrlEncoding} annotations to a {@link org.apache.juneau.Context.Builder}.
041    */
042   public static class Apply extends AnnotationApplier<UrlEncoding,Context.Builder> {
043
044      /**
045       * Constructor.
046       *
047       * @param vr The resolver for resolving values in annotations.
048       */
049      public Apply(VarResolverSession vr) {
050         super(UrlEncoding.class, Context.Builder.class, vr);
051      }
052
053      @Override
054      public void apply(AnnotationInfo<UrlEncoding> ai, Context.Builder b) {
055         UrlEncoding a = ai.inner();
056         if (isEmptyArray(a.on()) && isEmptyArray(a.onClass()))
057            return;
058         b.annotations(copy(a, vr()));
059      }
060   }
061
062   /**
063    * A collection of {@link UrlEncoding @UrlEncoding annotations}.
064    */
065   @Documented
066   @Target({ METHOD, TYPE })
067   @Retention(RUNTIME)
068   @Inherited
069   public static @interface Array {
070
071      /**
072       * The child annotations.
073       *
074       * @return The annotation value.
075       */
076      UrlEncoding[] value();
077   }
078
079   /**
080    * Builder class.
081    *
082    * <h5 class='section'>See Also:</h5><ul>
083    *    <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#annotations(Annotation...)}
084    * </ul>
085    */
086   public static class Builder extends AppliedAnnotationObject.BuilderTMF {
087
088      private String[] description = {};
089      private boolean expandedParams;
090
091      /**
092       * Constructor.
093       */
094      protected Builder() {
095         super(UrlEncoding.class);
096      }
097
098      /**
099       * Instantiates a new {@link UrlEncoding @UrlEncoding} object initialized with this builder.
100       *
101       * @return A new {@link UrlEncoding @UrlEncoding} object.
102       */
103      public UrlEncoding build() {
104         return new Object(this);
105      }
106
107      /**
108       * Sets the description property on this annotation.
109       *
110       * @param value The new value for this property.
111       * @return This object.
112       */
113      public Builder description(String...value) {
114         description = value;
115         return this;
116      }
117
118      /**
119       * Sets the {@link UrlEncoding#expandedParams} property on this annotation.
120       *
121       * @param value The new value for this property.
122       * @return This object.
123       */
124      public Builder expandedParams(boolean value) {
125         expandedParams = value;
126         return this;
127      }
128
129      @Override /* Overridden from AppliedAnnotationObject.Builder */
130      public Builder on(String...value) {
131         super.on(value);
132         return this;
133      }
134
135      @Override /* Overridden from AppliedAnnotationObject.BuilderT */
136      public Builder on(Class<?>...value) {
137         super.on(value);
138         return this;
139      }
140
141      @Override /* Overridden from AppliedOnClassAnnotationObject.Builder */
142      public Builder onClass(Class<?>...value) {
143         super.onClass(value);
144         return this;
145      }
146
147      @Override /* Overridden from AppliedAnnotationObject.BuilderM */
148      public Builder on(Method...value) {
149         super.on(value);
150         return this;
151      }
152
153      @Override /* Overridden from AppliedAnnotationObject.BuilderMF */
154      public Builder on(Field...value) {
155         super.on(value);
156         return this;
157      }
158
159      @Override /* Overridden from AppliedAnnotationObject.BuilderT */
160      public Builder on(ClassInfo...value) {
161         super.on(value);
162         return this;
163      }
164
165      @Override /* Overridden from AppliedAnnotationObject.BuilderT */
166      public Builder onClass(ClassInfo...value) {
167         super.onClass(value);
168         return this;
169      }
170
171      @Override /* Overridden from AppliedAnnotationObject.BuilderTMF */
172      public Builder on(FieldInfo...value) {
173         super.on(value);
174         return this;
175      }
176
177      @Override /* Overridden from AppliedAnnotationObject.BuilderTMF */
178      public Builder on(MethodInfo...value) {
179         super.on(value);
180         return this;
181      }
182
183   }
184
185   private static class Object extends AppliedOnClassAnnotationObject implements UrlEncoding {
186
187      private final String[] description;
188      private final boolean expandedParams;
189
190      Object(UrlEncodingAnnotation.Builder b) {
191         super(b);
192         description = copyOf(b.description);
193         expandedParams = b.expandedParams;
194      }
195
196      @Override /* Overridden from UrlEncoding */
197      public boolean expandedParams() {
198         return expandedParams;
199      }
200
201      @Override /* Overridden from annotation */
202      public String[] description() {
203         return description;
204      }
205   }
206
207   /** Default value */
208   public static final UrlEncoding DEFAULT = create().build();
209
210   /**
211    * Creates a copy of the specified annotation.
212    *
213    * @param a The annotation to copy.s
214    * @param r The var resolver for resolving any variables.
215    * @return A copy of the specified annotation.
216    */
217   public static UrlEncoding copy(UrlEncoding a, VarResolverSession r) {
218      // @formatter:off
219      return
220         create()
221         .expandedParams(a.expandedParams())
222         .on(r.resolve(a.on()))
223         .onClass(a.onClass())
224         .build();
225      // @formatter:on
226   }
227
228   /**
229    * Instantiates a new builder for this class.
230    *
231    * @return A new builder object.
232    */
233   public static Builder create() {
234      return new Builder();
235   }
236
237   /**
238    * Instantiates a new builder for this class.
239    *
240    * @param on The targets this annotation applies to.
241    * @return A new builder object.
242    */
243   public static Builder create(Class<?>...on) {
244      return create().on(on);
245   }
246
247   /**
248    * Instantiates a new builder for this class.
249    *
250    * @param on The targets this annotation applies to.
251    * @return A new builder object.
252    */
253   public static Builder create(String...on) {
254      return create().on(on);
255   }
256}