001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.spi.preferences; 003 004import java.util.LinkedList; 005import java.util.List; 006import java.util.Map; 007import java.util.Map.Entry; 008import java.util.TreeMap; 009 010import org.openstreetmap.josm.tools.Logging; 011 012/** 013 * Abstract implementation of the {@link IPreferences} interface. 014 * @since 12847 015 */ 016public abstract class AbstractPreferences implements IPreferences { 017 018 @Override 019 public synchronized String get(final String key, final String def) { 020 return getSetting(key, new StringSetting(def), StringSetting.class).getValue(); 021 } 022 023 @Override 024 public boolean put(final String key, String value) { 025 return putSetting(key, value == null || value.isEmpty() ? null : new StringSetting(value)); 026 } 027 028 @Override 029 public boolean getBoolean(final String key, final boolean def) { 030 return Boolean.parseBoolean(get(key, Boolean.toString(def))); 031 } 032 033 @Override 034 public boolean putBoolean(final String key, final boolean value) { 035 return put(key, Boolean.toString(value)); 036 } 037 038 @Override 039 public synchronized int getInt(String key, int def) { 040 String v = get(key, Integer.toString(def)); 041 if (v.isEmpty()) 042 return def; 043 044 try { 045 return Integer.parseInt(v); 046 } catch (NumberFormatException e) { 047 // fall out 048 Logging.trace(e); 049 } 050 return def; 051 } 052 053 @Override 054 public boolean putInt(String key, int value) { 055 return put(key, Integer.toString(value)); 056 } 057 058 @Override 059 public long getLong(String key, long def) { 060 String v = get(key, Long.toString(def)); 061 if (null == v) 062 return def; 063 064 try { 065 return Long.parseLong(v); 066 } catch (NumberFormatException e) { 067 // fall out 068 Logging.trace(e); 069 } 070 return def; 071 } 072 073 @Override 074 public boolean putLong(final String key, final long value) { 075 return put(key, Long.toString(value)); 076 } 077 078 @Override 079 public synchronized double getDouble(String key, double def) { 080 String v = get(key, Double.toString(def)); 081 if (null == v) 082 return def; 083 084 try { 085 return Double.parseDouble(v); 086 } catch (NumberFormatException e) { 087 // fall out 088 Logging.trace(e); 089 } 090 return def; 091 } 092 093 @Override 094 public boolean putDouble(final String key, final double value) { 095 return put(key, Double.toString(value)); 096 } 097 098 @Override 099 public List<String> getList(String key, List<String> def) { 100 return getSetting(key, new ListSetting(def), ListSetting.class).getValue(); 101 } 102 103 @Override 104 public boolean putList(String key, List<String> value) { 105 return putSetting(key, value == null ? null : new ListSetting(value)); 106 } 107 108 @Override 109 public List<List<String>> getListOfLists(String key, List<List<String>> def) { 110 return getSetting(key, new ListListSetting(def), ListListSetting.class).getValue(); 111 } 112 113 @Override 114 public boolean putListOfLists(String key, List<List<String>> value) { 115 return putSetting(key, value == null ? null : new ListListSetting(value)); 116 } 117 118 @Override 119 public List<Map<String, String>> getListOfMaps(String key, List<Map<String, String>> def) { 120 return getSetting(key, new MapListSetting(def), MapListSetting.class).getValue(); 121 } 122 123 @Override 124 public boolean putListOfMaps(String key, List<Map<String, String>> value) { 125 return putSetting(key, value == null ? null : new MapListSetting(value)); 126 } 127 128 /** 129 * Gets a map of all settings that are currently stored 130 * @return The settings 131 */ 132 public abstract Map<String, Setting<?>> getAllSettings(); 133 134 /** 135 * Set a value for a certain setting. The changed setting is saved to the preference file immediately. 136 * Due to caching mechanisms on modern operating systems and hardware, this shouldn't be a performance problem. 137 * @param key the unique identifier for the setting 138 * @param setting the value of the setting. In case it is null, the key-value entry will be removed. 139 * @return {@code true}, if something has changed (i.e. value is different than before) 140 */ 141 public abstract boolean putSetting(String key, Setting<?> setting); 142 143 /** 144 * Get settings value for a certain key and provide default a value. 145 * @param <T> the setting type 146 * @param key the identifier for the setting 147 * @param def the default value. For each call of getSetting() with a given key, the default value must be the same. 148 * <code>def</code> must not be null, but the value of <code>def</code> can be null. 149 * @param klass the setting type (same as T) 150 * @return the corresponding value if the property has been set before, {@code def} otherwise 151 */ 152 public abstract <T extends Setting<?>> T getSetting(String key, T def, Class<T> klass); 153 154 /** 155 * Gets all normal (string) settings that have a key starting with the prefix 156 * @param prefix The start of the key 157 * @return The key names of the settings 158 */ 159 public Map<String, String> getAllPrefix(String prefix) { 160 final Map<String, String> all = new TreeMap<>(); 161 for (final Entry<String, Setting<?>> e : getAllSettings().entrySet()) { 162 if (e.getKey().startsWith(prefix) && (e.getValue() instanceof StringSetting)) { 163 all.put(e.getKey(), ((StringSetting) e.getValue()).getValue()); 164 } 165 } 166 return all; 167 } 168 169 /** 170 * Gets all list settings that have a key starting with the prefix 171 * @param prefix The start of the key 172 * @return The key names of the list settings 173 */ 174 public List<String> getAllPrefixCollectionKeys(String prefix) { 175 final List<String> all = new LinkedList<>(); 176 for (Entry<String, Setting<?>> entry : getAllSettings().entrySet()) { 177 if (entry.getKey().startsWith(prefix) && entry.getValue() instanceof ListSetting) { 178 all.add(entry.getKey()); 179 } 180 } 181 return all; 182 } 183}