001package Torello.JavaDoc.Annotations; 002 003import Torello.JavaDoc.Annotations.hidden.LJSRepeatable; 004 005import java.util.Set; 006import java.util.TreeSet; 007 008 009// NOTE: This is a complete nightmare. Java-Sun-Oracle sort-of treated "Annotations" as kind of 010// an "after-thought"... The classes needed to process an annotation are distributed 011// across 5 or 6 different Java-Packages (all listed below). 012// 013// The "@StaticFunctional" Annotation began in the middle of Year-2021, and I have optimized-it 014// and added comments ever since (to better explain what it is doing). It is almost the end of 015// Year-2022 and I'm still optimizing this. 016// 017// The comments on the Annotation-Processors in this package are actually pretty good. I'm kind of 018// ashamed to admit that I looked some of this up on "StackOverlow" - since the people on that site 019// are so completely terrible... But I did ... 020 021import javax.annotation.processing.Messager; 022import javax.annotation.processing.AbstractProcessor; 023import javax.annotation.processing.RoundEnvironment; 024import javax.annotation.processing.ProcessingEnvironment; 025 026import javax.lang.model.SourceVersion; 027 028import javax.lang.model.element.Element; 029import javax.lang.model.element.TypeElement; 030import javax.lang.model.element.AnnotationMirror; 031 032import javax.tools.Diagnostic; 033 034// Top-Level Dispatch Annotation-Processor for <I>both</I> JavaDoc-Upgrader Annotations. 035public class JDUAnnotationProcessorDispatch extends AbstractProcessor 036{ 037 private javax.annotation.processing.Messager messager = null; 038 private javax.annotation.processing.Filer filer = null; 039 040 /** 041 * Method that is requuired by the {@code 'AbstractProcessor'} interface that allows this 042 * processor to initialize & receive the necessary environment variables. 043 * 044 * @param env This provides the instance-reference to the messaging-output tool. 045 */ 046 @Override 047 public synchronized void init(ProcessingEnvironment env) 048 { 049 this.messager = env.getMessager(); 050 this.filer = env.getFiler(); 051 } 052 053 /** 054 * Method required by {@code AbstractProcessor} 055 * 056 * @return The set of annotations supported by this processor. The {@code Set} that is 057 * returned contains just the name of the {@code StaticFunctional} class-name. 058 */ 059 @Override 060 public Set<String> getSupportedAnnotationTypes() 061 { 062 TreeSet<String> ret = new TreeSet<>(); 063 064 ret.add(StaticFunctional.class.getCanonicalName()); 065 ret.add(JDHeaderBackgroundImg.class.getCanonicalName()); 066 ret.add(CSSLinks.class.getCanonicalName()); 067 ret.add(JavaScriptImport.class.getCanonicalName()); 068 069 ret.add(IntoHTMLTable.class.getCanonicalName()); 070 ret.add(LinkJavaSource.class.getCanonicalName()); 071 ret.add(LJSRepeatable.class.getCanonicalName()); 072 073 // DO I NEED THIS? 074 //ret.add(LJSRepeatable.class.getCanonicalName()); 075 076 return ret; 077 } 078 079 /** 080 * Method required by {@code AbstractProcessor} 081 * @return the Java version supported 082 */ 083 @Override 084 public SourceVersion getSupportedSourceVersion() 085 { return SourceVersion.latestSupported(); } 086 087 /** 088 * This implements the processing for the Annotation @{@link StaticFunctional}. It does a lot 089 * of validity checks on the parameter input. 090 */ 091 @Override 092 public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv) 093 { 094 boolean errors = false; 095 096 // REMEMBER: There are **THREE** different classes/types for an Annotation: 097 // 098 // 1) The actual Annotation itself - which is the one the end-user is supposed to use. 099 // 100 // 2) The Processor (which is now three classes - to keep it all separated out) 101 // 102 // 3) The Annotation-Mirror (which is now one class - to keep it all together), which the 103 // JavaDoc Upgrader uses to retrieve the values of the Elements that the user provided 104 // so that it can react accordingly during the upgrader processing 105 // 106 // Annotations just feel like one giant Spaghetti Mess. I think they should have allowed 107 // all three of these concepts to reside INSIDE THE SAME CLASS: The processor, the mirror 108 // and the annotation itself... They should be on simple/single class, but Java will not 109 // allow it. 110 // 111 // Because they are so messy, Java-HTML doesn't use a lot of annotations. As of October 112 // 2022, there are only two in the entire JAR Library... Although "StaticFunctional" is 113 // used on almost every '.class' in the entire JAR. 114 // 115 // NOTE: AGAIN, the @StaticFunctional Annotation is really just used to say "This is not 116 // really an Object-Class, it is a standad '.c' File, and doesn't have any data" 117 // 118 // Just about every class in the Java-HTML JAR Library that is not a "Data Class" 119 // has had @StaticFunctional placed on it. 120 121 122 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 123 // Processor-Dispatch for @CSSStyleSheets 124 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 125 126 // All the classes that are annotated with @CSSStyleSheets 127 for (Element ciet : roundEnv.getElementsAnnotatedWith(CSSLinks.class)) 128 129 // There may be many annotations on that class (other than @CSSStyleSheets) 130 // This retrieves all of the mirrors on the class, even ones not about @JDHBI... 131 132 for (AnnotationMirror am : ciet.getAnnotationMirrors()) 133 134 // If the annotation-mirror on that class (whose-mirrors are being iterated) is 135 // a @CSSStyleSheets data/value mirror (all the values that the user gave 136 // the annotation when he placed it on a class), then-and-only-then should it be 137 // processed. 138 139 if (am.getAnnotationType().toString().equals 140 ("Torello.JavaDoc.Annotations.CSSLinks")) 141 142 // Do the @CSSStyleSheets Processing... For readability this has been 143 // placed in a separate-file. All this does is make sure the user didn't 144 // screw-up the values that he (may or may not have) given to the annotation. 145 // If there are no values assigned to the members, this method exists 146 // immediately. 147 148 errors |= CSSLProcessor.process(ciet, am, filer, this.messager); 149 150 151 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 152 // Processor-Dispatch for @JDHeaderBackgroundImg 153 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 154 // 155 // NOTE: The next set of loops were **ALL** Block Copied from the first loop. This means 156 // that all applicable documentation-explanations are the exact same thing for these 157 // Annotations as well. 158 159 for (Element ciet : roundEnv.getElementsAnnotatedWith(JDHeaderBackgroundImg.class)) 160 for (AnnotationMirror am : ciet.getAnnotationMirrors()) 161 if (am.getAnnotationType().toString().equals 162 ("Torello.JavaDoc.Annotations.JDHeaderBackgroundImg")) 163 errors |= JDHBIProcessor.process(ciet, am, this.messager); 164 165 166 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 167 // Processor-Dispatch for @StaticFunctional 168 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 169 170 for (Element ciet : roundEnv.getElementsAnnotatedWith(StaticFunctional.class)) 171 for (AnnotationMirror am : ciet.getAnnotationMirrors()) 172 if (am.getAnnotationType().toString().equals 173 ("Torello.JavaDoc.Annotations.StaticFunctional")) 174 errors |= SFProcessor.process(ciet, am, this.messager); 175 176 177 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 178 // Processor-Dispatch for @LinkJavaSource 179 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 180 181 for (Element ciet : roundEnv.getElementsAnnotatedWith(LinkJavaSource.class)) 182 for (AnnotationMirror am : ciet.getAnnotationMirrors()) 183 if (am.getAnnotationType().toString().equals 184 ("Torello.JavaDoc.Annotations.LinkJavaSource")) 185 errors |= LJSProcessor.process(ciet, am, this.messager); 186 187 188 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 189 // Processor-Dispatch for @IntoHTMLTable 190 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 191 192 for (Element ciet : roundEnv.getElementsAnnotatedWith(IntoHTMLTable.class)) 193 for (AnnotationMirror am : ciet.getAnnotationMirrors()) 194 if (am.getAnnotationType().toString().equals 195 ("Torello.JavaDoc.Annotations.IntoHTMLTable")) 196 errors |= IHTProcessor.process(ciet, am, this.messager); 197 198 return errors; 199 } 200} 201