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

Last change on this file since 12893 was 12893, checked in by bastiK, 17 months ago

see #15229 - add getopt to ant target "compile-cots"; minor fix

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