source: josm/trunk/src/org/openstreetmap/josm/data/Preferences.java@ 1243

Last change on this file since 1243 was 1243, checked in by stoecker, 15 years ago

restart-warn when changing mappaint colors

  • Property svn:eol-style set to native
File size: 17.8 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.data;
3
4import java.awt.Color;
5import java.io.BufferedReader;
6import java.io.File;
7import java.io.FileReader;
8import java.io.FileWriter;
9import java.io.IOException;
10import java.io.PrintWriter;
11import java.util.ArrayList;
12import java.util.Arrays;
13import java.util.Collection;
14import java.util.Collections;
15import java.util.LinkedList;
16import java.util.Map;
17import java.util.Properties;
18import java.util.SortedMap;
19import java.util.TreeMap;
20import java.util.Map.Entry;
21import java.util.regex.Matcher;
22import java.util.regex.Pattern;
23
24import org.openstreetmap.josm.Main;
25import org.openstreetmap.josm.actions.AboutAction;
26import org.openstreetmap.josm.gui.preferences.ProxyPreferences;
27import org.openstreetmap.josm.tools.ColorHelper;
28
29/**
30 * This class holds all preferences for JOSM.
31 *
32 * Other classes can register their beloved properties here. All properties will be
33 * saved upon set-access.
34 *
35 * @author imi
36 */
37public class Preferences {
38
39 /**
40 * Internal storage for the preferenced directory.
41 * Do not access this variable directly!
42 * @see #getPreferencesDirFile()
43 */
44 private File preferencesDirFile = null;
45
46 public static interface PreferenceChangedListener {
47 void preferenceChanged(String key, String newValue);
48 }
49
50 /**
51 * Class holding one bookmarkentry.
52 * @author imi
53 */
54 public static class Bookmark implements Comparable<Bookmark> {
55 public String name;
56 public double[] latlon = new double[4]; // minlat, minlon, maxlat, maxlon
57 @Override public String toString() {
58 return name;
59 }
60 public int compareTo(Bookmark b) {
61 return name.toLowerCase().compareTo(b.name.toLowerCase());
62 }
63 }
64
65 public final ArrayList<PreferenceChangedListener> listener = new ArrayList<PreferenceChangedListener>();
66
67 /**
68 * Map the property name to the property object.
69 */
70 protected final SortedMap<String, String> properties = new TreeMap<String, String>();
71 protected final SortedMap<String, String> defaults = new TreeMap<String, String>();
72
73 /**
74 * Override some values on read. This is intended to be used for technology previews
75 * where we want to temporarily modify things without changing the user's preferences
76 * file.
77 */
78 protected static final SortedMap<String, String> override = new TreeMap<String, String>();
79 static {
80 //override.put("osm-server.version", "0.5");
81 //override.put("osm-server.additional-versions", "");
82 //override.put("osm-server.url", "http://openstreetmap.gryph.de/api");
83 //override.put("plugins", null);
84 }
85
86 /**
87 * Return the location of the user defined preferences file
88 */
89 public String getPreferencesDir() {
90 final String path = getPreferencesDirFile().getPath();
91 if (path.endsWith(File.separator))
92 return path;
93 return path + File.separator;
94 }
95
96 public File getPreferencesDirFile() {
97 if (preferencesDirFile != null)
98 return preferencesDirFile;
99 String path;
100 path = System.getProperty("josm.home");
101 if (path != null) {
102 preferencesDirFile = new File(path);
103 } else {
104 path = System.getenv("APPDATA");
105 if (path != null) {
106 preferencesDirFile = new File(path, "JOSM");
107 } else {
108 preferencesDirFile = new File(System.getProperty("user.home"), ".josm");
109 }
110 }
111 return preferencesDirFile;
112 }
113
114 public File getPluginsDirFile() {
115 return new File(getPreferencesDirFile(), "plugins");
116 }
117
118 /**
119 * @return A list of all existing directories where resources could be stored.
120 */
121 public Collection<String> getAllPossiblePreferenceDirs() {
122 LinkedList<String> locations = new LinkedList<String>();
123 locations.add(Main.pref.getPreferencesDir());
124 String s;
125 if ((s = System.getenv("JOSM_RESOURCES")) != null) {
126 if (!s.endsWith(File.separator))
127 s = s + File.separator;
128 locations.add(s);
129 }
130 if ((s = System.getProperty("josm.resources")) != null) {
131 if (!s.endsWith(File.separator))
132 s = s + File.separator;
133 locations.add(s);
134 }
135 String appdata = System.getenv("APPDATA");
136 if (System.getenv("ALLUSERSPROFILE") != null && appdata != null
137 && appdata.lastIndexOf(File.separator) != -1) {
138 appdata = appdata.substring(appdata.lastIndexOf(File.separator));
139 locations.add(new File(new File(System.getenv("ALLUSERSPROFILE"),
140 appdata), "JOSM").getPath());
141 }
142 locations.add("/usr/local/share/josm/");
143 locations.add("/usr/local/lib/josm/");
144 locations.add("/usr/share/josm/");
145 locations.add("/usr/lib/josm/");
146 return locations;
147 }
148
149 synchronized public boolean hasKey(final String key) {
150 return override.containsKey(key) ? override.get(key) != null : properties.containsKey(key);
151 }
152
153 synchronized public String get(final String key) {
154 putDefault(key, null);
155 if (override.containsKey(key))
156 return override.get(key);
157 if (!properties.containsKey(key))
158 return "";
159 return properties.get(key);
160 }
161
162 synchronized public String get(final String key, final String def) {
163 putDefault(key, def);
164 if (override.containsKey(key))
165 return override.get(key);
166 final String prop = properties.get(key);
167 if (prop == null || prop.equals(""))
168 return def;
169 return prop;
170 }
171
172 synchronized public Map<String, String> getAllPrefix(final String prefix) {
173 final Map<String,String> all = new TreeMap<String,String>();
174 for (final Entry<String,String> e : properties.entrySet())
175 if (e.getKey().startsWith(prefix))
176 all.put(e.getKey(), e.getValue());
177 for (final Entry<String,String> e : override.entrySet())
178 if (e.getKey().startsWith(prefix))
179 if (e.getValue() == null)
180 all.remove(e.getKey());
181 else
182 all.put(e.getKey(), e.getValue());
183 return all;
184 }
185
186 synchronized public TreeMap<String, String> getAllColors() {
187 final TreeMap<String,String> all = new TreeMap<String,String>();
188 for (final Entry<String,String> e : defaults.entrySet())
189 if (e.getKey().startsWith("color.") && e.getValue() != null)
190 all.put(e.getKey().substring(6), e.getValue());
191 for (final Entry<String,String> e : properties.entrySet())
192 if (e.getKey().startsWith("color."))
193 all.put(e.getKey().substring(6), e.getValue());
194 for (final Entry<String,String> e : override.entrySet())
195 if (e.getKey().startsWith("color."))
196 if (e.getValue() == null)
197 all.remove(e.getKey().substring(6));
198 else
199 all.put(e.getKey().substring(6), e.getValue());
200 return all;
201 }
202
203 synchronized public Map<String, String> getDefaults() {
204 return defaults;
205 }
206
207 synchronized public void putDefault(final String key, final String def) {
208 if(!defaults.containsKey(key) || defaults.get(key) == null)
209 defaults.put(key, def);
210 else if(def != null && !defaults.get(key).equals(def))
211 System.out.println("Defaults for " + key + " differ: " + def + " != " + defaults.get(key));
212 }
213
214 synchronized public boolean getBoolean(final String key) {
215 putDefault(key, null);
216 if (override.containsKey(key))
217 return override.get(key) == null ? false : Boolean.parseBoolean(override.get(key));
218 return properties.containsKey(key) ? Boolean.parseBoolean(properties.get(key)) : false;
219 }
220
221 synchronized public boolean getBoolean(final String key, final boolean def) {
222 putDefault(key, Boolean.toString(def));
223 if (override.containsKey(key))
224 return override.get(key) == null ? def : Boolean.parseBoolean(override.get(key));
225 return properties.containsKey(key) ? Boolean.parseBoolean(properties.get(key)) : def;
226 }
227
228 synchronized public boolean put(final String key, String value) {
229 String oldvalue = properties.get(key);
230 if(value != null && value.length() == 0)
231 value = null;
232 if(!((oldvalue == null && (value == null || value.equals(defaults.get(key))))
233 || (value != null && oldvalue != null && oldvalue.equals(value))))
234 {
235 if (value == null)
236 properties.remove(key);
237 else
238 properties.put(key, value);
239 save();
240 firePreferenceChanged(key, value);
241 return true;
242 }
243 return false;
244 }
245
246 synchronized public boolean put(final String key, final boolean value) {
247 return put(key, Boolean.toString(value));
248 }
249
250 synchronized public boolean putInteger(final String key, final Integer value) {
251 return put(key, Integer.toString(value));
252 }
253
254 synchronized public boolean putDouble(final String key, final Double value) {
255 return put(key, Double.toString(value));
256 }
257
258 private final void firePreferenceChanged(final String key, final String value) {
259 for (final PreferenceChangedListener l : listener)
260 l.preferenceChanged(key, value);
261 }
262
263 /**
264 * Called after every put. In case of a problem, do nothing but output the error
265 * in log.
266 */
267 public void save() {
268 /* currently unused, but may help to fix configuration issues in future */
269 properties.put("josm.version", AboutAction.getVersionString());
270 try {
271 setSystemProperties();
272 final PrintWriter out = new PrintWriter(new FileWriter(getPreferencesDir() + "preferences"), false);
273 for (final Entry<String, String> e : properties.entrySet()) {
274 String s = defaults.get(e.getKey());
275 /* don't save default values */
276 if(s == null || !s.equals(e.getValue()))
277 out.println(e.getKey() + "=" + e.getValue());
278 }
279 out.close();
280 } catch (final IOException e) {
281 e.printStackTrace();
282 // do not message anything, since this can be called from strange
283 // places.
284 }
285 }
286
287 public void load() throws IOException {
288 properties.clear();
289 final BufferedReader in = new BufferedReader(new FileReader(getPreferencesDir()+"preferences"));
290 int lineNumber = 0;
291 ArrayList<Integer> errLines = new ArrayList<Integer>();
292 for (String line = in.readLine(); line != null; line = in.readLine(), lineNumber++) {
293 final int i = line.indexOf('=');
294 if (i == -1 || i == 0) {
295 errLines.add(lineNumber);
296 continue;
297 }
298 properties.put(line.substring(0,i), line.substring(i+1));
299 }
300 if (!errLines.isEmpty()) {
301 throw new IOException("Malformed config file at lines " + errLines);
302 }
303 setSystemProperties();
304 }
305
306 public final void resetToDefault() {
307 properties.clear();
308 put("layerlist.visible", true);
309 put("propertiesdialog.visible", true);
310 put("selectionlist.visible", true);
311 put("commandstack.visible", true);
312 put("osm-server.url", "http://www.openstreetmap.org/api");
313 if (System.getProperty("os.name").toUpperCase().indexOf("WINDOWS") == -1) {
314 put("laf", "javax.swing.plaf.metal.MetalLookAndFeel");
315 } else {
316 put("laf", "com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
317 }
318 save();
319 }
320
321 public Collection<Bookmark> loadBookmarks() throws IOException {
322 File bookmarkFile = new File(getPreferencesDir()+"bookmarks");
323 if (!bookmarkFile.exists())
324 bookmarkFile.createNewFile();
325 BufferedReader in = new BufferedReader(new FileReader(bookmarkFile));
326
327 LinkedList<Bookmark> bookmarks = new LinkedList<Bookmark>();
328 // use pattern matches to scan text, as text may contain a "," itself
329 for (String line = in.readLine(); line != null; line = in.readLine()) {
330 Matcher m = Pattern.compile("^(.+),(-?\\d+.\\d+),(-?\\d+.\\d+),(-?\\d+.\\d+),(-?\\d+.\\d+)$").matcher(line);
331 if(m.matches())
332 {
333 Bookmark b = new Bookmark();
334 b.name = m.group(1);
335 for (int i = 0; i < b.latlon.length; ++i)
336 b.latlon[i] = Double.parseDouble(m.group(i+2));
337 bookmarks.add(b);
338 }
339 }
340 in.close();
341 Collections.sort(bookmarks);
342 return bookmarks;
343 }
344
345 public void saveBookmarks(Collection<Bookmark> bookmarks) throws IOException {
346 File bookmarkFile = new File(Main.pref.getPreferencesDir()+"bookmarks");
347 if (!bookmarkFile.exists())
348 bookmarkFile.createNewFile();
349 PrintWriter out = new PrintWriter(new FileWriter(bookmarkFile));
350 for (Bookmark b : bookmarks) {
351 out.print(b.name+",");
352 for (int i = 0; i < b.latlon.length; ++i)
353 out.print(b.latlon[i]+(i<b.latlon.length-1?",":""));
354 out.println();
355 }
356 out.close();
357 }
358
359 /**
360 * Convenience method for accessing colour preferences.
361 *
362 * @param colName name of the colour
363 * @param def default value
364 * @return a Color object for the configured colour, or the default value if none configured.
365 */
366 synchronized public Color getColor(String colName, Color def) {
367 return getColor(colName, null, def);
368 }
369
370 /**
371 * Convenience method for accessing colour preferences.
372 *
373 * @param colName name of the colour
374 * @param specName name of the special colour settings
375 * @param def default value
376 * @return a Color object for the configured colour, or the default value if none configured.
377 */
378 synchronized public Color getColor(String colName, String specName, Color def) {
379 putDefault("color."+colName, ColorHelper.color2html(def));
380 String colStr = specName != null ? get("color."+specName) : "";
381 if(colStr.equals(""))
382 colStr = get("color."+colName);
383 return colStr.equals("") ? def : ColorHelper.html2color(colStr);
384 }
385
386 synchronized public boolean putColor(String colName, Color val) {
387 return put("color."+colName, val != null ? ColorHelper.color2html(val) : null);
388 }
389
390 synchronized public int getInteger(String key, int def) {
391 putDefault(key, Integer.toString(def));
392 String v = get(key);
393 if(null == v)
394 return def;
395
396 try {
397 return Integer.parseInt(v);
398 } catch(NumberFormatException e) {
399 // fall out
400 }
401 return def;
402 }
403
404 synchronized public long getLong(String key, long def) {
405 putDefault(key, Long.toString(def));
406 String v = get(key);
407 if(null == v)
408 return def;
409
410 try {
411 return Long.parseLong(v);
412 } catch(NumberFormatException e) {
413 // fall out
414 }
415 return def;
416 }
417
418 synchronized public double getDouble(String key, double def) {
419 putDefault(key, Double.toString(def));
420 String v = get(key);
421 if(null == v)
422 return def;
423
424 try {
425 return Double.parseDouble(v);
426 } catch(NumberFormatException e) {
427 // fall out
428 }
429 return def;
430 }
431
432 synchronized public double getDouble(String key, String def) {
433 putDefault(key, def);
434 String v = get(key);
435 try {
436 return Double.parseDouble(v == null ? def : v);
437 } catch(NumberFormatException e) {
438 // fall out
439 }
440 return 0.0;
441 }
442
443 synchronized public Collection<String> getCollection(String key, Collection<String> def) {
444 String s = get(key);
445 if(s != null && s.length() != 0)
446 {
447 /* handle old comma separated stuff - remove in future */
448 if(s.indexOf(',') >= 0)
449 return Arrays.asList(s.split(","));
450 /* handle space separated stuff - remove in future */
451 else if(s.indexOf(' ') >= 0)
452 return Arrays.asList(s.split(","));
453 else
454 return Arrays.asList(s.split(";"));
455 }
456 return def;
457 }
458 synchronized public void removeFromCollection(String key, String value) {
459 ArrayList<String> a = new ArrayList<String>(getCollection(key, null));
460 if(a != null)
461 {
462 a.remove(value);
463 putCollection(key, a);
464 }
465 }
466 synchronized public boolean putCollection(String key, Collection<String> val) {
467 String s = null;
468 if(val != null)
469 {
470 for(String a : val)
471 {
472 if(s != null)
473 s += ";" + a;
474 else
475 s = a;
476 }
477 }
478
479 return put(key, s);
480 }
481
482 private void setSystemProperties() {
483 Properties sysProp = System.getProperties();
484 if (getBoolean(ProxyPreferences.PROXY_ENABLE)) {
485 sysProp.put("proxySet", "true");
486 sysProp.put("http.proxyHost", get(ProxyPreferences.PROXY_HOST));
487 sysProp.put("proxyPort", get(ProxyPreferences.PROXY_PORT));
488 if (!getBoolean(ProxyPreferences.PROXY_ANONYMOUS)) {
489 sysProp.put("proxyUser", get(ProxyPreferences.PROXY_USER));
490 sysProp.put("proxyPassword", get(ProxyPreferences.PROXY_PASS));
491 }
492 }/* else {
493 sysProp.put("proxySet", "false");
494 sysProp.remove("http.proxyHost");
495 sysProp.remove("proxyPort");
496 sysProp.remove("proxyUser");
497 sysProp.remove("proxyPassword");
498 }*/
499 System.setProperties(sysProp);
500 }
501}
Note: See TracBrowser for help on using the repository browser.