Modify ↓
Opened 9 years ago
#13446 new enhancement
Preference cleanup
Reported by: | michael2402 | Owned by: | team |
---|---|---|---|
Priority: | normal | Milestone: | |
Component: | Core | Version: | |
Keywords: | preferences | Cc: |
Description
JOSM preferences were a String->String map. They have been enhanced to be a String->whatever map.
Over the time, this system has grown to support multiple data types by converting them to strings.
This includes:
Type | direct access | proxy access | notes |
---|---|---|---|
String | pref.get(String) | new StringProperty() | |
Boolean | pref.getBoolean(String) | new BooleanProperty() | no type hints |
Boolean | pref.getInteger(String) | new IntegerProperty() | no type hints |
Boolean | pref.getDouble(String) | new DoubleProperty() | no type hints |
Boolean | pref.getLong(String) | new LongProperty() | no type hints |
Color | pref.getColor(String) | new ColorProperty() | type identified by start with color.
|
Collection<String> | pref.getCollection(String) | ListSetting class | |
Collection<Collection<String>> | pref.getArray(String) | ListListSetting class | |
Object (Struct) | serializeStruct | - | See @pref annotation |
List<Object> (Structs) | getListOfStructs | - | See @pref annotation |
The interface to all those types differs a lot.
I propose:
- Remove all public access to the Setting classes -> Make them internal.
- Support only those internal
Setting
classes:StringSetting
(represented as simple string)ListSetting<? extends Setting>
([0...n-1] -> value map)MapSetting<? extends Setting>
(name -> value map)
- Replace ListListSetting by ListSetting<ListSetting<StringSetting>>
- Use setting classes during writing/reading the xml file only.
- Do not expose the string representation of settings to the user. No more Main.pref.get() calls. No more matching-the-default-values, since we can store the property objects as constants.
- Replace all public access using
..Property
objects. - Do type check in the Property objects when registering them.
- Store the Property objects in a
knownProperties
map. They already contain the default value and the type information.
So we could replace this code:
List<ImageryPreferenceEntry> entries = new ArrayList<>(); for (ImageryInfo info : layers) { entries.add(new ImageryPreferenceEntry(info)); } Main.pref.putListOfStructs("imagery.entries", entries, ImageryPreferenceEntry.class);
// Use the builder pattern here // Uses ListCompoundProperty and MapCompoundProperty internally CompoundProperty<List<Map<String, String>> pref = CompoundProperty.map().list().for("imagery.entries"); // expects List<Map<String, String>> pref.put(layers.stream() .map(info -> new ImageryPreferenceEntry(info)) .map(Preferences::serializeStruct) // < can be moved to utility class .collect(Collectors.toList())
We can also move the serilaization to a Property object:
// Use the builder pattern here // Uses ListCompoundProperty and MapCompoundProperty internally CompoundProperty<List<ImageryPreferenceEntry> pref = CompoundProperty.serialized(ImageryPreferenceEntry.class).list().for("imagery.entries"); // expects List<Map<String, String>> pref.put(layers.stream() .map(ImageryPreferenceEntry::new) .collect(Collectors.toList())
Next example:
return Main.pref.getCollection("imagery.layers.sites", Arrays.asList(DEFAULT_LAYER_SITES));
return CompoundProperty.list().for("imagery.layers.sites", Arrays.asList(DEFAULT_LAYER_SITES)).get();
Next example:
private static volatile Collection<String> uninteresting; public static Collection<String> getUninterestingKeys() { if (uninteresting == null) { List<String> l = ... uninteresting = Main.pref.getCollection("tags.uninteresting", l); } return uninteresting; }
private static UNINTERESTING = CompoundProperty.list().for("tags.uninteresting", l).get().cached(); public static Collection<String> getUninterestingKeys() { return UNINTERESTING.get(); }
Attachments (0)
Note:
See TracTickets
for help on using tickets.