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