001package io.jstach.jstache;
002
003import java.lang.annotation.Documented;
004import java.lang.annotation.ElementType;
005import java.lang.annotation.Retention;
006import java.lang.annotation.RetentionPolicy;
007import java.lang.annotation.Target;
008
009/**
010 * This annotation is useful to force models and templates implement interfaces or have
011 * annotations particularly where you want all models to implement a lambda mixin
012 * interface. It also maybe useful to make generateed code have annotations for DI
013 * frameworks (Spring, Dagger, CDI, etc) to find generated templates as components.
014 * <p>
015 * Order of config lookup and precedence is as follows:
016 * <ol>
017 * <li>type annotated with JStache and this annotation.
018 * <li>enclosing class (of type annotated with JStache) with this annotation with inner to
019 * outer order.
020 * <li>package annotated with this annotation.
021 * <li>module annotated with this annotation.
022 * </ol>
023 * If multiple annotations are found the first one is picked and there is no combining of
024 * settings. See {@link JStacheConfig} for general config resolution.
025 * <p>
026 * <strong>Example</strong>
027 *
028 * <pre><code class="language-java">
029 * &#64;JStacheInterfaces(templateAnnotations=Component.class)
030 * module com.myapp {
031 *   require transitive io.jstach.jstachio;
032 * }
033 * </code> </pre> or for package level <pre><code class="language-java">
034 * &#64;JStacheInterfaces(templateImplements=MyMixin.class)
035 * package com.myapp.templates;
036 * </code> </pre>
037 *
038 * Now all generated templates (aka renderers) that are in the <code>com.myapp</code>
039 * module and <code>com.myapp.templates</code> will be generated like:
040 *
041 * <pre><code class="language-java">
042 * &#64;Component
043 * public class MyTemplate implements MyMixin &#47;*, possibly more needed for jstachio *&#47; {
044 *  &#47;&#47; implementation ommitted
045 * }
046 * </code> </pre>
047 *
048 * @author agentgt
049 * @see JStacheLambda
050 * @see JStacheConfig
051 */
052@Retention(RetentionPolicy.SOURCE)
053@Target({ ElementType.TYPE, ElementType.PACKAGE, ElementType.MODULE })
054@Documented
055public @interface JStacheInterfaces {
056
057        /**
058         * Will make all generated templates that are in the annotated class/package/module
059         * implement the array of interfaces. If the interface has a single generic type
060         * parameter (e.g. {@code SomeInterface<T>}) then the parameter will be assumed to be
061         * the model type (the class annotated with JStache) and thus will be parameterized
062         * with the model type (e.g.
063         * {@code SomeModelRenderer implements SomeInterface<SomeModel>}).
064         * <p>
065         * <strong>The interfaces should have a default implementation for all of its methods
066         * otherwise possible compilation errors might happen. </strong>
067         * @return interfaces that generated template will implement
068         */
069        public Class<?>[] templateImplements() default {};
070
071        // We have to turn off the formatter because it breaks long a href attribute links
072        // into multiple lines which angers javadoc
073        //@formatter:off
074        /**
075         * Will make all generated templates that are in the annotated class/package/module
076         * extened a class. If the class has a single generic type parameter (e.g.
077         * {@code SomeClass<T>}) then the parameter will be assumed to be the model type (the
078         * class annotated with JStache) and thus will be parameterized with the model type
079         * (e.g. {@code SomeModelRenderer extends SomeClass<SomeModel>}).
080         * <p>
081         * <strong> The class needs a no arg default constructor but may provide other
082         * constructors that will simply be replicated (<em>including annotations!</em>) on
083         * the genererated template. </strong>
084         * <p>
085         * Furthermore some methods will not be generated if the <code>templateExtends</code>
086         * class has a concrete implementation (not abstract).
087         * <p>
088         * Below are the methods that will not be generated if present on the parent class:
089         * <ol>
090         * <li><code>templateFormatter()</code> (see 
091         * <a href="{@docRoot}/io.jstach.jstachio/io/jstach/jstachio/TemplateInfo.html">
092         * io.jstach.jstachio.TemplateInfo</a>)</li>
093         * <li><code>templateEscaper()</code> (see 
094         * <a href="{@docRoot}/io.jstach.jstachio/io/jstach/jstachio/TemplateInfo.html">
095         * io.jstach.jstachio.TemplateInfo</a>)</li>
096         * <li><code>execute(T, Appendable)</code> (see 
097         * <a href="{@docRoot}/io.jstach.jstachio/io/jstach/jstachio/Template.html">
098         * io.jstach.jstachio.Template
099         * </a>, 
100         * the
101         * templateExtends class will need to be parameterized for this to work)</li>
102         * </ol>
103         * @return interfaces that generated template will implement
104         */
105        //@formatter:on
106        public Class<?> templateExtends() default Object.class;
107
108        /**
109         * Will make all generated templates that are in the annotated class/package/module be
110         * annotated with the array of annotations. The order is preserved in the generated
111         * code.
112         * @return annotations to be added to generate templates
113         */
114        public Class<?>[] templateAnnotations() default {};
115
116        /**
117         * Will <strong>check</strong> that all models in the annotated class/package/module
118         * annotated with {@link io.jstach.jstache.JStache} implement the array of interfaces.
119         * If a model does not a compilation error will happen.
120         * @return interfaces that the models <strong>should</strong> implement
121         */
122        public Class<?>[] modelImplements() default {};
123
124}