1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package de.smartics.properties.spi.config.support;
17
18 import java.beans.PropertyChangeListener;
19 import java.beans.PropertyChangeSupport;
20 import java.util.LinkedHashMap;
21 import java.util.Map;
22 import java.util.UUID;
23 import java.util.concurrent.locks.Lock;
24 import java.util.concurrent.locks.ReentrantReadWriteLock;
25
26 import javax.annotation.CheckForNull;
27 import javax.annotation.concurrent.ThreadSafe;
28
29 import de.smartics.properties.api.config.domain.Property;
30 import de.smartics.properties.api.config.domain.PropertyCollection;
31 import de.smartics.properties.api.config.domain.PropertyLocation;
32 import de.smartics.properties.api.config.domain.PropertyManager;
33 import de.smartics.properties.api.config.domain.key.ConfigurationKey;
34 import de.smartics.util.lang.Arg;
35
36
37
38
39
40 @ThreadSafe
41 public final class InMemoryPropertiesManager implements PropertyManager
42 {
43
44
45
46
47
48
49
50 private static final long serialVersionUID = 1L;
51
52
53
54
55
56
57
58
59 private final ConfigurationKey<?> configurationKey;
60
61
62
63
64
65
66 private final PropertyLocation sourceId;
67
68
69
70
71
72
73 private final Map<String, Property> propertiesKeyToValueMap =
74 new LinkedHashMap<String, Property>();
75
76
77
78
79
80
81 private final PropertyChangeSupport support;
82
83
84
85
86
87
88 private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
89
90
91
92
93
94
95 private final Lock readLock = lock.readLock();
96
97
98
99
100
101
102 private final Lock writeLock = lock.writeLock();
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 public InMemoryPropertiesManager(final ConfigurationKey<?> configurationKey,
118 final PropertyLocation sourceId) throws NullPointerException
119 {
120 Arg.checkNotNull("configurationKey", configurationKey);
121 Arg.checkNotNull("sourceId", sourceId);
122
123 this.configurationKey = configurationKey;
124 this.sourceId = sourceId;
125 support = new PropertyChangeSupport(this);
126 }
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143 public InMemoryPropertiesManager(final ConfigurationKey<?> configurationKey)
144 throws NullPointerException
145 {
146 this(configurationKey, new PropertyLocation("inmemory:"
147 + UUID.randomUUID().toString()));
148 }
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163 @Override
164 public ConfigurationKey<?> getConfigurationKey()
165 {
166 return configurationKey;
167 }
168
169 @Override
170 public PropertyLocation getSourceId()
171 {
172 return sourceId;
173 }
174
175 @Override
176 public boolean isLazy()
177 {
178 return false;
179 }
180
181
182
183 @Override
184 @CheckForNull
185 public Property setProperty(final Property property)
186 throws NullPointerException
187 {
188 Arg.checkNotNull("property", property);
189
190 final String name = property.getName();
191 final Property oldValue;
192 writeLock.lock();
193 try
194 {
195 oldValue = propertiesKeyToValueMap.put(name, property);
196 }
197 finally
198 {
199 writeLock.unlock();
200 }
201
202 support.firePropertyChange(name, oldValue, property);
203
204 return oldValue;
205 }
206
207 @Override
208 @CheckForNull
209 public Property getProperty(final String name) throws NullPointerException,
210 IllegalArgumentException
211 {
212 Arg.checkNotNull("name", name);
213
214 final Property property;
215 readLock.lock();
216 try
217 {
218 property = propertiesKeyToValueMap.get(name);
219 if (property == null && !propertiesKeyToValueMap.containsKey(name))
220 {
221 throw new IllegalArgumentException("Unknown property '" + name + "'.");
222 }
223 }
224 finally
225 {
226 readLock.unlock();
227 }
228
229 return property;
230 }
231
232 @Override
233 public boolean containsKey(final String name) throws NullPointerException
234 {
235 Arg.checkNotNull("name", name);
236
237 readLock.lock();
238 try
239 {
240 return propertiesKeyToValueMap.containsKey(name);
241 }
242 finally
243 {
244 readLock.unlock();
245 }
246 }
247
248 @Override
249 @CheckForNull
250 public Property removeProperty(final String name) throws NullPointerException
251 {
252 Arg.checkNotNull("name", name);
253
254 final Property property;
255 writeLock.lock();
256 try
257 {
258 property = propertiesKeyToValueMap.remove(name);
259 }
260 finally
261 {
262 writeLock.unlock();
263 }
264
265 support.firePropertyChange(name, property, null);
266
267 return property;
268 }
269
270 @Override
271 public PropertyCollection getProperties()
272 {
273 readLock.lock();
274
275 try
276 {
277 final PropertyCollection collection =
278 new NativePropertyCollection(propertiesKeyToValueMap);
279 return collection;
280 }
281 finally
282 {
283 readLock.unlock();
284 }
285 }
286
287 @Override
288 public void addPropertyChangeListener(final String name,
289 final PropertyChangeListener listener) throws NullPointerException
290 {
291 Arg.checkNotNull("name", name);
292 Arg.checkNotNull("listener", listener);
293
294 support.addPropertyChangeListener(name, listener);
295 }
296
297 @Override
298 public void removePropertyChangeListener(final String name,
299 final PropertyChangeListener listener) throws NullPointerException
300 {
301 Arg.checkNotNull("name", name);
302 Arg.checkNotNull("listener", listener);
303
304 support.removePropertyChangeListener(name, listener);
305 }
306
307 @Override
308 public void addPropertyChangeListener(final PropertyChangeListener listener)
309 throws NullPointerException
310 {
311 Arg.checkNotNull("listener", listener);
312
313 support.addPropertyChangeListener(listener);
314 }
315
316 @Override
317 public void removePropertyChangeListener(final PropertyChangeListener listener)
318 throws NullPointerException
319 {
320 Arg.checkNotNull("listener", listener);
321
322 support.removePropertyChangeListener(listener);
323 }
324
325
326
327
328
329
330
331
332 @Override
333 public String toString()
334 {
335 final StringBuilder buffer = new StringBuilder();
336
337 for (final Property property : propertiesKeyToValueMap.values())
338 {
339 buffer.append(property).append('\n');
340 }
341
342 return buffer.toString();
343 }
344
345 }