1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | package Torello.JDUInternal.Annotations.TypeAnnotations.Processor; import Torello.HTML.NodeSearch.CSSStrException; import Torello.Java.Additional.EffectivelyFinal; import Torello.Java.StringParse; import Torello.JDUInternal.Annotations.HELPER; import java.util.List; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; import javax.tools.Diagnostic; // Annotation Processor for the {@link JDHeaderBackgroundImg} Annotation. // // // @JDHeaderBackgroundImg Annotation // // EXPORTS: // String[] CSSClass() default { }; // String[] EmbedTagFileID() default { }; // // * Torello.JavaDoc.JDHeaderBackgroundImg // This is the actual User-Annotation that is part of the API. A user may place the // @JDHeaderBackgroundImg Annotation on a Type / CIET (Class, Interface, Enum, Annotation or // Rec - And a Wood-Plank Background with the provided HTML will be placed onto the Java-Doc // for the Class / Type / CIET that the user has annotated. // // * package Torello.JDUInternal.Features.EXTERNAL_HTML_FILES // The classes in this package do the processing for inserting the HTML from External-HTML // Files into Java-Doc '.html' Output-Files. It places an HTML <IMG SRC=...> at the top of // the page. The Imge contains a Wooden-Panel, and the User's JDHBI HTML for that class is // then placed on top of / over the Wood-Paneling // // * Torello.JDUInternal.Annotations.TypeAnnotations.Processor.JDHBImgProcessor // This is Annotation-Processsor that is / can-be invoked by the 'javac' (Java-Compiler) at // Compile-Time. This Annotation-Processor largely does nothing other than to guarantee that // any String-Tokens which have been provided are, indeed, valid tokens which obey the syntax // rules. // // * Torello.JDUInternal.Annotations.TypeAnnotations.Mirror.JDHBIMirror // After the JDU Detects that a CIET / Type has had the @JDHBIMirror Annotation placed upon // it, this class extracts the relevant information out of the Annotation using the AST // Library in 'com.sun.source.tree' and all of it's helper classes. public class JDHBImgProcessor { // This implements the processing for the Annotation @JDHeaderBackgroundImg. // It does validity checks on the parameter input. public static boolean process (Element ciet, AnnotationMirror am, javax.annotation.processing.Messager messager) { EffectivelyFinal<Boolean> errors = new EffectivelyFinal<>(false); am.getElementValues().forEach((ExecutableElement ee, AnnotationValue av) -> { // This is the "thing-y" inside the Annotation. It is called a "Member" by the // Annotation-Processor. It is called a "Required-Element" or "Optional-Element" in a // Java-Doc Web-Page. Understanding the 'terminology' in Annotations and Annotation // Processor's is half of the work in using it. In the JD Upgrader Package (this // Package), these are "Entity" - Entity.ANNOTATION_ELEM // // In **THIS** Annotation (JDHeaderBackgroundImg), the two Elements (Members / Entites) // are "CSSClass" and "EmbedTagFiledID" String memberName = ee.toString(); // The value assigned to this Member. In the @JDHeaderBackgroundImg, both of the // "Members" or "Elements" (whichever of the many terms is more appealing) that are // defined - are both listed (inside the Annotation-Definition '.java' file) as // **String-Arrays**. Here, in the Annotation-Processor, their values will be returned // as instances of: // // com.sun...List - a class which implements the "java.util.List" class. // But is not actually included by the JDK! Object val = av.getValue(); // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // Java Assertion. This Really **SHOULD** Hold, but just in case.... // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** if (! java.util.List.class.isAssignableFrom(val.getClass())) // Don't use the Messager, this is a "Java-Error" (or else I'm just not quite // understanding Annotations-Processors yet) throw new InternalError( memberName + " Annotation-Element-Value Type is not a List, " + '[' + val.getClass().getName() + ']' ); List<?> list = (List) val; // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // Dispatch to either the handler for "CSSClass" or "EmbedTagFileID" // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** switch (memberName) { case "CSSClass()" : errors.f |= checkCSSClass(list, messager); break; case "EmbedTagFileID()" : // This was moved to the main class, since this method which checks the // FILE-ID for validity is reused by the AutoFindID Annotation as well. // Both of these Annotations which use this method are checking for the exact // same thing, so there is no reason to keep them separate. errors.f |= HELPER.checkFileID(list, messager); break; default: // If the 'javac' (Java-Compiler) Annotation-Processing Whole-Mechanism Thingy // is working, the only two Annotation-Elements that could possibly be sent to // this loop are the two listed above... These two "Elements" or "Members" // "Entites" (I'll say this again) are the ones defined inside the '.java' // File having name "JDHeaderBackgroundImg.java". The Java-Doc Page for them // explains (very well) the two Array-Parameter Elements // // This should be UNREACHABLE-CODE. The Java-Compiler, itself, should do the // complaining that the user has provided an Annotation-Member that is not // listed inside the definition for that Annotation. // // Don't use the Messager, this simply cannot happen unless I'm just not // understanding all of the nuances of this stuff-ola. throw new InternalError( "There was an annotation parameter whose name wasn't recognized: " + ee.toString() + "\n" + "The only parameter's that may be passed to @JDHeaderBackgroundImg " + "are 'CSSClass' and 'EmbedTagFileID'\n" ); } }); return errors.f; } // Check each of the User-Provided "<DIV> CLASS's". There is a Predicate-Checker // inside the NodeSearch Package for CSS-CLASS Strings private static boolean checkCSSClass (List<?> list, javax.annotation.processing.Messager messager) { String classStr; boolean errors = false; for (Object classObj : list) // In Java 11, this returns a quoted-string, and in Java 17, there were no quotes if ((classStr = StringParse.ifQuotesStripQuotes(classObj.toString())).length() > 0) // Predicate for checking Valid CSS-Class Names if (! CSSStrException.VALID_CSS_CLASS_OR_NAME_TOKEN_PRED.test(classStr)) { // Don't Return Immediately, Check all of the CSS-Classes (in case there are // more than one defined). AGAIN: It is always better to print as many errors // as possible during each phase of compilation, so that the end-user doesn't // have to keep typing 'javac' messager.printMessage (Diagnostic.Kind.ERROR, "Invalid CSS Class-Name: [" + classStr + "]"); errors = true; } return errors; } } |