Ignore:
Timestamp:
2016-08-17T09:18:31+02:00 (8 years ago)
Author:
Don-vip
Message:

see #13309 - Caching and notifying preferences (patch by michael2402) - gsoc-core

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/Preferences.java

    r10788 r10824  
    3737import java.util.SortedMap;
    3838import java.util.TreeMap;
    39 import java.util.concurrent.CopyOnWriteArrayList;
    4039import java.util.function.Predicate;
    4140import java.util.regex.Matcher;
    4241import java.util.regex.Pattern;
     42import java.util.stream.Stream;
    4343
    4444import javax.json.Json;
     
    5555
    5656import org.openstreetmap.josm.Main;
     57import org.openstreetmap.josm.data.preferences.BooleanProperty;
    5758import org.openstreetmap.josm.data.preferences.ColorProperty;
     59import org.openstreetmap.josm.data.preferences.DoubleProperty;
     60import org.openstreetmap.josm.data.preferences.IntegerProperty;
    5861import org.openstreetmap.josm.data.preferences.ListListSetting;
    5962import org.openstreetmap.josm.data.preferences.ListSetting;
     63import org.openstreetmap.josm.data.preferences.LongProperty;
    6064import org.openstreetmap.josm.data.preferences.MapListSetting;
    6165import org.openstreetmap.josm.data.preferences.PreferencesReader;
     
    6872import org.openstreetmap.josm.tools.ColorHelper;
    6973import org.openstreetmap.josm.tools.I18n;
     74import org.openstreetmap.josm.tools.ListenerList;
    7075import org.openstreetmap.josm.tools.MultiMap;
    71 import org.openstreetmap.josm.tools.SubclassFilteredCollection;
    7276import org.openstreetmap.josm.tools.Utils;
    7377import org.xml.sax.SAXException;
     
    215219    }
    216220
     221    /**
     222     * Old color interface
     223     * <p>
     224     * To be removed: end of 2016
     225     * @deprecated Use a {@link ColorProperty} instead.
     226     */
     227    @Deprecated
    217228    public interface ColorKey {
    218229        String getColorName();
     
    223234    }
    224235
    225     private final CopyOnWriteArrayList<PreferenceChangedListener> listeners = new CopyOnWriteArrayList<>();
     236    private final ListenerList<PreferenceChangedListener> listeners = ListenerList.create();
     237
     238    private final HashMap<String, ListenerList<PreferenceChangedListener>> keyListeners = new HashMap<>();
    226239
    227240    /**
     
    231244    public void addPreferenceChangeListener(PreferenceChangedListener listener) {
    232245        if (listener != null) {
    233             listeners.addIfAbsent(listener);
     246            listeners.addListener(listener);
    234247        }
    235248    }
     
    240253     */
    241254    public void removePreferenceChangeListener(PreferenceChangedListener listener) {
    242         listeners.remove(listener);
     255        listeners.removeListener(listener);
     256    }
     257
     258    /**
     259     * Adds a listener that only listens to changes in one preference
     260     * @param key The preference key to listen to
     261     * @param listener The listener to add.
     262     * @since 10824
     263     */
     264    public void addKeyPreferenceChangeListener(String key, PreferenceChangedListener listener) {
     265        listenersForKey(key).addListener(listener);
     266    }
     267
     268    /**
     269     * Adds a weak listener that only listens to changes in one preference
     270     * @param key The preference key to listen to
     271     * @param listener The listener to add.
     272     * @since 10824
     273     */
     274    public void addWeakKeyPreferenceChangeListener(String key, PreferenceChangedListener listener) {
     275        listenersForKey(key).addWeakListener(listener);
     276    }
     277
     278    private ListenerList<PreferenceChangedListener> listenersForKey(String key) {
     279        ListenerList<PreferenceChangedListener> keyListener = keyListeners.get(key);
     280        if (keyListener == null) {
     281            keyListener = ListenerList.create();
     282            keyListeners.put(key, keyListener);
     283        }
     284        return keyListener;
     285    }
     286
     287    /**
     288     * Removes a listener that only listens to changes in one preference
     289     * @param key The preference key to listen to
     290     * @param listener The listener to add.
     291     */
     292    public void removeKeyPreferenceChangeListener(String key, PreferenceChangedListener listener) {
     293        ListenerList<PreferenceChangedListener> keyListener = keyListeners.get(key);
     294        if (keyListener == null) {
     295            throw new IllegalArgumentException("There are no listeners registered for " + key);
     296        }
     297        keyListener.removeListener(listener);
    243298    }
    244299
    245300    protected void firePreferenceChanged(String key, Setting<?> oldValue, Setting<?> newValue) {
    246         PreferenceChangeEvent evt = new DefaultPreferenceChangeEvent(key, oldValue, newValue);
    247         for (PreferenceChangedListener l : listeners) {
    248             l.preferenceChanged(evt);
     301        final PreferenceChangeEvent evt = new DefaultPreferenceChangeEvent(key, oldValue, newValue);
     302        listeners.fireEvent(listener -> listener.preferenceChanged(evt));
     303
     304        ListenerList<PreferenceChangedListener> forKey = keyListeners.get(key);
     305        if (forKey != null) {
     306            forKey.fireEvent(listener -> listener.preferenceChanged(evt));
    249307        }
    250308    }
     
    479537     */
    480538    public boolean put(final String key, String value) {
    481         if (value != null && value.isEmpty()) {
    482             value = null;
    483         }
    484         return putSetting(key, value == null ? null : new StringSetting(value));
    485     }
    486 
     539        return putSetting(key, value == null || value.isEmpty() ? null : new StringSetting(value));
     540    }
     541
     542    /**
     543     * Set a boolean value for a certain setting.
     544     * @param key the unique identifier for the setting
     545     * @param value The new value
     546     * @return {@code true}, if something has changed (i.e. value is different than before)
     547     * @see BooleanProperty
     548     */
    487549    public boolean put(final String key, final boolean value) {
    488550        return put(key, Boolean.toString(value));
    489551    }
    490552
     553    /**
     554     * Set a boolean value for a certain setting.
     555     * @param key the unique identifier for the setting
     556     * @param value The new value
     557     * @return {@code true}, if something has changed (i.e. value is different than before)
     558     * @see IntegerProperty
     559     */
    491560    public boolean putInteger(final String key, final Integer value) {
    492561        return put(key, Integer.toString(value));
    493562    }
    494563
     564    /**
     565     * Set a boolean value for a certain setting.
     566     * @param key the unique identifier for the setting
     567     * @param value The new value
     568     * @return {@code true}, if something has changed (i.e. value is different than before)
     569     * @see DoubleProperty
     570     */
    495571    public boolean putDouble(final String key, final Double value) {
    496572        return put(key, Double.toString(value));
    497573    }
    498574
     575    /**
     576     * Set a boolean value for a certain setting.
     577     * @param key the unique identifier for the setting
     578     * @param value The new value
     579     * @return {@code true}, if something has changed (i.e. value is different than before)
     580     * @see LongProperty
     581     */
    499582    public boolean putLong(final String key, final Long value) {
    500583        return put(key, Long.toString(value));
     
    506589     */
    507590    public synchronized void save() throws IOException {
    508         save(getPreferenceFile(),
    509                 new SubclassFilteredCollection<>(settingsMap.entrySet(), NO_DEFAULT_SETTINGS_ENTRY), false);
     591        save(getPreferenceFile(), settingsMap.entrySet().stream().filter(NO_DEFAULT_SETTINGS_ENTRY), false);
    510592    }
    511593
    512594    public synchronized void saveDefaults() throws IOException {
    513         save(getDefaultsCacheFile(), defaultsMap.entrySet(), true);
    514     }
    515 
    516     protected void save(File prefFile, Collection<Entry<String, Setting<?>>> settings, boolean defaults) throws IOException {
    517 
     595        save(getDefaultsCacheFile(), defaultsMap.entrySet().stream(), true);
     596    }
     597
     598    protected void save(File prefFile, Stream<Entry<String, Setting<?>>> settings, boolean defaults) throws IOException {
    518599        if (!defaults) {
    519600            /* currently unused, but may help to fix configuration issues in future */
     
    719800    /**
    720801     * Convenience method for accessing colour preferences.
     802     * <p>
     803     * To be removed: end of 2016
    721804     *
    722805     * @param colName name of the colour
    723806     * @param def default value
    724807     * @return a Color object for the configured colour, or the default value if none configured.
    725      */
     808     * @deprecated Use a {@link ColorProperty} instead.
     809     */
     810    @Deprecated
    726811    public synchronized Color getColor(String colName, Color def) {
    727812        return getColor(colName, null, def);
     
    743828    /**
    744829     * Returns the color for the given key.
     830     * <p>
     831     * To be removed: end of 2016
    745832     * @param key The color key
    746833     * @return the color
    747      */
     834     * @deprecated Use a {@link ColorProperty} instead.
     835     */
     836    @Deprecated
    748837    public Color getColor(ColorKey key) {
    749838        return getColor(key.getColorName(), key.getSpecialName(), key.getDefaultValue());
     
    752841    /**
    753842     * Convenience method for accessing colour preferences.
    754      *
     843     * <p>
     844     * To be removed: end of 2016
    755845     * @param colName name of the colour
    756846     * @param specName name of the special colour settings
    757847     * @param def default value
    758848     * @return a Color object for the configured colour, or the default value if none configured.
    759      */
     849     * @deprecated Use a {@link ColorProperty} instead.
     850     * You can replace this by: <code>new ColorProperty(colName, def).getChildColor(specName)</code>
     851     */
     852    @Deprecated
    760853    public synchronized Color getColor(String colName, String specName, Color def) {
    761854        String colKey = ColorProperty.getColorKey(colName);
    762         if (!colKey.equals(colName)) {
    763             colornames.put(colKey, colName);
    764         }
     855        registerColor(colKey, colName);
    765856        String colStr = specName != null ? get("color."+specName) : "";
    766857        if (colStr.isEmpty()) {
     
    771862        } else {
    772863            return def;
     864        }
     865    }
     866
     867    /**
     868     * Registers a color name conversion for the global color registry.
     869     * @param colKey The key
     870     * @param colName The name of the color.
     871     * @since 10824
     872     */
     873    public void registerColor(String colKey, String colName) {
     874        if (!colKey.equals(colName)) {
     875            colornames.put(colKey, colName);
    773876        }
    774877    }
Note: See TracChangeset for help on using the changeset viewer.