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

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

Rework console output:

  • new log level "error"
  • Replace nearly all calls to system.out and system.err to Main.(error|warn|info|debug)
  • Remove some unnecessary debug output
  • Some messages are modified (removal of "Info", "Warning", "Error" from the message itself -> notable i18n impact but limited to console error messages not seen by the majority of users, so that's ok)
  • Property svn:eol-style set to native
File size: 19.4 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;
6import gnu.getopt.Getopt;
7import gnu.getopt.LongOpt;
8
9import java.awt.Image;
10import java.awt.Toolkit;
11import java.awt.event.WindowAdapter;
12import java.awt.event.WindowEvent;
13import java.io.File;
14import java.net.Authenticator;
15import java.net.ProxySelector;
16import java.net.URL;
17import java.security.AllPermission;
18import java.security.CodeSource;
19import java.security.PermissionCollection;
20import java.security.Permissions;
21import java.security.Policy;
22import java.util.ArrayList;
23import java.util.Collection;
24import java.util.HashMap;
25import java.util.LinkedList;
26import java.util.List;
27import java.util.Map;
28
29import javax.swing.JFrame;
30import javax.swing.RepaintManager;
31import javax.swing.SwingUtilities;
32
33import org.jdesktop.swinghelper.debug.CheckThreadViolationRepaintManager;
34import org.openstreetmap.josm.Main;
35import org.openstreetmap.josm.data.AutosaveTask;
36import org.openstreetmap.josm.data.CustomConfigurator;
37import org.openstreetmap.josm.data.Preferences;
38import org.openstreetmap.josm.data.Version;
39import org.openstreetmap.josm.gui.download.DownloadDialog;
40import org.openstreetmap.josm.gui.preferences.server.OAuthAccessTokenHolder;
41import org.openstreetmap.josm.gui.progress.ProgressMonitor;
42import org.openstreetmap.josm.gui.util.GuiHelper;
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;
52import org.openstreetmap.josm.tools.Utils;
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, 0);
86 }
87 });
88 mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
89 }
90
91 /**
92 * Displays help on the console
93 * @since 2748
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 /**
134 * JOSM command line options.
135 * @see <a href="http://josm.openstreetmap.de/wiki/Help/CommandLineOptions">Help/CommandLineOptions</a>
136 * @since 5279
137 */
138 public enum Option {
139 /** --help|-h Show this help */
140 HELP(false),
141 /** --version Displays the JOSM version and exits */
142 VERSION(false),
143 /** --language=<language> Set the language */
144 LANGUAGE(true),
145 /** --reset-preferences Reset the preferences to default */
146 RESET_PREFERENCES(false),
147 /** --load-preferences=<url-to-xml> Changes preferences according to the XML file */
148 LOAD_PREFERENCES(true),
149 /** --set=<key>=<value> Set preference key to value */
150 SET(true),
151 /** --geometry=widthxheight(+|-)x(+|-)y Standard unix geometry argument */
152 GEOMETRY(true),
153 /** --no-maximize Do not launch in maximized mode */
154 NO_MAXIMIZE(false),
155 /** --maximize Launch in maximized mode */
156 MAXIMIZE(false),
157 /** --download=minlat,minlon,maxlat,maxlon Download the bounding box <br>
158 * --download=<URL> Download the location at the URL (with lat=x&lon=y&zoom=z) <br>
159 * --download=<filename> Open a file (any file type that can be opened with File/Open) */
160 DOWNLOAD(true),
161 /** --downloadgps=minlat,minlon,maxlat,maxlon Download the bounding box as raw GPS <br>
162 * --downloadgps=<URL> Download the location at the URL (with lat=x&lon=y&zoom=z) as raw GPS */
163 DOWNLOADGPS(true),
164 /** --selection=<searchstring> Select with the given search */
165 SELECTION(true);
166
167 private String name;
168 private boolean requiresArgument;
169
170 private Option(boolean requiresArgument) {
171 this.name = name().toLowerCase().replace("_", "-");
172 this.requiresArgument = requiresArgument;
173 }
174
175 /**
176 * Replies the option name
177 * @return The option name, in lowercase
178 */
179 public String getName() {
180 return name;
181 }
182
183 /**
184 * Determines if this option requires an argument.
185 * @return {@code true} if this option requires an argument, {@code false} otherwise
186 */
187 public boolean requiresArgument() {
188 return requiresArgument;
189 }
190
191 public static Map<Option, Collection<String>> fromStringMap(Map<String, Collection<String>> opts) {
192 Map<Option, Collection<String>> res = new HashMap<Option, Collection<String>>();
193 for (Map.Entry<String, Collection<String>> e : opts.entrySet()) {
194 Option o = Option.valueOf(e.getKey().toUpperCase().replace("-", "_"));
195 if (o != null) {
196 res.put(o, e.getValue());
197 }
198 }
199 return res;
200 }
201 }
202
203 private static Map<Option, Collection<String>> buildCommandLineArgumentMap(String[] args) {
204
205 List<LongOpt> los = new ArrayList<LongOpt>();
206 for (Option o : Option.values()) {
207 los.add(new LongOpt(o.getName(), o.requiresArgument() ? LongOpt.REQUIRED_ARGUMENT : LongOpt.NO_ARGUMENT, null, 0));
208 }
209
210 Getopt g = new Getopt("JOSM", args, "hv", los.toArray(new LongOpt[los.size()]));
211
212 Map<Option, Collection<String>> argMap = new HashMap<Option, Collection<String>>();
213
214 int c;
215 while ((c = g.getopt()) != -1 ) {
216 Option opt = null;
217 switch (c) {
218 case 'h':
219 opt = Option.HELP;
220 break;
221 case 'v':
222 opt = Option.VERSION;
223 break;
224 case 0:
225 opt = Option.values()[g.getLongind()];
226 break;
227 }
228 if (opt != null) {
229 Collection<String> values = argMap.get(opt);
230 if (values == null) {
231 values = new ArrayList<String>();
232 argMap.put(opt, values);
233 }
234 values.add(g.getOptarg());
235 } else
236 throw new IllegalArgumentException();
237 }
238 // positional arguments are a shortcut for the --download ... option
239 for (int i = g.getOptind(); i < args.length; ++i) {
240 Collection<String> values = argMap.get(Option.DOWNLOAD);
241 if (values == null) {
242 values = new ArrayList<String>();
243 argMap.put(Option.DOWNLOAD, values);
244 }
245 values.add(args[i]);
246 }
247
248 return argMap;
249 }
250
251 /**
252 * Main application Startup
253 * @param argArray Command-line arguments
254 */
255 public static void main(final String[] argArray) {
256 I18n.init();
257 Main.checkJava6();
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 final boolean languageGiven = args.containsKey(Option.LANGUAGE);
268
269 if (languageGiven) {
270 I18n.set(args.get(Option.LANGUAGE).iterator().next());
271 }
272
273 Main.pref = new Preferences();
274
275 Policy.setPolicy(new Policy() {
276 // Permissions for plug-ins loaded when josm is started via webstart
277 private PermissionCollection pc;
278
279 {
280 pc = new Permissions();
281 pc.add(new AllPermission());
282 }
283
284 @Override
285 public void refresh() { }
286
287 @Override
288 public PermissionCollection getPermissions(CodeSource codesource) {
289 return pc;
290 }
291 });
292
293 Thread.setDefaultUncaughtExceptionHandler(new BugReportExceptionHandler());
294 // http://stuffthathappens.com/blog/2007/10/15/one-more-note-on-uncaught-exception-handlers/
295 System.setProperty("sun.awt.exception.handler", BugReportExceptionHandler.class.getName());
296
297 // initialize the platform hook, and
298 Main.determinePlatformHook();
299 // call the really early hook before we do anything else
300 Main.platform.preStartupHook();
301
302 Main.commandLineArgs = Utils.copyArray(argArray);
303
304 if (args.containsKey(Option.VERSION)) {
305 System.out.println(Version.getInstance().getAgentString());
306 System.exit(0);
307 }
308
309 Main.pref.init(args.containsKey(Option.RESET_PREFERENCES));
310
311 if (!languageGiven) {
312 I18n.set(Main.pref.get("language", null));
313 }
314 Main.pref.updateSystemProperties();
315
316 final JFrame mainFrame = new JFrame(tr("Java OpenStreetMap Editor"));
317 Main.parent = mainFrame;
318
319 if (args.containsKey(Option.LOAD_PREFERENCES)) {
320 CustomConfigurator.XMLCommandProcessor config = new CustomConfigurator.XMLCommandProcessor(Main.pref);
321 for (String i : args.get(Option.LOAD_PREFERENCES)) {
322 info("Reading preferences from " + i);
323 try {
324 config.openAndReadXML(Utils.openURL(new URL(i)));
325 } catch (Exception ex) {
326 throw new RuntimeException(ex);
327 }
328 }
329 }
330
331 if (args.containsKey(Option.SET)) {
332 for (String i : args.get(Option.SET)) {
333 String[] kv = i.split("=", 2);
334 Main.pref.put(kv[0], "null".equals(kv[1]) ? null : kv[1]);
335 }
336 }
337
338 DefaultAuthenticator.createInstance();
339 Authenticator.setDefault(DefaultAuthenticator.getInstance());
340 ProxySelector.setDefault(new DefaultProxySelector(ProxySelector.getDefault()));
341 OAuthAccessTokenHolder.getInstance().init(Main.pref, CredentialsManager.getInstance());
342
343 // asking for help? show help and exit
344 if (args.containsKey(Option.HELP)) {
345 showHelp();
346 System.exit(0);
347 }
348
349 final SplashScreen splash = new SplashScreen();
350 final ProgressMonitor monitor = splash.getProgressMonitor();
351 monitor.beginTask(tr("Initializing"));
352 splash.setVisible(Main.pref.getBoolean("draw.splashscreen", true));
353 Main.setInitStatusListener(new InitStatusListener() {
354
355 @Override
356 public void updateStatus(String event) {
357 monitor.indeterminateSubTask(event);
358 }
359 });
360
361 List<PluginInformation> pluginsToLoad = PluginHandler.buildListOfPluginsToLoad(splash,monitor.createSubTaskMonitor(1, false));
362 if (!pluginsToLoad.isEmpty() && PluginHandler.checkAndConfirmPluginUpdate(splash)) {
363 monitor.subTask(tr("Updating plugins"));
364 pluginsToLoad = PluginHandler.updatePlugins(splash,pluginsToLoad, monitor.createSubTaskMonitor(1, false));
365 }
366
367 monitor.indeterminateSubTask(tr("Installing updated plugins"));
368 PluginHandler.installDownloadedPlugins(true);
369
370 monitor.indeterminateSubTask(tr("Loading early plugins"));
371 PluginHandler.loadEarlyPlugins(splash,pluginsToLoad, monitor.createSubTaskMonitor(1, false));
372
373 monitor.indeterminateSubTask(tr("Setting defaults"));
374 preConstructorInit(args);
375
376 monitor.indeterminateSubTask(tr("Creating main GUI"));
377 final Main main = new MainApplication(mainFrame);
378
379 monitor.indeterminateSubTask(tr("Loading plugins"));
380 PluginHandler.loadLatePlugins(splash,pluginsToLoad, monitor.createSubTaskMonitor(1, false));
381 toolbar.refreshToolbarControl();
382
383 GuiHelper.runInEDT(new Runnable() {
384 @Override
385 public void run() {
386 splash.setVisible(false);
387 splash.dispose();
388 mainFrame.setVisible(true);
389 }
390 });
391
392 Main.MasterWindowListener.setup();
393
394 boolean maximized = Boolean.parseBoolean(Main.pref.get("gui.maximized"));
395 if ((!args.containsKey(Option.NO_MAXIMIZE) && maximized) || args.containsKey(Option.MAXIMIZE)) {
396 if (Toolkit.getDefaultToolkit().isFrameStateSupported(JFrame.MAXIMIZED_BOTH)) {
397 Main.windowState = JFrame.MAXIMIZED_BOTH;
398 mainFrame.setExtendedState(Main.windowState);
399 } else {
400 Main.debug("Main window: maximizing not supported");
401 }
402 }
403 if (main.menu.fullscreenToggleAction != null) {
404 main.menu.fullscreenToggleAction.initial();
405 }
406
407 final Map<Option, Collection<String>> args_final = args;
408
409 SwingUtilities.invokeLater(new Runnable() {
410 @Override
411 public void run() {
412 if (AutosaveTask.PROP_AUTOSAVE_ENABLED.get()) {
413 AutosaveTask autosaveTask = new AutosaveTask();
414 List<File> unsavedLayerFiles = autosaveTask.getUnsavedLayersFiles();
415 if (!unsavedLayerFiles.isEmpty()) {
416 ExtendedDialog dialog = new ExtendedDialog(
417 Main.parent,
418 tr("Unsaved osm data"),
419 new String[] {tr("Restore"), tr("Cancel"), tr("Discard")}
420 );
421 dialog.setContent(
422 trn("JOSM found {0} unsaved osm data layer. ",
423 "JOSM found {0} unsaved osm data layers. ", unsavedLayerFiles.size(), unsavedLayerFiles.size()) +
424 tr("It looks like JOSM crashed last time. Would you like to restore the data?"));
425 dialog.setButtonIcons(new String[] {"ok", "cancel", "dialogs/delete"});
426 int selection = dialog.showDialog().getValue();
427 if (selection == 1) {
428 autosaveTask.recoverUnsavedLayers();
429 } else if (selection == 3) {
430 autosaveTask.dicardUnsavedLayers();
431 }
432 }
433 autosaveTask.schedule();
434 }
435
436 postConstructorProcessCmdLine(args_final);
437
438 DownloadDialog.autostartIfNeeded();
439 }
440 });
441
442 if (RemoteControl.PROP_REMOTECONTROL_ENABLED.get()) {
443 RemoteControl.start();
444 }
445
446 if (Main.pref.getBoolean("debug.edt-checker.enable", Version.getInstance().isLocalBuild())) {
447 // 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
448 info("Enabled EDT checker, wrongful access to gui from non EDT thread will be printed to console");
449 RepaintManager.setCurrentManager(new CheckThreadViolationRepaintManager());
450 }
451 }
452}
Note: See TracBrowser for help on using the repository browser.