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 &amp; 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