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