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.*;
021
022import java.lang.annotation.*;
023
024import org.apache.juneau.annotation.*;
025import org.apache.juneau.html.*;
026
027/**
028 * Annotation that can be applied to classes, fields, and methods to tweak how they are handled by {@link HtmlSerializer}.
029 *
030 * <p>
031 * Can be used in the following locations:
032 * <ul>
033 *    <li>Marshalled classes/methods/fields.
034 *    <li><ja>@Rest</ja>-annotated classes and <ja>@RestOp</ja>-annotated methods when an {@link #on()} value is specified.
035 * </ul>
036 *
037 * <h5 class='section'>See Also:</h5><ul>
038 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/HtmlAnnotation">@Html Annotation</a>
039 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/HtmlBasics">HTML Basics</a>
040 * </ul>
041 */
042@Documented
043@Target({TYPE,FIELD,METHOD})
044@Retention(RUNTIME)
045@Inherited
046@Repeatable(HtmlAnnotation.Array.class)
047@ContextApply(HtmlAnnotation.Apply.class)
048public @interface Html {
049
050   /**
051    * Use the specified anchor text when serializing a URI.
052    *
053    * <p>
054    * The text can contain any bean property values resolved through variables of the form <js>"{property-name}"</js>.
055    *
056    * <h5 class='figure'>Example:</h5>
057    * <p class='bjava'>
058    *    <jc>// Produces &lt;a href&#61;'...'&gt;drive&lt;/a&gt; when serialized to HTML.</jc>
059    *    <ja>@Html</ja>(anchorText=<js>"drive"</js>)
060    *    <ja>@URI</ja> <jc>// Treat property as a URL</jc>
061    *    <jk>public</jk> String getDrive() {...}
062    * </p>
063    *
064    * <p>
065    * This overrides the behavior specified by {@link org.apache.juneau.html.HtmlSerializer.Builder#uriAnchorText(AnchorText)}.
066    *
067    * @return The annotation value.
068    */
069   String anchorText() default "";
070
071    /**
072     * Optional description for the exposed API.
073     *
074     * @return The annotation value.
075     * @since 9.2.0
076     */
077    String[] description() default {};
078
079    /**
080    * Specifies what format to use for the HTML element.
081    *
082    * @return The annotation value.
083    */
084   HtmlFormat format() default HtmlFormat.HTML;
085
086   /**
087    * Adds a hyperlink to a bean property when rendered as HTML.
088    *
089    * <p>
090    * The text can contain any bean property values resolved through variables of the form <js>"{property-name}"</js>.
091    *
092    * <p>
093    * The URLs can be any of the following forms:
094    * <ul>
095    *    <li>Absolute - e.g. <js>"http://host:123/myContext/myServlet/myPath"</js>
096    *    <li>Context-root-relative - e.g. <js>"/myContext/myServlet/myPath"</js>
097    *    <li>Context-relative - e.g. <js>"context:/myServlet/myPath"</js>
098    *    <li>Servlet-relative - e.g. <js>"servlet:/myPath"</js>
099    *    <li>Path-info-relative - e.g. <js>"myPath"</js>
100    * </ul>
101    *
102    * <h5 class='figure'>Example:</h5>
103    * <p class='bjava'>
104    *    <jk>public class</jk> FileSpace {
105    *
106    *       <ja>@Html</ja>(link=<js>"servlet:/drive/{drive}"</js>)
107    *       <jk>public</jk> String getDrive() {
108    *          ...;
109    *       }
110    *    }
111    * </p>
112    *
113    * @return The annotation value.
114    */
115   String link() default "";
116
117   /**
118    * When <jk>true</jk>, don't add headers to tables.
119    *
120    * <h5 class='section'>See Also:</h5><ul>
121    *    <li class='jm'>{@link org.apache.juneau.html.HtmlSerializer.Builder#addKeyValueTableHeaders()}
122    * </ul>
123    *
124    * @return The annotation value.
125    */
126   boolean noTableHeaders() default false;
127
128   /**
129    * When <jk>true</jk>, collections of beans should be rendered as trees instead of tables.
130    *
131    * <p>
132    * Default is <jk>false</jk>.
133    *
134    * @return The annotation value.
135    */
136   boolean noTables() default false;
137
138   /**
139    * Dynamically apply this annotation to the specified classes/methods/fields.
140    *
141    * <p>
142    * Used in conjunction with {@link org.apache.juneau.BeanContext.Builder#applyAnnotations(Class...)} to dynamically apply an annotation to an existing class/method/field.
143    * It is ignored when the annotation is applied directly to classes/methods/fields.
144    *
145    * <h5 class='section'>Valid patterns:</h5>
146    * <ul class='spaced-list'>
147    *  <li>Classes:
148    *       <ul>
149    *          <li>Fully qualified:
150    *             <ul>
151    *                <li><js>"com.foo.MyClass"</js>
152    *             </ul>
153    *          <li>Fully qualified inner class:
154    *             <ul>
155    *                <li><js>"com.foo.MyClass$Inner1$Inner2"</js>
156    *             </ul>
157    *          <li>Simple:
158    *             <ul>
159    *                <li><js>"MyClass"</js>
160    *             </ul>
161    *          <li>Simple inner:
162    *             <ul>
163    *                <li><js>"MyClass$Inner1$Inner2"</js>
164    *                <li><js>"Inner1$Inner2"</js>
165    *                <li><js>"Inner2"</js>
166    *             </ul>
167    *       </ul>
168    *    <li>Methods:
169    *       <ul>
170    *          <li>Fully qualified with args:
171    *             <ul>
172    *                <li><js>"com.foo.MyClass.myMethod(String,int)"</js>
173    *                <li><js>"com.foo.MyClass.myMethod(java.lang.String,int)"</js>
174    *                <li><js>"com.foo.MyClass.myMethod()"</js>
175    *             </ul>
176    *          <li>Fully qualified:
177    *             <ul>
178    *                <li><js>"com.foo.MyClass.myMethod"</js>
179    *             </ul>
180    *          <li>Simple with args:
181    *             <ul>
182    *                <li><js>"MyClass.myMethod(String,int)"</js>
183    *                <li><js>"MyClass.myMethod(java.lang.String,int)"</js>
184    *                <li><js>"MyClass.myMethod()"</js>
185    *             </ul>
186    *          <li>Simple:
187    *             <ul>
188    *                <li><js>"MyClass.myMethod"</js>
189    *             </ul>
190    *          <li>Simple inner class:
191    *             <ul>
192    *                <li><js>"MyClass$Inner1$Inner2.myMethod"</js>
193    *                <li><js>"Inner1$Inner2.myMethod"</js>
194    *                <li><js>"Inner2.myMethod"</js>
195    *             </ul>
196    *       </ul>
197    *    <li>Fields:
198    *       <ul>
199    *          <li>Fully qualified:
200    *             <ul>
201    *                <li><js>"com.foo.MyClass.myField"</js>
202    *             </ul>
203    *          <li>Simple:
204    *             <ul>
205    *                <li><js>"MyClass.myField"</js>
206    *             </ul>
207    *          <li>Simple inner class:
208    *             <ul>
209    *                <li><js>"MyClass$Inner1$Inner2.myField"</js>
210    *                <li><js>"Inner1$Inner2.myField"</js>
211    *                <li><js>"Inner2.myField"</js>
212    *             </ul>
213    *       </ul>
214    *    <li>A comma-delimited list of anything on this list.
215    * </ul>
216    *
217    * <h5 class='section'>See Also:</h5><ul>
218    *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a>
219    * </ul>
220    *
221    * @return The annotation value.
222    */
223   String[] on() default {};
224
225   /**
226    * Dynamically apply this annotation to the specified classes.
227    *
228    * <p>
229    * Identical to {@link #on()} except allows you to specify class objects instead of a strings.
230    *
231    * <h5 class='section'>See Also:</h5><ul>
232    *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a>
233    * </ul>
234    *
235    * @return The annotation value.
236    */
237   Class<?>[] onClass() default {};
238
239   /**
240    * Associates an {@link HtmlRender} with a bean property for custom HTML rendering of the property.
241    *
242    * <p>
243    * This annotation applies to bean properties and classes.
244    *
245    * @return The annotation value.
246    */
247   @SuppressWarnings("rawtypes")
248   Class<? extends HtmlRender> render() default HtmlRender.class;
249}