Changeset 9821 in josm


Ignore:
Timestamp:
2016-02-18T11:07:38+01:00 (3 years ago)
Author:
bastiK
Message:

fixed #12522 - Advanced preferences: display default entries consistently

Saves default preference entries to a cache file (cache/default_preferences.xml), so the list of advanced preferences is filled with all known default values consistently from the start and not gradually as you use different features during a session.

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/data/preferences.xsd

    r9813 r9821  
    2626        <attribute name="key" type="string" use="required" />
    2727    </complexType>
    28    
     28
    2929    <complexType name="lists">
    3030        <sequence>
     
    5656        <attribute name="value" type="string" use="required"/>
    5757    </complexType>
     58
     59    <!-- cache for default preference values -->
     60
     61    <element name="preferences-defaults" type="tns:root-def"/>
     62
     63    <complexType name="root-def">
     64        <choice minOccurs="0" maxOccurs="unbounded">
     65            <element name="tag" type="tns:tag-def" nillable="true"/>
     66            <element name="list" type="tns:list-def" nillable="true"/>
     67            <element name="lists" type="tns:lists-def" nillable="true"/>
     68            <element name="maps" type="tns:maps-def" nillable="true"/>
     69        </choice>
     70        <attribute name="version" type="string" />
     71    </complexType>
     72
     73    <complexType name="tag-def">
     74        <attribute name="key" type="string" use="required" />
     75        <!-- element must be either nil or have the value attribute -->
     76        <attribute name="value" type="string" use="optional"/>
     77        <attribute name="time" type="decimal" use="required"/>
     78    </complexType>
     79
     80    <complexType name="list-def">
     81         <complexContent>
     82             <extension base="tns:list">
     83                <attribute name="time" type="decimal" use="required"/>
     84            </extension>
     85         </complexContent>
     86    </complexType>
     87
     88    <complexType name="lists-def">
     89         <complexContent>
     90             <extension base="tns:lists">
     91                <attribute name="time" type="decimal" use="required"/>
     92            </extension>
     93         </complexContent>
     94    </complexType>
     95
     96    <complexType name="maps-def">
     97         <complexContent>
     98             <extension base="tns:maps">
     99                <attribute name="time" type="decimal" use="required"/>
     100            </extension>
     101         </complexContent>
     102    </complexType>
    58103</schema>
  • trunk/src/org/openstreetmap/josm/Main.java

    r9751 r9821  
    1515import java.awt.event.WindowEvent;
    1616import java.io.File;
     17import java.io.IOException;
    1718import java.lang.ref.WeakReference;
    1819import java.net.URI;
     
    10981099                }
    10991100            }
     1101            try {
     1102                pref.saveDefaults();
     1103            } catch (IOException ex) {
     1104                Main.warn(tr("Failed to save default preferences."));
     1105            }
    11001106            worker.shutdownNow();
    11011107            ImageProvider.shutdown(true);
  • trunk/src/org/openstreetmap/josm/data/Preferences.java

    r9805 r9821  
    6666import org.openstreetmap.josm.tools.CheckParameterUtil;
    6767import org.openstreetmap.josm.tools.ColorHelper;
     68import org.openstreetmap.josm.tools.FilteredCollection;
    6869import org.openstreetmap.josm.tools.I18n;
    6970import org.openstreetmap.josm.tools.MultiMap;
     71import org.openstreetmap.josm.tools.Predicate;
    7072import org.openstreetmap.josm.tools.Utils;
    7173import org.xml.sax.SAXException;
     
    102104    };
    103105
     106    private static final long MAX_AGE_DEFAULT_PREFERENCES = 60 * 60 * 24 * 50; // 50 days (in seconds)
     107
    104108    /**
    105109     * Internal storage for the preference directory.
     
    137141     */
    138142    protected final SortedMap<String, Setting<?>> defaultsMap = new TreeMap<>();
     143
     144    private final Predicate<Entry<String, Setting<?>>> NO_DEFAULT_SETTINGS_ENTRY = new Predicate<Entry<String, Setting<?>>>() {
     145        @Override
     146        public boolean evaluate(Entry<String, Setting<?>> e) {
     147            return !e.getValue().equals(defaultsMap.get(e.getKey()));
     148        }
     149    };
    139150
    140151    /**
     
    293304
    294305    /**
    295      * Returns the user preferences file (preferences.xml)
     306     * Returns the user preferences file (preferences.xml).
    296307     * @return The user preferences file (preferences.xml)
    297308     */
     
    301312
    302313    /**
    303      * Returns the user plugin directory
     314     * Returns the cache file for default preferences.
     315     * @return the cache file for default preferences
     316     */
     317    public File getDefaultsCacheFile() {
     318        return new File(getCacheDirectory(), "default_preferences.xml");
     319    }
     320
     321    /**
     322     * Returns the user plugin directory.
    304323     * @return The user plugin directory
    305324     */
     
    493512     */
    494513    public void save() throws IOException {
    495         /* currently unused, but may help to fix configuration issues in future */
    496         putInteger("josm.version", Version.getInstance().getVersion());
    497 
    498         updateSystemProperties();
    499 
    500         File prefFile = getPreferenceFile();
     514        save(getPreferenceFile(),
     515                new FilteredCollection<>(settingsMap.entrySet(), NO_DEFAULT_SETTINGS_ENTRY), false);
     516    }
     517
     518    public void saveDefaults() throws IOException {
     519        save(getDefaultsCacheFile(), defaultsMap.entrySet(), true);
     520    }
     521
     522    public void save(File prefFile, Collection<Entry<String, Setting<?>>> settings, boolean defaults) throws IOException {
     523
     524        if (!defaults) {
     525            /* currently unused, but may help to fix configuration issues in future */
     526            putInteger("josm.version", Version.getInstance().getVersion());
     527
     528            updateSystemProperties();
     529        }
     530
    501531        File backupFile = new File(prefFile + "_backup");
    502532
     
    508538        try (PrintWriter out = new PrintWriter(new OutputStreamWriter(
    509539                new FileOutputStream(prefFile + "_tmp"), StandardCharsets.UTF_8), false)) {
    510             out.print(toXML(settingsMap, false));
     540            out.print(toXML(settings, false, defaults));
    511541        }
    512542
     
    546576        File pref = getPreferenceFile();
    547577        PreferencesReader.validateXML(pref);
    548         PreferencesReader reader = new PreferencesReader();
     578        PreferencesReader reader = new PreferencesReader(false);
    549579        reader.fromXML(pref);
    550580        settingsMap.clear();
     
    555585
    556586    /**
     587     * Loads default preferences from default settings cache file.
     588     *
     589     * Discards entries older than {@link #MAX_AGE_DEFAULT_PREFERENCES}.
     590     *
     591     * @throws IOException if any I/O error occurs while reading the file
     592     * @throws SAXException if the settings file does not contain valid XML
     593     * @throws XMLStreamException if an XML error occurs while parsing the file (after validation)
     594     */
     595    protected void loadDefaults() throws IOException, XMLStreamException, SAXException {
     596        File def = getDefaultsCacheFile();
     597        PreferencesReader.validateXML(def);
     598        PreferencesReader reader = new PreferencesReader(true);
     599        reader.fromXML(def);
     600        defaultsMap.clear();
     601        long minTime = System.currentTimeMillis() / 1000 - MAX_AGE_DEFAULT_PREFERENCES;
     602        for (Entry<String, Setting<?>> e : reader.getSettings().entrySet()) {
     603            if (e.getValue().getTime() >= minTime) {
     604                defaultsMap.put(e.getKey(), e.getValue());
     605            }
     606        }
     607    }
     608
     609    /**
    557610     * Loads preferences from XML reader.
    558611     * @param in XML reader
     
    560613     */
    561614    public void fromXML(Reader in) throws XMLStreamException {
    562         PreferencesReader reader = new PreferencesReader();
     615        PreferencesReader reader = new PreferencesReader(false);
    563616        reader.fromXML(in);
    564617        settingsMap.clear();
     
    629682            load();
    630683            initSuccessful = true;
    631         } catch (Exception e) {
     684        } catch (IOException | SAXException | XMLStreamException e) {
    632685            Main.error(e);
    633686            File backupFile = new File(prefDir, "preferences.xml.bak");
     
    647700                Main.error(e1);
    648701                Main.warn(tr("Failed to initialize preferences. Failed to reset preference file to default: {0}", getPreferenceFile()));
     702            }
     703        }
     704        File def = getDefaultsCacheFile();
     705        if (def.exists()) {
     706            try {
     707                loadDefaults();
     708            } catch (IOException | XMLStreamException | SAXException e) {
     709                Main.error(e);
     710                Main.warn(tr("Failed to load defaults cache file: {0}", def));
     711                defaultsMap.clear();
     712                if (!def.delete()) {
     713                    Main.warn(tr("Failed to delete faulty defaults cache file: {0}", def));
     714                }
    649715            }
    650716        }
     
    880946        CheckParameterUtil.ensureParameterNotNull(def);
    881947        Setting<?> oldDef = defaultsMap.get(key);
    882         if (oldDef != null && oldDef.getValue() != null && def.getValue() != null && !def.equals(oldDef)) {
     948        if (oldDef != null && oldDef.isNew() && oldDef.getValue() != null && def.getValue() != null && !def.equals(oldDef)) {
    883949            Main.info("Defaults for " + key + " differ: " + def + " != " + defaultsMap.get(key));
    884950        }
    885951        if (def.getValue() != null || oldDef == null) {
    886             defaultsMap.put(key, def.copy());
     952            Setting<?> defCopy = def.copy();
     953            defCopy.setTime(System.currentTimeMillis() / 1000);
     954            defCopy.setNew(true);
     955            defaultsMap.put(key, defCopy);
    887956        }
    888957        Setting<?> prop = settingsMap.get(key);
     
    13331402        private final StringBuilder b;
    13341403        private final boolean noPassword;
     1404        private final boolean defaults;
    13351405        private String key;
    13361406
    1337         SettingToXml(StringBuilder b, boolean noPassword) {
     1407        SettingToXml(StringBuilder b, boolean noPassword, boolean defaults) {
    13381408            this.b = b;
    13391409            this.noPassword = noPassword;
     1410            this.defaults = defaults;
    13401411        }
    13411412
    13421413        public void setKey(String key) {
    13431414            this.key = key;
     1415        }
     1416
     1417        private void addTime(Setting setting) {
     1418            if (defaults) {
     1419                Long time = setting.getTime();
     1420                if (time == null) throw new IllegalStateException();
     1421                b.append("' time='").append(time);
     1422            }
    13441423        }
    13451424
     
    13481427            if (noPassword && "osm-server.password".equals(key))
    13491428                return; // do not store plain password.
    1350             /* don't save default values */
    1351             if (setting.equals(defaultsMap.get(key)))
    1352                 return;
    13531429            b.append("  <tag key='");
    13541430            b.append(XmlWriter.encode(key));
    1355             b.append("' value='");
    1356             b.append(XmlWriter.encode(setting.getValue()));
    1357             b.append("'/>\n");
     1431            addTime(setting);
     1432            if (setting.getValue() != null) {
     1433                b.append("' value='");
     1434                b.append(XmlWriter.encode(setting.getValue()));
     1435                b.append("'/>\n");
     1436            } else if (defaults) {
     1437                b.append("' xsi:nil='true'/>\n");
     1438            } else {
     1439                throw new NullPointerException();
     1440            }
    13581441        }
    13591442
    13601443        @Override
    13611444        public void visit(ListSetting setting) {
    1362             /* don't save default values */
    1363             if (setting.equals(defaultsMap.get(key)))
    1364                 return;
    1365             b.append("  <list key='").append(XmlWriter.encode(key)).append("'>\n");
    1366             for (String s : setting.getValue()) {
    1367                 b.append("    <entry value='").append(XmlWriter.encode(s)).append("'/>\n");
    1368             }
    1369             b.append("  </list>\n");
     1445            b.append("  <list key='").append(XmlWriter.encode(key));
     1446            addTime(setting);
     1447            if (setting.getValue() != null) {
     1448                b.append("'>\n");
     1449                for (String s : setting.getValue()) {
     1450                    b.append("    <entry value='").append(XmlWriter.encode(s)).append("'/>\n");
     1451                }
     1452                b.append("  </list>\n");
     1453            } else if (defaults) {
     1454                b.append("' xsi:nil='true'/>\n");
     1455            } else {
     1456                throw new NullPointerException();
     1457            }
    13701458        }
    13711459
    13721460        @Override
    13731461        public void visit(ListListSetting setting) {
    1374             /* don't save default values */
    1375             if (setting.equals(defaultsMap.get(key)))
    1376                 return;
    1377             b.append("  <lists key='").append(XmlWriter.encode(key)).append("'>\n");
    1378             for (List<String> list : setting.getValue()) {
    1379                 b.append("    <list>\n");
    1380                 for (String s : list) {
    1381                     b.append("      <entry value='").append(XmlWriter.encode(s)).append("'/>\n");
     1462            b.append("  <lists key='").append(XmlWriter.encode(key));
     1463            addTime(setting);
     1464            if (setting.getValue() != null) {
     1465                b.append("'>\n");
     1466                for (List<String> list : setting.getValue()) {
     1467                    b.append("    <list>\n");
     1468                    for (String s : list) {
     1469                        b.append("      <entry value='").append(XmlWriter.encode(s)).append("'/>\n");
     1470                    }
     1471                    b.append("    </list>\n");
    13821472                }
    1383                 b.append("    </list>\n");
    1384             }
    1385             b.append("  </lists>\n");
     1473                b.append("  </lists>\n");
     1474            } else if (defaults) {
     1475                b.append("' xsi:nil='true'/>\n");
     1476            } else {
     1477                throw new NullPointerException();
     1478            }
    13861479        }
    13871480
    13881481        @Override
    13891482        public void visit(MapListSetting setting) {
    1390             b.append("  <maps key='").append(XmlWriter.encode(key)).append("'>\n");
    1391             for (Map<String, String> struct : setting.getValue()) {
    1392                 b.append("    <map>\n");
    1393                 for (Entry<String, String> e : struct.entrySet()) {
    1394                     b.append("      <tag key='").append(XmlWriter.encode(e.getKey()))
    1395                      .append("' value='").append(XmlWriter.encode(e.getValue())).append("'/>\n");
     1483            b.append("  <maps key='").append(XmlWriter.encode(key));
     1484            addTime(setting);
     1485            if (setting.getValue() != null) {
     1486                b.append("'>\n");
     1487                for (Map<String, String> struct : setting.getValue()) {
     1488                    b.append("    <map>\n");
     1489                    for (Entry<String, String> e : struct.entrySet()) {
     1490                        b.append("      <tag key='").append(XmlWriter.encode(e.getKey()))
     1491                         .append("' value='").append(XmlWriter.encode(e.getValue())).append("'/>\n");
     1492                    }
     1493                    b.append("    </map>\n");
    13961494                }
    1397                 b.append("    </map>\n");
    1398             }
    1399             b.append("  </maps>\n");
     1495                b.append("  </maps>\n");
     1496            } else if (defaults) {
     1497                b.append("' xsi:nil='true'/>\n");
     1498            } else {
     1499                throw new NullPointerException();
     1500            }
    14001501        }
    14011502    }
     
    14071508     */
    14081509    public String toXML(boolean nopass) {
    1409         return toXML(settingsMap, nopass);
     1510        return toXML(settingsMap.entrySet(), nopass, false);
    14101511    }
    14111512
     
    14161517     * @return XML
    14171518     */
    1418     public String toXML(Map<String, Setting<?>> settings, boolean nopass) {
    1419         StringBuilder b = new StringBuilder(
    1420                 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<preferences xmlns=\"")
    1421                 .append(Main.getXMLBase()).append("/preferences-1.0\" version=\"")
    1422                 .append(Version.getInstance().getVersion()).append("\">\n");
    1423         SettingToXml toXml = new SettingToXml(b, nopass);
    1424         for (Entry<String, Setting<?>> e : settings.entrySet()) {
     1519    public String toXML(Collection<Entry<String, Setting<?>>> settings, boolean nopass, boolean defaults) {
     1520        String rootElement = defaults ? "preferences-defaults" : "preferences";
     1521        StringBuilder b = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<")
     1522                .append(rootElement).append(" xmlns='")
     1523                .append(Main.getXMLBase()).append("/preferences-1.0'");
     1524        if (defaults) {
     1525            b.append(" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'");
     1526        }
     1527        b.append(" version='").append(Version.getInstance().getVersion()).append("'>\n");
     1528        SettingToXml toXml = new SettingToXml(b, nopass, defaults);
     1529        for (Entry<String, Setting<?>> e : settings) {
    14251530            toXml.setKey(e.getKey());
    14261531            e.getValue().visit(toXml);
    14271532        }
    1428         b.append("</preferences>\n");
     1533        b.append("</").append(rootElement).append(">\n");
    14291534        return b.toString();
    14301535    }
  • trunk/src/org/openstreetmap/josm/data/preferences/AbstractSetting.java

    r9759 r9821  
    1212public abstract class AbstractSetting<T> implements Setting<T> {
    1313    protected final T value;
     14    protected Long time;
     15    protected boolean isNew;
    1416    /**
    1517     * Constructs a new {@code AbstractSetting} with the given value
     
    1820    public AbstractSetting(T value) {
    1921        this.value = value;
     22        this.time = null;
     23        this.isNew = false;
    2024    }
    2125
     
    2327    public T getValue() {
    2428        return value;
     29    }
     30
     31    @Override
     32    public void setTime(Long time) {
     33        this.time = time;
     34    }
     35
     36    @Override
     37    public Long getTime() {
     38        return this.time;
     39    }
     40
     41    @Override
     42    public void setNew(boolean isNew) {
     43        this.isNew = isNew;
     44    }
     45
     46    @Override
     47    public boolean isNew() {
     48        return isNew;
    2549    }
    2650
  • trunk/src/org/openstreetmap/josm/data/preferences/PreferencesReader.java

    r9798 r9821  
    3838public class PreferencesReader {
    3939
     40    private static final String XSI_NS = "http://www.w3.org/2001/XMLSchema-instance";
     41
    4042    private final SortedMap<String, Setting<?>> settings = new TreeMap<>();
    4143    private int version = 0;
    4244    private XMLStreamReader parser;
     45
     46    private final boolean defaults;
     47
     48    /**
     49     * Constructs a new {@code PreferencesReader}.
     50     * @param defaults true when reading from the cache file for default preferences,
     51     * false for the regular preferences config file
     52     */
     53    public PreferencesReader(boolean defaults) {
     54        this.defaults = defaults;
     55    }
    4356
    4457    /**
     
    111124        while (true) {
    112125            if (event == XMLStreamConstants.START_ELEMENT) {
     126                String topLevelElementName = defaults ? "preferences-defaults" : "preferences";
     127                String localName = parser.getLocalName();
     128                if (!topLevelElementName.equals(localName)) {
     129                    throw new XMLStreamException(tr("Expected element ''{0}'', but got ''{1}''", topLevelElementName, localName), parser.getLocation());
     130                }
    113131                try {
    114132                    version = Integer.parseInt(parser.getAttributeValue(null, "version"));
     
    138156                switch(localName) {
    139157                case "tag":
    140                     settings.put(parser.getAttributeValue(null, "key"), new StringSetting(parser.getAttributeValue(null, "value")));
     158                    Setting setting;
     159                    if (defaults && isNil()) {
     160                        setting = new StringSetting(null);
     161                    } else {
     162                        String value = parser.getAttributeValue(null, "value");
     163                        if (value == null) {
     164                            throw new XMLStreamException(tr("value expected"), parser.getLocation());
     165                        }
     166                        setting = new StringSetting(value);
     167                    }
     168                    if (defaults) {
     169                        setting.setTime(Math.round(Double.parseDouble(parser.getAttributeValue(null, "time"))));
     170                    }
     171                    settings.put(parser.getAttributeValue(null, "key"), setting);
    141172                    jumpToEnd();
    142173                    break;
    143174                case "list":
    144                 case "collection":
    145175                case "lists":
    146176                case "maps":
     
    169199    private void parseToplevelList() throws XMLStreamException {
    170200        String key = parser.getAttributeValue(null, "key");
     201        Long time = null;
     202        if (defaults) {
     203            time = Math.round(Double.parseDouble(parser.getAttributeValue(null, "time")));
     204        }
    171205        String name = parser.getLocalName();
    172206
     
    174208        List<List<String>> lists = null;
    175209        List<Map<String, String>> maps = null;
    176         while (true) {
    177             int event = parser.next();
    178             if (event == XMLStreamConstants.START_ELEMENT) {
    179                 String localName = parser.getLocalName();
    180                 switch(localName) {
    181                 case "entry":
    182                     if (entries == null) {
    183                         entries = new ArrayList<>();
     210        if (defaults && isNil()) {
     211            Setting setting;
     212            switch (name) {
     213                case "lists":
     214                    setting = new ListListSetting(null);
     215                    break;
     216                case "maps":
     217                    setting = new MapListSetting(null);
     218                    break;
     219                default:
     220                    setting = new ListSetting(null);
     221                    break;
     222            }
     223            setting.setTime(time);
     224            settings.put(key, setting);
     225            jumpToEnd();
     226        } else {
     227            while (true) {
     228                int event = parser.next();
     229                if (event == XMLStreamConstants.START_ELEMENT) {
     230                    String localName = parser.getLocalName();
     231                    switch(localName) {
     232                    case "entry":
     233                        if (entries == null) {
     234                            entries = new ArrayList<>();
     235                        }
     236                        entries.add(parser.getAttributeValue(null, "value"));
     237                        jumpToEnd();
     238                        break;
     239                    case "list":
     240                        if (lists == null) {
     241                            lists = new ArrayList<>();
     242                        }
     243                        lists.add(parseInnerList());
     244                        break;
     245                    case "map":
     246                        if (maps == null) {
     247                            maps = new ArrayList<>();
     248                        }
     249                        maps.add(parseMap());
     250                        break;
     251                    default:
     252                        throwException("Unexpected element: "+localName);
    184253                    }
    185                     entries.add(parser.getAttributeValue(null, "value"));
    186                     jumpToEnd();
    187                     break;
    188                 case "list":
    189                     if (lists == null) {
    190                         lists = new ArrayList<>();
    191                     }
    192                     lists.add(parseInnerList());
    193                     break;
    194                 case "map":
    195                     if (maps == null) {
    196                         maps = new ArrayList<>();
    197                     }
    198                     maps.add(parseMap());
    199                     break;
    200                 default:
    201                     throwException("Unexpected element: "+localName);
    202                 }
    203             } else if (event == XMLStreamConstants.END_ELEMENT) {
    204                 break;
    205             }
    206         }
    207         if (entries != null) {
    208             settings.put(key, new ListSetting(Collections.unmodifiableList(entries)));
    209         } else if (lists != null) {
    210             settings.put(key, new ListListSetting(Collections.unmodifiableList(lists)));
    211         } else if (maps != null) {
    212             settings.put(key, new MapListSetting(Collections.unmodifiableList(maps)));
    213         } else {
    214             if ("lists".equals(name)) {
    215                 settings.put(key, new ListListSetting(Collections.<List<String>>emptyList()));
    216             } else if ("maps".equals(name)) {
    217                 settings.put(key, new MapListSetting(Collections.<Map<String, String>>emptyList()));
     254                } else if (event == XMLStreamConstants.END_ELEMENT) {
     255                    break;
     256                }
     257            }
     258            Setting setting;
     259            if (entries != null) {
     260                setting = new ListSetting(Collections.unmodifiableList(entries));
     261            } else if (lists != null) {
     262                setting = new ListListSetting(Collections.unmodifiableList(lists));
     263            } else if (maps != null) {
     264                setting = new MapListSetting(Collections.unmodifiableList(maps));
    218265            } else {
    219                 settings.put(key, new ListSetting(Collections.<String>emptyList()));
    220             }
     266                switch (name) {
     267                    case "lists":
     268                        setting = new ListListSetting(Collections.<List<String>>emptyList());
     269                        break;
     270                    case "maps":
     271                        setting = new MapListSetting(Collections.<Map<String, String>>emptyList());
     272                        break;
     273                    default:
     274                        setting = new ListSetting(Collections.<String>emptyList());
     275                        break;
     276                }
     277            }
     278            if (defaults) {
     279                setting.setTime(time);
     280            }
     281            settings.put(key, setting);
    221282        }
    222283    }
     
    258319    }
    259320
     321    /**
     322     * Check if the current element is nil (meaning the value of the setting is null).
     323     * @return true, if the current element is nil
     324     * @see https://msdn.microsoft.com/en-us/library/2b314yt2(v=vs.85).aspx
     325     */
     326    private boolean isNil() {
     327        String nil = parser.getAttributeValue(XSI_NS, "nil");
     328        return "true".equals(nil) || "1".equals(nil);
     329    }
     330
     331    /**
     332     * Throw RuntimeException with line and column number.
     333     *
     334     * Only use this for errors that should not be possible after schema validation.
     335     * @param msg the error message
     336     */
    260337    private void throwException(String msg) {
    261338        throw new RuntimeException(msg + tr(" (at line {0}, column {1})",
  • trunk/src/org/openstreetmap/josm/data/preferences/Setting.java

    r9759 r9821  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.data.preferences;
     3
     4import org.openstreetmap.josm.data.Preferences;
    35
    46/**
     
    4648     */
    4749    Setting<T> getNullInstance();
     50
     51    /**
     52     * Set the time for this setting.
     53     *
     54     * For default preferences. They are saved in a cache file. Keeping the
     55     * time allows to discard very old default settings.
     56     * @param time the time in seconds since epoch
     57     */
     58    void setTime(Long time);
     59
     60    /**
     61     * Get the time for this setting.
     62     * @return the time for this setting
     63     * @see #setTime(java.lang.Long)
     64     */
     65    Long getTime();
     66
     67    /**
     68     * Mark setting as new.
     69     *
     70     * For default preferences. A setting is marked as new, if it has been seen
     71     * in the current session.
     72     * Methods like {@link Preferences#get(java.lang.String, java.lang.String)},
     73     * can be called from different parts of the code with the same key. In this case,
     74     * the supplied default value must match. However, this is only an error if the mismatching
     75     * default value has been seen in the same session (and not loaded from cache).
     76     * @param isNew true, if it is new
     77     */
     78    void setNew(boolean isNew);
     79
     80    /**
     81     * Return if the setting has been marked as new.
     82     * @return true, if the setting has been marked as new
     83     * @see #setNew(boolean)
     84     */
     85    boolean isNew();
    4886}
Note: See TracChangeset for help on using the changeset viewer.