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