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 * @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 * @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 * @Component 043 * public class MyTemplate implements MyMixin /*, possibly more needed for jstachio */ { 044 * // 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}