Changeset 4612 in josm
- Timestamp:
- 2011-11-26T17:56:25+01:00 (13 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/data/preferences.xsd
r4553 r4612 10 10 <element name="tag" type="tns:tag" /> 11 11 <element name="collection" type="tns:collection" /> 12 <element name="list" type="tns:list" /> 12 13 </choice> 13 14 </sequence> … … 20 21 </complexType> 21 22 23 <!-- deprecated: remove mid 2012 --> 22 24 <complexType name="collection"> 23 25 <sequence> … … 29 31 </complexType> 30 32 33 <complexType name="list"> 34 <choice> 35 <sequence> 36 <element name="entry" type="tns:entry" minOccurs="0" maxOccurs="unbounded"/> 37 </sequence> 38 <sequence> 39 <element name="list" type="tns:slist" minOccurs="0" maxOccurs="unbounded"/> 40 </sequence> 41 <sequence> 42 <element name="map" type="tns:map" minOccurs="0" maxOccurs="unbounded"/> 43 </sequence> 44 </choice> 45 <attribute name="key" type="string" use="required" /> 46 </complexType> 47 48 <complexType name="slist"> 49 <sequence> 50 <element name="entry" type="tns:entry" minOccurs="0" maxOccurs="unbounded"/> 51 </sequence> 52 </complexType> 53 54 <complexType name="map"> 55 <sequence> 56 <element name="tag" type="tns:tag" minOccurs="0" maxOccurs="unbounded"/> 57 </sequence> 58 </complexType> 59 31 60 <complexType name="entry"> 32 61 <attribute name="value" type="string" use="required"/> -
trunk/src/org/openstreetmap/josm/data/Preferences.java
r4592 r4612 22 22 import java.util.Collection; 23 23 import java.util.Collections; 24 import java.util.Iterator; 25 import java.util.LinkedHashMap; 24 26 import java.util.LinkedList; 25 27 import java.util.List; … … 35 37 import javax.swing.JOptionPane; 36 38 import javax.swing.UIManager; 39 import javax.xml.parsers.SAXParserFactory; 40 import javax.xml.stream.XMLInputFactory; 41 import javax.xml.stream.XMLStreamConstants; 42 import javax.xml.stream.XMLStreamException; 43 import javax.xml.stream.XMLStreamReader; 44 import javax.xml.transform.stax.StAXSource; 45 import javax.xml.transform.stream.StreamSource; 46 import javax.xml.validation.Schema; 47 import javax.xml.validation.SchemaFactory; 48 import javax.xml.validation.Validator; 37 49 38 50 import org.openstreetmap.josm.Main; 51 import org.openstreetmap.josm.io.MirroredInputStream; 39 52 import org.openstreetmap.josm.io.XmlWriter; 40 53 import org.openstreetmap.josm.tools.ColorHelper; 41 54 import org.openstreetmap.josm.tools.Utils; 42 55 import org.openstreetmap.josm.tools.XmlObjectParser; 43 import org.xml.sax.SAXException;44 56 45 57 /** … … 75 87 protected final SortedMap<String, String> colornames = new TreeMap<String, String>(); 76 88 77 public interface PreferenceChangeEvent{ 89 protected final SortedMap<String, List<String>> collectionProperties = new TreeMap<String, List<String>>(); 90 protected final SortedMap<String, List<String>> collectionDefaults = new TreeMap<String, List<String>>(); 91 92 protected final SortedMap<String, List<List<String>>> arrayProperties = new TreeMap<String, List<List<String>>>(); 93 protected final SortedMap<String, List<List<String>>> arrayDefaults = new TreeMap<String, List<List<String>>>(); 94 95 protected final SortedMap<String, List<Map<String,String>>> listOfStructsProperties = new TreeMap<String, List<Map<String,String>>>(); 96 protected final SortedMap<String, List<Map<String,String>>> listOfStructsDefaults = new TreeMap<String, List<Map<String,String>>>(); 97 98 public interface Setting<T> { 99 T getValue(); 100 void visit(SettingVisitor visitor); 101 } 102 103 abstract public static class AbstractSetting<T> implements Setting<T> { 104 private T value; 105 public AbstractSetting(T value) { 106 this.value = value; 107 } 108 public T getValue() { 109 return value; 110 } 111 } 112 113 public static class StringSetting extends AbstractSetting<String> { 114 public StringSetting(String value) { 115 super(value); 116 } 117 public void visit(SettingVisitor visitor) { 118 visitor.visit(this); 119 } 120 } 121 122 public static class ListSetting extends AbstractSetting<List<String>> { 123 public ListSetting(List<String> value) { 124 super(value); 125 } 126 public void visit(SettingVisitor visitor) { 127 visitor.visit(this); 128 } 129 } 130 131 public static class ListListSetting extends AbstractSetting<List<List<String>>> { 132 public ListListSetting(List<List<String>> value) { 133 super(value); 134 } 135 public void visit(SettingVisitor visitor) { 136 visitor.visit(this); 137 } 138 } 139 140 public static class MapListSetting extends AbstractSetting<List<Map<String, String>>> { 141 public MapListSetting(List<Map<String, String>> value) { 142 super(value); 143 } 144 public void visit(SettingVisitor visitor) { 145 visitor.visit(this); 146 } 147 } 148 149 public interface SettingVisitor { 150 void visit(StringSetting setting); 151 void visit(ListSetting value); 152 void visit(ListListSetting value); 153 void visit(MapListSetting value); 154 } 155 156 public interface PreferenceChangeEvent<T> { 78 157 String getKey(); 79 S tringgetOldValue();80 S tringgetNewValue();158 Setting<T> getOldValue(); 159 Setting<T> getNewValue(); 81 160 } 82 161 … … 85 164 } 86 165 87 private static class DefaultPreferenceChangeEvent implements PreferenceChangeEvent{166 private static class DefaultPreferenceChangeEvent<T> implements PreferenceChangeEvent<T> { 88 167 private final String key; 89 private final S tringoldValue;90 private final S tringnewValue;91 92 public DefaultPreferenceChangeEvent(String key, S tring oldValue, StringnewValue) {168 private final Setting<T> oldValue; 169 private final Setting<T> newValue; 170 171 public DefaultPreferenceChangeEvent(String key, Setting<T> oldValue, Setting<T> newValue) { 93 172 this.key = key; 94 173 this.oldValue = oldValue; … … 99 178 return key; 100 179 } 101 public S tringgetOldValue() {180 public Setting<T> getOldValue() { 102 181 return oldValue; 103 182 } 104 public S tringgetNewValue() {183 public Setting<T> getNewValue() { 105 184 return newValue; 106 185 } … … 125 204 } 126 205 127 protected void firePreferenceChanged(String key, String oldValue, StringnewValue) {128 PreferenceChangeEvent evt = new DefaultPreferenceChangeEvent(key, oldValue, newValue);206 protected <T> void firePreferenceChanged(String key, Setting<T> oldValue, Setting<T> newValue) { 207 PreferenceChangeEvent<T> evt = new DefaultPreferenceChangeEvent<T>(key, oldValue, newValue); 129 208 for (PreferenceChangedListener l : listeners) { 130 209 l.preferenceChanged(evt); … … 346 425 if (changed) { 347 426 // Call outside of synchronized section in case some listener wait for other thread that wait for preference lock 348 firePreferenceChanged(key, oldValue, value);427 firePreferenceChanged(key, new StringSetting(oldValue), new StringSetting(value)); 349 428 } 350 429 return changed; … … 446 525 private void load(boolean old) throws Exception { 447 526 properties.clear(); 448 if (!Main.applet) {449 final BufferedReader in = new BufferedReader(new InputStreamReader(450 new FileInputStream(old ? getOldPreferenceFile() : getPreferenceFile()), "utf-8"));527 if (!Main.applet) { 528 File pref = old ? getOldPreferenceFile() : getPreferenceFile(); 529 BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(pref), "utf-8")); 451 530 /* FIXME: TODO: remove old style config file end of 2012 */ 452 531 try { … … 456 535 in.reset(); 457 536 if(v == '<') { 537 validateXML(in); 538 Utils.close(in); 539 in = new BufferedReader(new InputStreamReader(new FileInputStream(pref), "utf-8")); 458 540 fromXML(in); 459 541 } else { … … 476 558 } 477 559 } else { 560 validateXML(in); 561 Utils.close(in); 562 in = new BufferedReader(new InputStreamReader(new FileInputStream(pref), "utf-8")); 478 563 fromXML(in); 479 564 } … … 732 817 } 733 818 734 synchronized public String getCollectionAsString(final String key) {735 String s = get(key);736 if(s != null && s.length() != 0) {737 s = s.replaceAll("\u001e",",");738 }739 return s;740 }741 742 public boolean isCollection(String key, boolean def) {743 String s = get(key);744 if (s != null && s.length() != 0)745 return s.indexOf("\u001e") >= 0;746 else747 return def;748 }749 750 819 /** 751 820 * Get a list of values for a certain key … … 755 824 * def otherwise 756 825 */ 757 synchronized public Collection<String> getCollection(String key, Collection<String> def) { 758 putCollectionDefault(key, def); 759 String s = get(key); 760 if(s != null && s.length() != 0) 761 return Arrays.asList(s.split("\u001e", -1)); 762 return def; 826 public Collection<String> getCollection(String key, Collection<String> def) { 827 if (def != null) { 828 putCollectionDefault(key, new ArrayList<String>(def)); 829 } 830 Collection<String> prop = getCollectionInternal(key); 831 if (prop != null) 832 return prop; 833 else 834 return def; 763 835 } 764 836 … … 769 841 * an empty Collection otherwise. 770 842 */ 771 synchronizedpublic Collection<String> getCollection(String key) {843 public Collection<String> getCollection(String key) { 772 844 putCollectionDefault(key, null); 773 String s = get(key); 774 if (s != null && s.length() != 0) 775 return Arrays.asList(s.split("\u001e", -1)); 776 return Collections.emptyList(); 777 } 778 779 /* old style conversion, replace by above call after some transition time */ 780 /* remove this function, when no more old-style preference collections in the code */ 781 @Deprecated 782 synchronized public Collection<String> getCollectionOld(String key, String sep) { 783 putCollectionDefault(key, null); 784 String s = get(key); 785 if (s != null && s.length() != 0) { 786 if(!s.contains("\u001e") && s.contains(sep)) { 787 s = s.replace(sep, "\u001e"); 788 put(key, s); 789 } 790 return Arrays.asList(s.split("\u001e", -1)); 791 } 792 return Collections.emptyList(); 845 Collection<String> prop = getCollectionInternal(key); 846 if (prop != null) 847 return prop; 848 else 849 return Collections.emptyList(); 850 } 851 852 synchronized private List<String> getCollectionInternal(String key) { 853 List<String> prop = collectionProperties.get(key); 854 if (prop != null) 855 return prop; 856 else { 857 String s = properties.get(key); 858 if(s != null) { 859 prop = Arrays.asList(s.split("\u001e", -1)); 860 collectionProperties.put(key, Collections.unmodifiableList(prop)); 861 properties.remove(key); 862 defaults.remove(key); 863 return prop; 864 } 865 } 866 return null; 793 867 } 794 868 … … 799 873 } 800 874 801 synchronized public boolean putCollection(String key, Collection<String> val) { 802 return put(key, Utils.join("\u001e", val)); 875 public boolean putCollection(String key, Collection<String> value) { 876 List<String> oldValue = null; 877 List<String> valueCopy = null; 878 879 synchronized (this) { 880 if (value == null) { 881 oldValue = collectionProperties.remove(key); 882 boolean changed = oldValue != null; 883 changed |= properties.remove(key) != null; 884 if (!changed) return false; 885 } else { 886 oldValue = getCollectionInternal(key); 887 if (equalCollection(value, oldValue)) return false; 888 Collection<String> defValue = collectionDefaults.get(key); 889 if (oldValue == null && equalCollection(value, defValue)) return false; 890 891 valueCopy = new ArrayList<String>(value); 892 collectionProperties.put(key, Collections.unmodifiableList(valueCopy)); 893 try { 894 save(); 895 } catch(IOException e){ 896 System.out.println(tr("Warning: failed to persist preferences to ''{0}''", getPreferenceFile().getAbsoluteFile())); 897 } 898 } 899 } 900 // Call outside of synchronized section in case some listener wait for other thread that wait for preference lock 901 firePreferenceChanged(key, new ListSetting(oldValue), new ListSetting(valueCopy)); 902 return true; 903 } 904 905 private static boolean equalCollection(Collection<String> a, Collection<String> b) { 906 if (a == null) return b == null; 907 if (b == null) return false; 908 if (a.size() != b.size()) return false; 909 Iterator<String> itA = a.iterator(); 910 Iterator<String> itB = b.iterator(); 911 while (itA.hasNext()) { 912 String aStr = itA.next(); 913 String bStr = itB.next(); 914 if (!Utils.equal(aStr,bStr)) return false; 915 } 916 return true; 803 917 } 804 918 … … 817 931 } 818 932 819 synchronized private void putCollectionDefault(String key, Collection<String> val) {820 putDefault(key, Utils.join("\u001e", val));933 synchronized private void putCollectionDefault(String key, List<String> val) { 934 collectionDefaults.put(key, val); 821 935 } 822 936 … … 825 939 * If not a single entry could be found, def is returned. 826 940 */ 827 synchronized public Collection<Collection<String>> getArray(String key, 828 Collection<Collection<String>> def) 829 { 830 if(def != null) { 831 putArrayDefault(key, def); 832 } 833 key += "."; 834 int num = 0; 835 Collection<Collection<String>> col = new LinkedList<Collection<String>>(); 836 while(properties.containsKey(key+num)) { 837 col.add(getCollection(key+num++, null)); 838 } 839 return num == 0 ? def : col; 840 } 841 842 synchronized public boolean putArray(String key, Collection<Collection<String>> val) { 941 synchronized public Collection<Collection<String>> getArray(String key, Collection<Collection<String>> def) { 942 if (def != null) { 943 List<List<String>> defCopy = new ArrayList<List<String>>(def.size()); 944 for (Collection<String> lst : def) { 945 defCopy.add(Collections.unmodifiableList(new ArrayList<String>(lst))); 946 } 947 putArrayDefault(key, Collections.unmodifiableList(defCopy)); 948 } 949 List<List<String>> prop = getArrayInternal(key); 950 if (prop != null) { 951 @SuppressWarnings("unchecked") 952 Collection<Collection<String>> prop_cast = (Collection) prop; 953 return prop_cast; 954 } else 955 return def; 956 } 957 958 synchronized private List<List<String>> getArrayInternal(String key) { 959 List<List<String>> prop = arrayProperties.get(key); 960 if (prop != null) 961 return prop; 962 else { 963 String keyDot = key + "."; 964 int num = 0; 965 List<List<String>> col = new ArrayList<List<String>>(); 966 while (true) { 967 List<String> c = getCollectionInternal(keyDot+num); 968 if (c == null) { 969 break; 970 } 971 col.add(c); 972 collectionProperties.remove(keyDot+num); 973 collectionDefaults.remove(keyDot+num); 974 num++; 975 } 976 if (num > 0) { 977 arrayProperties.put(key, Collections.unmodifiableList(col)); 978 return col; 979 } 980 } 981 return null; 982 } 983 984 public boolean putArray(String key, Collection<Collection<String>> value) { 843 985 boolean changed = false; 844 key += "."; 845 Collection<String> keys = getAllPrefix(key).keySet(); 846 if(val != null) { 847 int num = 0; 848 for(Collection<String> c : val) { 849 keys.remove(key+num); 850 changed |= putCollection(key+num++, c); 851 } 852 } 853 int l = key.length(); 854 for(String k : keys) { 855 try { 856 Integer.valueOf(k.substring(l)); 857 changed |= put(k, null); 858 } catch(NumberFormatException e) { 859 /* everything which does not end with a number should not be deleted */ 860 } 861 } 862 return changed; 863 } 864 865 synchronized private void putArrayDefault(String key, Collection<Collection<String>> val) { 866 key += "."; 867 Collection<String> keys = getAllPrefixDefault(key).keySet(); 868 int num = 0; 869 for(Collection<String> c : val) { 870 keys.remove(key+num); 871 putCollectionDefault(key+num++, c); 872 } 873 int l = key.length(); 874 for(String k : keys) { 875 try { 876 Integer.valueOf(k.substring(l)); 877 defaults.remove(k); 878 } catch(Exception e) { 879 /* everything which does not end with a number should not be deleted */ 880 } 881 } 986 987 List<List<String>> oldValue = null; 988 List<List<String>> valueCopy = null; 989 990 synchronized (this) { 991 if (value == null) { 992 oldValue = getArrayInternal(key); 993 if (arrayProperties.remove(key) != null) return false; 994 } else { 995 oldValue = getArrayInternal(key); 996 if (equalArray(value, oldValue)) return false; 997 998 List<List<String>> defValue = arrayDefaults.get(key); 999 if (oldValue == null && equalArray(value, defValue)) return false; 1000 1001 valueCopy = new ArrayList<List<String>>(value.size()); 1002 for (Collection<String> lst : value) { 1003 valueCopy.add(Collections.unmodifiableList(new ArrayList<String>(lst))); 1004 } 1005 arrayProperties.put(key, Collections.unmodifiableList(valueCopy)); 1006 try { 1007 save(); 1008 } catch(IOException e){ 1009 System.out.println(tr("Warning: failed to persist preferences to ''{0}''", getPreferenceFile().getAbsoluteFile())); 1010 } 1011 } 1012 } 1013 // Call outside of synchronized section in case some listener wait for other thread that wait for preference lock 1014 firePreferenceChanged(key, new ListListSetting(oldValue), new ListListSetting(valueCopy)); 1015 return true; 1016 } 1017 1018 private static boolean equalArray(Collection<Collection<String>> a, Collection<List<String>> b) { 1019 if (a == null) return b == null; 1020 if (b == null) return false; 1021 if (a.size() != b.size()) return false; 1022 Iterator<Collection<String>> itA = a.iterator(); 1023 Iterator<List<String>> itB = b.iterator(); 1024 while (itA.hasNext()) { 1025 if (!equalCollection(itA.next(), itB.next())) return false; 1026 } 1027 return true; 1028 } 1029 1030 synchronized private void putArrayDefault(String key, List<List<String>> val) { 1031 arrayDefaults.put(key, val); 1032 } 1033 1034 public Collection<Map<String, String>> getListOfStructs(String key, Collection<Map<String, String>> def) { 1035 if (def != null) { 1036 List<Map<String, String>> defCopy = new ArrayList<Map<String, String>>(def.size()); 1037 for (Map<String, String> map : def) { 1038 defCopy.add(Collections.unmodifiableMap(new LinkedHashMap<String,String>(map))); 1039 } 1040 putListOfStructsDefault(key, Collections.unmodifiableList(defCopy)); 1041 } 1042 Collection<Map<String, String>> prop = getListOfStructsInternal(key); 1043 if (prop != null) 1044 return prop; 1045 else 1046 return def; 1047 } 1048 1049 private synchronized List<Map<String, String>> getListOfStructsInternal(String key) { 1050 List<Map<String, String>> prop = listOfStructsProperties.get(key); 1051 if (prop != null) 1052 return prop; 1053 else { 1054 List<List<String>> array = getArrayInternal(key); 1055 if (array == null) return null; 1056 prop = new ArrayList<Map<String, String>>(array.size()); 1057 for (Collection<String> mapStr : array) { 1058 Map<String, String> map = new LinkedHashMap<String, String>(); 1059 for (String key_value : mapStr) { 1060 final int i = key_value.indexOf(':'); 1061 if (i == -1 || i == 0) { 1062 continue; 1063 } 1064 String k = key_value.substring(0,i); 1065 String v = key_value.substring(i+1); 1066 map.put(k, v); 1067 } 1068 prop.add(Collections.unmodifiableMap(map)); 1069 } 1070 arrayProperties.remove(key); 1071 arrayDefaults.remove(key); 1072 listOfStructsProperties.put(key, Collections.unmodifiableList(prop)); 1073 return prop; 1074 } 1075 } 1076 1077 public boolean putListOfStructs(String key, Collection<Map<String, String>> value) { 1078 boolean changed = false; 1079 1080 List<Map<String, String>> oldValue; 1081 List<Map<String, String>> valueCopy = null; 1082 1083 synchronized (this) { 1084 if (value == null) { 1085 oldValue = getListOfStructsInternal(key); 1086 if (listOfStructsProperties.remove(key) != null) return false; 1087 } else { 1088 oldValue = getListOfStructsInternal(key); 1089 if (equalListOfStructs(oldValue, value)) return false; 1090 1091 List<Map<String, String>> defValue = listOfStructsDefaults.get(key); 1092 if (oldValue == null && equalListOfStructs(value, defValue)) return false; 1093 1094 valueCopy = new ArrayList<Map<String, String>>(value.size()); 1095 for (Map<String, String> map : value) { 1096 valueCopy.add(Collections.unmodifiableMap(new LinkedHashMap<String,String>(map))); 1097 } 1098 listOfStructsProperties.put(key, Collections.unmodifiableList(valueCopy)); 1099 try { 1100 save(); 1101 } catch(IOException e){ 1102 System.out.println(tr("Warning: failed to persist preferences to ''{0}''", getPreferenceFile().getAbsoluteFile())); 1103 } 1104 } 1105 } 1106 // Call outside of synchronized section in case some listener wait for other thread that wait for preference lock 1107 firePreferenceChanged(key, new MapListSetting(oldValue), new MapListSetting(valueCopy)); 1108 return true; 1109 } 1110 1111 private static boolean equalListOfStructs(Collection<Map<String, String>> a, Collection<Map<String, String>> b) { 1112 if (a == null) return b == null; 1113 if (b == null) return false; 1114 if (a.size() != b.size()) return false; 1115 Iterator<Map<String, String>> itA = a.iterator(); 1116 Iterator<Map<String, String>> itB = b.iterator(); 1117 while (itA.hasNext()) { 1118 if (!equalMap(itA.next(), itB.next())) return false; 1119 } 1120 return true; 1121 } 1122 1123 private static boolean equalMap(Map<String, String> a, Map<String, String> b) { 1124 if (a == null) return b == null; 1125 if (b == null) return false; 1126 if (a.size() != b.size()) return false; 1127 for (Entry<String, String> e : a.entrySet()) { 1128 if (!Utils.equal(e.getValue(), b.get(e.getKey()))) return false; 1129 } 1130 return true; 1131 } 1132 1133 synchronized private void putListOfStructsDefault(String key, List<Map<String, String>> val) { 1134 listOfStructsDefaults.put(key, val); 882 1135 } 883 1136 … … 911 1164 */ 912 1165 public <T> List<T> getListOfStructs(String key, Collection<T> def, Class<T> klass) { 913 Collection< Collection<String>> array=914 get Array(key, def == null ? null : serializeListOfStructs(def, klass));915 if ( array== null)1166 Collection<Map<String,String>> prop = 1167 getListOfStructs(key, def == null ? null : serializeListOfStructs(def, klass)); 1168 if (prop == null) 916 1169 return def == null ? null : new ArrayList<T>(def); 917 1170 List<T> lst = new ArrayList<T>(); 918 for ( Collection<String> entries : array) {1171 for (Map<String,String> entries : prop) { 919 1172 T struct = deserializeStruct(entries, klass); 920 1173 lst.add(struct); … … 937 1190 */ 938 1191 public <T> boolean putListOfStructs(String key, Collection<T> val, Class<T> klass) { 939 return put Array(key, serializeListOfStructs(val, klass));940 } 941 942 private <T> Collection< Collection<String>> serializeListOfStructs(Collection<T> l, Class<T> klass) {1192 return putListOfStructs(key, serializeListOfStructs(val, klass)); 1193 } 1194 1195 private <T> Collection<Map<String,String>> serializeListOfStructs(Collection<T> l, Class<T> klass) { 943 1196 if (l == null) 944 1197 return null; 945 Collection< Collection<String>> vals = new ArrayList<Collection<String>>();1198 Collection<Map<String,String>> vals = new ArrayList<Map<String,String>>(); 946 1199 for (T struct : l) { 947 1200 if (struct == null) { … … 953 1206 } 954 1207 955 private <T> Collection<String> serializeStruct(T struct, Class<T> klass) {1208 private <T> Map<String,String> serializeStruct(T struct, Class<T> klass) { 956 1209 T structPrototype; 957 1210 try { … … 963 1216 } 964 1217 965 Collection<String> hash = new ArrayList<String>();1218 Map<String,String> hash = new LinkedHashMap<String,String>(); 966 1219 for (Field f : klass.getDeclaredFields()) { 967 1220 if (f.getAnnotation(pref.class) == null) { … … 974 1227 if (fieldValue != null) { 975 1228 if (f.getAnnotation(writeExplicitly.class) != null || !Utils.equal(fieldValue, defaultFieldValue)) { 976 hash. add(String.format("%s:%s", f.getName().replace("_", "-"), fieldValue.toString()));1229 hash.put(f.getName().replace("_", "-"), fieldValue.toString()); 977 1230 } 978 1231 } … … 986 1239 } 987 1240 988 private <T> T deserializeStruct( Collection<String> hash, Class<T> klass) {1241 private <T> T deserializeStruct(Map<String,String> hash, Class<T> klass) { 989 1242 T struct = null; 990 1243 try { … … 995 1248 throw new RuntimeException(); 996 1249 } 997 for (String key_value : hash) { 998 final int i = key_value.indexOf(':'); 999 if (i == -1 || i == 0) { 1000 continue; 1001 } 1002 String key = key_value.substring(0,i); 1003 String valueString = key_value.substring(i+1); 1004 1250 for (Entry<String,String> key_value : hash.entrySet()) { 1005 1251 Object value = null; 1006 1252 Field f; 1007 1253 try { 1008 f = klass.getDeclaredField(key .replace("-", "_"));1254 f = klass.getDeclaredField(key_value.getKey().replace("-", "_")); 1009 1255 } catch (NoSuchFieldException ex) { 1010 1256 continue; … … 1017 1263 f.setAccessible(true); 1018 1264 if (f.getType() == Boolean.class || f.getType() == boolean.class) { 1019 value = Boolean.parseBoolean( valueString);1265 value = Boolean.parseBoolean(key_value.getValue()); 1020 1266 } else if (f.getType() == Integer.class || f.getType() == int.class) { 1021 1267 try { 1022 value = Integer.parseInt( valueString);1268 value = Integer.parseInt(key_value.getValue()); 1023 1269 } catch (NumberFormatException nfe) { 1024 1270 continue; … … 1026 1272 } else if (f.getType() == Double.class || f.getType() == double.class) { 1027 1273 try { 1028 value = Double.parseDouble( valueString);1274 value = Double.parseDouble(key_value.getValue()); 1029 1275 } catch (NumberFormatException nfe) { 1030 1276 continue; 1031 1277 } 1032 1278 } else if (f.getType() == String.class) { 1033 value = valueString;1279 value = key_value.getValue(); 1034 1280 } else 1035 1281 throw new RuntimeException("unsupported preference primitive type"); … … 1080 1326 } 1081 1327 1082 public static class XMLTag { 1083 public String key; 1084 public String value; 1085 } 1086 public static class XMLCollection { 1087 public String key; 1088 } 1089 public static class XMLEntry { 1090 public String value; 1091 } 1092 public void fromXML(Reader in) throws SAXException { 1093 XmlObjectParser parser = new XmlObjectParser(); 1094 parser.map("tag", XMLTag.class); 1095 parser.map("entry", XMLEntry.class); 1096 parser.map("collection", XMLCollection.class); 1097 parser.startWithValidation(in, 1098 "http://josm.openstreetmap.de/preferences-1.0", "resource://data/preferences.xsd"); 1099 LinkedList<String> vals = new LinkedList<String>(); 1100 while(parser.hasNext()) { 1101 Object o = parser.next(); 1102 if(o instanceof XMLTag) { 1103 properties.put(((XMLTag)o).key, ((XMLTag)o).value); 1104 } else if (o instanceof XMLEntry) { 1105 vals.add(((XMLEntry)o).value); 1106 } else if (o instanceof XMLCollection) { 1107 properties.put(((XMLCollection)o).key, Utils.join("\u001e", vals)); 1108 vals = new LinkedList<String>(); 1109 } 1328 protected XMLStreamReader parser; 1329 1330 public void validateXML(Reader in) throws Exception { 1331 SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); 1332 Schema schema = factory.newSchema(new StreamSource(new MirroredInputStream("resource://data/preferences.xsd"))); 1333 XMLStreamReader parser = XMLInputFactory.newInstance().createXMLStreamReader(in); 1334 Validator validator = schema.newValidator(); 1335 validator.validate(new StAXSource(parser)); 1336 } 1337 1338 public void fromXML(Reader in) throws XMLStreamException { 1339 XMLStreamReader parser = XMLInputFactory.newInstance().createXMLStreamReader(in); 1340 this.parser = parser; 1341 parse(); 1342 } 1343 1344 public void parse() throws XMLStreamException { 1345 int event = parser.getEventType(); 1346 while (true) { 1347 if (event == XMLStreamConstants.START_ELEMENT) { 1348 parseRoot(); 1349 } else if (event == XMLStreamConstants.END_ELEMENT) { 1350 return; 1351 } 1352 if (parser.hasNext()) { 1353 event = parser.next(); 1354 } else { 1355 break; 1356 } 1357 } 1358 parser.close(); 1359 } 1360 1361 public void parseRoot() throws XMLStreamException { 1362 while (true) { 1363 int event = parser.next(); 1364 if (event == XMLStreamConstants.START_ELEMENT) { 1365 if (parser.getLocalName().equals("tag")) { 1366 properties.put(parser.getAttributeValue(null, "key"), parser.getAttributeValue(null, "value")); 1367 jumpToEnd(); 1368 } else if (parser.getLocalName().equals("list") || parser.getLocalName().equals("collection")) { 1369 parseToplevelList(); 1370 } else { 1371 throwException("Unexpected element: "+parser.getLocalName()); 1372 } 1373 } else if (event == XMLStreamConstants.END_ELEMENT) { 1374 return; 1375 } 1376 } 1377 } 1378 1379 private void jumpToEnd() throws XMLStreamException { 1380 while (true) { 1381 int event = parser.next(); 1382 if (event == XMLStreamConstants.START_ELEMENT) { 1383 jumpToEnd(); 1384 } else if (event == XMLStreamConstants.END_ELEMENT) { 1385 return; 1386 } 1387 } 1388 } 1389 1390 protected void parseToplevelList() throws XMLStreamException { 1391 String key = parser.getAttributeValue(null, "key"); 1392 List<String> entries = null; 1393 List<List<String>> lists = null; 1394 List<Map<String, String>> maps = null; 1395 while (true) { 1396 int event = parser.next(); 1397 if (event == XMLStreamConstants.START_ELEMENT) { 1398 if (parser.getLocalName().equals("entry")) { 1399 if (entries == null) { 1400 entries = new ArrayList<String>(); 1401 } 1402 entries.add(parser.getAttributeValue(null, "value")); 1403 jumpToEnd(); 1404 } else if (parser.getLocalName().equals("list")) { 1405 if (lists == null) { 1406 lists = new ArrayList<List<String>>(); 1407 } 1408 lists.add(parseInnerList()); 1409 } else if (parser.getLocalName().equals("map")) { 1410 if (maps == null) { 1411 maps = new ArrayList<Map<String, String>>(); 1412 } 1413 maps.add(parseMap()); 1414 } else { 1415 throwException("Unexpected element: "+parser.getLocalName()); 1416 } 1417 } else if (event == XMLStreamConstants.END_ELEMENT) { 1418 break; 1419 } 1420 } 1421 if (entries != null) { 1422 collectionProperties.put(key, Collections.unmodifiableList(entries)); 1423 } 1424 if (lists != null) { 1425 arrayProperties.put(key, Collections.unmodifiableList(lists)); 1426 } 1427 if (maps != null) { 1428 listOfStructsProperties.put(key, Collections.unmodifiableList(maps)); 1429 } 1430 } 1431 1432 protected List<String> parseInnerList() throws XMLStreamException { 1433 List<String> entries = new ArrayList<String>(); 1434 while (true) { 1435 int event = parser.next(); 1436 if (event == XMLStreamConstants.START_ELEMENT) { 1437 if (parser.getLocalName().equals("entry")) { 1438 entries.add(parser.getAttributeValue(null, "value")); 1439 jumpToEnd(); 1440 } else { 1441 throwException("Unexpected element: "+parser.getLocalName()); 1442 } 1443 } else if (event == XMLStreamConstants.END_ELEMENT) { 1444 break; 1445 } 1446 } 1447 return Collections.unmodifiableList(entries); 1448 } 1449 1450 protected Map<String, String> parseMap() throws XMLStreamException { 1451 Map<String, String> map = new LinkedHashMap<String, String>(); 1452 while (true) { 1453 int event = parser.next(); 1454 if (event == XMLStreamConstants.START_ELEMENT) { 1455 if (parser.getLocalName().equals("tag")) { 1456 map.put(parser.getAttributeValue(null, "key"), parser.getAttributeValue(null, "value")); 1457 jumpToEnd(); 1458 } else { 1459 throwException("Unexpected element: "+parser.getLocalName()); 1460 } 1461 } else if (event == XMLStreamConstants.END_ELEMENT) { 1462 break; 1463 } 1464 } 1465 return Collections.unmodifiableMap(map); 1466 } 1467 1468 protected void throwException(String msg) { 1469 throw new RuntimeException(msg + tr(" (at line {0}, column {1})", parser.getLocation().getLineNumber(), parser.getLocation().getColumnNumber())); 1470 } 1471 1472 private class SettingToXml implements SettingVisitor { 1473 private StringBuilder b; 1474 private boolean noPassword; 1475 private String key; 1476 1477 public SettingToXml(StringBuilder b, boolean noPassword) { 1478 this.b = b; 1479 this.noPassword = noPassword; 1480 } 1481 1482 public void setKey(String key) { 1483 this.key = key; 1484 } 1485 1486 public void visit(StringSetting setting) { 1487 if (noPassword && key.equals("osm-server.password")) 1488 return; // do not store plain password. 1489 String r = setting.getValue(); 1490 String s = defaults.get(key); 1491 /* don't save default values */ 1492 if(s == null || !s.equals(r)) { 1493 if(r.contains("\u001e")) 1494 { 1495 b.append(" <list key='"); 1496 b.append(XmlWriter.encode(key)); 1497 b.append("'>\n"); 1498 for (String val : r.split("\u001e", -1)) 1499 { 1500 b.append(" <entry value='"); 1501 b.append(XmlWriter.encode(val)); 1502 b.append("'/>\n"); 1503 } 1504 b.append(" </list>\n"); 1505 } 1506 else 1507 { 1508 b.append(" <tag key='"); 1509 b.append(XmlWriter.encode(key)); 1510 b.append("' value='"); 1511 b.append(XmlWriter.encode(setting.getValue())); 1512 b.append("'/>\n"); 1513 } 1514 } 1515 } 1516 1517 public void visit(ListSetting setting) { 1518 b.append(" <list key='").append(XmlWriter.encode(key)).append("'>\n"); 1519 for (String s : setting.getValue()) { 1520 b.append(" <entry value='").append(XmlWriter.encode(s)).append("'/>\n"); 1521 } 1522 b.append(" </list>\n"); 1523 } 1524 1525 public void visit(ListListSetting setting) { 1526 b.append(" <list key='").append(XmlWriter.encode(key)).append("'>\n"); 1527 for (List<String> list : setting.getValue()) { 1528 b.append(" <list>\n"); 1529 for (String s : list) { 1530 b.append(" <entry value='").append(XmlWriter.encode(s)).append("'/>\n"); 1531 } 1532 b.append(" </list>\n"); 1533 } 1534 b.append(" </list>\n"); 1535 } 1536 1537 public void visit(MapListSetting setting) { 1538 b.append(" <list key='").append(XmlWriter.encode(key)).append("'>\n"); 1539 for (Map<String, String> struct : setting.getValue()) { 1540 b.append(" <map>\n"); 1541 for (Entry<String, String> e : struct.entrySet()) { 1542 b.append(" <tag key='").append(XmlWriter.encode(e.getKey())).append("' value='").append(XmlWriter.encode(e.getValue())).append("'/>\n"); 1543 } 1544 b.append(" </map>\n"); 1545 } 1546 b.append(" </list>\n"); 1110 1547 } 1111 1548 } … … 1116 1553 "<preferences xmlns=\"http://josm.openstreetmap.de/preferences-1.0\" version=\""+ 1117 1554 Version.getInstance().getVersion() + "\">\n"); 1118 for (Entry<String, String> p : properties.entrySet()) { 1119 if (nopass && p.getKey().equals("osm-server.password")) { 1120 continue; // do not store plain password. 1121 } 1122 String r = p.getValue(); 1123 String s = defaults.get(p.getKey()); 1124 /* don't save default values */ 1125 if(s == null || !s.equals(r)) { 1126 if(r.contains("\u001e")) 1127 { 1128 b.append(" <collection key='"); 1129 b.append(XmlWriter.encode(p.getKey())); 1130 b.append("'>\n"); 1131 for (String val : r.split("\u001e", -1)) 1132 { 1133 b.append(" <entry value='"); 1134 b.append(XmlWriter.encode(val)); 1135 b.append("' />\n"); 1136 } 1137 b.append(" </collection>\n"); 1138 } 1139 else 1140 { 1141 b.append(" <tag key='"); 1142 b.append(XmlWriter.encode(p.getKey())); 1143 b.append("' value='"); 1144 b.append(XmlWriter.encode(p.getValue())); 1145 b.append("' />\n"); 1146 } 1147 } 1148 } 1149 b.append("</preferences>"); 1555 SettingToXml toXml = new SettingToXml(b, nopass); 1556 Map<String, Setting> settings = new TreeMap<String, Setting>(); 1557 1558 for (Entry<String, String> e : properties.entrySet()) { 1559 settings.put(e.getKey(), new StringSetting(e.getValue())); 1560 } 1561 for (Entry<String, List<String>> e : collectionProperties.entrySet()) { 1562 settings.put(e.getKey(), new ListSetting(e.getValue())); 1563 } 1564 for (Entry<String, List<List<String>>> e : arrayProperties.entrySet()) { 1565 settings.put(e.getKey(), new ListListSetting(e.getValue())); 1566 } 1567 for (Entry<String, List<Map<String, String>>> e : listOfStructsProperties.entrySet()) { 1568 settings.put(e.getKey(), new MapListSetting(e.getValue())); 1569 } 1570 for (Entry<String, Setting> e : settings.entrySet()) { 1571 toXml.setKey(e.getKey()); 1572 e.getValue().visit(toXml); 1573 } 1574 b.append("</preferences>\n"); 1150 1575 return b.toString(); 1151 1576 } -
trunk/src/org/openstreetmap/josm/data/ServerSidePreferences.java
r4191 r4612 22 22 23 23 import javax.swing.JOptionPane; 24 import javax.xml.stream.XMLStreamException; 24 25 25 26 import org.openstreetmap.josm.Main; … … 27 28 import org.openstreetmap.josm.io.OsmTransferException; 28 29 import org.openstreetmap.josm.tools.Base64; 29 import org.xml.sax.SAXException;30 30 31 31 /** … … 171 171 } catch (RuntimeException e) { 172 172 e.printStackTrace(); 173 } catch ( SAXException e) {173 } catch (XMLStreamException e) { 174 174 e.printStackTrace(); 175 175 } -
trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
r4431 r4612 608 608 */ 609 609 static { 610 // Legacy support - convert list of keys to search pattern611 if (Main.pref.isCollection("tags.direction", false)) {612 System.out.println("Collection of keys in tags.direction is no longer supported, value will converted to search pattern");613 Collection<String> keys = Main.pref.getCollection("tags.direction", null);614 StringBuilder builder = new StringBuilder();615 for (String key:keys) {616 builder.append(key);617 builder.append("=* | ");618 }619 builder.delete(builder.length() - 3, builder.length());620 Main.pref.put("tags.direction", builder.toString());621 }622 623 610 // FIXME: incline=\"-*\" search pattern does not work. 624 611 String reversedDirectionDefault = "oneway=\"-1\" | incline=down | incline=\"-*\""; -
trunk/src/org/openstreetmap/josm/gui/JosmUserIdentityManager.java
r4263 r4612 9 9 import org.openstreetmap.josm.data.Preferences.PreferenceChangeEvent; 10 10 import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener; 11 import org.openstreetmap.josm.data.Preferences.StringSetting; 11 12 import org.openstreetmap.josm.data.osm.UserInfo; 12 13 import org.openstreetmap.josm.io.auth.CredentialsManager; … … 202 203 public void preferenceChanged(PreferenceChangeEvent evt) { 203 204 if (evt.getKey().equals("osm-server.username")) { 204 String newValue = evt.getNewValue(); 205 if (!(evt.getNewValue() instanceof StringSetting)) return; 206 String newValue = ((StringSetting) evt.getNewValue()).getValue(); 205 207 if (newValue == null || newValue.trim().length() == 0) { 206 208 setAnonymous(); … … 214 216 215 217 if (evt.getKey().equals("osm-server.url")) { 216 String newValue = evt.getNewValue(); 218 if (!(evt.getNewValue() instanceof StringSetting)) return; 219 String newValue = ((StringSetting) evt.getNewValue()).getValue(); 217 220 if (newValue == null || newValue.trim().equals("")) { 218 221 setAnonymous(); -
trunk/src/org/openstreetmap/josm/io/MirroredInputStream.java
r4343 r4612 15 15 import java.net.URL; 16 16 import java.net.URLConnection; 17 import java.util.ArrayList; 17 18 import java.util.Arrays; 18 19 import java.util.Collection; 19 20 import java.util.Enumeration; 21 import java.util.List; 20 22 import java.util.zip.ZipEntry; 21 23 import java.util.zip.ZipFile; … … 188 190 long age = 0L; 189 191 File localFile = null; 190 Collection<String> localPathEntry = Main.pref.getCollection(prefKey); 191 if(localPathEntry.size() == 2) { 192 String[] lp = (String[]) localPathEntry.toArray(); 193 localFile = new File(lp[1]); 192 List<String> localPathEntry = new ArrayList<String>(Main.pref.getCollection(prefKey)); 193 if (localPathEntry.size() == 2) { 194 localFile = new File(localPathEntry.get(1)); 194 195 if(!localFile.exists()) 195 196 localFile = null; … … 200 201 maxTime = Main.pref.getInteger("mirror.maxtime", 7*24*60*60); 201 202 } 202 age = System.currentTimeMillis() - Long.parseLong(l p[0]);203 age = System.currentTimeMillis() - Long.parseLong(localPathEntry.get(0)); 203 204 if (age < maxTime*1000) { 204 205 return localFile; -
trunk/src/org/openstreetmap/josm/plugins/ReadRemotePluginInformationTask.java
r4087 r4612 149 149 try { 150 150 /* replace %<x> with empty string or x=plugins (separated with comma) */ 151 String pl = Main.pref.getCollectionAsString("plugins");151 String pl = Utils.join(",", Main.pref.getCollection("plugins")); 152 152 String printsite = site.replaceAll("%<(.*)>", ""); 153 153 if(pl != null && pl.length() != 0) {
Note:
See TracChangeset
for help on using the changeset viewer.