001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.preferences.sources;
003
004import java.util.ArrayList;
005import java.util.Collection;
006import java.util.HashMap;
007import java.util.LinkedHashSet;
008import java.util.List;
009import java.util.Map;
010import java.util.Set;
011
012import org.openstreetmap.josm.spi.preferences.Config;
013
014/**
015 * Helper class for specialized extensions preferences.
016 * @since 12649 (extracted from gui.preferences package)
017 */
018public abstract class SourcePrefHelper {
019
020    private final String pref;
021    protected final SourceType type;
022
023    /**
024     * Constructs a new {@code SourcePrefHelper} for the given preference key.
025     * @param pref The preference key
026     * @param type The source type
027     * @since 12825
028     */
029    public SourcePrefHelper(String pref, SourceType type) {
030        this.pref = pref;
031        this.type = type;
032    }
033
034    /**
035     * Returns the default sources provided by JOSM core.
036     * @return the default sources provided by JOSM core
037     */
038    public abstract Collection<ExtendedSourceEntry> getDefault();
039
040    /**
041     * Serializes the given source entry as a map.
042     * @param entry source entry to serialize
043     * @return map (key=value)
044     */
045    public abstract Map<String, String> serialize(SourceEntry entry);
046
047    /**
048     * Deserializes the given map as a source entry.
049     * @param entryStr map (key=value)
050     * @return source entry
051     */
052    public abstract SourceEntry deserialize(Map<String, String> entryStr);
053
054    /**
055     * Returns the list of sources.
056     * @return The list of sources
057     */
058    public List<SourceEntry> get() {
059
060        List<Map<String, String>> src = Config.getPref().getListOfMaps(pref, null);
061        if (src == null)
062            return new ArrayList<>(getDefault());
063
064        List<SourceEntry> entries = new ArrayList<>();
065        for (Map<String, String> sourcePref : src) {
066            SourceEntry e = deserialize(new HashMap<>(sourcePref));
067            if (e != null) {
068                entries.add(e);
069            }
070        }
071        return entries;
072    }
073
074    /**
075     * Saves a list of sources to JOSM preferences.
076     * @param entries list of sources
077     * @return {@code true}, if something has changed (i.e. value is different than before)
078     */
079    public boolean put(Collection<? extends SourceEntry> entries) {
080        List<Map<String, String>> setting = serializeList(entries);
081        boolean unset = Config.getPref().getListOfMaps(pref, null) == null;
082        if (unset) {
083            Collection<Map<String, String>> def = serializeList(getDefault());
084            if (setting.equals(def))
085                return false;
086        }
087        return Config.getPref().putListOfMaps(pref, setting);
088    }
089
090    private List<Map<String, String>> serializeList(Collection<? extends SourceEntry> entries) {
091        List<Map<String, String>> setting = new ArrayList<>(entries.size());
092        for (SourceEntry e : entries) {
093            setting.add(serialize(e));
094        }
095        return setting;
096    }
097
098    /**
099     * Returns the set of active source URLs.
100     * @return The set of active source URLs.
101     */
102    public final Set<String> getActiveUrls() {
103        Set<String> urls = new LinkedHashSet<>(); // retain order
104        for (SourceEntry e : get()) {
105            if (e.active) {
106                urls.add(e.url);
107            }
108        }
109        return urls;
110    }
111}