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
package Torello.JDUInternal.Annotations.TypeAnnotations.Mirror;

import Torello.HTML.TagNode;
import Torello.HTML.TextNode;
import Torello.HTML.HTMLNode;

import Torello.Java.StrCSV;

import Torello.Java.ReadOnly.ReadOnlyList;
import Torello.Java.ReadOnly.ReadOnlyArrayList;
import Torello.Java.ReadOnly.ROArrayListBuilder;

import Torello.JDUInternal.Messager.Messager;
import Torello.JDUInternal.Messager.MsgVerbose;
import Torello.JDUInternal.Messager.Where.JDUAnnotations;

import Torello.JDUInternal.Annotations.HELPER;
import Torello.JDUInternal.Messager.Where.JDUAnnotations;

import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.AssignmentTree;

import java.util.List;

import static com.sun.source.tree.Tree.Kind.ASSIGNMENT;


// @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 JDHBIMirror
{
    public final ReadOnlyList<HTMLNode> externalEmbedTags;
    public final TagNode                tnDIV;

    private static final String JDHBI_ATTR_NAME =
        Torello.JDUInternal.Features.EXTERNAL_HTML_FILES.ReplaceTags.EXPORT.JDHBI_ATTR_NAME();

    private static final String JDHBI_ATTR_VALUE =
        Torello.JDUInternal.Features.EXTERNAL_HTML_FILES.ReplaceTags.EXPORT.JDHBI_ATTR_VALUE();

    // Used simply to insert a new-line character into an HTML-Vector
    private static final TextNode NEW_LINE = new TextNode("\n");

    public JDHBIMirror(final List<? extends ExpressionTree> arguments)
    {
        ReadOnlyList<String>    cssClasses          = null;
        ReadOnlyList<String>    embedTagFileIDs     = null;
        ReadOnlyList<HTMLNode>  externalEmbedTags   = null;
        TagNode                 tnDIV               = null;

        for (ExpressionTree argument : arguments)
        {
            /*
            System.out.println(
                "argument:                            " + argument.toString() + '\n' +
                "argument.getKind():                  " + argument.getKind().toString() + '\n' +
                "argument.getClass().getSimpleName(): " + argument.getClass().getSimpleName()
            );
            */

            // System.out.println(argument);

            if (argument.getKind() != ASSIGNMENT) Messager.assertFailOracleParser(
                "The ExpressionTree returned by the @JDHeaderBackgroundImg arguments list was " +
                "not of type ASSIGNMENT, but rather " + argument.getKind() + '\n' +
                "ExpressionTree.toString(): " + argument.toString() + '\n' +
                "All Annotation Expressions: " + StrCSV.toCSV(arguments, true, true, null),
                null,
                JDUAnnotations.JDHBIMirror
            );

            String          elemName    = ((AssignmentTree) argument).getVariable().toString();
            ExpressionTree  elemValue   = ((AssignmentTree) argument).getExpression();

            /*
            System.out.println(
                "    elemName:             " + elemName + '\n' +
                "    elemValue.toString(): " + elemValue.toString() + '\n' +
                "    elemValue.getKind():  " + elemValue.getKind().toString() + '\n' +
                "    elemValue.getClass(): " + elemValue.getClass().getSimpleName() + '\n'
            );
            */

            if (elemName.equals("CSSClass")) cssClasses =
                HELPER.handleStringArray(elemValue, "CSSClass", JDUAnnotations.CSSLMirror);

            else if (elemName.equals("EmbedTagFileID")) embedTagFileIDs =
                HELPER.handleStringArray(elemValue, "EmbedTagFileID", JDUAnnotations.CSSLMirror);

            else Messager.assertFailOracleParser(
                "There was an Expression Variable-Name that was neither 'CSSClass' nor " +
                "'EmbedTagFileID', but rather: " + elemName,
                null,
                JDUAnnotations.JDHBIMirror
            );
        }

        if (embedTagFileIDs == null)
            externalEmbedTags = ReadOnlyArrayList.emptyROAL();

        else 
        {
            int i = 0;

            ROArrayListBuilder<HTMLNode> roalb = new ROArrayListBuilder<>();

            for (String embedTagFileID : embedTagFileIDs)
            {
                roalb.add(
                    new TagNode(
                        "<EMBED DATA-" + JDHBI_ATTR_NAME + '=' + JDHBI_ATTR_VALUE +
                        " CLASS='external-html' DATA-FILE-ID=" +
                        embedTagFileIDs.get(i++) +">"
                    ));

                roalb.add(NEW_LINE);
            }

            externalEmbedTags = roalb.build();
        }


        // These are used in class "EmbedTag" which does all of the HTML work for
        // "JDHeaderBackgroundImg"

        if (cssClasses == null)
            tnDIV = null;

        else if (cssClasses.size() == 1)
            tnDIV = new TagNode("<DIV CLASS=" + cssClasses.get(0) + ">");

        else
        {
            // When the user uses the annotation as below:
            // @JDHeaderBackgroundImg(CSSClass={"MyCSSClassA", "MyCSSClassB", "MyCSSClassC", ...})

            StringBuilder sb = new StringBuilder();

            for (String cssClass : cssClasses) sb.append(cssClass + " ");

            tnDIV = new TagNode
                ("<DIV CLASS='" + sb.subSequence(0, sb.length() - 1) + "'>");
        }

        if (MsgVerbose.isVerbose()) MsgVerbose.println(
            "@JDHeaderBackgroundImg Annotation-Processing Mirror Class:" +
            "    cssClasses:      " + StrCSV.toCSV(cssClasses, true, false, null) + '\n' +
            "    embedTagFileIDs: " + StrCSV.toCSV(embedTagFileIDs, true, false, null)
        );

        this.externalEmbedTags  = externalEmbedTags;
        this.tnDIV              = tnDIV;
    }
}