Ticket #12522: save_default_settings.patch

File save_default_settings.patch, 17.1 KB (added by bastiK, 5 years ago)
  • src/org/openstreetmap/josm/Main.java

     
    1414import java.awt.event.WindowAdapter;
    1515import java.awt.event.WindowEvent;
    1616import java.io.File;
     17import java.io.IOException;
    1718import java.lang.ref.WeakReference;
    1819import java.net.URI;
    1920import java.net.URISyntaxException;
     
    10971098                    Main.main.removeLayer(l);
    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);
    11021108
  • src/org/openstreetmap/josm/data/Preferences.java

     
    6565import org.openstreetmap.josm.io.XmlWriter;
    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;
    7274
     
    299301        return new File(getPreferencesDirectory(), "preferences.xml");
    300302    }
    301303
     304    public File getDefaultsCacheFile() {
     305        return new File(getCacheDirectory(), "default_preferences.xml");
     306    }
     307
    302308    /**
    303309     * Returns the user plugin directory
    304310     * @return The user plugin directory
     
    487493        return put(key, Long.toString(value));
    488494    }
    489495
     496    private Predicate<Entry<String, Setting<?>>> NO_DEFAULT_SETTINGS_ENTRY = new Predicate<Entry<String, Setting<?>>>() {
     497        @Override
     498        public boolean evaluate(Entry<String, Setting<?>> e) {
     499            return !e.getValue().equals(defaultsMap.get(e.getKey()));
     500        }
     501    };
     502   
    490503    /**
    491504     * Called after every put. In case of a problem, do nothing but output the error in log.
    492505     * @throws IOException if any I/O error occurs
    493506     */
    494507    public void save() throws IOException {
     508        save(getPreferenceFile(),
     509                new FilteredCollection<>(settingsMap.entrySet(), NO_DEFAULT_SETTINGS_ENTRY), false);
     510    }
     511   
     512    public void saveDefaults() throws IOException {
     513        save(getDefaultsCacheFile(), defaultsMap.entrySet(), true);
     514    }
     515   
     516    public void save(File prefFile, Collection<Entry<String, Setting<?>>> settings, boolean nullValueAllowed) throws IOException {
    495517        /* currently unused, but may help to fix configuration issues in future */
    496518        putInteger("josm.version", Version.getInstance().getVersion());
    497519
    498520        updateSystemProperties();
    499521
    500         File prefFile = getPreferenceFile();
    501522        File backupFile = new File(prefFile + "_backup");
    502523
    503524        // Backup old preferences if there are old preferences
     
    507528
    508529        try (PrintWriter out = new PrintWriter(new OutputStreamWriter(
    509530                new FileOutputStream(prefFile + "_tmp"), StandardCharsets.UTF_8), false)) {
    510             out.print(toXML(settingsMap, false));
     531            out.print(toXML(settings, false, nullValueAllowed));
    511532        }
    512533
    513534        File tmpFile = new File(prefFile + "_tmp");
     
    552573        updateSystemProperties();
    553574        removeObsolete(reader.getVersion());
    554575    }
     576   
     577    protected void loadDefaults() throws IOException, XMLStreamException, SAXException {
     578        File def = getDefaultsCacheFile();
     579        PreferencesReader reader = new PreferencesReader();
     580        reader.fromXML(def);
     581        defaultsMap.clear();
     582        defaultsMap.putAll(reader.getSettings());
     583    }
    555584
    556585    public void fromXML(Reader in) throws XMLStreamException {
    557586        PreferencesReader reader = new PreferencesReader();
     
    623652        try {
    624653            load();
    625654            initSuccessful = true;
    626         } catch (Exception e) {
     655        } catch (IOException | SAXException | XMLStreamException e) {
    627656            Main.error(e);
    628657            File backupFile = new File(prefDir, "preferences.xml.bak");
    629658            JOptionPane.showMessageDialog(
     
    643672                Main.warn(tr("Failed to initialize preferences. Failed to reset preference file to default: {0}", getPreferenceFile()));
    644673            }
    645674        }
     675        File def = getDefaultsCacheFile();
     676        if (def.exists()) {
     677            try {
     678                loadDefaults();
     679            } catch (IOException | XMLStreamException | SAXException e) {
     680                Main.error(e);
     681                Main.warn(tr("Failed to initialize defaults cache."));
     682                try {
     683                    defaultsMap.clear();
     684                    saveDefaults();
     685                } catch (IOException e1) {
     686                    Main.error(e1);
     687                    Main.warn(tr("Failed to initialize defaults cache."));
     688                }
     689            }
     690        }
    646691    }
    647692
    648693    public final void resetToDefault() {
     
    13271372    private class SettingToXml implements SettingVisitor {
    13281373        private final StringBuilder b;
    13291374        private final boolean noPassword;
     1375        private final boolean nullValueAllowed;
    13301376        private String key;
    13311377
    1332         SettingToXml(StringBuilder b, boolean noPassword) {
     1378        SettingToXml(StringBuilder b, boolean noPassword, boolean nullValueAllowed) {
    13331379            this.b = b;
    13341380            this.noPassword = noPassword;
     1381            this.nullValueAllowed = nullValueAllowed;
    13351382        }
    13361383
    13371384        public void setKey(String key) {
     
    13421389        public void visit(StringSetting setting) {
    13431390            if (noPassword && "osm-server.password".equals(key))
    13441391                return; // do not store plain password.
    1345             /* don't save default values */
    1346             if (setting.equals(defaultsMap.get(key)))
    1347                 return;
    13481392            b.append("  <tag key='");
    13491393            b.append(XmlWriter.encode(key));
    1350             b.append("' value='");
    1351             b.append(XmlWriter.encode(setting.getValue()));
    1352             b.append("'/>\n");
     1394            if (setting.getValue() != null) {
     1395                b.append("' value='");
     1396                b.append(XmlWriter.encode(setting.getValue()));
     1397                b.append("'/>\n");
     1398            } else if (nullValueAllowed) {
     1399                b.append("' novalue='true'/>\n");
     1400            } else {
     1401                throw new NullPointerException();
     1402            }
    13531403        }
    13541404
    13551405        @Override
    13561406        public void visit(ListSetting setting) {
    1357             /* don't save default values */
    1358             if (setting.equals(defaultsMap.get(key)))
    1359                 return;
    1360             b.append("  <list key='").append(XmlWriter.encode(key)).append("'>\n");
    1361             for (String s : setting.getValue()) {
    1362                 b.append("    <entry value='").append(XmlWriter.encode(s)).append("'/>\n");
     1407            b.append("  <list key='").append(XmlWriter.encode(key));
     1408            if (setting.getValue() != null) {
     1409                b.append("'>\n");
     1410                for (String s : setting.getValue()) {
     1411                    b.append("    <entry value='").append(XmlWriter.encode(s)).append("'/>\n");
     1412                }
     1413                b.append("  </list>\n");
     1414            } else if (nullValueAllowed) {
     1415                b.append("' novalue='true'/>\n");
     1416            } else {
     1417                throw new NullPointerException();
    13631418            }
    1364             b.append("  </list>\n");
    13651419        }
    13661420
    13671421        @Override
    13681422        public void visit(ListListSetting setting) {
    1369             /* don't save default values */
    1370             if (setting.equals(defaultsMap.get(key)))
    1371                 return;
    1372             b.append("  <lists key='").append(XmlWriter.encode(key)).append("'>\n");
    1373             for (List<String> list : setting.getValue()) {
    1374                 b.append("    <list>\n");
    1375                 for (String s : list) {
    1376                     b.append("      <entry value='").append(XmlWriter.encode(s)).append("'/>\n");
     1423            b.append("  <lists key='").append(XmlWriter.encode(key));
     1424            if (setting.getValue() != null) {
     1425                b.append("'>\n");
     1426                for (List<String> list : setting.getValue()) {
     1427                    b.append("    <list>\n");
     1428                    for (String s : list) {
     1429                        b.append("      <entry value='").append(XmlWriter.encode(s)).append("'/>\n");
     1430                    }
     1431                    b.append("    </list>\n");
    13771432                }
    1378                 b.append("    </list>\n");
     1433                b.append("  </lists>\n");
     1434            } else if (nullValueAllowed) {
     1435                b.append("' novalue='true'/>\n");
     1436            } else {
     1437                throw new NullPointerException();
    13791438            }
    1380             b.append("  </lists>\n");
    13811439        }
    13821440
    13831441        @Override
    13841442        public void visit(MapListSetting setting) {
    1385             b.append("  <maps key='").append(XmlWriter.encode(key)).append("'>\n");
    1386             for (Map<String, String> struct : setting.getValue()) {
    1387                 b.append("    <map>\n");
    1388                 for (Entry<String, String> e : struct.entrySet()) {
    1389                     b.append("      <tag key='").append(XmlWriter.encode(e.getKey()))
    1390                      .append("' value='").append(XmlWriter.encode(e.getValue())).append("'/>\n");
     1443            b.append("  <maps key='").append(XmlWriter.encode(key));
     1444            if (setting.getValue() != null) {
     1445                b.append("'>\n");
     1446                for (Map<String, String> struct : setting.getValue()) {
     1447                    b.append("    <map>\n");
     1448                    for (Entry<String, String> e : struct.entrySet()) {
     1449                        b.append("      <tag key='").append(XmlWriter.encode(e.getKey()))
     1450                         .append("' value='").append(XmlWriter.encode(e.getValue())).append("'/>\n");
     1451                    }
     1452                    b.append("    </map>\n");
    13911453                }
    1392                 b.append("    </map>\n");
     1454                b.append("  </maps>\n");
     1455            } else if (nullValueAllowed) {
     1456                b.append("' novalue='true'/>\n");
     1457            } else {
     1458                throw new NullPointerException();
    13931459            }
    1394             b.append("  </maps>\n");
    13951460        }
    13961461    }
    13971462
    13981463    public String toXML(boolean nopass) {
    1399         return toXML(settingsMap, nopass);
     1464        return toXML(settingsMap.entrySet(), nopass, false);
    14001465    }
    14011466
    1402     public String toXML(Map<String, Setting<?>> settings, boolean nopass) {
     1467    public String toXML(Collection<Entry<String, Setting<?>>> settings, boolean nopass, boolean nullValueAllowed) {
    14031468        StringBuilder b = new StringBuilder(
    14041469                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<preferences xmlns=\"")
    14051470                .append(Main.getXMLBase()).append("/preferences-1.0\" version=\"")
    14061471                .append(Version.getInstance().getVersion()).append("\">\n");
    1407         SettingToXml toXml = new SettingToXml(b, nopass);
    1408         for (Entry<String, Setting<?>> e : settings.entrySet()) {
     1472        SettingToXml toXml = new SettingToXml(b, nopass, nullValueAllowed);
     1473        for (Entry<String, Setting<?>> e : settings) {
    14091474            toXml.setKey(e.getKey());
    14101475            e.getValue().visit(toXml);
    14111476        }
  • src/org/openstreetmap/josm/data/preferences/PreferencesReader.java

     
    137137                String localName = parser.getLocalName();
    138138                switch(localName) {
    139139                case "tag":
    140                     settings.put(parser.getAttributeValue(null, "key"), new StringSetting(parser.getAttributeValue(null, "value")));
     140                    if (parser.getAttributeValue(null, "novalue") != null) {
     141                        settings.put(parser.getAttributeValue(null, "key"), new StringSetting(null));
     142                    } else {
     143                        settings.put(parser.getAttributeValue(null, "key"), new StringSetting(parser.getAttributeValue(null, "value")));
     144                    }
    141145                    jumpToEnd();
    142146                    break;
    143147                case "list":
     
    173177        List<String> entries = null;
    174178        List<List<String>> lists = null;
    175179        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<>();
    184                     }
    185                     entries.add(parser.getAttributeValue(null, "value"));
    186                     jumpToEnd();
     180        if (parser.getAttributeValue(null, "novalue") != null) {
     181            switch (name) {
     182                case "lists":
     183                    settings.put(key, new ListListSetting(null));
    187184                    break;
    188                 case "list":
    189                     if (lists == null) {
    190                         lists = new ArrayList<>();
    191                     }
    192                     lists.add(parseInnerList());
     185                case "maps":
     186                    settings.put(key, new MapListSetting(null));
    193187                    break;
    194                 case "map":
    195                     if (maps == null) {
    196                         maps = new ArrayList<>();
     188                default:
     189                    settings.put(key, new ListSetting(null));
     190                    break;
     191            }
     192            jumpToEnd();
     193        } else {
     194            while (true) {
     195                int event = parser.next();
     196                if (event == XMLStreamConstants.START_ELEMENT) {
     197                    String localName = parser.getLocalName();
     198                    switch(localName) {
     199                    case "entry":
     200                        if (entries == null) {
     201                            entries = new ArrayList<>();
     202                        }
     203                        entries.add(parser.getAttributeValue(null, "value"));
     204                        jumpToEnd();
     205                        break;
     206                    case "list":
     207                        if (lists == null) {
     208                            lists = new ArrayList<>();
     209                        }
     210                        lists.add(parseInnerList());
     211                        break;
     212                    case "map":
     213                        if (maps == null) {
     214                            maps = new ArrayList<>();
     215                        }
     216                        maps.add(parseMap());
     217                        break;
     218                    default:
     219                        throwException("Unexpected element: "+localName);
    197220                    }
    198                     maps.add(parseMap());
     221                } else if (event == XMLStreamConstants.END_ELEMENT) {
    199222                    break;
    200                 default:
    201                     throwException("Unexpected element: "+localName);
    202223                }
    203             } else if (event == XMLStreamConstants.END_ELEMENT) {
    204                 break;
    205224            }
    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()));
     225            if (entries != null) {
     226                settings.put(key, new ListSetting(Collections.unmodifiableList(entries)));
     227            } else if (lists != null) {
     228                settings.put(key, new ListListSetting(Collections.unmodifiableList(lists)));
     229            } else if (maps != null) {
     230                settings.put(key, new MapListSetting(Collections.unmodifiableList(maps)));
    218231            } else {
    219                 settings.put(key, new ListSetting(Collections.<String>emptyList()));
     232                switch (name) {
     233                    case "lists":
     234                        settings.put(key, new ListListSetting(Collections.<List<String>>emptyList()));
     235                        break;
     236                    case "maps":
     237                        settings.put(key, new MapListSetting(Collections.<Map<String, String>>emptyList()));
     238                        break;
     239                    default:
     240                        settings.put(key, new ListSetting(Collections.<String>emptyList()));
     241                        break;
     242                }
    220243            }
    221244        }
    222245    }