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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
package Torello.JDUInternal.Annotations;

import Torello.Java.Additional.EffectivelyFinal;
import Torello.Java.StringParse;

import java.io.File;
import java.util.List;
import java.net.URI;

import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;

import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;

public class CSSLinksProcessor
{
    // This is used by the Error-Message Printer
    private static final String CSSLINKSNAME = Torello.JavaDoc.CSSLinks.class.getSimpleName();

    // This implements the processing for the Annotation @JDHeaderBackgroundImg.
    // It does validity checks on the parameter input.

    private static final String FS = File.separator;

    private CSSLinksProcessor() { }

    static boolean process(
            Element                                 ciet, 
            AnnotationMirror                        am,
            Filer                                   filer,
            javax.annotation.processing.Messager    messager
        )
    {
        /*
        try
        {
            // This will have the Complete-Name of the Annotated CIET/Type
            //
            // NOTE: Currently, I have no idea how to tell which part is a "Package-Name", and
            //       which part is a "Container-Class"
            // Is Torello.Java.Additional.ReadJSON.XL a class that is inside 
            // sub-package ReadJSON or container-class ReadJSON
            //
            // This has to stop for now, this will be easier to work with once I have finished the
            // new Build classes

            String typeName = ciet.asType().toString();

            // THEORETICALLY, This should be a file inside the same directory as the .java file
            JavaFileObject sourceFile = filer.createSourceFile(typeName + "$Dummy");

            // THEREFORE, NO (AGAIN, THEORETICALLY), THIS HOLDS THE FILE-NAME NO MATTER WHERE THIS
            // FILE IS LOCATED INSIDE THE CLASS-PATH.
            String filePath = sourceFile.toUri().getPath();

            // NO IDEA WHAT THIS IS DOING
            sourceFile.delete();

            messager.printMessage(
                Diagnostic.Kind.NOTE,    
                JDUAnnotationProcessorDispatch.LOCATION(ciet, CSSLINKSNAME) +
                "    Path: " + filePath
            );
        }

        catch (Exception e)
        {

        }
        */

        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 (CSSLinks), there is only one Element / Member / Entity,
            // and its name is "FileName"

            String memberName = ee.toString();

            // The value assigned to this Member.  In the @CSSLinks, the "Member" or "Element"
            // (whichever of the many terms is more appealing) that's defined - is listed (inside
            // the Annotation-Definition '.java' file) as a **String-Array**.  Here, in the
            // Annotation-Processor, its value will be returned as an 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 the handler for "FileNames"
            // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

            switch (memberName)
            {
                case "FileNames()" :
                    errors.f |= checkCSSFile(ciet, 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 that may be passed to @CSSFiles is 'FileNames\n'"
                    );
            }
        });

        return errors.f;
    }

    private static final String curDir()
    { return "THIS PART ISN'T WORKING AT THE MOMENT"; }

    // 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 checkCSSFile
        (Element ciet, List<?> list, javax.annotation.processing.Messager messager)
    {
        String fileName;
        boolean errors = false;

        for (Object fileNameObj : list)

            // In Java 11, this returns a quoted-string, and in Java 17, there were no quotes
            if ((fileName = StringParse.ifQuotesStripQuotes(fileNameObj.toString())).length() > 0)
            {
                String fullPathName = null;
                boolean relativeOrAbsolute;
                File file;


                // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
                // Identify the actual Full-Path Name of the File
                // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
                //
                // Get the Full-Path Name for this File - regardless of whether the File-String
                // provided by the user is a relative File-Name, or an absolute File-Name

                if (fileName.contains(File.separator))
                {
                    relativeOrAbsolute  = false;
                    fullPathName        = fileName;
                }

                else
                {
                    relativeOrAbsolute = true;

                    fullPathName = curDir() + FS + "upgrade-files" + FS + "stylesheets" + FS + 
                        fileName;
                }

                // In it's current incarnation, there is simply no way to get the relative
                // directory where a Source-File is located.  In all actuallity, it isn't going to
                // matter much anyway, since finding the /upgrade-files/stylesheets just isn't
                // going to work at the present moment.

                if (relativeOrAbsolute) continue;


                // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
                // Check that the file actually exists on the File-System, and if not, flag error
                // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

                try
                {
                    file = new File(fullPathName);

                    if (! file.exists())
                    {
                        messager.printMessage(
                            Diagnostic.Kind.ERROR,    
                            JDUAnnotationProcessorDispatch.LOCATION(ciet, CSSLINKSNAME) +
                            "    [" + fileName + "]\n    File not found" +
                            (relativeOrAbsolute
                                ? " in the upgrade-files/stylesheets/ directory"
                                : ""
                            )
                        );

                        errors = true;
                        continue;
                    }
                }

                catch (Exception e)
                {
                    messager.printMessage(
                        Diagnostic.Kind.ERROR,
                        JDUAnnotationProcessorDispatch.LOCATION(ciet, CSSLINKSNAME) +
                        "Exception thrown attempting to open / locate File:\n[" + fileName + "]\n" +
                        "    e.getClass():   " + e.getClass().getName() + 'n' +
                        "    e.getMessage(): " + e.getMessage() + '\n'
                    );

                    errors = true;
                    continue;
                }


                // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
                // Make sure that the specified File is not a Directory, otherwise Flag and Error
                // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

                try
                {
                    if (file.isDirectory())
                    {
                        messager.printMessage(
                            Diagnostic.Kind.ERROR,
                            JDUAnnotationProcessorDispatch.LOCATION(ciet, CSSLINKSNAME) +
                            "[" + fileName + "] seems to specify a Directory, rather than a File."
                        );

                        errors = true;
                        continue;
                    }
                }

                catch (Exception e)
                {
                    messager.printMessage(
                        Diagnostic.Kind.ERROR,
                        JDUAnnotationProcessorDispatch.LOCATION(ciet, CSSLINKSNAME) +
                        "Exception thrown attempting to open / locate File:\n[" + fileName + "]\n" +
                        "    e.getClass():   " + e.getClass().getName() + 'n' +
                        "    e.getMessage(): " + e.getMessage() + '\n'
                    );

                    errors = true;
                    continue;
                }
            }

        return errors;
    }

}