1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.settings;
20
21 import java.io.IOError;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.OutputStream;
25 import java.io.PrintStream;
26 import java.io.PrintWriter;
27 import java.io.Reader;
28 import java.io.Writer;
29 import java.util.Collection;
30 import java.util.Collections;
31 import java.util.Enumeration;
32 import java.util.InvalidPropertiesFormatException;
33 import java.util.Map;
34 import java.util.Properties;
35 import java.util.Set;
36 import java.util.function.BiConsumer;
37 import java.util.function.BiFunction;
38 import java.util.function.Consumer;
39 import java.util.function.Function;
40 import java.util.function.Supplier;
41
42 class WrapperProperties extends Properties {
43
44 final Supplier<Map<String, String>> getter;
45 final Consumer<Properties> setter;
46
47 WrapperProperties(Supplier<Map<String, String>> getter, Consumer<Properties> setter) {
48 this.getter = getter;
49 this.setter = setter;
50 }
51
52 @Override
53 public String getProperty(String key) {
54 return getter.get().get(key);
55 }
56
57 @Override
58 public String getProperty(String key, String defaultValue) {
59 return getter.get().getOrDefault(key, defaultValue);
60 }
61
62 @Override
63 public Enumeration<?> propertyNames() {
64 return Collections.enumeration(getter.get().keySet());
65 }
66
67 @Override
68 public Set<String> stringPropertyNames() {
69 return getter.get().keySet();
70 }
71
72 @Override
73 public void list(PrintStream out) {
74 throw new UnsupportedOperationException();
75 }
76
77 @Override
78 public void list(PrintWriter out) {
79 throw new UnsupportedOperationException();
80 }
81
82 @Override
83 public int size() {
84 return getter.get().size();
85 }
86
87 @Override
88 public boolean isEmpty() {
89 return getter.get().isEmpty();
90 }
91
92 @Override
93 public Enumeration<Object> keys() {
94 return Collections.enumeration((Set) getter.get().keySet());
95 }
96
97 @Override
98 public Enumeration<Object> elements() {
99 return Collections.enumeration((Collection) getter.get().values());
100 }
101
102 @Override
103 public boolean contains(Object value) {
104 return getter.get().containsKey(value != null ? value.toString() : null);
105 }
106
107 @Override
108 public boolean containsValue(Object value) {
109 return getter.get().containsValue(value);
110 }
111
112 @Override
113 public boolean containsKey(Object key) {
114 return getter.get().containsKey(key);
115 }
116
117 @Override
118 public Object get(Object key) {
119 return getter.get().get(key);
120 }
121
122 @Override
123 public synchronized String toString() {
124 return getter.get().toString();
125 }
126
127 @Override
128 public Set<Object> keySet() {
129 return (Set) getter.get().keySet();
130 }
131
132 @Override
133 public Collection<Object> values() {
134 return (Collection) getter.get().values();
135 }
136
137 @Override
138 public Set<Map.Entry<Object, Object>> entrySet() {
139 return (Set) getter.get().entrySet();
140 }
141
142 @Override
143 public synchronized boolean equals(Object o) {
144 if (o instanceof WrapperProperties) {
145 o = ((WrapperProperties) o).getter.get();
146 }
147 return getter.get().equals(o);
148 }
149
150 @Override
151 public synchronized int hashCode() {
152 return getter.get().hashCode();
153 }
154
155 @Override
156 public Object getOrDefault(Object key, Object defaultValue) {
157 return getter.get().getOrDefault(key, defaultValue != null ? defaultValue.toString() : null);
158 }
159
160 @Override
161 public synchronized void forEach(BiConsumer<? super Object, ? super Object> action) {
162 getter.get().forEach(action);
163 }
164
165 interface WriteOp<T> {
166 T perform(Properties props);
167 }
168
169 interface WriteOpVoid {
170 void perform(Properties props);
171 }
172
173 private <T> T writeOperation(WriteOp<T> runner) {
174 Properties props = new Properties();
175 props.putAll(getter.get());
176 T ret = runner.perform(props);
177 if (!props.equals(getter.get())) {
178 setter.accept(props);
179 }
180 return ret;
181 }
182
183 private void writeOperationVoid(WriteOpVoid runner) {
184 Properties props = new Properties();
185 props.putAll(getter.get());
186 runner.perform(props);
187 if (!props.equals(getter.get())) {
188 setter.accept(props);
189 }
190 }
191
192 @Override
193 public synchronized Object setProperty(String key, String value) {
194 return writeOperation(p -> p.setProperty(key, value));
195 }
196
197 @Override
198 public synchronized Object put(Object key, Object value) {
199 return writeOperation(p -> p.put(key, value));
200 }
201
202 @Override
203 public synchronized Object remove(Object key) {
204 return writeOperation(p -> p.remove(key));
205 }
206
207 @Override
208 public synchronized void putAll(Map<?, ?> t) {
209 writeOperationVoid(p -> p.putAll(t));
210 }
211
212 @Override
213 public synchronized void clear() {
214 writeOperationVoid(Properties::clear);
215 }
216
217 @Override
218 public synchronized void replaceAll(BiFunction<? super Object, ? super Object, ?> function) {
219 writeOperationVoid(p -> p.replaceAll(function));
220 }
221
222 @Override
223 public synchronized Object putIfAbsent(Object key, Object value) {
224 return writeOperation(p -> p.putIfAbsent(key, value));
225 }
226
227 @Override
228 public synchronized boolean remove(Object key, Object value) {
229 return writeOperation(p -> p.remove(key, value));
230 }
231
232 @Override
233 public synchronized boolean replace(Object key, Object oldValue, Object newValue) {
234 return writeOperation(p -> p.replace(key, oldValue, newValue));
235 }
236
237 @Override
238 public synchronized Object replace(Object key, Object value) {
239 return writeOperation(p -> p.replace(key, value));
240 }
241
242 @Override
243 public synchronized Object computeIfAbsent(Object key, Function<? super Object, ?> mappingFunction) {
244 return writeOperation(p -> p.computeIfAbsent(key, mappingFunction));
245 }
246
247 @Override
248 public synchronized Object computeIfPresent(
249 Object key, BiFunction<? super Object, ? super Object, ?> remappingFunction) {
250 return writeOperation(p -> p.computeIfPresent(key, remappingFunction));
251 }
252
253 @Override
254 public synchronized Object compute(Object key, BiFunction<? super Object, ? super Object, ?> remappingFunction) {
255 return writeOperation(p -> p.compute(key, remappingFunction));
256 }
257
258 @Override
259 public synchronized Object merge(
260 Object key, Object value, BiFunction<? super Object, ? super Object, ?> remappingFunction) {
261 return writeOperation(p -> p.merge(key, value, remappingFunction));
262 }
263
264 @Override
265 public synchronized void load(Reader reader) throws IOException {
266 try {
267 writeOperationVoid(p -> {
268 try {
269 p.load(reader);
270 } catch (IOException e) {
271 throw new IOError(e);
272 }
273 });
274 } catch (IOError e) {
275 throw (IOException) e.getCause();
276 }
277 }
278
279 @Override
280 public synchronized void load(InputStream inStream) throws IOException {
281 try {
282 writeOperationVoid(p -> {
283 try {
284 p.load(inStream);
285 } catch (IOException e) {
286 throw new IOError(e);
287 }
288 });
289 } catch (IOError e) {
290 throw (IOException) e.getCause();
291 }
292 }
293
294 @Override
295 public void save(OutputStream out, String comments) {
296 Properties props = new Properties();
297 props.putAll(getter.get());
298 props.save(out, comments);
299 }
300
301 @Override
302 public void store(Writer writer, String comments) throws IOException {
303 Properties props = new Properties();
304 props.putAll(getter.get());
305 props.store(writer, comments);
306 }
307
308 @Override
309 public void store(OutputStream out, String comments) throws IOException {
310 Properties props = new Properties();
311 props.putAll(getter.get());
312 props.store(out, comments);
313 }
314
315 @Override
316 public synchronized void loadFromXML(InputStream in) throws IOException, InvalidPropertiesFormatException {
317 throw new UnsupportedOperationException();
318 }
319
320 @Override
321 public void storeToXML(OutputStream os, String comment) throws IOException {
322 Properties props = new Properties();
323 props.putAll(getter.get());
324 props.storeToXML(os, comment);
325 }
326
327 @Override
328 public void storeToXML(OutputStream os, String comment, String encoding) throws IOException {
329 Properties props = new Properties();
330 props.putAll(getter.get());
331 props.storeToXML(os, comment, encoding);
332 }
333 }