View Javadoc

1   /*
2    * Copyright 2012-2013 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.properties.impl.config.cache;
17  
18  import java.beans.PropertyChangeListener;
19  import java.util.List;
20  
21  import javax.annotation.concurrent.ThreadSafe;
22  
23  import org.apache.commons.lang.ObjectUtils;
24  
25  import de.smartics.properties.api.config.domain.AbstractAdminModeSupportedPropertiesManagement;
26  import de.smartics.properties.api.config.domain.ConfigurationPropertiesManagement;
27  import de.smartics.properties.api.config.domain.ConfigurationValidationException;
28  import de.smartics.properties.api.config.domain.DescribedProperty;
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.PropertyProvider;
32  import de.smartics.properties.api.config.domain.ValidatedProperty;
33  import de.smartics.properties.api.config.domain.UnknownPropertyException;
34  import de.smartics.properties.api.config.domain.key.ConfigurationKey;
35  import de.smartics.properties.api.core.app.PropertyRootException;
36  import de.smartics.properties.api.core.domain.DuplicatePropertyDeclarationsException;
37  import de.smartics.properties.api.core.domain.PropertiesContext;
38  import de.smartics.properties.api.core.domain.PropertyContext;
39  import de.smartics.properties.api.core.domain.PropertyDescriptor;
40  import de.smartics.properties.api.core.domain.PropertyDescriptorRegistry;
41  import de.smartics.properties.api.core.domain.PropertyKey;
42  import de.smartics.properties.api.core.domain.PropertyValidationException;
43  import de.smartics.properties.api.core.domain.PropertyValueConversionException;
44  import de.smartics.properties.api.core.domain.ReadOnlyPropertyException;
45  import de.smartics.properties.api.core.security.PropertyValueSecurity;
46  import de.smartics.properties.api.core.security.SecurityException;
47  import de.smartics.properties.spi.config.support.ConfigurationPropertiesManagementSpi;
48  import de.smartics.util.lang.Arg;
49  
50  /**
51   * A delegate that provides a cache.
52   */
53  @ThreadSafe
54  public abstract class AbstractCacheConfigurationPropertiesManagement extends
55      AbstractAdminModeSupportedPropertiesManagement
56  { // NOPMD
57    // ********************************* Fields *********************************
58  
59    // --- constants ------------------------------------------------------------
60  
61    /**
62     * The class version identifier.
63     */
64    private static final long serialVersionUID = 1L;
65  
66    // --- members --------------------------------------------------------------
67  
68    /**
69     * The cache implementation that provides synchronized access to the stored
70     * elements.
71     */
72    private final DependencyTrackingCache cache;
73  
74    // ****************************** Initializer *******************************
75  
76    // ****************************** Constructors ******************************
77  
78    /**
79     * Default constructor.
80     *
81     * @param configurationKey the key to the configuration this cache
82     *          implementation works for.
83     */
84    public AbstractCacheConfigurationPropertiesManagement(
85        final ConfigurationKey<?> configurationKey)
86    {
87      this(new DependencyTrackingCache(configurationKey));
88    }
89  
90    /**
91     * Default constructor that allows to specify a cache to be used.
92     *
93     * @param cache the synchronized cache.
94     * @throws NullPointerException if {@code cache} is <code>null</code>.
95     */
96    protected AbstractCacheConfigurationPropertiesManagement(
97        final DependencyTrackingCache cache) throws NullPointerException
98    {
99      this.cache = Arg.checkNotNull("cache", cache);
100   }
101 
102   // ****************************** Inner Classes *****************************
103 
104   // ********************************* Methods ********************************
105 
106   // --- init -----------------------------------------------------------------
107 
108   // --- get&set --------------------------------------------------------------
109 
110   /**
111    * Returns a reference to the delegate.
112    *
113    * @return a reference to the delegate. Never <code>null</code>.
114    */
115   protected abstract ConfigurationPropertiesManagementSpi getDelegate();
116 
117   /**
118    * Provides access to the cache.
119    *
120    * @return the cache.
121    */
122   protected final DependencyTrackingCache getCache()
123   {
124     return cache;
125   }
126 
127   // --- business -------------------------------------------------------------
128 
129   // ... cache relevant methods ...............................................
130 
131   @Override
132   public Object getPropertyAsType(final PropertyDescriptor descriptor)
133     throws IllegalArgumentException, UnknownPropertyException,
134     PropertyValueConversionException, SecurityException, PropertyRootException
135   {
136     final DependencyTrackingCache cache = getCache();
137     // FIXME: We should not validate the value (only resolve and convert)...
138     // But we do not want to dodge the cache.
139     final ValidatedProperty property =
140         cache.getValidatedProperty(getDelegate(), descriptor, null);
141     final Object value = property.getValidatedValue();
142     return value;
143   }
144 
145   // ... get property / properties
146 
147   @Override
148   public final ValidatedProperty getValidatedProperty(
149       final PropertyDescriptor descriptor, final Object defaultValue)
150     throws IllegalArgumentException, UnknownPropertyException,
151     PropertyValidationException
152   {
153     final DependencyTrackingCache cache = getCache();
154     final ValidatedProperty property =
155         cache.getValidatedProperty(getDelegate(), descriptor, defaultValue);
156     return property;
157   }
158 
159   @Override
160   public final DescribedProperty getProperty(final PropertyDescriptor descriptor,
161       final Object defaultValue) throws IllegalArgumentException,
162     UnknownPropertyException
163   {
164     final DependencyTrackingCache cache = getCache();
165     final DescribedProperty property =
166         cache.getProperty(getDelegate(), descriptor, defaultValue);
167     return property;
168   }
169 
170   @Override
171   public final DescribedProperty getProperty(final String key)
172     throws IllegalArgumentException, UnknownPropertyException
173   {
174     return getProperty(key, null);
175   }
176 
177   @Override
178   public final DescribedProperty getProperty(final String key, final Object defaultValue)
179     throws IllegalArgumentException, UnknownPropertyException
180   {
181     final PropertyDescriptor descriptor = getDescriptor(key);
182     return getProperty(descriptor, defaultValue);
183   }
184 
185   @Override
186   public final Object getPropertyValue(final PropertyDescriptor descriptor,
187       final Object defaultValue) throws IllegalArgumentException,
188     UnknownPropertyException, PropertyValidationException
189   {
190     final ValidatedProperty property =
191         getValidatedProperty(descriptor, defaultValue);
192     return property.getValidatedValue();
193   }
194 
195   @Override
196   public final <T> T getProperties(final Class<T> propertiesInterface)
197   {
198     return getDelegate().getProperties(propertiesInterface, toSerializable());
199   }
200 
201   // ... set property / properties
202 
203   @Override
204   public final Property setProperty(final PropertyKey key, final String value)
205     throws NullPointerException, PropertyValidationException,
206     ReadOnlyPropertyException
207   {
208     final Property oldProperty = getDelegate().setProperty(key, value);
209     final String stringKey = key.toString();
210     cache.removeFromCache(stringKey);
211     return oldProperty;
212   }
213 
214   @Override
215   public final Property unsetProperty(final PropertyKey key)
216     throws NullPointerException, ReadOnlyPropertyException
217   {
218     final Property oldProperty = getDelegate().unsetProperty(key);
219     final String stringKey = key.toString();
220     cache.removeFromCache(stringKey);
221     return oldProperty;
222   }
223 
224   @Override
225   public final ConfigurationPropertiesManagement addDefinitions(
226       final PropertyProvider provider) throws NullPointerException
227   {
228     final ConfigurationPropertiesManagement manager =
229         getDelegate().addDefinitions(provider);
230 
231     final PropertyCollection collection = provider.getProperties();
232     cache.removeFromCache(collection);
233 
234     return manager;
235   }
236 
237   @Override
238   public final void flush()
239   {
240     getDelegate().flush();
241   }
242 
243   // ... delegation only ......................................................
244 
245   @Override
246   public final PropertyDescriptorRegistry getRegistry()
247   {
248     return getDelegate().getRegistry();
249   }
250 
251   @Override
252   public PropertyValueSecurity getPropertyValueSecurity()
253   {
254     return getDelegate().getPropertyValueSecurity();
255   }
256 
257   @Override
258   public final Object getPropertyValue(final PropertyDescriptor descriptor)
259     throws NullPointerException, PropertyValidationException
260   {
261     return getPropertyValue(descriptor, null);
262   }
263 
264   @Override
265   public final Object getPropertyValue(final PropertyKey key)
266     throws IllegalArgumentException, UnknownPropertyException,
267     PropertyValidationException
268   {
269     final PropertyDescriptor descriptor = getDescriptor(key.toString());
270     return getPropertyValue(descriptor);
271   }
272 
273   @Override
274   public final Object getPropertyValue(final String key,
275       final Object defaultValue) throws NullPointerException,
276     PropertyValueConversionException, PropertyValidationException,
277     UnknownPropertyException
278   {
279     final PropertyDescriptor descriptor = getDescriptor(key);
280     return getPropertyValue(descriptor, defaultValue);
281   }
282 
283   @Override
284   public final Object getPropertyValue(final String key)
285     throws IllegalArgumentException, UnknownPropertyException,
286     PropertyValidationException
287   {
288     return getPropertyValue(key, null);
289   }
290 
291   @Override
292   public final String getPropertyValueAsString(
293       final PropertyDescriptor descriptor) throws NullPointerException,
294     PropertyValidationException
295   {
296     final Object value = getPropertyValue(descriptor);
297     return ObjectUtils.toString(value, null);
298   }
299 
300   @Override
301   public final String getPropertyValueAsString(final String key)
302     throws IllegalArgumentException, UnknownPropertyException,
303     PropertyValidationException
304   {
305     final PropertyDescriptor descriptor = getDescriptor(key);
306     final Object value = getPropertyValue(descriptor);
307     return ObjectUtils.toString(value, null);
308   }
309 
310   @Override
311   public final String getPropertyValueAsString(
312       final PropertyDescriptor descriptor, final Object defaultValue)
313     throws NullPointerException, PropertyValidationException
314   {
315     final Object value = getPropertyValue(descriptor, defaultValue);
316     return ObjectUtils.toString(value, null);
317   }
318 
319   @Override
320   public final String getPropertyValueAsString(final String key,
321       final Object defaultValue) throws IllegalArgumentException,
322     UnknownPropertyException, PropertyValidationException
323   {
324     final PropertyDescriptor descriptor = getDescriptor(key);
325     final Object value = getPropertyValue(descriptor, defaultValue);
326     return ObjectUtils.toString(value, null);
327   }
328 
329   @Override
330   public final DescribedProperty getProperty(final PropertyKey key)
331     throws IllegalArgumentException, UnknownPropertyException
332   {
333     final PropertyDescriptor descriptor = getDescriptor(key.toString());
334     return getProperty(descriptor);
335   }
336 
337   @Override
338   public final DescribedProperty getProperty(final PropertyDescriptor descriptor)
339     throws IllegalArgumentException, UnknownPropertyException
340   {
341     return getProperty(descriptor, null);
342   }
343 
344   @Override
345   public final ValidatedProperty getValidatedProperty(final String key,
346       final Object defaultValue) throws IllegalArgumentException,
347     UnknownPropertyException, PropertyValidationException
348   {
349     final PropertyDescriptor descriptor = getDescriptor(key);
350     return getValidatedProperty(descriptor, defaultValue);
351   }
352 
353   @Override
354   public final ValidatedProperty getValidatedProperty(final PropertyKey key,
355       final Object defaultValue) throws IllegalArgumentException,
356     UnknownPropertyException, PropertyValidationException
357   {
358     final PropertyDescriptor descriptor = getDescriptor(key.toString());
359     return getValidatedProperty(descriptor, defaultValue);
360   }
361 
362   @Override
363   public final void addDescriptors(final Class<?> propertySetType)
364     throws DuplicatePropertyDeclarationsException
365   {
366     getDelegate().addDescriptors(propertySetType);
367   }
368 
369   @Override
370   public final ConfigurationKey<?> getKey()
371   {
372     return getDelegate().getKey();
373   }
374 
375   @Override
376   public final PropertyDescriptor getDescriptor(final String key)
377     throws UnknownPropertyException
378   {
379     return getDelegate().getDescriptor(key);
380   }
381 
382   @Override
383   public final PropertiesContext getContext(final Class<?> declaringType)
384     throws NullPointerException
385   {
386     return getDelegate().getContext(declaringType);
387   }
388 
389   @Override
390   public final PropertyDescriptor getDescriptor(final PropertyKey key)
391     throws UnknownPropertyException
392   {
393     return getDelegate().getDescriptor(key);
394   }
395 
396   @Override
397   public final List<PropertyDescriptor> getMandatoryPropertyDescriptors()
398   {
399     return getDelegate().getMandatoryPropertyDescriptors();
400   }
401 
402   @Override
403   public final PropertyContext getContext(final PropertyDescriptor descriptor)
404     throws NullPointerException
405   {
406     return getDelegate().getContext(descriptor);
407   }
408 
409   @Override
410   public final void validate() throws ConfigurationValidationException
411   {
412     getDelegate().validate();
413   }
414 
415   @Override
416   public final void validate(final Class<?>... groups)
417     throws ConfigurationValidationException
418   {
419     getDelegate().validate(groups);
420   }
421 
422   @Override
423   public final void validate(final boolean lenient, final Class<?>... groups)
424     throws ConfigurationValidationException
425   {
426     getDelegate().validate(lenient, groups);
427   }
428 
429   @Override
430   public final void validate(final PropertyDescriptor descriptor,
431       final Class<?>... ifInOneOfTheseGroups)
432     throws ConfigurationValidationException
433   {
434     getDelegate().validate(descriptor, ifInOneOfTheseGroups);
435   }
436 
437   @Override
438   public final void validate(final PropertyDescriptor descriptor,
439       final String value, final Class<?>... ifInOneOfTheseGroups)
440     throws ConfigurationValidationException
441   {
442     getDelegate().validate(descriptor, value, ifInOneOfTheseGroups);
443   }
444 
445   @Override
446   public final void addPropertyChangeListener(final PropertyKey name,
447       final PropertyChangeListener listener) throws NullPointerException
448   {
449     getDelegate().addPropertyChangeListener(name, listener);
450   }
451 
452   @Override
453   public final void removePropertyChangeListener(final PropertyKey name,
454       final PropertyChangeListener listener) throws NullPointerException
455   {
456     getDelegate().removePropertyChangeListener(name, listener);
457   }
458 
459   @Override
460   public final void addPropertyChangeListener(
461       final PropertyChangeListener listener) throws NullPointerException
462   {
463     getDelegate().addPropertyChangeListener(listener);
464   }
465 
466   @Override
467   public final void removePropertyChangeListener(
468       final PropertyChangeListener listener) throws NullPointerException
469   {
470     getDelegate().removePropertyChangeListener(listener);
471   }
472 
473   // --- object basics --------------------------------------------------------
474 
475 }