001package Torello.JavaDoc;
002
003import java.util.Vector; // used once in a static initializer for "Replaceable"
004
005import Torello.Java.*;
006
007import static Torello.Java.C.*;
008
009// These are used in Java-Doc Link Examples only, not in source-code.
010import Torello.Java.ParallelArrayException;
011import Torello.HTML.Replaceable;
012
013/**
014 * An abstract helper class for user-provided {@code SummarySorter.class} files for sorting the
015 * Table of Contents inside the Field / Method / Constructor Summaries inside a Java Doc Web Page.
016 */
017public abstract class SummarySorterHelper
018{
019    // ********************************************************************************************
020    // String Constants
021    // ********************************************************************************************
022
023    /**
024     * Label for methods inherited from class {@code Object}
025     * 
026     * <BR /><BR />Checker Method {@link #OBJECT_M(Method)} matches methods named:
027     * {@code "hashCode", "toString", "equals"}
028     * 
029     * @see #OBJECT_M(Method)
030     */
031    protected static final String OBJECT_M =
032        "<B CLASS=STBLabel>Methods:</B> class java.lang.Object";
033
034    /**
035     * Label for methods inherited from class {@code Combarable}
036     * 
037     * <BR /><BR />Checker Method {@link #COMPARABLE_M(Method)} matches methods named:
038     * {@code "compareTo"}
039     * 
040     * @see #COMPARABLE_M(Method)
041     */
042    protected static final String COMPARABLE_M =
043        "<B CLASS=STBLabel>Methods:</B> interface java.lang.Comparable";
044
045    /**
046     * Label for methods inherited from class {@code CharSequence}
047     * 
048     * <BR /><BR />Checker Method {@link #CHARSEQUENCE_M(Method)} matches method named:
049     * {@code "toString", "subSequence", "charAt", "length"}
050     * 
051     * @see #CHARSEQUENCE_M(Method)
052     */
053    protected static final String CHARSEQUENCE_M =
054        "<B CLASS=STBLabel>Methods:</B> interface java.lang.CharSequence";
055
056    /**
057     * Label for methods inherited from class {@code Cloneable}
058     * 
059     * <BR /><BR />Checker Method {@link #CLONEABLE_M(Method)} matches method named:
060     * {@code "clone"}
061     * 
062     * @see #CLONEABLE_M(Method)
063     */
064    protected static final String CLONEABLE_M =
065        "<B CLASS=STBLabel>Methods:</B> interface java.lang.Cloneable";
066
067    /**
068     * Label for methods inherited from class {@code Iterable}
069     */
070    protected static final String ITERABLE_M =
071        "<B CLASS=STBLabel>Methods:</B> interface java.lang.Iterable";
072
073    /**
074     * Label for methods inherited from class {@code Iterator}
075     * 
076     * <BR /><BR />Checker Method {@link #CLONEABLE_M(Method)} matches method named:
077     * {@code "next", "hasNext", "remove", "forEachRemaining"}
078     * 
079     * @see #ITERATOR_M(Method)
080     */
081    protected static final String ITERATOR_M =
082        "<B CLASS=STBLabel>Methods:</B> interface java.lang.Iterator";
083
084    /**
085     * Label for methods inherited from interface {@code Appendable}
086     * 
087     * <BR /><BR />Checker Method {@link #APPENDABLE_M(Method)} matches method named:
088     * {@code "append"}
089     * 
090     * @see #APPENDABLE_M(Method)
091     */
092    protected static final String APPENDABLE_M =
093        "<B CLASS=STBLabel>Methods:</B> interface java.lang.Appendable";
094
095    /**
096     * Label for methods in a {@code FunctionalInterface}
097     * @see #fInterface$M$Sections
098     * @see #fInterface$M$Sorter(String, Method)
099     */
100    protected static final String FINTERFACE_M =
101        "<B CLASS=STBLabel>@FunctionalInterface:</B> (Lambda) Method";
102
103    /**
104     * Label for methods inherited from class {@code java.io.Closeable}
105     * 
106     * <BR /><BR />Checker Method {@link #CLOSEABLE_M(Method)} matches method named:
107     * {@code "close"}
108     * 
109     * @see #CLOSEABLE_M(Method)
110     */
111    protected static final String CLOSEABLE_M =
112        "<B CLASS=STBLabel>Methods:</B> interface java.io.Closeable";
113
114    /**
115     * Label for methods inherited from class {@code java.io.Flushable}
116     * 
117     * <BR /><BR />Checker Method {@link #FLUSHABLE_M(Method)} matches method named:
118     * {@code "flush"}
119     * 
120     * @see #FLUSHABLE_M(Method)
121     */
122    protected static final String FLUSHABLE_M =
123        "<B CLASS=STBLabel>Methods:</B> interface java.io.Flushable";
124
125    /**
126     * Label for methods inherited from class {@code java.io.Writer}
127     * 
128     * <BR /><BR />Checker Method {@link #WRITER_M(Method)} matches method named:
129     * {@code "write", "close", "flush", "append"}
130     * 
131     * @see #WRITER_M(Method)
132     */
133    protected static final String WRITER_M =
134        "<B CLASS=STBLabel>Methods:</B> class java.io.Writer";
135
136    /**
137     * Label for methods inherited from class {@code java.io.PrintStream}
138     * 
139     * <BR /><BR />Checker Method {@link #PRINTSTREAM_M(Method)} matches method named:
140     * {@code "print", "println", "printf", "format"}
141     * 
142     * @see #PRINTSTREAM_M(Method)
143     */
144    protected static final String PRINTSTREAM_M =
145        "<B CLASS=STBLabel>Methods:</B> class java.io.PrintStream";
146
147    /**
148     * Label for methods inherited from class {@link Replaceable}
149     * 
150     * <BR /><BR />Checker Method {@link #REPLACEABLE_M(Method)} matches method-names of all the
151     * methods currently listed in {@link Replaceable}.  Review the methods listed in that class to
152     * review those method-names.
153     * 
154     * @see #REPLACEABLE_M(Method)
155     */
156    protected static final String REPLACEABLE_M =
157        "<B CLASS=STBLabel>Methods:</B> interface Torello.HTML.Replaceable";
158
159
160    // ********************************************************************************************
161    // Throw UnreachableError, faster typing.
162    // ********************************************************************************************
163
164    /**
165     * Label for fields inherited from interface {@code java.io.Serializable}
166     */
167    protected static final String SERIALIZABLE_F = "Serializable ID";
168
169    /**
170     * Label for fields that are <B>{@code static}</B> singleton instances of a class.
171     */
172    protected static final String SINGLETON_F = "Singleton Instance";
173
174
175    // ********************************************************************************************
176    // Throw UnreachableError, faster typing.
177    // ********************************************************************************************
178
179    /**
180     * When writing a sorter method, it is often a good practice to throw the
181     * {@link UnreachableError} on the very last line of the sorter's code to ensure that every 
182     * entity being sorted has been properly placed into one of the Table Of Contents Section
183     * Title Categories.  This way, you ever add a new method / field / entity to the class, but
184     * forget to categorize it under a specific Section Title, an {@code UnreachableError} will
185     * instantly throw, reminding you to sort your newly created method, field, or other entity.
186     * 
187     * <BR /><BR />The other primary reason for writing this method is to shorten the amount of
188     * typing that you need to do.  The below example sorts all of the methods in a class into a 
189     * Method Summary Section (on the JavaDoc Generated HTML Page) which has three Sections 
190     * each with their own Title.  The Titles, themselves, are listed in the {@code String[]}
191     * array.  The sorting method for placing method's into one of these three Section Categories
192     * is directly beneath the listed categories.
193     * 
194     * <BR /><BR />Notice in this example, the last line of code invokes this method
195     * ({@code "UE(Declaration d)"})
196     * 
197     * <DIV CLASS=EXAMPLE>{@code
198     * public static final String[] MyClass$Method$Sections =
199     * {  "Main Method", "Printing Methods", "File Saving Methods" };
200     *
201     * public static int MyClass$Method$Sorter(Method m)
202     * {
203     *     if (m.name.equals("someName1"))          return 0;
204     *     if (eqOR(m, "someName2", "someName3"))   return 1;
205     *     if (swOR(m, "someName3"))                return 2;
206     * 
207     *     throw UE(m); // <== RIGHT-HERE, if the method is not categorized, it would have to be
208     *                  // becuase you have added another method into the class.  This will halt
209     *                  // your build process until you update your Method-Sorter Function.
210     * }
211     * }</DIV>
212     * 
213     * @param d Any Declaration ({@link Method}, {@link Field}, {@link Constructor}, etc...). This
214     * is actually just supposed to be the entity that was passed to your sorter.  If a call to
215     * {@code 'UE(d)'} is made one the last line of your sorter-function, the {@code 'toString'}
216     * method for the declaration will be printed to the terminal.
217     * 
218     * @return This returns a newly created instance of {@link UnreachableError}, which may be
219     * immediately thrown.  Remember, the general idea behind this method is to shorten the amount
220     * of typing you (the user / programmer) has to do.  When writing Class "Entity Sorters", you
221     * will find yourself typing many short sorting methods, like in the example above, over and
222     * over again.
223     */
224    protected static UnreachableError UE(Declaration d)
225    {
226        System.out.println(
227            '\n' + // Messager.Quiet && Messager.Silent needs this
228            BRED + "Un Classified " + d.getClass().getSimpleName() + " Found:\n" + RESET +
229            d.toString(PF.BODY | PF.JOW_ALSO | PF.UNIX_COLORS)
230        );
231
232        return new UnreachableError();
233    }
234
235
236    // ********************************************************************************************
237    // ********************************************************************************************
238    // Faster Typing, **ONLY COMPARES NAME**
239    // ********************************************************************************************
240    // ********************************************************************************************
241
242
243    /**
244     * <EMBED CLASS='external-html' DATA-FILE-ID=SSH_ABBREV DATA-METHNAME=equalsXOR>
245     * @param d Any {@link Method}, {@link Field}, {@link Constructor} etc.
246     * @param sArr <EMBED CLASS='external-html' DATA-FILE-ID=SSH_SARRP DATA-STROP='Equals'>
247     * @return {@code TRUE} - if and only if {@code d.name}
248     * <B STYLE='color:red;'>{@code Equals}</B> one of the elements of {@code 'sArr'}
249     * @see StrCmpr#equalsXOR(String, String[])
250     */
251    protected static boolean eqOR(Declaration d, String... sArr)
252    { return StrCmpr.equalsXOR(d.name, sArr); }
253
254    /**
255     * <EMBED CLASS='external-html' DATA-FILE-ID=SSH_ABBREV DATA-METHNAME=containsOR>
256     * @param d Any {@link Method}, {@link Field}, {@link Constructor} etc.
257     * @param sArr <EMBED CLASS='external-html' DATA-FILE-ID=SSH_SARRP DATA-STROP='Contains'>
258     * @return {@code TRUE} - if and only if {@code d.name}
259     * <B STYLE='color:red;'>{@code Contains}</B> one of the elements of {@code 'sArr'}
260     * @see StrCmpr#containsOR(String, String[])
261     */
262    protected static boolean cOR(Declaration d, String... sArr)
263    { return StrCmpr.containsOR(d.name, sArr); }
264
265    /**
266     * <EMBED CLASS='external-html' DATA-FILE-ID=SSH_ABBREV DATA-METHNAME=startsWithXOR>
267     * @param d Any {@link Method}, {@link Field}, {@link Constructor} etc.
268     * @param sArr <EMBED CLASS='external-html' DATA-FILE-ID=SSH_SARRP DATA-STROP='Starts-With'>
269     * @return {@code TRUE} - if and only if {@code d.name}
270     * <B STYLE='color:red;'>{@code Starts-With}</B> one of the elements of {@code 'sArr'}
271     * @see StrCmpr#startsWithXOR(String, String[])
272     */
273    protected static boolean swOR(Declaration d, String... sArr)
274    { return StrCmpr.startsWithXOR(d.name, sArr); }
275
276    /**
277     * <EMBED CLASS='external-html' DATA-FILE-ID=SSH_ABBREV DATA-METHNAME=endsWithXOR>
278     * @param d Any {@link Method}, {@link Field}, {@link Constructor} etc.
279     * @param sArr <EMBED CLASS='external-html' DATA-FILE-ID=SSH_SARRP DATA-STROP='Ends-With'>
280     * @return {@code TRUE} - if and only if {@code d.name}
281     * <B STYLE='color:red;'>{@code Ends-With}</B> one of the elements of {@code 'sArr'}
282     * @see StrCmpr#endsWithXOR(String, String[])
283     */
284    protected static boolean ewOR(Declaration d, String... sArr)
285    { return StrCmpr.endsWithXOR(d.name, sArr); }
286
287
288    // ********************************************************************************************
289    // ********************************************************************************************
290    // Default Method Name Sorters
291    // ********************************************************************************************
292    // ********************************************************************************************
293
294
295    /**
296     * Identifies whether or not a particular method should be placed under the <I>Method Summary
297     * Section Title</I> for methods which implement or extend {@code java.lang.Object}.
298     * <EMBED CLASS=defs DATA-Type=Object>
299     * @param m <EMBED CLASS='external-html' DATA-FILE-ID=SSH_METHP>
300     * @return <EMBED CLASS='external-html' DATA-FILE-ID=SSH_RETM>
301     * @see #OBJECT_M
302     * @see StrCmpr#equalsXOR(String, String[])
303     */
304    protected static boolean OBJECT_M(Method m)
305    { return StrCmpr.equalsXOR(m.name, "hashCode", "toString", "equals"); }
306
307    /**
308     * Identifies whether or not a particular method should be placed under the <I>Method Summary
309     * Section Title</I> for methods which implement or extend {@code java.util.Iterator}.
310     * <EMBED CLASS=defs DATA-Type=Iterator>
311     * @param m <EMBED CLASS='external-html' DATA-FILE-ID=SSH_METHP>
312     * @return <EMBED CLASS='external-html' DATA-FILE-ID=SSH_RETM>
313     * @see #ITERATOR_M
314     * @see StrCmpr#equalsXOR(String, String[])
315     */
316    protected static boolean ITERATOR_M(Method m)
317    { return StrCmpr.equalsXOR(m.name, "next", "hasNext", "remove", "forEachRemaining"); }
318
319    /**
320     * Identifies whether or not a particular method should be placed under the <I>Method Summary
321     * Section Title</I> for methods which implement or extend {@code java.lang.Cloneable}.
322     * <EMBED CLASS=defs DATA-Type=Cloneable>
323     * @param m <EMBED CLASS='external-html' DATA-FILE-ID=SSH_METHP>
324     * @return <EMBED CLASS='external-html' DATA-FILE-ID=SSH_RETM>
325     * @see #CLONEABLE_M
326     */
327    protected static boolean CLONEABLE_M(Method m)
328    { return m.name.equals("clone"); }
329
330    /**
331     * Identifies whether or not a particular method should be placed under the <I>Method Summary
332     * Section Title</I> for methods which implement or extend {@code java.lang.Appendable}.
333     * <EMBED CLASS=defs DATA-Type=Appendable>
334     * @param m <EMBED CLASS='external-html' DATA-FILE-ID=SSH_METHP>
335     * @return <EMBED CLASS='external-html' DATA-FILE-ID=SSH_RETM>
336     * @see #APPENDABLE_M
337     */
338    protected static boolean APPENDABLE_M(Method m)
339    { return m.name.equals("append"); }
340
341    /**
342     * Identifies whether or not a particular method should be placed under the <I>Method Summary
343     * Section Title</I> for methods which implement or extend {@code java.lang.Comparable}.
344     * <EMBED CLASS=defs DATA-Type=Comparable>
345     * @param m <EMBED CLASS='external-html' DATA-FILE-ID=SSH_METHP>
346     * @return <EMBED CLASS='external-html' DATA-FILE-ID=SSH_RETM>
347     * @see #COMPARABLE_M
348     */
349    protected static boolean COMPARABLE_M(Method m)
350    { return m.name.equals("compareTo"); }
351
352    /**
353     * Identifies whether or not a particular method should be placed under the <I>Method Summary
354     * Section Title</I> for methods which implement or extend {@code java.lang.CharSequence}.
355     * <EMBED CLASS=defs DATA-Type=CharSequence>
356     * @param m <EMBED CLASS='external-html' DATA-FILE-ID=SSH_METHP>
357     * @return <EMBED CLASS='external-html' DATA-FILE-ID=SSH_RETM>
358     * @see #CHARSEQUENCE_M
359     * @see StrCmpr#equalsXOR(String, String[])
360     */
361    protected static boolean CHARSEQUENCE_M(Method m)
362    { return StrCmpr.equalsXOR(m.name, "toString", "subSequence", "charAt", "length"); }
363
364    /**
365     * Identifies whether or not a particular method should be placed under the <I>Method Summary
366     * Section Title</I> for methods which implement or extend {@code java.io.Closeable}.
367     * <EMBED CLASS=defs DATA-Type=Closeable>
368     * @param m <EMBED CLASS='external-html' DATA-FILE-ID=SSH_METHP>
369     * @return <EMBED CLASS='external-html' DATA-FILE-ID=SSH_RETM>
370     * @see #CLOSEABLE_M
371     */
372    protected static boolean CLOSEABLE_M(Method m)
373    { return m.name.equals("close") && m.returnType.equals("void"); }
374
375    /**
376     * Identifies whether or not a particular method should be placed under the <I>Method Summary
377     * Section Title</I> for methods which implement or extend {@code java.io.Flushable}.
378     * <EMBED CLASS=defs DATA-Type=Flushable>
379     * @param m <EMBED CLASS='external-html' DATA-FILE-ID=SSH_METHP>
380     * @return <EMBED CLASS='external-html' DATA-FILE-ID=SSH_RETM>
381     * @see #FLUSHABLE_M
382     */
383    protected static boolean FLUSHABLE_M(Method m)
384    { return m.name.equals("flush") && m.returnType.equals("void"); }
385
386    /**
387     * Identifies whether or not a particular method should be placed under the <I>Method Summary
388     * Section Title</I> for methods which implement or extend {@code java.io.Writer}.
389     * <EMBED CLASS=defs DATA-Type=Writer>
390     * @param m <EMBED CLASS='external-html' DATA-FILE-ID=SSH_METHP>
391     * @return <EMBED CLASS='external-html' DATA-FILE-ID=SSH_RETM>
392     * @see #WRITER_M
393     * @see StrCmpr#equalsXOR(String, String[])
394     */
395    protected static boolean WRITER_M(Method m)
396    { return StrCmpr.equalsXOR(m.name, "write", "close", "flush", "append"); }
397
398    /**
399     * Identifies whether or not a particular method should be placed under the <I>Method Summary
400     * Section Title</I> for methods which implement or extend {@code java.io.PrintStream}.
401     * <EMBED CLASS=defs DATA-Type=PrintStream>
402     * @param m <EMBED CLASS='external-html' DATA-FILE-ID=SSH_METHP>
403     * @return <EMBED CLASS='external-html' DATA-FILE-ID=SSH_RETM>
404     * @see #PRINTSTREAM_M
405     * @see StrCmpr#equalsXOR(String, String[])
406     */
407    protected static boolean PRINTSTREAM_M(Method m)
408    { return StrCmpr.equalsXOR(m.name, "print", "println", "printf", "format"); }
409
410    private static final Vector<String> REPLACEABLE_METHODS;
411
412    static
413    {
414        java.lang.reflect.Method[] mArr = Replaceable.class.getMethods();
415        REPLACEABLE_METHODS = new Vector<>(mArr.length);
416        for (int i=0; i < mArr.length; i++) REPLACEABLE_METHODS.add(mArr[i].getName());
417    }
418
419    /**
420     * Identifies whether or not a particular method should be placed under the <I>Method Summary
421     * Section Title</I> for methods which implement or extend {@link Replaceable}.
422     * <EMBED CLASS=defs DATA-Type=Replaceable>
423     * @param m <EMBED CLASS='external-html' DATA-FILE-ID=SSH_METHP>
424     * @return <EMBED CLASS='external-html' DATA-FILE-ID=SSH_RETM>
425     * @see #REPLACEABLE_M
426     */
427    protected static boolean REPLACEABLE_M(Method m)
428    { return REPLACEABLE_METHODS.contains(m.name); }
429
430
431    // ********************************************************************************************
432    // ********************************************************************************************
433    // Default Field Name Sorters
434    // ********************************************************************************************
435    // ********************************************************************************************
436
437
438    /**
439     * Checks if a {@link Field} is named {@code 'serialVersionUID'}.
440     * @see #SERIALIZABLE_F
441     */
442    protected static boolean SERIALIZABLE_F(Field f)
443    { return f.name.equals("serialVersionUID"); }
444
445
446    // ********************************************************************************************
447    // ********************************************************************************************
448    // Automatic Sorter & Section-Titles
449    // ********************************************************************************************
450    // ********************************************************************************************
451
452
453    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
454    // Field Summary Sort - One Field, "serialVersionUID"
455    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
456
457    /**
458     * A Section-Titles {@code String[]} Array List containing only one category.  The category
459     * is for Field Summaries having only one field - <B>{@code 'serialVersionUID'}</B>
460     * @see #ONLY_SERIALIZABLE_F(Field)
461     */
462    protected static String[] ONLY_SERIALIZABLE_F =
463    { SERIALIZABLE_F };
464
465    /**
466     * A sorter for Field Summaries with only one field - <B>{@code 'serialVersionUID'}</B>
467     * @see #ONLY_SERIALIZABLE_F
468     * @throws UnreachableError If there are other fields in the class.
469     */
470    protected static int ONLY_SERIALIZABLE_F(Field f)
471    { if (SERIALIZABLE_F(f)) return 0; throw UE(f); }
472
473
474    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
475    // Exception Sorters and Titles
476    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
477
478    /**
479     * A Section-Titles {@code String[]} Array List containing two categories.  The first merely
480     * used for the {@code serialVersionUID}, and the second contains all other fields.  This is
481     * intended to be used for sorting {@code Exception} classes that provide "convenience" or
482     * "introspection" fields where data about the error that has occured is saved inside the
483     * exception.
484     * 
485     * @see #EXCEPTION_CONVENIENCE_F(Field)
486     */
487    protected static String[] EXCEPTION_CONVENIENCE_F =
488    { SERIALIZABLE_F, "<CODE STYLE='font-size: 108%'>'final'</CODE> Exception Convenience Fields" };
489
490    /**
491     * This can be used to sort the {@code Field's} of an exception, provided that they fields
492     * obey the convenience-construct.  This sorter will place the {@code 'serialVersionUID'}
493     * field into the first category, and all other fields into the second.
494     * 
495     * <BR /><BR />It is <B STYLE='color: red;'>assumed</B> that the convenience-fields are
496     * declared <B>{@code final}</B>.  If a field is not declared {@code 'final'}, it will not be
497     * categorized, and an {@code UnreachableError} will throw.
498     * 
499     * @param f This is the {@link Field} that the Java Doc Upgrader is currently categorizing.
500     * 
501     * @throws UnreachableError If there are other fields in the class besides the Serial ID, and
502     * fields which aren't declared {@code 'final'}
503     * 
504     * @see #EXCEPTION_CONVENIENCE_F
505     */
506    protected static int EXCEPTION_CONVENIENCE_F(Field f)
507    {
508        if (SERIALIZABLE_F(f))              return 0;
509        if (f.modifiers.contains("final"))  return 1;
510        throw UE(f);
511    }
512
513    /**
514     * If an {@code Exception} class contains 'checker' methods, then this title-bar 
515     * {@code String[]} Array can be used to categorize them.  Note that this array only allows
516     * for this lone-category, and does not provide others.  The sorter for this Titles-Bar
517     * requires that each method in the class have a name that begins with <B>{@code 'check'}</B>
518     * 
519     * @see #EXCEPTION_CHECKERS_M(Method)
520     */
521    protected static String[] EXCEPTION_CHECKERS_M =
522    { "<CODE STYLE='font-size: 108%'>'static'</CODE> Exception Check Methods" };
523
524    /**
525     * Sorts a Method Summary Section for an {@code Exception} class that contains 'checker'
526     * methods.  In Java HTML, {@code 'check'} methods are declared {@code 'static'}, and will
527     * test parameter-input for exception cases, <I>and then throw the exception in which those
528     * methods reside if there are errors with the input</I>.
529     * 
530     * <BR /><BR /><B>NOTE:</B> See, for example <B>{@link ParallelArrayException}</B>, which 
531     * contains multiple methods of this variety.
532     * 
533     * @param m This is the {@link Method} that the Java Doc Upgrader is currently categorizing.
534     * 
535     * @throws UnreachableError If there are methods which aren't declared {@code 'static'}, or
536     * there are methods whose name does not begin with {@code "check"}.
537     * 
538     * @see #EXCEPTION_CHECKERS_M
539     */
540    protected static int EXCEPTION_CHECKERS_M(Method m)
541    {
542        if (m.name.startsWith("check") && m.modifiers.contains("static")) return 0;
543        throw UE(m);
544    }
545
546
547    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
548    // Method Summary Sort - The 'enum' *SYNTHETIC* (Auto-Generated) methods: values(), valueOf()
549    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
550
551    /**
552     * First Section-Title / Category for the <B STYLE='color: red;'>Synthetic</B> Enum-Method
553     * {@code 'values()'}.  All {@code 'enums'} have a {@code 'values'} method that is
554     * auto-generated by the Java Compiler.
555     * @see #enum$M$Sections
556     * @see #enum2$M$Sections
557     */
558    protected static final String VALUES_M = "List all Enum Constants";
559
560    /**
561     * Second Section-Title / Category for the <B STYLE='color: red;'>Synthetic</B> Enum-Method
562     * {@code 'valueOf(String)'}.  All {@code 'enums'} have a {@code 'valueOf'} method that is
563     * auto-generated by the Java Compiler.
564     * @see #enum$M$Sections
565     * @see #enum2$M$Sections
566     */
567    protected static final String VALUEOF_M = "Convert String to Enum Constant";
568
569    /**
570     * <EMBED CLASS='external-html' DATA-FILE-ID=SSH_ENUM_DESC>
571     * 
572     * <BR /><BR />If you have written additional functions, then you should use
573     * {@link #enum2$M$Sections}, because that {@code String[]} Array has an extra Category /
574     * Section-Title called "More Methods".
575     * 
576     * @see #VALUEOF_M
577     * @see #VALUES_M
578     * @see #enum$M$Sorter
579     */
580    protected static String[] enum$M$Sections =
581    { VALUEOF_M, VALUES_M };
582
583    /**
584     * <EMBED CLASS='external-html' DATA-FILE-ID=SSH_ENUM_DESC>
585     * 
586     * <BR /><BR />If your {@code enum} only has these two synthetic-Java methods, then you should
587     * use {@link #enum$M$Sections}.
588     * 
589     * @see #VALUEOF_M
590     * @see #VALUES_M
591     * @see #enum2$M$Sorter
592     */
593    protected static String[] enum2$M$Sections =
594    { VALUEOF_M, VALUES_M, "More Methods" };
595
596    /**
597     * Sorts an {@code enum's} methods (in the Java Doc 'Method Summary') into the Categories /
598     * Section-Titles provided by {@link #enum$M$Sections}.
599     * 
600     * <BR /><BR /><B>NOTE:</B> If the {@code 'enum'} whose methods you are sorting has other
601     * methods besides the ones auto-created by the Java Compiler, you should use the pair
602     * {@link #enum2$M$Sections} and {@link #enum2$M$Sorter(Method)}.  This one will throw an
603     * {@link UnreachableError} if other methods are received.
604     * 
605     * @param m This is the {@link Method} that the Java Doc Upgrader is currently categorizing.
606     * 
607     * @return The category number where this method belongs.
608     * 
609     * @throws UnreachableError If the {@code 'enum'} to which this Method Summary-Sorter has been
610     * applied has methods other than the <B STYLE='color:red;'>Synthetically</B> auto-generated
611     * methods {@code 'values'} and {@code 'valueOf'}, then when those methods are received by this
612     * sorter, this error will throw.
613     * 
614     * @see #enum$M$Sections
615     */
616    protected static int enum$M$Sorter(Method m)
617    {
618        if (m.name.equals("valueOf"))   return 0;
619        if (m.name.equals("values"))    return 1;
620        throw UE(m);
621    }
622
623    /**
624     * Sorts an {@code enum's} methods (in the Java Doc 'Method Summary') into the Categories /
625     * Section-Titles provided by {@link #enum2$M$Sections}.
626     * 
627     * @param m This is the {@link Method} that the Java Doc Upgrader is currently categorizing.
628     * 
629     * @return The category number where this method belongs.
630     * 
631     * @see #enum2$M$Sections
632     */
633    protected static int enum2$M$Sorter(Method m)
634    {
635        if (m.name.equals("valueOf"))   return 0;
636        if (m.name.equals("values"))    return 1;
637        return 2;
638    }
639
640
641    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
642    // @FunctionalInterface: interfaces which only have the one abstract-method, and no others
643    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
644
645    /** Title-Category for methods that are <B>{@code 'static'} Factory</B> Methods. */
646    protected static final String STATIC_FACTORY =
647        "<B CLASS=STBLabel>Methods:</B> Static Factory-Builder";
648
649    /** Title-Category for composition methods (for instance {@code 'andThen'}) */
650    protected static final String DEFAULT_COMP =
651        "<B CLASS=STBLabel>Methods:</B> Default Composition & Builder";
652
653    /** {@code Iterator.remove()} Method Title-Category. */
654    protected static final String DEF_ITER_REMOVE = 
655        "<B CLASS=STBLabel>Default Methods:</B> Remove Elements with Iterator.remove()";
656
657    /**
658     * A "Section Titles" {@code String[]} Array that contains only one Title/Category.  This
659     * category identifies a Functional-Interface's <B STYLE='color:red;'>Lambda-Target</B>
660     * method.
661     * 
662     * @see #FINTERFACE_M
663     */
664    protected static final String[] fInterface$M$Sections = { FINTERFACE_M };
665
666    /**
667     * This can be used to place a functional-interface method under the sectional title
668     * for functional-interfaces.  <I>This method will only work on interfaces that have
669     * only method (namely: the lambda-target method).</I>
670     * 
671     * @param functionalIntMethName This is the name of the 'lone method' that is used as a
672     * lambda-target of a {@code FunctionalInterface}.
673     * 
674     * @param m This is the {@link Method} that the Java Doc Upgrader is currently categorizing.
675     * 
676     * @throws UnreachableError If there are other methods in the class besides the one whose name
677     * equals {@code 'functionalIntMethName'}
678     */
679    protected static int fInterface$M$Sorter(String functionalIntMethName, Method m)
680    {
681        if (m.name.equals(functionalIntMethName)) return 0;
682        throw UE(m);
683    }
684}