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