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 | package Torello.JDUInternal.Annotations; import Torello.HTML.NodeSearch.CSSStrException; import Torello.Java.Additional.EffectivelyFinal; import Torello.Java.StringParse; import java.util.*; import javax.annotation.processing.*; import javax.lang.model.*; import javax.lang.model.element.*; import javax.tools.Diagnostic; /** * Annotation Processor for the {@link JDHeaderBackgroundImg} Annotation. */ class JDHBImgProcessor { // This implements the processing for the Annotation @JDHeaderBackgroundImg. // It does validity checks on the parameter input. 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 |= JDUAnnotationProcessorDispatch.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( "\tThere was an annotation parameter whose name wasn't recognized: " + ee.toString() + "\n" + "\tThe 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; } } |