001package Torello.JavaDoc.Annotations; 002 003import Torello.HTML.NodeSearch.CSSStrException; 004import Torello.Java.Additional.EffectivelyFinal; 005import Torello.Java.StringParse; 006 007import java.util.List; 008 009import javax.lang.model.element.Element; 010import javax.lang.model.element.ExecutableElement; 011import javax.lang.model.element.AnnotationMirror; 012import javax.lang.model.element.AnnotationValue; 013 014import javax.tools.Diagnostic; 015 016// EXPORTS: 017// String[] CSSClass() default { }; 018// String[] EmbedTagFileID() default { }; 019// 020// package Torello.JDUInternal.Features.EXTERNAL_HTML_FILES 021// The classes in this package do the processing for inserting the HTML from External-HTML 022// Files into Java-Doc '.html' Output-Files. It places an HTML <IMG SRC=...> at the top of 023// the page. The Imge contains a Wooden-Panel, and the User's JDHBI HTML for that class is 024// then placed on top of / over the Wood-Paneling 025 026 027@Torello.JavaDoc.Annotations.JDHeaderBackgroundImg(EmbedTagFileID="ANNOT_PROC_JDHBI") 028public class JDHBIProcessor 029{ 030 private JDHBIProcessor() { } 031 032 // This implements the processing for the Annotation @JDHeaderBackgroundImg. 033 // It does validity checks on the parameter input. 034 035 static boolean process 036 (Element ciet, AnnotationMirror am, javax.annotation.processing.Messager messager) 037 { 038 final EffectivelyFinal<Boolean> errors = new EffectivelyFinal<>(false); 039 040 am.getElementValues().forEach((ExecutableElement ee, AnnotationValue av) -> 041 { 042 // This is the "thing-y" inside the Annotation. It is called a "Member" by the 043 // Annotation-Processor. It is called a "Required-Element" or "Optional-Element" in a 044 // Java-Doc Web-Page. Understanding the 'terminology' in Annotations and Annotation 045 // Processor's is half of the work in using it. In the JD Upgrader Package (this 046 // Package), these are "Entity" - Entity.ANNOTATION_ELEM 047 // 048 // In **THIS** Annotation (JDHeaderBackgroundImg), the two Elements (Members / Entites) 049 // are "CSSClass" and "EmbedTagFiledID" 050 051 String memberName = ee.toString(); 052 053 // The value assigned to this Member. In the @JDHeaderBackgroundImg, both of the 054 // "Members" or "Elements" (whichever of the many terms is more appealing) that are 055 // defined - are both listed (inside the Annotation-Definition '.java' file) as 056 // **String-Arrays**. Here, in the Annotation-Processor, their values will be returned 057 // as instances of: 058 // 059 // com.sun...List - a class which implements the "java.util.List" class. 060 // But is not actually included by the JDK! 061 062 Object val = av.getValue(); 063 064 065 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 066 // Java Assertion. This Really **SHOULD** Hold, but just in case.... 067 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 068 069 if (! java.util.List.class.isAssignableFrom(val.getClass())) 070 071 // Don't use the Messager, this is a "Java-Error" (or else I'm just not quite 072 // understanding Annotations-Processors yet) 073 074 throw new InternalError( 075 memberName + " Annotation-Element-Value Type is not a List, " + 076 '[' + val.getClass().getName() + ']' 077 ); 078 079 List<?> list = (List) val; 080 081 082 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 083 // Dispatch to either the handler for "CSSClass" or "EmbedTagFileID" 084 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 085 086 switch (memberName) 087 { 088 case "CSSClass()" : 089 errors.f |= checkCSSClass(list, messager); break; 090 091 case "EmbedTagFileID()" : 092 093 // This was moved to the main class, since this method which checks the 094 // FILE-ID for validity is reused by the AutoFindID Annotation as well. 095 // Both of these Annotations which use this method are checking for the exact 096 // same thing, so there is no reason to keep them separate. 097 098 errors.f |= HELPER.checkFileID(list, messager); break; 099 100 default: 101 102 // If the 'javac' (Java-Compiler) Annotation-Processing Whole-Mechanism Thingy 103 // is working, the only two Annotation-Elements that could possibly be sent to 104 // this loop are the two listed above... These two "Elements" or "Members" 105 // "Entites" (I'll say this again) are the ones defined inside the '.java' 106 // File having name "JDHeaderBackgroundImg.java". The Java-Doc Page for them 107 // explains (very well) the two Array-Parameter Elements 108 // 109 // This should be UNREACHABLE-CODE. The Java-Compiler, itself, should do the 110 // complaining that the user has provided an Annotation-Member that is not 111 // listed inside the definition for that Annotation. 112 // 113 // Don't use the Messager, this simply cannot happen unless I'm just not 114 // understanding all of the nuances of this stuff-ola. 115 116 throw new InternalError( 117 "There was an annotation parameter whose name wasn't recognized: " + 118 ee.toString() + "\n" + 119 "The only parameter's that may be passed to @JDHeaderBackgroundImg " + 120 "are 'CSSClass' and 'EmbedTagFileID'\n" 121 ); 122 } 123 }); 124 125 return errors.f; 126 } 127 128 // Check each of the User-Provided "<DIV> CLASS's". There is a Predicate-Checker 129 // inside the NodeSearch Package for CSS-CLASS Strings 130 131 private static boolean checkCSSClass 132 (List<?> list, javax.annotation.processing.Messager messager) 133 { 134 String classStr; 135 boolean errors = false; 136 137 for (Object classObj : list) 138 139 // In Java 11, this returns a quoted-string, and in Java 17, there were no quotes 140 if ((classStr = StringParse.ifQuotesStripQuotes(classObj.toString())).length() > 0) 141 142 // Predicate for checking Valid CSS-Class Names 143 if (! CSSStrException.VALID_CSS_CLASS_OR_NAME_TOKEN_PRED.test(classStr)) 144 145 { 146 // Don't Return Immediately, Check all of the CSS-Classes (in case there are 147 // more than one defined). AGAIN: It is always better to print as many errors 148 // as possible during each phase of compilation, so that the end-user doesn't 149 // have to keep typing 'javac' 150 151 messager.printMessage 152 (Diagnostic.Kind.ERROR, "Invalid CSS Class-Name: [" + classStr + "]"); 153 154 errors = true; 155 } 156 157 return errors; 158 } 159} 160