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