source: josm/trunk/src/org/openstreetmap/josm/gui/MainApplication.java@ 5299

Last change on this file since 5299 was 5279, checked in by bastiK, 12 years ago

use gnu getopt for command line processing

improvements:

  • long options can be separated by space from the argument (currently

only "=" works as seperator)

  • short options can be grouped (there aren't many short options at the moment, this is for later)
  • Property svn:eol-style set to native
File size: 17.2 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.gui;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6
7import java.awt.Image;
8import java.awt.Toolkit;
9import java.awt.event.WindowAdapter;
10import java.awt.event.WindowEvent;
11import java.io.File;
12import java.net.Authenticator;
13import java.net.ProxySelector;
14import java.net.URL;
15import java.security.AllPermission;
16import java.security.CodeSource;
17import java.security.PermissionCollection;
18import java.security.Permissions;
19import java.security.Policy;
20import java.util.ArrayList;
21import java.util.Collection;
22import java.util.HashMap;
23import java.util.LinkedList;
24import java.util.List;
25import java.util.Map;
26
27import javax.swing.JFrame;
28import javax.swing.RepaintManager;
29import javax.swing.SwingUtilities;
30
31import gnu.getopt.Getopt;
32import gnu.getopt.LongOpt;
33
34import org.jdesktop.swinghelper.debug.CheckThreadViolationRepaintManager;
35import org.openstreetmap.josm.Main;
36import org.openstreetmap.josm.data.AutosaveTask;
37import org.openstreetmap.josm.data.CustomConfigurator;
38import org.openstreetmap.josm.data.Preferences;
39import org.openstreetmap.josm.data.Version;
40import org.openstreetmap.josm.gui.download.DownloadDialog;
41import org.openstreetmap.josm.gui.preferences.server.OAuthAccessTokenHolder;
42import org.openstreetmap.josm.gui.progress.ProgressMonitor;
43import org.openstreetmap.josm.io.DefaultProxySelector;
44import org.openstreetmap.josm.io.auth.CredentialsManager;
45import org.openstreetmap.josm.io.auth.DefaultAuthenticator;
46import org.openstreetmap.josm.io.remotecontrol.RemoteControl;
47import org.openstreetmap.josm.plugins.PluginHandler;
48import org.openstreetmap.josm.plugins.PluginInformation;
49import org.openstreetmap.josm.tools.BugReportExceptionHandler;
50import org.openstreetmap.josm.tools.I18n;
51import org.openstreetmap.josm.tools.ImageProvider;
52
53/**
54 * Main window class application.
55 *
56 * @author imi
57 */
58public class MainApplication extends Main {
59 /**
60 * Allow subclassing (see JOSM.java)
61 */
62 public MainApplication() {}
63
64 /**
65 * Construct an main frame, ready sized and operating. Does not
66 * display the frame.
67 */
68 public MainApplication(JFrame mainFrame) {
69 super();
70 mainFrame.setContentPane(contentPanePrivate);
71 mainFrame.setJMenuBar(menu);
72 geometry.applySafe(mainFrame);
73 LinkedList<Image> l = new LinkedList<Image>();
74 l.add(ImageProvider.get("logo_16x16x32").getImage());
75 l.add(ImageProvider.get("logo_16x16x8").getImage());
76 l.add(ImageProvider.get("logo_32x32x32").getImage());
77 l.add(ImageProvider.get("logo_32x32x8").getImage());
78 l.add(ImageProvider.get("logo_48x48x32").getImage());
79 l.add(ImageProvider.get("logo_48x48x8").getImage());
80 l.add(ImageProvider.get("logo").getImage());
81 mainFrame.setIconImages(l);
82 mainFrame.addWindowListener(new WindowAdapter(){
83 @Override public void windowClosing(final WindowEvent arg0) {
84 Main.exitJosm(true);
85 }
86 });
87 mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
88 }
89
90 /**
91 * Displays help on the console
92 *
93 */
94 public static void showHelp() {
95 // TODO: put in a platformHook for system that have no console by default
96 System.out.println(tr("Java OpenStreetMap Editor")+"\n\n"+
97 tr("usage")+":\n"+
98 "\tjava -jar josm.jar <options>...\n\n"+
99 tr("options")+":\n"+
100 "\t--help|-h "+tr("Show this help")+"\n"+
101 "\t--geometry=widthxheight(+|-)x(+|-)y "+tr("Standard unix geometry argument")+"\n"+
102 "\t[--download=]minlat,minlon,maxlat,maxlon "+tr("Download the bounding box")+"\n"+
103 "\t[--download=]<url> "+tr("Download the location at the url (with lat=x&lon=y&zoom=z)")+"\n"+
104 "\t[--download=]<filename> "+tr("Open a file (any file type that can be opened with File/Open)")+"\n"+
105 "\t--downloadgps=minlat,minlon,maxlat,maxlon "+tr("Download the bounding box as raw gps")+"\n"+
106 "\t--downloadgps=<url> "+tr("Download the location at the url (with lat=x&lon=y&zoom=z) as raw gps")+"\n"+
107 "\t--selection=<searchstring> "+tr("Select with the given search")+"\n"+
108 "\t--[no-]maximize "+tr("Launch in maximized mode")+"\n"+
109 "\t--reset-preferences "+tr("Reset the preferences to default")+"\n\n"+
110 "\t--load-preferences=<url-to-xml> "+tr("Changes preferences according to the XML file")+"\n\n"+
111 "\t--set=<key>=<value> "+tr("Set preference key to value")+"\n\n"+
112 "\t--language=<language> "+tr("Set the language")+"\n\n"+
113 tr("options provided as Java system properties")+":\n"+
114 "\t-Djosm.home="+tr("/PATH/TO/JOSM/FOLDER/ ")+tr("Change the folder for all user settings")+"\n\n"+
115 tr("note: For some tasks, JOSM needs a lot of memory. It can be necessary to add the following\n" +
116 " Java option to specify the maximum size of allocated memory in megabytes")+":\n"+
117 "\t-Xmx...m\n\n"+
118 tr("examples")+":\n"+
119 "\tjava -jar josm.jar track1.gpx track2.gpx london.osm\n"+
120 "\tjava -jar josm.jar http://www.openstreetmap.org/index.html?lat=43.2&lon=11.1&zoom=13\n"+
121 "\tjava -jar josm.jar london.osm --selection=http://www.ostertag.name/osm/OSM_errors_node-duplicate.xml\n"+
122 "\tjava -jar josm.jar 43.2,11.1,43.4,11.4\n"+
123 "\tjava -Djosm.home=/home/user/.josm_dev -jar josm.jar\n"+
124 "\tjava -Xmx400m -jar josm.jar\n\n"+
125 tr("Parameters --download, --downloadgps, and --selection are processed in this order.")+"\n"+
126 tr("Make sure you load some data if you use --selection.")+"\n"
127 );
128 }
129
130 public enum Option {
131 HELP(false),
132 VERSION(false),
133 LANGUAGE(true),
134 RESET_PREFERENCES(false),
135 LOAD_PREFERENCES(true),
136 SET(true),
137 GEOMETRY(true),
138 NO_MAXIMIZE(false),
139 MAXIMIZE(false),
140 DOWNLOAD(true),
141 DOWNLOADGPS(true),
142 SELECTION(true);
143
144 private String name;
145 private boolean requiresArgument;
146
147 private Option(boolean requiresArgument) {
148 this.name = name().toLowerCase().replace("_", "-");
149 this.requiresArgument = requiresArgument;
150 }
151
152 public String getName() {
153 return name;
154 }
155
156 public boolean requiresArgument() {
157 return requiresArgument;
158 }
159
160 public static Map<Option, Collection<String>> fromStringMap(Map<String, Collection<String>> opts) {
161 Map<Option, Collection<String>> res = new HashMap<Option, Collection<String>>();
162 for (Map.Entry<String, Collection<String>> e : opts.entrySet()) {
163 Option o = Option.valueOf(e.getKey().toUpperCase().replace("-", "_"));
164 if (o != null) {
165 res.put(o, e.getValue());
166 }
167 }
168 return res;
169 }
170 }
171
172 private static Map<Option, Collection<String>> buildCommandLineArgumentMap(String[] args) {
173
174 List<LongOpt> los = new ArrayList<LongOpt>();
175 for (Option o : Option.values()) {
176 los.add(new LongOpt(o.getName(), o.requiresArgument() ? LongOpt.REQUIRED_ARGUMENT : LongOpt.NO_ARGUMENT, null, 0));
177 }
178
179 Getopt g = new Getopt("JOSM", args, "hv", los.toArray(new LongOpt[0]));
180
181 Map<Option, Collection<String>> argMap = new HashMap<Option, Collection<String>>();
182
183 int c;
184 while ((c = g.getopt()) != -1 ) {
185 Option opt = null;
186 switch (c) {
187 case 'h':
188 opt = Option.HELP;
189 break;
190 case 'v':
191 opt = Option.VERSION;
192 break;
193 case 0:
194 opt = Option.values()[g.getLongind()];
195 break;
196 }
197 if (opt != null) {
198 Collection<String> values = argMap.get(opt);
199 if (values == null) {
200 values = new ArrayList<String>();
201 argMap.put(opt, values);
202 }
203 values.add(g.getOptarg());
204 } else
205 throw new IllegalArgumentException();
206 }
207 // positional arguments are a shortcut for the --download ... option
208 for (int i = g.getOptind(); i < args.length; ++i) {
209 Collection<String> values = argMap.get(Option.DOWNLOAD);
210 if (values == null) {
211 values = new ArrayList<String>();
212 argMap.put(Option.DOWNLOAD, values);
213 }
214 values.add(args[i]);
215 }
216
217 return argMap;
218 }
219
220 /**
221 * Main application Startup
222 */
223 public static void main(final String[] argArray) {
224 I18n.init();
225 Main.checkJava6();
226 Main.pref = new Preferences();
227
228 Policy.setPolicy(new Policy() {
229 // Permissions for plug-ins loaded when josm is started via webstart
230 private PermissionCollection pc;
231
232 {
233 pc = new Permissions();
234 pc.add(new AllPermission());
235 }
236
237 @Override
238 public void refresh() { }
239
240 @Override
241 public PermissionCollection getPermissions(CodeSource codesource) {
242 return pc;
243 }
244 });
245
246 Thread.setDefaultUncaughtExceptionHandler(new BugReportExceptionHandler());
247 // http://stuffthathappens.com/blog/2007/10/15/one-more-note-on-uncaught-exception-handlers/
248 System.setProperty("sun.awt.exception.handler", BugReportExceptionHandler.class.getName());
249
250 // initialize the platform hook, and
251 Main.determinePlatformHook();
252 // call the really early hook before we do anything else
253 Main.platform.preStartupHook();
254
255 // construct argument table
256 Map<Option, Collection<String>> args = null;
257 try {
258 args = buildCommandLineArgumentMap(argArray);
259 } catch (IllegalArgumentException e) {
260 System.exit(1);
261 }
262
263 if (args.containsKey(Option.VERSION)) {
264 System.out.println(Version.getInstance().getAgentString());
265 System.exit(0);
266 } else {
267 System.out.println(Version.getInstance().getReleaseAttributes());
268 }
269
270 Main.pref.init(args.containsKey(Option.RESET_PREFERENCES));
271
272 // Check if passed as parameter
273 if (args.containsKey(Option.LANGUAGE)) {
274 I18n.set(args.get(Option.LANGUAGE).iterator().next());
275 } else {
276 I18n.set(Main.pref.get("language", null));
277 }
278 Main.pref.updateSystemProperties();
279
280 JFrame mainFrame = new JFrame(tr("Java OpenStreetMap Editor"));
281 Main.parent = mainFrame;
282
283 if (args.containsKey(Option.LOAD_PREFERENCES)) {
284 CustomConfigurator.XMLCommandProcessor config = new CustomConfigurator.XMLCommandProcessor(Main.pref);
285 for (String i : args.get(Option.LOAD_PREFERENCES)) {
286 System.out.println("Reading preferences from " + i);
287 try {
288 URL url = new URL(i);
289 config.openAndReadXML(url.openStream());
290 } catch (Exception ex) {
291 throw new RuntimeException(ex);
292 }
293 }
294 }
295
296 if (args.containsKey(Option.SET)) {
297 for (String i : args.get(Option.SET)) {
298 String[] kv = i.split("=", 2);
299 Main.pref.put(kv[0], "null".equals(kv[1]) ? null : kv[1]);
300 }
301 }
302
303 DefaultAuthenticator.createInstance();
304 Authenticator.setDefault(DefaultAuthenticator.getInstance());
305 ProxySelector.setDefault(new DefaultProxySelector(ProxySelector.getDefault()));
306 OAuthAccessTokenHolder.getInstance().init(Main.pref, CredentialsManager.getInstance());
307
308 // asking for help? show help and exit
309 if (args.containsKey(Option.HELP)) {
310 showHelp();
311 System.exit(0);
312 }
313
314 SplashScreen splash = new SplashScreen();
315 final ProgressMonitor monitor = splash.getProgressMonitor();
316 monitor.beginTask(tr("Initializing"));
317 splash.setVisible(Main.pref.getBoolean("draw.splashscreen", true));
318 Main.setInitStatusListener(new InitStatusListener() {
319
320 @Override
321 public void updateStatus(String event) {
322 monitor.indeterminateSubTask(event);
323 }
324 });
325
326 List<PluginInformation> pluginsToLoad = PluginHandler.buildListOfPluginsToLoad(splash,monitor.createSubTaskMonitor(1, false));
327 if (!pluginsToLoad.isEmpty() && PluginHandler.checkAndConfirmPluginUpdate(splash)) {
328 monitor.subTask(tr("Updating plugins"));
329 pluginsToLoad = PluginHandler.updatePlugins(splash,pluginsToLoad, monitor.createSubTaskMonitor(1, false));
330 }
331
332 monitor.indeterminateSubTask(tr("Installing updated plugins"));
333 PluginHandler.installDownloadedPlugins(true);
334
335 monitor.indeterminateSubTask(tr("Loading early plugins"));
336 PluginHandler.loadEarlyPlugins(splash,pluginsToLoad, monitor.createSubTaskMonitor(1, false));
337
338 monitor.indeterminateSubTask(tr("Setting defaults"));
339 preConstructorInit(args);
340
341 monitor.indeterminateSubTask(tr("Creating main GUI"));
342 Main.addListener();
343 final Main main = new MainApplication(mainFrame);
344
345 monitor.indeterminateSubTask(tr("Loading plugins"));
346 PluginHandler.loadLatePlugins(splash,pluginsToLoad, monitor.createSubTaskMonitor(1, false));
347 toolbar.refreshToolbarControl();
348 splash.setVisible(false);
349 splash.dispose();
350 mainFrame.setVisible(true);
351
352 boolean maximized = Boolean.parseBoolean(Main.pref.get("gui.maximized"));
353 if ((!args.containsKey(Option.NO_MAXIMIZE) && maximized) || args.containsKey(Option.MAXIMIZE)) {
354 if (Toolkit.getDefaultToolkit().isFrameStateSupported(JFrame.MAXIMIZED_BOTH)) {
355 // Main.debug("Main window maximized");
356 Main.windowState = JFrame.MAXIMIZED_BOTH;
357 mainFrame.setExtendedState(Main.windowState);
358 } else {
359 Main.debug("Main window: maximizing not supported");
360 }
361 } else {
362 // Main.debug("Main window not maximized");
363 }
364 if(main.menu.fullscreenToggleAction != null) {
365 main.menu.fullscreenToggleAction.initial();
366 }
367
368 final Map<Option, Collection<String>> args_final = args;
369
370 SwingUtilities.invokeLater(new Runnable() {
371 public void run() {
372 if (AutosaveTask.PROP_AUTOSAVE_ENABLED.get()) {
373 AutosaveTask autosaveTask = new AutosaveTask();
374 List<File> unsavedLayerFiles = autosaveTask.getUnsavedLayersFiles();
375 if (!unsavedLayerFiles.isEmpty()) {
376 ExtendedDialog dialog = new ExtendedDialog(
377 Main.parent,
378 tr("Unsaved osm data"),
379 new String[] {tr("Restore"), tr("Cancel"), tr("Discard")}
380 );
381 dialog.setContent(
382 trn("JOSM found {0} unsaved osm data layer. ",
383 "JOSM found {0} unsaved osm data layers. ", unsavedLayerFiles.size(), unsavedLayerFiles.size()) +
384 tr("It looks like JOSM crashed last time. Would you like to restore the data?"));
385 dialog.setButtonIcons(new String[] {"ok", "cancel", "dialogs/remove"});
386 int selection = dialog.showDialog().getValue();
387 if (selection == 1) {
388 autosaveTask.recoverUnsavedLayers();
389 } else if (selection == 3) {
390 autosaveTask.dicardUnsavedLayers();
391 }
392 }
393 autosaveTask.schedule();
394 }
395
396 main.postConstructorProcessCmdLine(args_final);
397
398 DownloadDialog.autostartIfNeeded();
399 }
400 });
401
402 if (RemoteControl.PROP_REMOTECONTROL_ENABLED.get()) {
403 RemoteControl.start();
404 }
405
406 if (Main.pref.getBoolean("debug.edt-checker.enable", Version.getInstance().isLocalBuild())) {
407 // Repaint manager is registered so late for a reason - there is lots of violation during startup process but they don't seem to break anything and are difficult to fix
408 System.out.println("Enabled EDT checker, wrongful access to gui from non EDT thread will be printed to console");
409 RepaintManager.setCurrentManager(new CheckThreadViolationRepaintManager());
410 }
411 }
412}
Note: See TracBrowser for help on using the repository browser.