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
package Torello.Java.Build;

import static Torello.Java.C.BRED;
import static Torello.Java.C.RESET;

import Torello.Java.UnreachableError;
import Torello.Java.Additional.ByRef;
import Torello.Java.ReadOnly.ReadOnlyList;

import Apache.CLI.Option;
import Apache.CLI.Options;
import Apache.CLI.OptionGroup;
import Apache.CLI.CommandLine;
import Apache.CLI.DefaultParser;
import Apache.CLI.MissingOptionException;
import Apache.CLI.ParseException;

class ProcessMainMenuChoice 
{
    static SelectedOptionsRecord process(
            final ReadOnlyList<BuildPackage>    packageList,
            final String[]                      argv,
            final Options                       options,
            final OptionGroup                   group,
            final CollatedOptsRecord            cor,
            final PrintHelpRecord               phr,

            // This constructor has a "Return-Value",  This is a Wrapper-Object, which allows
            // "returning" the User's Selected 'CloudSync' instance back to the method that
            // invoked this constructor by setting selectedCloudSync.f = [the one the user choose]
            // 
            // NOTE: The User "Chooses" a CloudSync instance when he enters a specific "-cb" or
            //       "-pb" CLI Main-Menu Option in the Terminal-Window / Command-Line.  Each of 
            //       the available "-cb" and "-pb" Main Menu-Options are mapped, explicitly to
            //       precisely one of the CloudSync Web-Domains / Storage-Buckets.

            final ByRef<CloudSync>  selectedCloudSync
        )
    {
        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        // Parse 'argv' using 'options' - Do some error checking
        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

        // Command-Line is an Apache.CLI class
        final CommandLine commandLine;

        try
        {
            // "DefaultParser" is an Apache-CLI class.  It parses the "String[] argv" parameter
            // that has been retrieved from the Command-Line, as has been typed by the user at the
            // Command-Line

            commandLine = DefaultParser
                .builder()
                .setAllowPartialMatching(false)         // Cute Little Apache Things... I dunno.
                .setStripLeadingAndTrailingQuotes(true) // Same.  I guess so...
                .build()
                .parse(options, argv, false /* stopAtNonOption */);
        }

        // This exception is thrown when the user hasn't provided at least one of the "OptionGroup"
        // switches.
        // 
        // All of the "Option" instances inside the "OptionGroup" are the **COMPLETE** list of 
        // Menu-Options offered by this build.  Precisely ONE of these Option's from 'OptionGroup'
        // must be provided at the command line, or else this exception throws.  If so, just print
        // an error message and exit.
        // 
        // It prints the Main Help-Menu.

        catch (MissingOptionException moe)
        {
            phr.print_MainMenu_Options();

            System.out.println(
                BRED + "You must select exactly one of the Primary or Composite Build-Options " +
                "listed above\n" + RESET +
                "Requesting that the Java-Doc Internal-URL Links-Checker be run is also allowed,\n" +
                "although currently, it has been disabled\n"
            );

            System.exit(1); throw null;
        }

        // I haven't been through all of Apache-CLI's list of other possible Error-Messages / 
        // Help-Menu-Features / Exported-API-Methods.  The Help-Menu that I have read-through and
        // looked at was the class "Apache.CLI.HelpFormatter" 
        // 
        // The output it generated wasn't "good enough", I really get into using the UNIX Colors
        // provided by Torello.Java.C - and so I have written my own help menu.  The Java-HTML
        // '.jar' uses UNIX-Color-Codes profusely for anything involving Terminal CLI-Output
        // because it is a tremendous help / benefit for effectively organizing and hiliting
        // somewhat complicated information to the user.
        // 
        // Anyway, the Main-Menu is printed (which is done in all error cases); and then the
        // exception is printed.  Then the system halts.  The 'throw null' that is needed to quiet
        // the 'javac' Java-Compiler.  Otherwise it would complain that 'final' field 'commandLine'
        // had not been properly initialized.  It is a completely UNREACHABLE-STATEMENT...

        catch (ParseException pe)
        {
            phr.print_MainMenu_Options(); 
            System.out.println(pe.getMessage());
            System.exit(1); throw null;
        }

        // NOTE: Anything else really unexpected - If any unknown exceptions are thrown - it would 
        //       be better to just let those exceptions "bubble up" through this CLI-Constructor
        //       and out to the End-User.
        //
        // The "Pray for Rain" way / means of dealing with exceptons is - well ... if you have
        // thought-through ever variant of exception-error case, then anything unexpected is best
        // left to halt the program and admit there is a bug!
        // 
        // I mean, that's what it means to have an unknown exception throw, so oh well!


        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        // Retrieve the Selected-Option's name and Object instance-reference
        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

        final String MENU_CHOICE = group.getSelected();

        Option selectedOpt = null;
        for (Option o : group.getOptions()) if (o.getOpt().equals(MENU_CHOICE))
        {
            selectedOpt = o;
            break;
        }


        // The argv-option parsing mechanism should already have thrown an exception if the user
        // failed to choose any of the provided options.
        // 
        // Since I did not write the Apache-CLI code, I'm going to leave this line here, as a
        // sanity check and "just in case I didn't quite get Apache-CLI" (and missed something in
        // that package, or if there is something unexpected that has happend).
        // 
        // Again, the "UnreachableError" is essentially an "assert" statement that cannot be 
        // disabled.  It is better to Fail-Fast, and admit there is a bug, then to cover it up...

        if (selectedOpt == null) throw new UnreachableError();


        // The "cloudSyncSwitchMapper" is a (ReadOnly) Hash-Map that merely maps the Command-Line
        // switch names directly to an actual instance of "CloudSync".
        //
        // In cases where the user has passed something like "-1", "-2" ... "-4" where there is
        // simply no Cloud-Synchronization going on, then the mapper will simply return null, and
        // the value stored inside (and returned, since 'selectedCloudSync' is a reference-wrapper)
        // WILL BE NULL
        // 
        // The Switch-Mapper Map will not have a key that maps to these switches because they do
        // not employ Cloud-Synchronization.  This 'mapper' is built by class 'Generate' (and one
        // of its sub-classes).  This line, right here, below - is the only actual place where
        // "cloudSyncSwitchMapper" is ever actually used!
        // 
        // Again, this class Constructor's "return value" is returned, precisely, here using this 
        // Wrapper-Class parameter ("selectedCloudSync") - which was passed to this constructor as
        // a parameter.

        selectedCloudSync.f = cor.cloudSyncSwitchMapper.get(MENU_CHOICE);

        final SelectedOptionsRecord sor = ProcessNickNameArgs.process(
            packageList,                        // BuildPackage[]
            MENU_CHOICE,                        // String
            selectedOpt,                        // Apache.CLI.Option
            cor.optionsWhichAcceptPkgNickNames, // ReadOnlyList<String>
            phr,                                // PrintHelpRecord
            commandLine                         // Apache.CLI.CommandLine
        );

        return sor;
    }
}