Ignore:
Timestamp:
2017-09-14T01:59:34+02:00 (2 years ago)
Author:
bastiK
Message:

see #15229 - extract "struct" handling from Preference to StructUtils

Location:
trunk/src/org/openstreetmap/josm/data
Files:
1 added
6 edited

Legend:

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

    r12847 r12851  
    1212import java.io.PrintWriter;
    1313import java.io.Reader;
    14 import java.io.StringReader;
    1514import java.io.StringWriter;
    1615import java.lang.annotation.Retention;
     
    2524import java.util.HashSet;
    2625import java.util.Iterator;
    27 import java.util.LinkedHashMap;
    2826import java.util.LinkedList;
    2927import java.util.List;
    3028import java.util.Map;
    3129import java.util.Map.Entry;
    32 import java.util.Objects;
    3330import java.util.Optional;
    3431import java.util.ResourceBundle;
     
    4340import java.util.stream.Stream;
    4441
    45 import javax.json.Json;
    46 import javax.json.JsonArray;
    47 import javax.json.JsonArrayBuilder;
    48 import javax.json.JsonObject;
    49 import javax.json.JsonObjectBuilder;
    50 import javax.json.JsonReader;
    51 import javax.json.JsonString;
    52 import javax.json.JsonValue;
    53 import javax.json.JsonWriter;
    5442import javax.swing.JOptionPane;
    5543import javax.xml.stream.XMLStreamException;
     
    7765import org.openstreetmap.josm.tools.ColorHelper;
    7866import org.openstreetmap.josm.tools.I18n;
    79 import org.openstreetmap.josm.tools.JosmRuntimeException;
    8067import org.openstreetmap.josm.tools.ListenerList;
    8168import org.openstreetmap.josm.tools.Logging;
    82 import org.openstreetmap.josm.tools.MultiMap;
    8369import org.openstreetmap.josm.tools.Utils;
    8470import org.xml.sax.SAXException;
     
    12121198     * @see #serializeStruct(java.lang.Object, java.lang.Class)
    12131199     * @see #deserializeStruct(java.util.Map, java.lang.Class)
    1214      */
     1200     * @deprecated use {@link StructUtils.StructEntry}
     1201     */
     1202    @Deprecated
    12151203    @Retention(RetentionPolicy.RUNTIME) // keep annotation at runtime
    12161204    public @interface pref { }
     
    12211209     *
    12221210     * @see #serializeStruct(java.lang.Object, java.lang.Class)
    1223      */
     1211     * @deprecated use {@link StructUtils.WriteExplicitly}
     1212     */
     1213    @Deprecated
    12241214    @Retention(RetentionPolicy.RUNTIME) // keep annotation at runtime
    12251215    public @interface writeExplicitly { }
     
    12331223     * @param klass The struct class
    12341224     * @return a list of objects of type T or an empty list if nothing was found
    1235      */
     1225     * @deprecated use {@link StructUtils#getListOfStructs(IPreferences, String, Class)}
     1226     */
     1227    @Deprecated
    12361228    public <T> List<T> getListOfStructs(String key, Class<T> klass) {
    1237         return Optional.ofNullable(getListOfStructs(key, null, klass)).orElseGet(Collections::emptyList);
     1229        return StructUtils.getListOfStructs(this, key, klass);
    12381230    }
    12391231
     
    12451237     * @param klass The struct class
    12461238     * @return a list of objects of type T or {@code def} if nothing was found
    1247      */
     1239     * @deprecated use {@link StructUtils#getListOfStructs(IPreferences, String, Collection, Class)}
     1240     */
     1241    @Deprecated
    12481242    public <T> List<T> getListOfStructs(String key, Collection<T> def, Class<T> klass) {
    1249         List<Map<String, String>> prop =
    1250             getListOfMaps(key, def == null ? null : serializeListOfStructs(def, klass));
    1251         if (prop == null)
    1252             return def == null ? null : new ArrayList<>(def);
    1253         return prop.stream().map(p -> deserializeStruct(p, klass)).collect(Collectors.toList());
     1243        return StructUtils.getListOfStructs(this, key, def, klass);
    12541244    }
    12551245
     
    12691259     * @param klass The struct class
    12701260     * @return true if something has changed
    1271      */
     1261     * @deprecated use {@link StructUtils#putListOfStructs(IPreferences, String, Collection, Class)}
     1262     */
     1263    @Deprecated
    12721264    public <T> boolean putListOfStructs(String key, Collection<T> val, Class<T> klass) {
    1273         return putListOfMaps(key, serializeListOfStructs(val, klass));
    1274     }
    1275 
    1276     private static <T> List<Map<String, String>> serializeListOfStructs(Collection<T> l, Class<T> klass) {
    1277         if (l == null)
    1278             return null;
    1279         List<Map<String, String>> vals = new ArrayList<>();
    1280         for (T struct : l) {
    1281             if (struct != null) {
    1282                 vals.add(serializeStruct(struct, klass));
    1283             }
    1284         }
    1285         return vals;
    1286     }
    1287 
    1288     @SuppressWarnings("rawtypes")
    1289     private static String mapToJson(Map map) {
    1290         StringWriter stringWriter = new StringWriter();
    1291         try (JsonWriter writer = Json.createWriter(stringWriter)) {
    1292             JsonObjectBuilder object = Json.createObjectBuilder();
    1293             for (Object o: map.entrySet()) {
    1294                 Entry e = (Entry) o;
    1295                 Object evalue = e.getValue();
    1296                 object.add(e.getKey().toString(), evalue.toString());
    1297             }
    1298             writer.writeObject(object.build());
    1299         }
    1300         return stringWriter.toString();
    1301     }
    1302 
    1303     @SuppressWarnings({ "rawtypes", "unchecked" })
    1304     private static Map mapFromJson(String s) {
    1305         Map ret = null;
    1306         try (JsonReader reader = Json.createReader(new StringReader(s))) {
    1307             JsonObject object = reader.readObject();
    1308             ret = new HashMap(object.size());
    1309             for (Entry<String, JsonValue> e: object.entrySet()) {
    1310                 JsonValue value = e.getValue();
    1311                 if (value instanceof JsonString) {
    1312                     // in some cases, when JsonValue.toString() is called, then additional quotation marks are left in value
    1313                     ret.put(e.getKey(), ((JsonString) value).getString());
    1314                 } else {
    1315                     ret.put(e.getKey(), e.getValue().toString());
    1316                 }
    1317             }
    1318         }
    1319         return ret;
    1320     }
    1321 
    1322     @SuppressWarnings("rawtypes")
    1323     private static String multiMapToJson(MultiMap map) {
    1324         StringWriter stringWriter = new StringWriter();
    1325         try (JsonWriter writer = Json.createWriter(stringWriter)) {
    1326             JsonObjectBuilder object = Json.createObjectBuilder();
    1327             for (Object o: map.entrySet()) {
    1328                 Entry e = (Entry) o;
    1329                 Set evalue = (Set) e.getValue();
    1330                 JsonArrayBuilder a = Json.createArrayBuilder();
    1331                 for (Object evo: evalue) {
    1332                     a.add(evo.toString());
    1333                 }
    1334                 object.add(e.getKey().toString(), a.build());
    1335             }
    1336             writer.writeObject(object.build());
    1337         }
    1338         return stringWriter.toString();
    1339     }
    1340 
    1341     @SuppressWarnings({ "rawtypes", "unchecked" })
    1342     private static MultiMap multiMapFromJson(String s) {
    1343         MultiMap ret = null;
    1344         try (JsonReader reader = Json.createReader(new StringReader(s))) {
    1345             JsonObject object = reader.readObject();
    1346             ret = new MultiMap(object.size());
    1347             for (Entry<String, JsonValue> e: object.entrySet()) {
    1348                 JsonValue value = e.getValue();
    1349                 if (value instanceof JsonArray) {
    1350                     for (JsonString js: ((JsonArray) value).getValuesAs(JsonString.class)) {
    1351                         ret.put(e.getKey(), js.getString());
    1352                     }
    1353                 } else if (value instanceof JsonString) {
    1354                     // in some cases, when JsonValue.toString() is called, then additional quotation marks are left in value
    1355                     ret.put(e.getKey(), ((JsonString) value).getString());
    1356                 } else {
    1357                     ret.put(e.getKey(), e.getValue().toString());
    1358                 }
    1359             }
    1360         }
    1361         return ret;
     1265        return StructUtils.putListOfStructs(this, key, val, klass);
    13621266    }
    13631267
     
    13771281     * @param klass the class T
    13781282     * @return the resulting map (same data content as <code>struct</code>)
    1379      */
     1283     * @deprecated use {@link StructUtils#serializeStruct(java.lang.Object, java.lang.Class)}
     1284     */
     1285    @Deprecated
    13801286    public static <T> Map<String, String> serializeStruct(T struct, Class<T> klass) {
    1381         T structPrototype;
    1382         try {
    1383             structPrototype = klass.getConstructor().newInstance();
    1384         } catch (ReflectiveOperationException ex) {
    1385             throw new IllegalArgumentException(ex);
    1386         }
    1387 
    1388         Map<String, String> hash = new LinkedHashMap<>();
    1389         for (Field f : klass.getDeclaredFields()) {
    1390             if (f.getAnnotation(pref.class) == null) {
    1391                 continue;
    1392             }
    1393             Utils.setObjectsAccessible(f);
    1394             try {
    1395                 Object fieldValue = f.get(struct);
    1396                 Object defaultFieldValue = f.get(structPrototype);
    1397                 if (fieldValue != null && (f.getAnnotation(writeExplicitly.class) != null || !Objects.equals(fieldValue, defaultFieldValue))) {
    1398                     String key = f.getName().replace('_', '-');
    1399                     if (fieldValue instanceof Map) {
    1400                         hash.put(key, mapToJson((Map<?, ?>) fieldValue));
    1401                     } else if (fieldValue instanceof MultiMap) {
    1402                         hash.put(key, multiMapToJson((MultiMap<?, ?>) fieldValue));
    1403                     } else {
    1404                         hash.put(key, fieldValue.toString());
    1405                     }
    1406                 }
    1407             } catch (IllegalAccessException ex) {
    1408                 throw new JosmRuntimeException(ex);
    1409             }
    1410         }
    1411         return hash;
     1287        return StructUtils.serializeStruct(struct, klass);
    14121288    }
    14131289
     
    14241300     * @param klass the class T
    14251301     * @return an object of class T, initialized as described above
    1426      */
     1302     * @deprecated use {@link StructUtils#deserializeStruct(java.util.Map, java.lang.Class)}
     1303     */
     1304    @Deprecated
    14271305    public static <T> T deserializeStruct(Map<String, String> hash, Class<T> klass) {
    1428         T struct = null;
    1429         try {
    1430             struct = klass.getConstructor().newInstance();
    1431         } catch (ReflectiveOperationException ex) {
    1432             throw new IllegalArgumentException(ex);
    1433         }
    1434         for (Entry<String, String> keyValue : hash.entrySet()) {
    1435             Object value;
    1436             Field f;
    1437             try {
    1438                 f = klass.getDeclaredField(keyValue.getKey().replace('-', '_'));
    1439             } catch (NoSuchFieldException ex) {
    1440                 Logging.trace(ex);
    1441                 continue;
    1442             }
    1443             if (f.getAnnotation(pref.class) == null) {
    1444                 continue;
    1445             }
    1446             Utils.setObjectsAccessible(f);
    1447             if (f.getType() == Boolean.class || f.getType() == boolean.class) {
    1448                 value = Boolean.valueOf(keyValue.getValue());
    1449             } else if (f.getType() == Integer.class || f.getType() == int.class) {
    1450                 try {
    1451                     value = Integer.valueOf(keyValue.getValue());
    1452                 } catch (NumberFormatException nfe) {
    1453                     continue;
    1454                 }
    1455             } else if (f.getType() == Double.class || f.getType() == double.class) {
    1456                 try {
    1457                     value = Double.valueOf(keyValue.getValue());
    1458                 } catch (NumberFormatException nfe) {
    1459                     continue;
    1460                 }
    1461             } else if (f.getType() == String.class) {
    1462                 value = keyValue.getValue();
    1463             } else if (f.getType().isAssignableFrom(Map.class)) {
    1464                 value = mapFromJson(keyValue.getValue());
    1465             } else if (f.getType().isAssignableFrom(MultiMap.class)) {
    1466                 value = multiMapFromJson(keyValue.getValue());
    1467             } else
    1468                 throw new JosmRuntimeException("unsupported preference primitive type");
    1469 
    1470             try {
    1471                 f.set(struct, value);
    1472             } catch (IllegalArgumentException ex) {
    1473                 throw new AssertionError(ex);
    1474             } catch (IllegalAccessException ex) {
    1475                 throw new JosmRuntimeException(ex);
    1476             }
    1477         }
    1478         return struct;
     1306        return StructUtils.deserializeStruct(hash, klass);
    14791307    }
    14801308
  • trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java

    r12846 r12851  
    2727import org.openstreetmap.gui.jmapviewer.tilesources.TileSourceInfo;
    2828import org.openstreetmap.josm.data.Bounds;
    29 import org.openstreetmap.josm.data.Preferences.pref;
     29import org.openstreetmap.josm.data.StructUtils.StructEntry;
    3030import org.openstreetmap.josm.io.Capabilities;
    3131import org.openstreetmap.josm.io.OsmApi;
     
    214214     */
    215215    public static class ImageryPreferenceEntry {
    216         @pref String name;
    217         @pref String d;
    218         @pref String id;
    219         @pref String type;
    220         @pref String url;
    221         @pref double pixel_per_eastnorth;
    222         @pref String eula;
    223         @pref String attribution_text;
    224         @pref String attribution_url;
    225         @pref String permission_reference_url;
    226         @pref String logo_image;
    227         @pref String logo_url;
    228         @pref String terms_of_use_text;
    229         @pref String terms_of_use_url;
    230         @pref String country_code = "";
    231         @pref String date;
    232         @pref int max_zoom;
    233         @pref int min_zoom;
    234         @pref String cookies;
    235         @pref String bounds;
    236         @pref String shapes;
    237         @pref String projections;
    238         @pref String icon;
    239         @pref String description;
    240         @pref MultiMap<String, String> noTileHeaders;
    241         @pref MultiMap<String, String> noTileChecksums;
    242         @pref int tileSize = -1;
    243         @pref Map<String, String> metadataHeaders;
    244         @pref boolean valid_georeference;
    245         @pref boolean bestMarked;
     216        @StructEntry String name;
     217        @StructEntry String d;
     218        @StructEntry String id;
     219        @StructEntry String type;
     220        @StructEntry String url;
     221        @StructEntry double pixel_per_eastnorth;
     222        @StructEntry String eula;
     223        @StructEntry String attribution_text;
     224        @StructEntry String attribution_url;
     225        @StructEntry String permission_reference_url;
     226        @StructEntry String logo_image;
     227        @StructEntry String logo_url;
     228        @StructEntry String terms_of_use_text;
     229        @StructEntry String terms_of_use_url;
     230        @StructEntry String country_code = "";
     231        @StructEntry String date;
     232        @StructEntry int max_zoom;
     233        @StructEntry int min_zoom;
     234        @StructEntry String cookies;
     235        @StructEntry String bounds;
     236        @StructEntry String shapes;
     237        @StructEntry String projections;
     238        @StructEntry String icon;
     239        @StructEntry String description;
     240        @StructEntry MultiMap<String, String> noTileHeaders;
     241        @StructEntry MultiMap<String, String> noTileChecksums;
     242        @StructEntry int tileSize = -1;
     243        @StructEntry Map<String, String> metadataHeaders;
     244        @StructEntry boolean valid_georeference;
     245        @StructEntry boolean bestMarked;
    246246        // TODO: disabled until change of layers is implemented
    247         // @pref String default_layers;
     247        // @StructEntry String default_layers;
    248248
    249249        /**
  • trunk/src/org/openstreetmap/josm/data/imagery/ImageryLayerInfo.java

    r12846 r12851  
    1919
    2020import org.openstreetmap.josm.Main;
     21import org.openstreetmap.josm.data.StructUtils;
    2122import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryPreferenceEntry;
    2223import org.openstreetmap.josm.gui.PleaseWaitRunnable;
     
    8687    public void load(boolean fastFail) {
    8788        clear();
    88         List<ImageryPreferenceEntry> entries = Main.pref.getListOfStructs("imagery.entries", null, ImageryPreferenceEntry.class);
     89        List<ImageryPreferenceEntry> entries = StructUtils.getListOfStructs(
     90                Config.getPref(), "imagery.entries", null, ImageryPreferenceEntry.class);
    8991        if (entries != null) {
    9092            for (ImageryPreferenceEntry prefEntry : entries) {
     
    362364            entries.add(new ImageryPreferenceEntry(info));
    363365        }
    364         Main.pref.putListOfStructs("imagery.entries", entries, ImageryPreferenceEntry.class);
     366        StructUtils.putListOfStructs(Config.getPref(), "imagery.entries", entries, ImageryPreferenceEntry.class);
    365367    }
    366368
  • trunk/src/org/openstreetmap/josm/data/imagery/OffsetBookmark.java

    r12846 r12851  
    1212
    1313import org.openstreetmap.josm.Main;
    14 import org.openstreetmap.josm.data.Preferences;
    15 import org.openstreetmap.josm.data.Preferences.pref;
    16 import org.openstreetmap.josm.data.Preferences.writeExplicitly;
     14import org.openstreetmap.josm.data.StructUtils;
     15import org.openstreetmap.josm.data.StructUtils.StructEntry;
     16import org.openstreetmap.josm.data.StructUtils.WriteExplicitly;
    1717import org.openstreetmap.josm.data.coor.EastNorth;
    1818import org.openstreetmap.josm.data.coor.LatLon;
     
    3434    private static final List<OffsetBookmark> allBookmarks = new ArrayList<>();
    3535
    36     @pref private String projection_code;
    37     @pref private String imagery_name;
    38     @pref private String name;
    39     @pref @writeExplicitly private double dx, dy;
    40     @pref private double center_lon, center_lat;
     36    @StructEntry private String projection_code;
     37    @StructEntry private String imagery_name;
     38    @StructEntry private String name;
     39    @StructEntry @WriteExplicitly private double dx, dy;
     40    @StructEntry private double center_lon, center_lat;
    4141
    4242    public boolean isUsable(ImageryLayer layer) {
     
    167167
    168168    public static void loadBookmarks() {
    169         List<OffsetBookmark> bookmarks = Main.pref.getListOfStructs("imagery.offsetbookmarks", null, OffsetBookmark.class);
     169        List<OffsetBookmark> bookmarks = StructUtils.getListOfStructs(
     170                Config.getPref(), "imagery.offsetbookmarks", null, OffsetBookmark.class);
    170171        if (bookmarks == null) {
    171172            loadBookmarksOld();
     
    184185
    185186    public static void saveBookmarks() {
    186         Main.pref.putListOfStructs("imagery.offsetbookmarks", allBookmarks, OffsetBookmark.class);
     187        StructUtils.putListOfStructs(Config.getPref(), "imagery.offsetbookmarks", allBookmarks, OffsetBookmark.class);
    187188    }
    188189
     
    276277     */
    277278    public Map<String, String> toPropertiesMap() {
    278         return Preferences.serializeStruct(this, OffsetBookmark.class);
     279        return StructUtils.serializeStruct(this, OffsetBookmark.class);
    279280    }
    280281
     
    287288     */
    288289    public static OffsetBookmark fromPropertiesMap(Map<String, String> properties) {
    289         return Preferences.deserializeStruct(properties, OffsetBookmark.class);
     290        return StructUtils.deserializeStruct(properties, OffsetBookmark.class);
    290291    }
    291292}
  • trunk/src/org/openstreetmap/josm/data/osm/Filter.java

    r12659 r12851  
    44import java.util.Objects;
    55
    6 import org.openstreetmap.josm.data.Preferences.pref;
    7 import org.openstreetmap.josm.data.Preferences.writeExplicitly;
     6import org.openstreetmap.josm.data.StructUtils.StructEntry;
     7import org.openstreetmap.josm.data.StructUtils.WriteExplicitly;
    88import org.openstreetmap.josm.data.osm.search.SearchMode;
    99import org.openstreetmap.josm.data.osm.search.SearchSetting;
     
    7171
    7272    public static class FilterPreferenceEntry {
    73         @writeExplicitly
    74         @pref public String version = "1";
     73        @WriteExplicitly
     74        @StructEntry public String version = "1";
    7575
    76         @pref public String text;
     76        @StructEntry public String text;
    7777
    7878        /**
     
    8585         * @see SearchMode
    8686         */
    87         @writeExplicitly
    88         @pref public String mode = "add";
     87        @WriteExplicitly
     88        @StructEntry public String mode = "add";
    8989
    90         @pref public boolean case_sensitive;
     90        @StructEntry public boolean case_sensitive;
    9191
    92         @pref public boolean regex_search;
     92        @StructEntry public boolean regex_search;
    9393
    94         @pref public boolean mapCSS_search;
     94        @StructEntry public boolean mapCSS_search;
    9595
    9696        /**
     
    9898         * @see Filter#enable
    9999         */
    100         @writeExplicitly
    101         @pref public boolean enable = true;
     100        @WriteExplicitly
     101        @StructEntry public boolean enable = true;
    102102
    103103        /**
     
    106106         * @see Filter#hiding
    107107         */
    108         @writeExplicitly
    109         @pref public boolean hiding;
     108        @WriteExplicitly
     109        @StructEntry public boolean hiding;
    110110
    111111        /**
     
    114114         * @see Filter#inverted
    115115         */
    116         @writeExplicitly
    117         @pref public boolean inverted;
     116        @WriteExplicitly
     117        @StructEntry public boolean inverted;
    118118
    119119        @Override
  • trunk/src/org/openstreetmap/josm/data/osm/FilterModel.java

    r12691 r12851  
    1717
    1818import org.openstreetmap.josm.Main;
     19import org.openstreetmap.josm.data.StructUtils;
    1920import org.openstreetmap.josm.data.osm.Filter.FilterPreferenceEntry;
    2021import org.openstreetmap.josm.data.osm.search.SearchParseError;
     
    2223import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    2324import org.openstreetmap.josm.gui.widgets.OSDLabel;
     25import org.openstreetmap.josm.spi.preferences.Config;
    2426import org.openstreetmap.josm.tools.Logging;
    2527import org.openstreetmap.josm.tools.Utils;
     
    7173     */
    7274    public void loadPrefs(String prefEntry) {
    73         List<FilterPreferenceEntry> entries = Main.pref.getListOfStructs(prefEntry, null, FilterPreferenceEntry.class);
     75        List<FilterPreferenceEntry> entries = StructUtils.getListOfStructs(
     76                Config.getPref(), prefEntry, null, FilterPreferenceEntry.class);
    7477        if (entries != null) {
    7578            for (FilterPreferenceEntry e : entries) {
     
    8992            entries.add(flt.getPreferenceEntry());
    9093        }
    91         Main.pref.putListOfStructs(prefEntry, entries, FilterPreferenceEntry.class);
     94        StructUtils.putListOfStructs(Config.getPref(), prefEntry, entries, FilterPreferenceEntry.class);
    9295    }
    9396
Note: See TracChangeset for help on using the changeset viewer.