001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.preferences; 003 004import java.io.PrintWriter; 005import java.util.Collection; 006import java.util.List; 007import java.util.Map; 008 009import org.openstreetmap.josm.Main; 010import org.openstreetmap.josm.data.Version; 011import org.openstreetmap.josm.io.XmlWriter; 012 013/** 014 * Write preferences to XML. 015 * @since 9823 016 */ 017public class PreferencesWriter extends XmlWriter implements SettingVisitor { 018 private final boolean noPassword; 019 private final boolean defaults; 020 private String key; 021 022 /** 023 * Construct new {@code PreferencesWriter}. 024 * @param out the {@link PrintWriter} 025 * @param noPassword if password must be excluded 026 * @param defaults true, if default values are converted to XML, false for regular preferences 027 */ 028 public PreferencesWriter(PrintWriter out, boolean noPassword, boolean defaults) { 029 super(out); 030 this.noPassword = noPassword; 031 this.defaults = defaults; 032 } 033 034 /** 035 * Write preferences. 036 * 037 * @param settings preferences settings to write 038 */ 039 public void write(Collection<Map.Entry<String, Setting<?>>> settings) { 040 out.write(String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>%n")); 041 String rootElement = defaults ? "preferences-defaults" : "preferences"; 042 out.write(String.format("<%s xmlns='%s/preferences-1.0'", rootElement, Main.getXMLBase())); 043 if (defaults) { 044 out.write(" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'"); 045 } 046 out.write(String.format(" version='%d'>%n", Version.getInstance().getVersion())); 047 for (Map.Entry<String, Setting<?>> e : settings) { 048 setKey(e.getKey()); 049 e.getValue().visit(this); 050 } 051 out.write(String.format("</%s>%n", rootElement)); 052 } 053 054 private void setKey(String key) { 055 this.key = key; 056 } 057 058 private void addTime(Setting<?> setting) { 059 if (defaults) { 060 Long time = setting.getTime(); 061 if (time == null) 062 throw new IllegalStateException(); 063 out.write("' time='" + time); 064 } 065 } 066 067 private void addDefaults() { 068 out.write(String.format("' xsi:nil='true'/>%n")); 069 } 070 071 @Override 072 public void visit(StringSetting setting) { 073 if (noPassword && "osm-server.password".equals(key)) 074 return; // do not store plain password. 075 out.write(" <tag key='" + XmlWriter.encode(key)); 076 addTime(setting); 077 if (setting.getValue() != null) { 078 out.write(String.format("' value='%s'/>%n", XmlWriter.encode(setting.getValue()))); 079 } else if (defaults) { 080 addDefaults(); 081 } else { 082 throw new NullPointerException(); 083 } 084 } 085 086 @Override 087 public void visit(ListSetting setting) { 088 out.write(" <list key='" + XmlWriter.encode(key)); 089 addTime(setting); 090 if (setting.getValue() != null) { 091 out.write(String.format("'>%n")); 092 for (String s : setting.getValue()) { 093 out.write(String.format(" <entry value='%s'/>%n", XmlWriter.encode(s))); 094 } 095 out.write(String.format(" </list>%n")); 096 } else if (defaults) { 097 addDefaults(); 098 } else { 099 throw new NullPointerException(); 100 } 101 } 102 103 @Override 104 public void visit(ListListSetting setting) { 105 out.write(" <lists key='" + XmlWriter.encode(key)); 106 addTime(setting); 107 if (setting.getValue() != null) { 108 out.write(String.format("'>%n")); 109 for (List<String> list : setting.getValue()) { 110 out.write(String.format(" <list>%n")); 111 for (String s : list) { 112 out.write(String.format(" <entry value='%s'/>%n", encode(s))); 113 } 114 out.write(String.format(" </list>%n")); 115 } 116 out.write(String.format(" </lists>%n")); 117 } else if (defaults) { 118 addDefaults(); 119 } else { 120 throw new NullPointerException(); 121 } 122 } 123 124 @Override 125 public void visit(MapListSetting setting) { 126 out.write(" <maps key='" + encode(key)); 127 addTime(setting); 128 if (setting.getValue() != null) { 129 out.write(String.format("'>%n")); 130 for (Map<String, String> struct : setting.getValue()) { 131 out.write(String.format(" <map>%n")); 132 for (Map.Entry<String, String> e : struct.entrySet()) { 133 out.write(String.format(" <tag key='%s' value='%s'/>%n", encode(e.getKey()), encode(e.getValue()))); 134 } 135 out.write(String.format(" </map>%n")); 136 } 137 out.write(String.format(" </maps>%n")); 138 } else if (defaults) { 139 addDefaults(); 140 } else { 141 throw new NullPointerException(); 142 } 143 } 144}