source: josm/trunk/src/org/openstreetmap/josm/gui/ProgramArguments.java @ 14415

Last change on this file since 14415 was 14415, checked in by michael2402, 4 months ago

See #16866: Drop getopt, use own option parser.

  • Property svn:eol-style set to native
File size: 7.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui;
3
4import java.util.ArrayList;
5import java.util.Arrays;
6import java.util.Collection;
7import java.util.Collections;
8import java.util.EnumMap;
9import java.util.HashMap;
10import java.util.List;
11import java.util.Locale;
12import java.util.Map;
13import java.util.Optional;
14import java.util.logging.Level;
15import java.util.stream.Stream;
16
17import org.openstreetmap.josm.tools.Logging;
18import org.openstreetmap.josm.tools.OptionParser;
19import org.openstreetmap.josm.tools.OptionParser.OptionCount;
20
21/**
22 * This class holds the arguments passed on to {@link MainApplication#main}.
23 * @author Michael Zangl
24 * @since 10899
25 */
26public class ProgramArguments {
27
28    /**
29     * JOSM command line options.
30     * @see <a href="https://josm.openstreetmap.de/wiki/Help/CommandLineOptions">Help/CommandLineOptions</a>
31     */
32    public enum Option {
33        /** --help|-h                                  Show this help */
34        HELP(false),
35        /** --version                                  Displays the JOSM version and exits */
36        VERSION(false),
37        /** --debug                                    Print debugging messages to console */
38        DEBUG(false),
39        /** --trace                                    Print detailed debugging messages to console */
40        TRACE(false),
41        /** --language=&lt;language&gt;                Set the language */
42        LANGUAGE(true),
43        /** --reset-preferences                        Reset the preferences to default */
44        RESET_PREFERENCES(false),
45        /** --load-preferences=&lt;url-to-xml&gt;      Changes preferences according to the XML file */
46        LOAD_PREFERENCES(true),
47        /** --set=&lt;key&gt;=&lt;value&gt;            Set preference key to value */
48        SET(true),
49        /** --geometry=widthxheight(+|-)x(+|-)y        Standard unix geometry argument */
50        GEOMETRY(true),
51        /** --no-maximize                              Do not launch in maximized mode */
52        NO_MAXIMIZE(false),
53        /** --maximize                                 Launch in maximized mode */
54        MAXIMIZE(false),
55        /** --download=minlat,minlon,maxlat,maxlon     Download the bounding box <br>
56         *  --download=&lt;URL&gt;                     Download the location at the URL (with lat=x&amp;lon=y&amp;zoom=z) <br>
57         *  --download=&lt;filename&gt;                Open a file (any file type that can be opened with File/Open) */
58        DOWNLOAD(true),
59        /** --downloadgps=minlat,minlon,maxlat,maxlon  Download the bounding box as raw GPS <br>
60         *  --downloadgps=&lt;URL&gt;                  Download the location at the URL (with lat=x&amp;lon=y&amp;zoom=z) as raw GPS */
61        DOWNLOADGPS(true),
62        /** --selection=&lt;searchstring&gt;           Select with the given search */
63        SELECTION(true),
64        /** --offline=&lt;osm_api|josm_website|all&gt; Disable access to the given resource(s), delimited by comma */
65        OFFLINE(true),
66        /** --skip-plugins */
67        SKIP_PLUGINS(false);
68
69        private final String name;
70        private final boolean requiresArg;
71
72        Option(boolean requiresArgument) {
73            this.name = name().toLowerCase(Locale.ENGLISH).replace('_', '-');
74            this.requiresArg = requiresArgument;
75        }
76
77        /**
78         * Replies the option name
79         * @return The option name, in lowercase
80         */
81        public String getName() {
82            return name;
83        }
84
85        /**
86         * Determines if this option requires an argument.
87         * @return {@code true} if this option requires an argument, {@code false} otherwise
88         */
89        public boolean requiresArgument() {
90            return requiresArg;
91        }
92    }
93
94    private final Map<Option, List<String>> argMap = new EnumMap<>(Option.class);
95
96    /**
97     * Construct the program arguments object
98     * @param args The args passed to main.
99     * @since 10936
100     */
101    public ProgramArguments(String... args) {
102        Stream.of(Option.values()).forEach(o -> argMap.put(o, new ArrayList<>()));
103        buildCommandLineArgumentMap(args);
104    }
105
106    /**
107     * Builds the command-line argument map.
108     * @param args command-line arguments array
109     */
110    private void buildCommandLineArgumentMap(String... args) {
111        OptionParser parser = new OptionParser("JOSM");
112        for (Option o : Option.values()) {
113            if (o.requiresArgument()) {
114                parser.addArgumentParameter(o.getName(), OptionCount.MULTIPLE, p -> addOption(o, p));
115            } else {
116                parser.addFlagParameter(o.getName(), () -> addOption(o, ""));
117            }
118        }
119
120        parser.addShortAlias(Option.HELP.getName(), "h");
121        parser.addShortAlias(Option.VERSION.getName(), "v");
122
123        List<String> remaining = parser.parseOptionsOrExit(Arrays.asList(args));
124
125        // positional arguments are a shortcut for the --download ... option
126        for (String arg : remaining) {
127            addOption(Option.DOWNLOAD, arg);
128        }
129    }
130
131    private void addOption(Option opt, String optarg) {
132        argMap.get(opt).add(optarg);
133    }
134
135    /**
136     * Gets a single argument (the first) that was given for the given option.
137     * @param option The option to search
138     * @return The argument as optional value.
139     */
140    public Optional<String> getSingle(Option option) {
141        return get(option).stream().findFirst();
142    }
143
144    /**
145     * Gets all values that are given for a given option
146     * @param option The option
147     * @return The values that were given. May be empty.
148     */
149    public Collection<String> get(Option option) {
150        return Collections.unmodifiableList(argMap.get(option));
151    }
152
153    /**
154     * Test if a given option was used by the user.
155     * @param option The option to test for
156     * @return <code>true</code> if the user used it.
157     */
158    public boolean hasOption(Option option) {
159        return !get(option).isEmpty();
160    }
161
162    /**
163     * Helper method to indicate if version should be displayed.
164     * @return <code>true</code> to display version
165     */
166    public boolean showVersion() {
167        return hasOption(Option.VERSION);
168    }
169
170    /**
171     * Helper method to indicate if help should be displayed.
172     * @return <code>true</code> to display version
173     */
174    public boolean showHelp() {
175        return !get(Option.HELP).isEmpty();
176    }
177
178    /**
179     * Get the log level the user wants us to use.
180     * @return The log level.
181     */
182    public Level getLogLevel() {
183        if (hasOption(Option.TRACE)) {
184            return Logging.LEVEL_TRACE;
185        } else if (hasOption(Option.DEBUG)) {
186            return Logging.LEVEL_DEBUG;
187        } else {
188            return Logging.LEVEL_INFO;
189        }
190    }
191
192    /**
193     * Gets a map of all preferences the user wants to set.
194     * @return The preferences to set. It contains null values for preferences to unset
195     */
196    public Map<String, String> getPreferencesToSet() {
197        HashMap<String, String> map = new HashMap<>();
198        get(Option.SET).stream().map(i -> i.split("=", 2)).forEach(kv -> map.put(kv[0], getValue(kv)));
199        return map;
200    }
201
202    private static String getValue(String... kv) {
203        if (kv.length < 2) {
204            return "";
205        } else if ("null".equals(kv[1])) {
206            return null;
207        } else {
208            return kv[1];
209        }
210    }
211}
Note: See TracBrowser for help on using the repository browser.