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

Last change on this file since 5831 was 5831, checked in by Don-vip, 11 years ago

see #8571 - Include command-line arguments in status report

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