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