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

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

fix some Findbugs warnings

  • Property svn:eol-style set to native
File size: 29.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6import gnu.getopt.Getopt;
7import gnu.getopt.LongOpt;
8
9import java.awt.Dimension;
10import java.awt.Image;
11import java.awt.Toolkit;
12import java.awt.event.WindowAdapter;
13import java.awt.event.WindowEvent;
14import java.io.File;
15import java.io.IOException;
16import java.io.InputStream;
17import java.net.Authenticator;
18import java.net.Inet6Address;
19import java.net.InetAddress;
20import java.net.ProxySelector;
21import java.net.URL;
22import java.security.AllPermission;
23import java.security.CodeSource;
24import java.security.KeyStoreException;
25import java.security.NoSuchAlgorithmException;
26import java.security.PermissionCollection;
27import java.security.Permissions;
28import java.security.Policy;
29import java.security.cert.CertificateException;
30import java.util.ArrayList;
31import java.util.Arrays;
32import java.util.Collection;
33import java.util.HashMap;
34import java.util.LinkedList;
35import java.util.List;
36import java.util.Map;
37import java.util.Set;
38import java.util.TreeSet;
39
40import javax.swing.JFrame;
41import javax.swing.JOptionPane;
42import javax.swing.RepaintManager;
43import javax.swing.SwingUtilities;
44
45import org.jdesktop.swinghelper.debug.CheckThreadViolationRepaintManager;
46import org.openstreetmap.josm.Main;
47import org.openstreetmap.josm.actions.PreferencesAction;
48import org.openstreetmap.josm.data.AutosaveTask;
49import org.openstreetmap.josm.data.CustomConfigurator;
50import org.openstreetmap.josm.data.Version;
51import org.openstreetmap.josm.gui.download.DownloadDialog;
52import org.openstreetmap.josm.gui.preferences.server.OAuthAccessTokenHolder;
53import org.openstreetmap.josm.gui.preferences.server.ProxyPreference;
54import org.openstreetmap.josm.gui.progress.ProgressMonitor;
55import org.openstreetmap.josm.gui.util.GuiHelper;
56import org.openstreetmap.josm.io.DefaultProxySelector;
57import org.openstreetmap.josm.io.MessageNotifier;
58import org.openstreetmap.josm.io.OnlineResource;
59import org.openstreetmap.josm.io.auth.CredentialsManager;
60import org.openstreetmap.josm.io.auth.DefaultAuthenticator;
61import org.openstreetmap.josm.io.remotecontrol.RemoteControl;
62import org.openstreetmap.josm.plugins.PluginHandler;
63import org.openstreetmap.josm.plugins.PluginInformation;
64import org.openstreetmap.josm.tools.BugReportExceptionHandler;
65import org.openstreetmap.josm.tools.FontsManager;
66import org.openstreetmap.josm.tools.I18n;
67import org.openstreetmap.josm.tools.ImageProvider;
68import org.openstreetmap.josm.tools.OsmUrlToBounds;
69import org.openstreetmap.josm.tools.PlatformHookWindows;
70import org.openstreetmap.josm.tools.Utils;
71
72/**
73 * Main window class application.
74 *
75 * @author imi
76 */
77public class MainApplication extends Main {
78 /**
79 * Allow subclassing (see JOSM.java)
80 */
81 public MainApplication() {}
82
83 /**
84 * Constructs a main frame, ready sized and operating. Does not display the frame.
85 * @param mainFrame The main JFrame of the application
86 */
87 public MainApplication(JFrame mainFrame) {
88 addListener();
89 mainFrame.setContentPane(contentPanePrivate);
90 mainFrame.setJMenuBar(menu);
91 geometry.applySafe(mainFrame);
92 List<Image> l = new LinkedList<>();
93 l.add(ImageProvider.get("logo_16x16x32").getImage());
94 l.add(ImageProvider.get("logo_16x16x8").getImage());
95 l.add(ImageProvider.get("logo_32x32x32").getImage());
96 l.add(ImageProvider.get("logo_32x32x8").getImage());
97 l.add(ImageProvider.get("logo_48x48x32").getImage());
98 l.add(ImageProvider.get("logo_48x48x8").getImage());
99 l.add(ImageProvider.get("logo").getImage());
100 mainFrame.setIconImages(l);
101 mainFrame.addWindowListener(new WindowAdapter(){
102 @Override
103 public void windowClosing(final WindowEvent arg0) {
104 Main.exitJosm(true, 0);
105 }
106 });
107 mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
108 }
109
110 /**
111 * Displays help on the console
112 * @since 2748
113 */
114 public static void showHelp() {
115 // TODO: put in a platformHook for system that have no console by default
116 System.out.println(tr("Java OpenStreetMap Editor")+" ["
117 +Version.getInstance().getAgentString()+"]\n\n"+
118 tr("usage")+":\n"+
119 "\tjava -jar josm.jar <options>...\n\n"+
120 tr("options")+":\n"+
121 "\t--help|-h "+tr("Show this help")+"\n"+
122 "\t--geometry=widthxheight(+|-)x(+|-)y "+tr("Standard unix geometry argument")+"\n"+
123 "\t[--download=]minlat,minlon,maxlat,maxlon "+tr("Download the bounding box")+"\n"+
124 "\t[--download=]<URL> "+tr("Download the location at the URL (with lat=x&lon=y&zoom=z)")+"\n"+
125 "\t[--download=]<filename> "+tr("Open a file (any file type that can be opened with File/Open)")+"\n"+
126 "\t--downloadgps=minlat,minlon,maxlat,maxlon "+tr("Download the bounding box as raw GPS")+"\n"+
127 "\t--downloadgps=<URL> "+tr("Download the location at the URL (with lat=x&lon=y&zoom=z) as raw GPS")+"\n"+
128 "\t--selection=<searchstring> "+tr("Select with the given search")+"\n"+
129 "\t--[no-]maximize "+tr("Launch in maximized mode")+"\n"+
130 "\t--reset-preferences "+tr("Reset the preferences to default")+"\n\n"+
131 "\t--load-preferences=<url-to-xml> "+tr("Changes preferences according to the XML file")+"\n\n"+
132 "\t--set=<key>=<value> "+tr("Set preference key to value")+"\n\n"+
133 "\t--language=<language> "+tr("Set the language")+"\n\n"+
134 "\t--version "+tr("Displays the JOSM version and exits")+"\n\n"+
135 "\t--debug "+tr("Print debugging messages to console")+"\n\n"+
136 "\t--skip-plugins "+tr("Skip loading plugins")+"\n\n"+
137 "\t--offline=<osm_api|josm_website|all> "+tr("Disable access to the given resource(s), separated by comma")+"\n\n"+
138 tr("options provided as Java system properties")+":\n"+
139 "\t-Djosm.pref=" +tr("/PATH/TO/JOSM/PREF ")+tr("Set the preferences directory")+"\n\n"+
140 "\t-Djosm.userdata="+tr("/PATH/TO/JOSM/USERDATA")+tr("Set the user data directory")+"\n\n"+
141 "\t-Djosm.cache=" +tr("/PATH/TO/JOSM/CACHE ")+tr("Set the cache directory")+"\n\n"+
142 "\t-Djosm.home=" +tr("/PATH/TO/JOSM/HOMEDIR ")+
143 tr("Relocate all 3 directories to homedir. Cache directory will be in homedir/cache")+"\n\n"+
144 tr("-Djosm.home has lower precedence, i.e. the specific setting overrides the general one")+"\n\n"+
145 tr("note: For some tasks, JOSM needs a lot of memory. It can be necessary to add the following\n" +
146 " Java option to specify the maximum size of allocated memory in megabytes")+":\n"+
147 "\t-Xmx...m\n\n"+
148 tr("examples")+":\n"+
149 "\tjava -jar josm.jar track1.gpx track2.gpx london.osm\n"+
150 "\tjava -jar josm.jar "+OsmUrlToBounds.getURL(43.2, 11.1, 13)+"\n"+
151 "\tjava -jar josm.jar london.osm --selection=http://www.ostertag.name/osm/OSM_errors_node-duplicate.xml\n"+
152 "\tjava -jar josm.jar 43.2,11.1,43.4,11.4\n"+
153 "\tjava -Djosm.pref=$XDG_CONFIG_HOME -Djosm.userdata=$XDG_DATA_HOME -Djosm.cache=$XDG_CACHE_HOME -jar josm.jar\n"+
154 "\tjava -Djosm.home=/home/user/.josm_dev -jar josm.jar\n"+
155 "\tjava -Xmx1024m -jar josm.jar\n\n"+
156 tr("Parameters --download, --downloadgps, and --selection are processed in this order.")+"\n"+
157 tr("Make sure you load some data if you use --selection.")+"\n"
158 );
159 }
160
161 /**
162 * JOSM command line options.
163 * @see <a href="https://josm.openstreetmap.de/wiki/Help/CommandLineOptions">Help/CommandLineOptions</a>
164 * @since 5279
165 */
166 public enum Option {
167 /** --help|-h Show this help */
168 HELP(false),
169 /** --version Displays the JOSM version and exits */
170 VERSION(false),
171 /** --debug Print debugging messages to console */
172 DEBUG(false),
173 /** --trace Print detailed debugging messages to console */
174 TRACE(false),
175 /** --language=&lt;language&gt; Set the language */
176 LANGUAGE(true),
177 /** --reset-preferences Reset the preferences to default */
178 RESET_PREFERENCES(false),
179 /** --load-preferences=&lt;url-to-xml&gt; Changes preferences according to the XML file */
180 LOAD_PREFERENCES(true),
181 /** --set=&lt;key&gt;=&lt;value&gt; Set preference key to value */
182 SET(true),
183 /** --geometry=widthxheight(+|-)x(+|-)y Standard unix geometry argument */
184 GEOMETRY(true),
185 /** --no-maximize Do not launch in maximized mode */
186 NO_MAXIMIZE(false),
187 /** --maximize Launch in maximized mode */
188 MAXIMIZE(false),
189 /** --download=minlat,minlon,maxlat,maxlon Download the bounding box <br>
190 * --download=&lt;URL&gt; Download the location at the URL (with lat=x&amp;lon=y&amp;zoom=z) <br>
191 * --download=&lt;filename&gt; Open a file (any file type that can be opened with File/Open) */
192 DOWNLOAD(true),
193 /** --downloadgps=minlat,minlon,maxlat,maxlon Download the bounding box as raw GPS <br>
194 * --downloadgps=&lt;URL&gt; Download the location at the URL (with lat=x&amp;lon=y&amp;zoom=z) as raw GPS */
195 DOWNLOADGPS(true),
196 /** --selection=&lt;searchstring&gt; Select with the given search */
197 SELECTION(true),
198 /** --offline=&lt;osm_api|josm_website|all&gt; Disable access to the given resource(s), delimited by comma */
199 OFFLINE(true),
200 /** --skip-plugins */
201 SKIP_PLUGINS(false),
202 ;
203
204 private final String name;
205 private final boolean requiresArg;
206
207 private Option(boolean requiresArgument) {
208 this.name = name().toLowerCase().replace("_", "-");
209 this.requiresArg = requiresArgument;
210 }
211
212 /**
213 * Replies the option name
214 * @return The option name, in lowercase
215 */
216 public String getName() {
217 return name;
218 }
219
220 /**
221 * Determines if this option requires an argument.
222 * @return {@code true} if this option requires an argument, {@code false} otherwise
223 */
224 public boolean requiresArgument() {
225 return requiresArg;
226 }
227
228 public static Map<Option, Collection<String>> fromStringMap(Map<String, Collection<String>> opts) {
229 Map<Option, Collection<String>> res = new HashMap<>();
230 for (Map.Entry<String, Collection<String>> e : opts.entrySet()) {
231 Option o = Option.valueOf(e.getKey().toUpperCase().replace("-", "_"));
232 if (o != null) {
233 res.put(o, e.getValue());
234 }
235 }
236 return res;
237 }
238 }
239
240 private static Map<Option, Collection<String>> buildCommandLineArgumentMap(String[] args) {
241
242 List<LongOpt> los = new ArrayList<>();
243 for (Option o : Option.values()) {
244 los.add(new LongOpt(o.getName(), o.requiresArgument() ? LongOpt.REQUIRED_ARGUMENT : LongOpt.NO_ARGUMENT, null, 0));
245 }
246
247 Getopt g = new Getopt("JOSM", args, "hv", los.toArray(new LongOpt[los.size()]));
248
249 Map<Option, Collection<String>> argMap = new HashMap<>();
250
251 int c;
252 while ((c = g.getopt()) != -1 ) {
253 Option opt = null;
254 switch (c) {
255 case 'h':
256 opt = Option.HELP;
257 break;
258 case 'v':
259 opt = Option.VERSION;
260 break;
261 case 0:
262 opt = Option.values()[g.getLongind()];
263 break;
264 }
265 if (opt != null) {
266 Collection<String> values = argMap.get(opt);
267 if (values == null) {
268 values = new ArrayList<>();
269 argMap.put(opt, values);
270 }
271 values.add(g.getOptarg());
272 } else
273 throw new IllegalArgumentException("Invalid option: "+c);
274 }
275 // positional arguments are a shortcut for the --download ... option
276 for (int i = g.getOptind(); i < args.length; ++i) {
277 Collection<String> values = argMap.get(Option.DOWNLOAD);
278 if (values == null) {
279 values = new ArrayList<>();
280 argMap.put(Option.DOWNLOAD, values);
281 }
282 values.add(args[i]);
283 }
284
285 return argMap;
286 }
287
288 /**
289 * Main application Startup
290 * @param argArray Command-line arguments
291 */
292 public static void main(final String[] argArray) {
293 I18n.init();
294 Main.checkJavaVersion();
295
296 // construct argument table
297 Map<Option, Collection<String>> args = null;
298 try {
299 args = buildCommandLineArgumentMap(argArray);
300 } catch (IllegalArgumentException e) {
301 System.exit(1);
302 return;
303 }
304
305 final boolean languageGiven = args.containsKey(Option.LANGUAGE);
306
307 if (languageGiven) {
308 I18n.set(args.get(Option.LANGUAGE).iterator().next());
309 }
310
311 initApplicationPreferences();
312
313 Policy.setPolicy(new Policy() {
314 // Permissions for plug-ins loaded when josm is started via webstart
315 private PermissionCollection pc;
316
317 {
318 pc = new Permissions();
319 pc.add(new AllPermission());
320 }
321
322 @Override
323 public void refresh() { }
324
325 @Override
326 public PermissionCollection getPermissions(CodeSource codesource) {
327 return pc;
328 }
329 });
330
331 Thread.setDefaultUncaughtExceptionHandler(new BugReportExceptionHandler());
332
333 // initialize the platform hook, and
334 Main.determinePlatformHook();
335 // call the really early hook before we do anything else
336 Main.platform.preStartupHook();
337
338 Main.COMMAND_LINE_ARGS.addAll(Arrays.asList(argArray));
339
340 if (args.containsKey(Option.VERSION)) {
341 System.out.println(Version.getInstance().getAgentString());
342 System.exit(0);
343 }
344
345 if (args.containsKey(Option.DEBUG) || args.containsKey(Option.TRACE)) {
346 // Enable JOSM debug level
347 logLevel = 4;
348 Main.info(tr("Printing debugging messages to console"));
349 }
350
351 boolean skipLoadingPlugins = false;
352 if (args.containsKey(Option.SKIP_PLUGINS)) {
353 skipLoadingPlugins = true;
354 Main.info(tr("Plugin loading skipped"));
355 }
356
357 if (args.containsKey(Option.TRACE)) {
358 // Enable JOSM debug level
359 logLevel = 5;
360 // Enable debug in OAuth signpost via system preference, but only at trace level
361 Utils.updateSystemProperty("debug", "true");
362 Main.info(tr("Enabled detailed debug level (trace)"));
363 }
364
365 Main.pref.init(args.containsKey(Option.RESET_PREFERENCES));
366
367 if (args.containsKey(Option.SET)) {
368 for (String i : args.get(Option.SET)) {
369 String[] kv = i.split("=", 2);
370 Main.pref.put(kv[0], "null".equals(kv[1]) ? null : kv[1]);
371 }
372 }
373
374 if (!languageGiven) {
375 I18n.set(Main.pref.get("language", null));
376 }
377 Main.pref.updateSystemProperties();
378
379 checkIPv6();
380
381 // asking for help? show help and exit
382 if (args.containsKey(Option.HELP)) {
383 showHelp();
384 System.exit(0);
385 }
386
387 processOffline(args);
388
389 Main.platform.afterPrefStartupHook();
390
391 FontsManager.initialize();
392
393 I18n.setupLanguageFonts();
394
395 final JFrame mainFrame = new JFrame(tr("Java OpenStreetMap Editor"));
396 Main.parent = mainFrame;
397
398 if (args.containsKey(Option.LOAD_PREFERENCES)) {
399 CustomConfigurator.XMLCommandProcessor config = new CustomConfigurator.XMLCommandProcessor(Main.pref);
400 for (String i : args.get(Option.LOAD_PREFERENCES)) {
401 info("Reading preferences from " + i);
402 try (InputStream is = Utils.openURL(new URL(i))) {
403 config.openAndReadXML(is);
404 } catch (Exception ex) {
405 throw new RuntimeException(ex);
406 }
407 }
408 }
409
410 DefaultAuthenticator.createInstance();
411 Authenticator.setDefault(DefaultAuthenticator.getInstance());
412 DefaultProxySelector proxySelector = new DefaultProxySelector(ProxySelector.getDefault());
413 ProxySelector.setDefault(proxySelector);
414 OAuthAccessTokenHolder.getInstance().init(Main.pref, CredentialsManager.getInstance());
415
416 final SplashScreen splash = new SplashScreen();
417 final ProgressMonitor monitor = splash.getProgressMonitor();
418 monitor.beginTask(tr("Initializing"));
419 splash.setVisible(Main.pref.getBoolean("draw.splashscreen", true));
420 Main.setInitStatusListener(new InitStatusListener() {
421
422 @Override
423 public void updateStatus(String event) {
424 monitor.indeterminateSubTask(event);
425 }
426 });
427
428 Collection<PluginInformation> pluginsToLoad = null;
429
430
431 if (!skipLoadingPlugins) {
432 pluginsToLoad = PluginHandler.buildListOfPluginsToLoad(splash, monitor.createSubTaskMonitor(1, false));
433 if (!pluginsToLoad.isEmpty() && PluginHandler.checkAndConfirmPluginUpdate(splash)) {
434 monitor.subTask(tr("Updating plugins"));
435 pluginsToLoad = PluginHandler.updatePlugins(splash, null, monitor.createSubTaskMonitor(1, false), false);
436 }
437
438 monitor.indeterminateSubTask(tr("Installing updated plugins"));
439 PluginHandler.installDownloadedPlugins(true);
440
441 monitor.indeterminateSubTask(tr("Loading early plugins"));
442 PluginHandler.loadEarlyPlugins(splash, pluginsToLoad, monitor.createSubTaskMonitor(1, false));
443 }
444
445 monitor.indeterminateSubTask(tr("Setting defaults"));
446 preConstructorInit(args);
447
448 monitor.indeterminateSubTask(tr("Creating main GUI"));
449 final Main main = new MainApplication(mainFrame);
450
451 if (!skipLoadingPlugins) {
452 monitor.indeterminateSubTask(tr("Loading plugins"));
453 PluginHandler.loadLatePlugins(splash, pluginsToLoad, monitor.createSubTaskMonitor(1, false));
454 toolbar.refreshToolbarControl();
455 }
456
457 // Wait for splash disappearance (fix #9714)
458 GuiHelper.runInEDTAndWait(new Runnable() {
459 @Override
460 public void run() {
461 splash.setVisible(false);
462 splash.dispose();
463 mainFrame.setVisible(true);
464 main.gettingStarted.requestFocusInWindow();
465 }
466 });
467
468 Main.MasterWindowListener.setup();
469
470 boolean maximized = Main.pref.getBoolean("gui.maximized", false);
471 if ((!args.containsKey(Option.NO_MAXIMIZE) && maximized) || args.containsKey(Option.MAXIMIZE)) {
472 if (Toolkit.getDefaultToolkit().isFrameStateSupported(JFrame.MAXIMIZED_BOTH)) {
473 Main.windowState = JFrame.MAXIMIZED_BOTH;
474 mainFrame.setExtendedState(Main.windowState);
475 } else {
476 Main.debug("Main window: maximizing not supported");
477 }
478 }
479 if (main.menu.fullscreenToggleAction != null) {
480 main.menu.fullscreenToggleAction.initial();
481 }
482
483 SwingUtilities.invokeLater(new GuiFinalizationWorker(args, proxySelector));
484
485 if (Main.isPlatformWindows()) {
486 try {
487 // Check for insecure certificates to remove.
488 // This is Windows-dependant code but it can't go to preStartupHook (need i18n) neither startupHook (need to be called before remote control)
489 PlatformHookWindows.removeInsecureCertificates();
490 } catch (NoSuchAlgorithmException | CertificateException | KeyStoreException | IOException e) {
491 error(e);
492 }
493 }
494
495 if (RemoteControl.PROP_REMOTECONTROL_ENABLED.get()) {
496 RemoteControl.start();
497 }
498
499 if (MessageNotifier.PROP_NOTIFIER_ENABLED.get()) {
500 MessageNotifier.start();
501 }
502
503 if (Main.pref.getBoolean("debug.edt-checker.enable", Version.getInstance().isLocalBuild())) {
504 // 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
505 info("Enabled EDT checker, wrongful access to gui from non EDT thread will be printed to console");
506 RepaintManager.setCurrentManager(new CheckThreadViolationRepaintManager());
507 }
508 }
509
510 private static void processOffline(Map<Option, Collection<String>> args) {
511 if (args.containsKey(Option.OFFLINE)) {
512 for (String s : args.get(Option.OFFLINE).iterator().next().split(",")) {
513 try {
514 Main.setOffline(OnlineResource.valueOf(s.toUpperCase()));
515 } catch (IllegalArgumentException e) {
516 Main.error(tr("''{0}'' is not a valid value for argument ''{1}''. Possible values are {2}, possibly delimited by commas.",
517 s.toUpperCase(), Option.OFFLINE.getName(), Arrays.toString(OnlineResource.values())));
518 System.exit(1);
519 return;
520 }
521 }
522 Set<OnlineResource> offline = Main.getOfflineResources();
523 if (!offline.isEmpty()) {
524 Main.warn(trn("JOSM is running in offline mode. This resource will not be available: {0}",
525 "JOSM is running in offline mode. These resources will not be available: {0}",
526 offline.size(), offline.size() == 1 ? offline.iterator().next() : Arrays.toString(offline.toArray())));
527 }
528 }
529 }
530
531 /**
532 * Check if IPv6 can be safely enabled and do so. Because this cannot be done after network activation,
533 * disabling or enabling IPV6 may only be done with next start.
534 */
535 private static void checkIPv6() {
536 if("auto".equals(Main.pref.get("prefer.ipv6", "auto"))) {
537 new Thread(new Runnable() { /* this may take some time (DNS, Connect) */
538 public void run() {
539 boolean hasv6 = false;
540 boolean wasv6 = Main.pref.getBoolean("validated.ipv6", false);
541 try {
542 /* Use the check result from last run of the software, as after the test, value
543 changes have no effect anymore */
544 if(wasv6) {
545 Utils.updateSystemProperty("java.net.preferIPv6Addresses", "true");
546 }
547 for(InetAddress a : InetAddress.getAllByName("josm.openstreetmap.de")) {
548 if(a instanceof Inet6Address) {
549 if(a.isReachable(1000)) {
550 Utils.updateSystemProperty("java.net.preferIPv6Addresses", "true");
551 if(!wasv6) {
552 Main.info(tr("Detected useable IPv6 network, prefering IPv6 over IPv4 after next restart."));
553 } else {
554 Main.info(tr("Detected useable IPv6 network, prefering IPv6 over IPv4."));
555 }
556 hasv6 = true;
557 }
558 break; /* we're done */
559 }
560 }
561 } catch (IOException | SecurityException e) {
562 if (Main.isDebugEnabled()) {
563 Main.debug("Exception while checking IPv6 connectivity: "+e);
564 }
565 }
566 if(wasv6 && !hasv6) {
567 Main.info(tr("Detected no useable IPv6 network, prefering IPv4 over IPv6 after next restart."));
568 }
569 Main.pref.put("validated.ipv6", hasv6);
570 }
571 }).start();
572 }
573 }
574
575 private static class GuiFinalizationWorker implements Runnable {
576
577 private final Map<Option, Collection<String>> args;
578 private final DefaultProxySelector proxySelector;
579
580 public GuiFinalizationWorker(Map<Option, Collection<String>> args, DefaultProxySelector proxySelector) {
581 this.args = args;
582 this.proxySelector = proxySelector;
583 }
584
585 @Override
586 public void run() {
587
588 // Handle proxy/network errors early to inform user he should change settings to be able to use JOSM correctly
589 if (!handleProxyErrors()) {
590 handleNetworkErrors();
591 }
592
593 // Restore autosave layers after crash and start autosave thread
594 handleAutosave();
595
596 // Handle command line instructions
597 postConstructorProcessCmdLine(args);
598
599 // Show download dialog if autostart is enabled
600 DownloadDialog.autostartIfNeeded();
601 }
602
603 private void handleAutosave() {
604 if (AutosaveTask.PROP_AUTOSAVE_ENABLED.get()) {
605 AutosaveTask autosaveTask = new AutosaveTask();
606 List<File> unsavedLayerFiles = autosaveTask.getUnsavedLayersFiles();
607 if (!unsavedLayerFiles.isEmpty()) {
608 ExtendedDialog dialog = new ExtendedDialog(
609 Main.parent,
610 tr("Unsaved osm data"),
611 new String[] {tr("Restore"), tr("Cancel"), tr("Discard")}
612 );
613 dialog.setContent(
614 trn("JOSM found {0} unsaved osm data layer. ",
615 "JOSM found {0} unsaved osm data layers. ", unsavedLayerFiles.size(), unsavedLayerFiles.size()) +
616 tr("It looks like JOSM crashed last time. Would you like to restore the data?"));
617 dialog.setButtonIcons(new String[] {"ok", "cancel", "dialogs/delete"});
618 int selection = dialog.showDialog().getValue();
619 if (selection == 1) {
620 autosaveTask.recoverUnsavedLayers();
621 } else if (selection == 3) {
622 autosaveTask.discardUnsavedLayers();
623 }
624 }
625 autosaveTask.schedule();
626 }
627 }
628
629 private boolean handleNetworkOrProxyErrors(boolean hasErrors, String title, String message) {
630 if (hasErrors) {
631 ExtendedDialog ed = new ExtendedDialog(
632 Main.parent, title,
633 new String[]{tr("Change proxy settings"), tr("Cancel")});
634 ed.setButtonIcons(new String[]{"dialogs/settings", "cancel"}).setCancelButton(2);
635 ed.setMinimumSize(new Dimension(460, 260));
636 ed.setIcon(JOptionPane.WARNING_MESSAGE);
637 ed.setContent(message);
638
639 if (ed.showDialog().getValue() == 1) {
640 PreferencesAction.forPreferenceSubTab(null, null, ProxyPreference.class).run();
641 }
642 }
643 return hasErrors;
644 }
645
646 private boolean handleProxyErrors() {
647 return handleNetworkOrProxyErrors(proxySelector.hasErrors(), tr("Proxy errors occurred"),
648 tr("JOSM tried to access the following resources:<br>" +
649 "{0}" +
650 "but <b>failed</b> to do so, because of the following proxy errors:<br>" +
651 "{1}" +
652 "Would you like to change your proxy settings now?",
653 Utils.joinAsHtmlUnorderedList(proxySelector.getErrorResources()),
654 Utils.joinAsHtmlUnorderedList(proxySelector.getErrorMessages())
655 ));
656 }
657
658 private boolean handleNetworkErrors() {
659 boolean condition = !NETWORK_ERRORS.isEmpty();
660 if (condition) {
661 Set<String> errors = new TreeSet<>();
662 for (Throwable t : NETWORK_ERRORS.values()) {
663 errors.add(t.toString());
664 }
665 return handleNetworkOrProxyErrors(condition, tr("Network errors occurred"),
666 tr("JOSM tried to access the following resources:<br>" +
667 "{0}" +
668 "but <b>failed</b> to do so, because of the following network errors:<br>" +
669 "{1}" +
670 "It may be due to a missing proxy configuration.<br>" +
671 "Would you like to change your proxy settings now?",
672 Utils.joinAsHtmlUnorderedList(NETWORK_ERRORS.keySet()),
673 Utils.joinAsHtmlUnorderedList(errors)
674 ));
675 }
676 return false;
677 }
678 }
679}
Note: See TracBrowser for help on using the repository browser.