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.Arguments;
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 Arguments.checkNotNull("configurationKey", configurationKey);
121 Arguments.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
176
177 @Override
178 @CheckForNull
179 public Property setProperty(final Property property)
180 throws NullPointerException
181 {
182 Arguments.checkNotNull("property", property);
183
184 final String name = property.getName();
185 final Property oldValue;
186 writeLock.lock();
187 try
188 {
189 oldValue = propertiesKeyToValueMap.put(name, property);
190 }
191 finally
192 {
193 writeLock.unlock();
194 }
195
196 support.firePropertyChange(name, oldValue, property);
197
198 return oldValue;
199 }
200
201 @Override
202 @CheckForNull
203 public Property getProperty(final String name) throws NullPointerException,
204 IllegalArgumentException
205 {
206 Arguments.checkNotNull("name", name);
207
208 final Property property;
209 readLock.lock();
210 try
211 {
212 property = propertiesKeyToValueMap.get(name);
213 if (property == null && !propertiesKeyToValueMap.containsKey(name))
214 {
215 throw new IllegalArgumentException("Unknown property '" + name + "'.");
216 }
217 }
218 finally
219 {
220 readLock.unlock();
221 }
222
223 return property;
224 }
225
226 @Override
227 public boolean containsKey(final String name) throws NullPointerException
228 {
229 Arguments.checkNotNull("name", name);
230
231 readLock.lock();
232 try
233 {
234 return propertiesKeyToValueMap.containsKey(name);
235 }
236 finally
237 {
238 readLock.unlock();
239 }
240 }
241
242 @Override
243 @CheckForNull
244 public Property removeProperty(final String name) throws NullPointerException
245 {
246 Arguments.checkNotNull("name", name);
247
248 final Property property;
249 writeLock.lock();
250 try
251 {
252 property = propertiesKeyToValueMap.remove(name);
253 }
254 finally
255 {
256 writeLock.unlock();
257 }
258
259 support.firePropertyChange(name, property, null);
260
261 return property;
262 }
263
264 @Override
265 public PropertyCollection getProperties()
266 {
267 readLock.lock();
268
269 try
270 {
271 final PropertyCollection collection =
272 new NativePropertyCollection(propertiesKeyToValueMap);
273 return collection;
274 }
275 finally
276 {
277 readLock.unlock();
278 }
279 }
280
281 @Override
282 public void addPropertyChangeListener(final String name,
283 final PropertyChangeListener listener) throws NullPointerException
284 {
285 Arguments.checkNotNull("name", name);
286 Arguments.checkNotNull("listener", listener);
287
288 support.addPropertyChangeListener(name, listener);
289 }
290
291 @Override
292 public void removePropertyChangeListener(final String name,
293 final PropertyChangeListener listener) throws NullPointerException
294 {
295 Arguments.checkNotNull("name", name);
296 Arguments.checkNotNull("listener", listener);
297
298 support.removePropertyChangeListener(name, listener);
299 }
300
301 @Override
302 public void addPropertyChangeListener(final PropertyChangeListener listener)
303 throws NullPointerException
304 {
305 Arguments.checkNotNull("listener", listener);
306
307 support.addPropertyChangeListener(listener);
308 }
309
310 @Override
311 public void removePropertyChangeListener(final PropertyChangeListener listener)
312 throws NullPointerException
313 {
314 Arguments.checkNotNull("listener", listener);
315
316 support.removePropertyChangeListener(listener);
317 }
318
319
320
321
322
323
324
325
326 @Override
327 public String toString()
328 {
329 final StringBuilder buffer = new StringBuilder();
330
331 for (final Property property : propertiesKeyToValueMap.values())
332 {
333 buffer.append(property).append('\n');
334 }
335
336 return buffer.toString();
337 }
338
339 }