001package Torello.JavaDoc.Annotations; 002 003import Torello.Java.StrSource; 004import Torello.Java.StrCh; 005import Torello.Java.StringParse; 006 007import Torello.Java.Additional.EffectivelyFinal; 008 009import javax.annotation.processing.Messager; 010 011import javax.lang.model.element.Element; 012import javax.lang.model.element.ExecutableElement; 013import javax.lang.model.element.AnnotationMirror; 014import javax.lang.model.element.AnnotationValue; 015 016import javax.tools.Diagnostic; 017 018import java.util.List; 019import java.util.Arrays; 020 021import java.util.stream.Stream; 022 023// EXPORTS: 024// public Background background() default Background.Blue; 025// public String title() default ""; 026// public String divCSSClass() default ""; 027// public String tableCSSClass() default ""; 028// 029// 030// The following files are relatedf to this 'javac' Annotation-Processor: 031// 032// * Torello.JDUInternal.SimpleFeatures.IntoHTMLTableProc 033// This is the primary or "Work Horse" Method for Generating the HTML-Table that is inserted 034// into the Detail-Entry "description()" section. 035// 036// * User-Annotations.css 037// For the CSS Color Choices/Options/Definitions 038// Since there are a suite of Color-Choices which have been presented to the user 039 040 041@Torello.JavaDoc.Annotations.JDHeaderBackgroundImg(EmbedTagFileID="ANNOT_PROC_JDHBI") 042public class IHTProcessor 043{ 044 private IHTProcessor() { } 045 046 // This is used by the Error-Message Printer 047 private static final String IHT_NAME = 048 Torello.JavaDoc.Annotations.IntoHTMLTable.class.getSimpleName(); 049 050 // @IntoHTMLTable Annotation: 051 // 052 // EXPORTS: 053 // public Background background() default Background.Blue; 054 // public String title() default ""; 055 // public String divCSSClass() default ""; 056 // public String tableCSSClass() default ""; 057 058 static boolean process( 059 Element ciet, 060 AnnotationMirror am, 061 javax.annotation.processing.Messager messager 062 ) 063 { 064 EffectivelyFinal<Boolean> errors = new EffectivelyFinal<>(false); 065 066 am.getElementValues().forEach((ExecutableElement ee, AnnotationValue av) -> 067 { 068 // Understanding the 'terminology' in Annotations and Annotation-Processor's is half of 069 // the work in using it. 070 071 final Object val = av.getValue(); 072 073 switch (ee.toString()) 074 { 075 case "background()" : 076 break; 077 078 case "title()" : 079 errors.f |= checkTitleAE(messager, ciet, (String) val); 080 break; 081 082 case "divCSSClass()" : 083 errors.f |= checkCSSClassAE(messager, ciet, "divCSSClass()", (String) val); 084 break; 085 086 case "tableCSSClass()" : 087 errors.f |= checkCSSClassAE(messager, ciet, "divCSSClass()", (String) val); 088 break; 089 090 default: 091 092 // This should be UNREACHABLE-CODE. The Java-Compiler, itself, should do the 093 // complaining that the user supplied an Annotation-Element name that is not 094 // among those listed above. Unless 'javac' changes, this cannot execute. 095 096 throw new InternalError( 097 "There was an annotation parameter whose name wasn't recognized: " + 098 ee.toString() + "\n" + 099 "The only parameter's that may be passed to @IntoHTMLTable are:\n" + 100 "'background()', 'title()', 'divCSSClass()' and 'tableCSSClass()'" 101 ); 102 } 103 }); 104 105 return errors.f; 106 } 107 108 109 // ******************************************************************************************** 110 // ******************************************************************************************** 111 // Checks both the "name()" and "handle()" Annotation-Elements 112 // ******************************************************************************************** 113 // ******************************************************************************************** 114 115 116 private static boolean checkTitleAE( 117 javax.annotation.processing.Messager messager, 118 Element ciet, 119 String aeValAsStr 120 ) 121 { 122 // THIS TEST IS BLOCK-COPIED IDENTICAL TO THE TEST THAT IS LOCATED INSIDE 123 // "Torello.JDUInternal.Annotations.EntityAnnotations.Mirror.IHTErrorCheck" 124 125 final boolean test = 126 (! StrCh.containsOR(aeValAsStr, '\t', '\n', '\r')) 127 && (aeValAsStr.length() <= 300); 128 129 if (test) return true; 130 131 // NOTE: Torello.JDUInternal.Messager **DOES NOT** ALLOW '\t' 132 messager.printMessage( 133 Diagnostic.Kind.ERROR, 134 HELPER.LOCATION(ciet, IHT_NAME) + 135 "\tString Annotation-Parameter 'title()' was passed " + 136 "[" + aeValAsStr + "]\n" + 137 "\tHowever, this String may not contain the characters: '\\t', '\\n', '\\r'\n" + 138 "\tNor may it be more than 300 Characters long." 139 ); 140 141 return false; 142 } 143 144 145 // ******************************************************************************************** 146 // ******************************************************************************************** 147 // Checks the "typeName()" Annotation-Elements 148 // ******************************************************************************************** 149 // ******************************************************************************************** 150 151 152 private static boolean checkCSSClassAE( 153 final javax.annotation.processing.Messager messager, 154 final Element ciet, 155 final String aeName, 156 final String aeValAsStr 157 ) 158 { 159 if (aeValAsStr.length() == 0) return true; 160 161 final String[] cssClasses = aeValAsStr.split("\\s"); 162 163 final Stream.Builder<String> b = Stream.builder(); 164 165 boolean errors = false; 166 167 for (final String cssClass : cssClasses) 168 169 if (! StrSource.isCSSClassName(cssClass)) 170 { 171 b.accept(cssClass); 172 errors = true; 173 } 174 175 if (! errors) return true; 176 177 messager.printMessage( 178 Diagnostic.Kind.ERROR, 179 HELPER.LOCATION(ciet, IHT_NAME) + 180 181 // NOTE: Torello.JDUInternal.Messager **DOES NOT** ALLOW '\t' 182 "\tString Annotation-Parameter " + aeName + " was passed " + 183 "[" + aeValAsStr + "]\n" + 184 "\tHowever, the following CSS-Classes are invalid CSS Class-Names:\n" + 185 Arrays.toString(b.build().toArray()) 186 ); 187 188 return false; 189 } 190}