001package Torello.JavaDoc.Annotations;
002
003import Torello.Java.ReadOnly.ReadOnlyList;
004import Torello.Java.ReadOnly.ReadOnlyArrayList;
005
006import Torello.Java.StringParse;
007
008import Torello.JavaDoc.Messager.Messager;
009import Torello.JavaDoc.Messager.MsgPrintTools;
010import Torello.JDUInternal.Miscellaneous.Where.JDUAnnotations;
011import Torello.JavaDoc.Messager.Where_Am_I;
012
013import static Torello.Java.C.BCYAN;
014import static Torello.Java.C.BGREEN;
015import static Torello.Java.C.BYELLOW;
016import static Torello.Java.C.BRED;
017import static Torello.Java.C.RESET;
018
019import java.util.List;
020
021import com.sun.source.tree.ExpressionTree;
022import com.sun.source.tree.AssignmentTree;
023import com.sun.source.tree.LiteralTree;
024
025
026// EXPORTS:
027//      public Background background() default Background.Blue;
028//      public String title() default "";
029//      public String divCSSClass() default "";
030//      public String tableCSSClass() default "";
031// 
032// The following files are relatedf to this Annotation-Mirror Data-Class:
033// 
034// * Torello.JDUInternal.SimpleFeatures.IntoHTMLTableProc
035//      This is the primary or "Work Horse" Method for Generating the HTML-Table that is inserted
036//      into the Detail-Entry "description()" section.
037// 
038// * User-Annotations.css
039//      For the CSS Color Choices/Options/Definitions
040//      Since there are a suite of Color-Choices which have been presented to the user
041
042
043/**
044 * An internally used data-record class used for storing all user-supplied annotation data 
045 * associated with a single use / application of the {@link IntoHTMLTable} annotation.
046 * 
047 * @see Torello.JavaDoc.Annotations.IntoHTMLTable
048 */
049@Torello.JavaDoc.Annotations.JDHeaderBackgroundImg(EmbedTagFileID="MIRROR_JDHBI")
050public class IHTMirror implements AnnotationMirror
051{
052    // ********************************************************************************************
053    // ********************************************************************************************
054    // Static-Constant Fields
055    // ********************************************************************************************
056    // ********************************************************************************************
057
058
059    // I usually don't do this, but this is used inside of switch-statement, and therefore using 
060    // this becomes extremely cumbersome if it isn't in a shorter variable name.
061
062    private static final Where_Am_I WHERE_AM_I = JDUAnnotations.IHTMirror;
063
064    private static final ECData<Torello.JavaDoc.Annotations.IntoHTMLTable.Background> ecParser =
065        new ECData<>(
066            IntoHTMLTable.Background.class,
067
068            // These are strictly needed for Error message which are being passed to the messager
069            JDUAnnotations.IHTMirror,               // Where_Am_I 
070            IntoHTMLTable.class.getSimpleName(),    // The name of the Annoation
071            "background"                            // The Annotation-Element being processed
072        );
073
074
075    // ********************************************************************************************
076    // ********************************************************************************************
077    // interface AnnotationMirror
078    // ********************************************************************************************
079    // ********************************************************************************************
080
081
082    // Stores the actual text of the @StaticFunctional annotation which was placed.
083    // This is nothing more than the exact line that was originally inserted into the class.
084    // The only reason this is even needed (in case you are wondering) is because the error 
085    // checking & error printing code outputs this text when printing an error message.
086
087    private final String annotationAsStr;
088
089    /** {@inheritDoc} */ @Override
090    public String getAnnotationAsString() { return annotationAsStr; }
091
092    /** {@inheritDoc} */ @Override
093    public String getAnnotationName() { return "IntoHTMLTable"; }
094
095
096    // ********************************************************************************************
097    // ********************************************************************************************
098    // Public, Final, ReadOnly, Mirrored Fields
099    // ********************************************************************************************
100    // ********************************************************************************************
101
102
103    /** Holds data extracted from {@link IntoHTMLTable#background()} */
104    public final IntoHTMLTable.Background background;
105
106    /** Holds data extracted from {@link IntoHTMLTable#title()} */
107    public final String title;
108
109    /** Holds data extracted from {@link IntoHTMLTable#divCSSClass()} */
110    public final ReadOnlyList<String> divCSSClass;
111
112    /** Holds data extracted from {@link IntoHTMLTable#tableCSSClass()} */
113    public final ReadOnlyList<String> tableCSSClass;
114
115
116    // ********************************************************************************************
117    // ********************************************************************************************
118    // Package-Private Constructor, Invoked by class "EntityAnnotationMirrors"
119    // ********************************************************************************************
120    // ********************************************************************************************
121
122
123    IHTMirror(
124            // The parsed arguments to to the Annotation
125            final List<? extends ExpressionTree> arguments,
126
127
128            // This is the Annotation, as a simple Java-String.  This is very useful for
129            // Error-Printing with the Messager.  That's the only purpose of it
130
131            final String annotationAsStr,
132
133
134            // The Signature of the Detail-Entity onto which this "@LinkJavaSource" Annotation
135            // was placed.  Very important for error messages
136
137            final String signature
138        )
139    {
140        IntoHTMLTable.Background    background          = null;
141        String                      title               = null;
142        String                      divCSSClassSTR      = null;
143        String                      tableCSSClassSTR    = null;
144
145        for (int i = 0; i < arguments.size(); i++)
146        {
147            final ExpressionTree expr = arguments.get(i);
148
149            if (! (expr instanceof AssignmentTree)) Messager.assertFail(
150                "Annotation Placed:\n" +
151                "    " + BCYAN + annotationAsStr + RESET + '\n' +
152                "While parsing the Arguments / Elements of an IHTMirror Annotation, the " +
153                "Oracle-Parser (com.sun.source.tree) returned an instance of `ExpressionTree` " +
154                "that was not an instance of `AssignmentTree`." +
155                MsgPrintTools.annotationProcessingError(),
156                WHERE_AM_I
157            );
158
159            final AssignmentTree assignExpr = (AssignmentTree) expr;
160
161            // Extracting the left-hand side (LHS) and right-hand side (RHS)
162            final ExpressionTree LHS = assignExpr.getVariable();
163            final ExpressionTree RHS = assignExpr.getExpression();
164
165            final String lhsStr = LHS.toString();
166
167            final String rhsStr = (RHS instanceof LiteralTree) 
168                ? ((LiteralTree) RHS).getValue().toString()
169                : RHS.toString();
170
171            switch (lhsStr)
172            {
173                case "background":
174
175                    if (background != null) HELPER.dupErrorAE
176                        (annotationAsStr, background, "background", rhsStr, WHERE_AM_I);
177                    else
178                        background = ecParser.valueOf(rhsStr, signature);
179
180                    break;
181
182
183                case "title":
184
185                    if (title != null) HELPER.dupErrorAE
186                        (annotationAsStr, title, "title", rhsStr, WHERE_AM_I);
187                    else
188                        title = rhsStr;
189
190                    break;
191
192
193                case "divCSSClass":
194
195                    if (divCSSClassSTR != null) HELPER.dupErrorAE
196                        (annotationAsStr, divCSSClassSTR,  "divCSSClass", rhsStr, WHERE_AM_I);
197                    else
198                        divCSSClassSTR = rhsStr;
199
200                    break;
201
202
203                case "tableCSSClass":
204
205                    if (tableCSSClassSTR != null) HELPER.dupErrorAE
206                        (annotationAsStr, tableCSSClassSTR, "tableCSSClass", rhsStr, WHERE_AM_I);
207                    else 
208                        tableCSSClassSTR = rhsStr;
209
210                    break;
211
212
213                default: Messager.userErrorContinue(
214                    "While proessing a @IntoHTMLTable Annotation, the following " +
215                    "Annotation-Element Name was found:\n" +
216                    "    [" + lhsStr + "]\n" +
217                    "This is not a valid Annotation-Argument.  This is not one of " +
218                    "@IntoHTMLTable' Elements (sometimes called \"Arguements\")\n" +
219                    "Valid Element-Names for this Annotation Include:\n" +
220                    "    background, title, divCSSClass, and tableCSSClass" +
221                    MsgPrintTools.annotationProcessingError(),
222                    WHERE_AM_I
223                );
224            }
225        }
226
227        this.annotationAsStr    = annotationAsStr;
228        this.background         = background;
229
230        this.title = (title.length() == 0)
231            ? null 
232            : title;
233
234        this.divCSSClass = ((divCSSClassSTR == null) || (divCSSClassSTR.length() == 0))
235            ? ReadOnlyArrayList.emptyROAL()
236            : new ReadOnlyArrayList<String>(divCSSClassSTR.split("\\s"));
237
238        this.tableCSSClass = ((tableCSSClassSTR == null) || (tableCSSClassSTR.length() == 0))
239            ? ReadOnlyArrayList.emptyROAL()
240            : new ReadOnlyArrayList<String>(tableCSSClassSTR.split("\\s"));
241
242        IHTErrorCheck.check(this, annotationAsStr, signature);
243    }
244
245
246    // ********************************************************************************************
247    // ********************************************************************************************
248    // toString
249    // ********************************************************************************************
250    // ********************************************************************************************
251
252
253    /** {@inheritDoc} */ @Override
254    public String toString()
255    {
256        // 19 ==> Width of the Title Strings....  They are all 19 characters wide
257        // 
258        // public final Background              background;
259        // public final String                  title;
260        // public final ReadOnlyList<String>    divCSSClass;
261        // public final ReadOnlyList<String>    tableCSSClass;
262
263        return
264            annotationAsStr + '\n' +
265            "{\n" +
266            "    background:    " + background.toString()                   + '\n' +
267            "    title:         " + HELPER.TOSTR(this.title, 19)            + '\n' +
268            "    divCSSClass:   " + HELPER.TOSTR(this.divCSSClass, 19)      + '\n' +
269            "    tableCSSClass: " + HELPER.TOSTR(this.tableCSSClass, 19)    + '\n' +
270            '}';
271    }
272}