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.api.config.domain;
17  
18  import java.beans.PropertyChangeListener;
19  
20  import de.smartics.properties.api.config.domain.key.ConfigurationKey;
21  import de.smartics.properties.api.core.app.PropertyRootException;
22  import de.smartics.properties.api.core.domain.PropertiesContext;
23  import de.smartics.properties.api.core.domain.PropertyContext;
24  import de.smartics.properties.api.core.domain.PropertyDescriptor;
25  import de.smartics.properties.api.core.domain.PropertyKey;
26  import de.smartics.properties.api.core.domain.PropertyValidationException;
27  import de.smartics.properties.api.core.domain.PropertyValueConversionException;
28  import de.smartics.properties.api.core.security.SecurityException;
29  
30  /**
31   * Provides access to all configuration properties for a given application in a
32   * given environment.
33   * <p>
34   * There are two ways to access property values.
35   * </p>
36   * <ol>
37   * <li>Use {@link #getProperties(Class)} to obtain an implementation of an
38   * interface that provides access to the property values through its methods.
39   * This is the recommended way to deal with properties.</li>
40   * <li>Use one of the {@code getProperty} methods. This access may be more
41   * convenient, if the context deals with property keys that are provided by the
42   * user (e.g. from an UI).</li>
43   * </ol>
44   *
45   * @impl This interface is intended to be implemented by service providers. API
46   *       users are intended to us this interface to access properties. For
47   *       details on creating instances of classes implementing this interface
48   *       please refer to {@link de.smartics.properties.api.config}.
49   */
50  public interface ConfigurationProperties
51  {
52    // ********************************* Fields *********************************
53  
54    // --- constants ------------------------------------------------------------
55  
56    // ****************************** Initializer *******************************
57  
58    // ****************************** Inner Classes *****************************
59  
60    // ********************************* Methods ********************************
61  
62    // --- get&set --------------------------------------------------------------
63  
64    /**
65     * Returns the key of the configuration.
66     *
67     * @return the key of the configuration. Never <code>null</code>.
68     */
69    ConfigurationKey<?> getKey();
70  
71    /**
72     * Returns the properties context for the declaring type. The declaring type
73     * is the interface type annotated with the
74     * {@link de.smartics.properties.api.core.annotations.PropertySet} annotation.
75     * The context provides information about the properties of that set.
76     *
77     * @param declaringType the type that declares the properties whose context is
78     *          requested.
79     * @return the context for the properties declared by the given type.
80     * @throws NullPointerException if {@code declaringType} is <code>null</code>.
81     */
82    PropertiesContext getContext(Class<?> declaringType)
83      throws NullPointerException;
84  
85    /**
86     * Returns the properties context the property described by the given
87     * descriptor is part of.
88     *
89     * @param descriptor the descriptor of the property whose context is
90     *          requested.
91     * @return the context of the property described by the descriptor.
92     * @throws NullPointerException if {@code descriptor} is <code>null</code>.
93     */
94    PropertyContext getContext(PropertyDescriptor descriptor)
95      throws NullPointerException;
96  
97    /**
98     * Checks whether or not this configuration is in administration mode. In this
99     * mode the configuration is less strict with certain validations. Especially
100    * it allows to edit otherwise read-only properties.
101    *
102    * @return <code>true</code> if the configuration is in administration mode,
103    *         <code>false</code> otherwise.
104    */
105   boolean isInAdminMode();
106 
107   // --- business -------------------------------------------------------------
108 
109   /**
110    * Returns a implementation of the given interface that has access to the
111    * property keys, the property descriptors and the properties itself, when
112    * they are declared in the given interface. The interface must be annotated
113    * with an {@link de.smartics.properties.api.core.annotations.PropertySet}
114    * annotation.
115    *
116    * @param propertiesInterface a
117    *          {@link de.smartics.properties.api.core.annotations.PropertySet}
118    *          annotated interface for which a implementation to access the
119    *          property keys, descriptors and values is requested.
120    * @param <T> type variable to enable a type save return value.
121    * @return a implementation of the given interface to access property
122    *         information.
123    */
124   <T> T getProperties(Class<T> propertiesInterface);
125 
126   /**
127    * Returns the property value for the given descriptor.
128    *
129    * @param descriptor the key to the property.
130    * @return the value to the property. A value of <code>null</code> is returned
131    *         in cause of an optional property being not set.
132    * @throws NullPointerException if {@code descriptor} is <code>null</code>.
133    * @throws PropertyValidationException if the property is invalid according to
134    *           its constraints.
135    */
136   Object getPropertyValue(PropertyDescriptor descriptor)
137     throws NullPointerException, PropertyValidationException;
138 
139   /**
140    * Returns the property value for the given key.
141    *
142    * @param key the key to the property.
143    * @return the value to the property. A value of <code>null</code> is returned
144    *         in cause of an optional property being not set.
145    * @throws IllegalArgumentException if {@code key} is blank.
146    * @throws UnknownPropertyException if {@code key} is not known.
147    * @throws PropertyValidationException if the property is invalid according to
148    *           its constraints.
149    */
150   Object getPropertyValue(String key) throws IllegalArgumentException,
151     UnknownPropertyException, PropertyValidationException;
152 
153   /**
154    * Returns the property value for the given key.
155    *
156    * @param key the key to the property.
157    * @return the value to the property. A value of <code>null</code> is returned
158    *         in cause of an optional property being not set.
159    * @throws IllegalArgumentException if {@code key} is blank.
160    * @throws UnknownPropertyException if {@code key} is not known.
161    * @throws PropertyValidationException if the property is invalid according to
162    *           its constraints.
163    */
164   Object getPropertyValue(PropertyKey key) throws IllegalArgumentException,
165     UnknownPropertyException, PropertyValidationException;
166 
167   /**
168    * Returns the property value for the given descriptor, allowing to
169    * transparently provide a default value to be returned in case the property
170    * has not been set.
171    *
172    * @param descriptor the key to the property.
173    * @param defaultValue the default value to use in case no value has been
174    *          specified.
175    * @return the value to the property. A value of <code>null</code> is returned
176    *         in cause of an optional property being not set.
177    * @throws NullPointerException if {@code descriptor} is <code>null</code>.
178    * @throws PropertyValueConversionException if conversion fails.
179    * @throws PropertyValidationException if the property is invalid according to
180    *           its constraints.
181    * @throws UnknownPropertyException if the requested property is not known to
182    *           the system.
183    */
184   Object getPropertyValue(PropertyDescriptor descriptor, Object defaultValue)
185     throws NullPointerException, PropertyValueConversionException,
186     PropertyValidationException, UnknownPropertyException;
187 
188   /**
189    * Returns the property value for the given key, allowing to transparently
190    * provide a default value to be returned in case the property has not been
191    * set.
192    *
193    * @param key the key to the property.
194    * @param defaultValue the default value to use in case no value has been
195    *          specified.
196    * @return the value to the property. A value of <code>null</code> is returned
197    *         in cause of an optional property being not set.
198    * @throws IllegalArgumentException if {@code key} is blank.
199    * @throws UnknownPropertyException if {@code key} is not known.
200    * @throws PropertyValidationException if the property is invalid according to
201    *           its constraints.
202    */
203   Object getPropertyValue(String key, Object defaultValue)
204     throws IllegalArgumentException, UnknownPropertyException,
205     PropertyValidationException;
206 
207   /**
208    * Returns the property for the given key.
209    *
210    * @param key the unique key of the property.
211    * @return the requested property.
212    * @throws IllegalArgumentException if {@code key} is blank.
213    * @throws UnknownPropertyException if {@code key} is not known.
214    */
215   DescribedProperty getProperty(String key) throws IllegalArgumentException,
216     UnknownPropertyException;
217 
218   /**
219    * Returns the property for the given key, allowing to transparently provide a
220    * default value to be returned in case the property has not been set.
221    *
222    * @param key the unique key of the property.
223    * @param defaultValue the default value to use in case no value has been
224    *          specified.
225    * @return the requested property.
226    * @throws IllegalArgumentException if {@code key} is blank.
227    * @throws UnknownPropertyException if {@code key} is not known.
228    */
229   DescribedProperty getProperty(String key, Object defaultValue)
230     throws IllegalArgumentException, UnknownPropertyException;
231 
232   /**
233    * Returns the property for the given key.
234    *
235    * @param key the unique key of the property.
236    * @return the requested property.
237    * @throws IllegalArgumentException if {@code key} is blank.
238    * @throws UnknownPropertyException if {@code key} is not known.
239    */
240   DescribedProperty getProperty(PropertyKey key) throws IllegalArgumentException,
241     UnknownPropertyException;
242 
243   /**
244    * Returns the property for the given descriptor.
245    *
246    * @param descriptor the descriptor containing the unique key of the property.
247    * @return the requested property.
248    * @throws NullPointerException if {@code descriptor} is <code>null</code>.
249    * @throws UnknownPropertyException if the key of the {@code descriptor} is
250    *           not known.
251    */
252   DescribedProperty getProperty(PropertyDescriptor descriptor)
253     throws NullPointerException, UnknownPropertyException;
254 
255   /**
256    * Returns the property for the given descriptor, allowing to transparently
257    * provide a default value to be returned in case the property has not been
258    * set.
259    *
260    * @param descriptor the descriptor containing the unique key of the property.
261    * @param defaultValue the default value to use in case no value has been
262    *          specified.
263    * @return the requested property.
264    * @throws NullPointerException if {@code descriptor} is <code>null</code>.
265    * @throws UnknownPropertyException if the key of the {@code descriptor} is
266    *           not known.
267    */
268   DescribedProperty getProperty(PropertyDescriptor descriptor, Object defaultValue)
269     throws NullPointerException, UnknownPropertyException;
270 
271   /**
272    * Returns the yet not validated property for the given descriptor's key. This
273    * is useful to access the resolved and converted value to apply validation
274    * only under certain conditions.
275    *
276    * @param descriptor descriptor key to the property.
277    * @return the resolved property. May be <code>null</code> if the property's
278    *         value is actually unset.
279    * @throws IllegalArgumentException if {@code descriptor} is blank.
280    * @throws UnknownPropertyException if {@code descriptor} is not known.
281    * @throws PropertyValueConversionException if the property cannot be
282    *           converted to its value.
283    * @throws SecurityException on any problem decrypting an encrypted value.
284    * @throws PropertyRootException on any problem.
285    */
286   Object getPropertyAsType(PropertyDescriptor descriptor)
287     throws IllegalArgumentException, UnknownPropertyException,
288     PropertyValueConversionException, SecurityException, PropertyRootException;
289 
290   /**
291    * Returns the validated property for the given descriptor's key, allowing to
292    * transparently provide a default value to be returned in case the property
293    * has not been set.
294    *
295    * @param descriptor descriptor key to the property.
296    * @param defaultValue the default value to use in case no value has been
297    *          specified.
298    * @return the validated property. Never <code>null</code>, although the value
299    *         / validated value of the returned property may be <code>null</code>.
300    * @throws IllegalArgumentException if {@code descriptor} is blank.
301    * @throws UnknownPropertyException if {@code descriptor} is not known.
302    * @throws PropertyValueConversionException if the property cannot be
303    *           converted to its value.
304    * @throws PropertyValidationException if the property is invalid according to
305    *           its constraints.
306    * @throws SecurityException on any problem decrypting an encrypted value.
307    * @throws PropertyRootException on any problem.
308    */
309   ValidatedProperty getValidatedProperty(PropertyDescriptor descriptor,
310       Object defaultValue) throws IllegalArgumentException,
311     UnknownPropertyException, PropertyValueConversionException,
312     PropertyValidationException, SecurityException, PropertyRootException;
313 
314   /**
315    * Returns the validated property for the given key, allowing to transparently
316    * provide a default value to be returned in case the property has not been
317    * set.
318    *
319    * @param key the key to the property.
320    * @param defaultValue the default value to use in case no value has been
321    *          specified.
322    * @return the validated property. Never <code>null</code>, although the value
323    *         / validated value of the returned property may be <code>null</code>.
324    * @throws IllegalArgumentException if {@code key} is blank.
325    * @throws UnknownPropertyException if {@code key} is not known.
326    * @throws PropertyValueConversionException if the property cannot be
327    *           converted to its value.
328    * @throws PropertyValidationException if the property is invalid according to
329    *           its constraints.
330    * @throws SecurityException on any problem decrypting an encrypted value.
331    * @throws PropertyRootException on any problem.
332    */
333   ValidatedProperty getValidatedProperty(PropertyKey key, Object defaultValue)
334     throws IllegalArgumentException, UnknownPropertyException,
335     PropertyValueConversionException, PropertyValidationException,
336     SecurityException, PropertyRootException;
337 
338   /**
339    * Returns the validated property for the given key, allowing to transparently
340    * provide a default value to be returned in case the property has not been
341    * set.
342    *
343    * @param key the key to the property.
344    * @param defaultValue the default value to use in case no value has been
345    *          specified.
346    * @return the validated property. Never <code>null</code>, although the value
347    *         / validated value of the returned property may be <code>null</code>.
348    * @throws IllegalArgumentException if {@code key} is blank.
349    * @throws UnknownPropertyException if {@code key} is not known.
350    * @throws PropertyValueConversionException if the property cannot be
351    *           converted to its value.
352    * @throws PropertyValidationException if the property is invalid according to
353    *           its constraints.
354    * @throws SecurityException on any problem decrypting an encrypted value.
355    * @throws PropertyRootException on any problem.
356    */
357   ValidatedProperty getValidatedProperty(String key, Object defaultValue)
358     throws IllegalArgumentException, UnknownPropertyException,
359     PropertyValueConversionException, PropertyValidationException,
360     SecurityException, PropertyRootException;
361 
362   /**
363    * Returns the property string value for the given descriptor. If the property
364    * type is not {@link String}, the {@link Object#toString()} method is called
365    * to create the string representation of the value. <code>null</code> is
366    * always returned as <code>null</code> (not as the String "null").
367    *
368    * @param descriptor the key to the property.
369    * @return the value to the property. A value of <code>null</code> is returned
370    *         in cause of an optional property being not set.
371    * @throws NullPointerException if {@code descriptor} is <code>null</code>.
372    * @throws PropertyValidationException if the property is invalid according to
373    *           its constraints.
374    */
375   String getPropertyValueAsString(PropertyDescriptor descriptor)
376     throws NullPointerException, PropertyValidationException;
377 
378   /**
379    * Returns the property string value for the given key. If the property type
380    * is not {@link String}, the {@link Object#toString()} method is called to
381    * create the string representation of the value. <code>null</code> is always
382    * returned as <code>null</code> (not as the String "null").
383    *
384    * @param key the key to the property.
385    * @return the value to the property. A value of <code>null</code> is returned
386    *         in cause of an optional property being not set.
387    * @throws IllegalArgumentException if {@code key} is blank.
388    * @throws UnknownPropertyException if {@code key} is not known.
389    * @throws PropertyValidationException if the property is invalid according to
390    *           its constraints.
391    */
392   String getPropertyValueAsString(String key) throws IllegalArgumentException,
393     UnknownPropertyException, PropertyValidationException;
394 
395   /**
396    * Returns the property string value for the given descriptor. If the property
397    * type is not {@link String}, the {@link Object#toString()} method is called
398    * to create the string representation of the value. <code>null</code> is
399    * always returned as <code>null</code> (not as the String "null").
400    *
401    * @param descriptor the key to the property.
402    * @param defaultValue the default value to use in case no value has been
403    *          specified.
404    * @return the value to the property. A value of <code>null</code> is returned
405    *         in cause of an optional property being not set.
406    * @throws NullPointerException if {@code descriptor} is <code>null</code>.
407    * @throws PropertyValidationException if the property is invalid according to
408    *           its constraints.
409    */
410   String getPropertyValueAsString(PropertyDescriptor descriptor,
411       Object defaultValue) throws NullPointerException,
412     PropertyValidationException;
413 
414   /**
415    * Returns the property string value for the given key. If the property type
416    * is not {@link String}, the {@link Object#toString()} method is called to
417    * create the string representation of the value. <code>null</code> is always
418    * returned as <code>null</code> (not as the String "null").
419    *
420    * @param key the key to the property.
421    * @param defaultValue the default value to use in case no value has been
422    *          specified.
423    * @return the value to the property. A value of <code>null</code> is returned
424    *         in cause of an optional property being not set.
425    * @throws IllegalArgumentException if {@code key} is blank.
426    * @throws UnknownPropertyException if {@code key} is not known.
427    * @throws PropertyValidationException if the property is invalid according to
428    *           its constraints.
429    */
430   String getPropertyValueAsString(String key, Object defaultValue)
431     throws IllegalArgumentException, UnknownPropertyException,
432     PropertyValidationException;
433 
434   /**
435    * Validates all properties in the given configuration in a non-lenient
436    * fashion.
437    *
438    * @throws ConfigurationValidationException if the configuration contains
439    *           properties that do not meet the required constraints.
440    */
441   void validate() throws ConfigurationValidationException;
442 
443   /**
444    * Validates all properties in the given configuration and groups in a
445    * non-lenient fashion.
446    *
447    * @param groups the validation groups to consider in the validation process.
448    *          The groups will be validated in the given order. As soon as a
449    *          validation group fails, the validation process is aborted without
450    *          checking the not yet processed groups.
451    * @throws ConfigurationValidationException if the configuration contains
452    *           properties that do not meet the required constraints.
453    */
454   void validate(Class<?>... groups) throws ConfigurationValidationException;
455 
456   /**
457    * Validates the given property in the given configuration.
458    *
459    * @param descriptor the descriptor whose value is to be validated.
460    * @param ifInOneOfTheseGroups the validation only takes place if this
461    *          constraint is part of any of the specified groups or the argument
462    *          is empty or <code>null</code>.
463    * @throws ConfigurationValidationException if property does not meet the
464    *           required constraints.
465    */
466   void validate(PropertyDescriptor descriptor, Class<?>... ifInOneOfTheseGroups)
467     throws ConfigurationValidationException;
468 
469   /**
470    * Validates the given property in the given configuration.
471    *
472    * @param descriptor the descriptor whose value is to be validated.
473    * @param value the property value to be validated.
474    * @param ifInOneOfTheseGroups the validation only takes place if this
475    *          constraint is part of any of the specified groups or the argument
476    *          is empty or <code>null</code>.
477    * @throws ConfigurationValidationException if property does not meet the
478    *           required constraints.
479    */
480   void validate(PropertyDescriptor descriptor, String value,
481       Class<?>... ifInOneOfTheseGroups) throws ConfigurationValidationException;
482 
483   /**
484    * Validates all properties in the given configuration.
485    *
486    * @param lenient the lenient flag that tells the validation process to handle
487    *          unknown properties gracefully if set to <code>true</code>. If the
488    *          value is <code>false</code> unknown properties are reported as
489    *          validation failures.
490    * @param groups the validation groups to consider in the validation process.
491    *          The groups will be validated in the given order. As soon as a
492    *          validation group fails, the validation process is aborted without
493    *          checking the not yet processed groups.
494    * @throws ConfigurationValidationException if the configuration contains
495    *           properties that do not meet the required constraints.
496    */
497   void validate(boolean lenient, Class<?>... groups)
498     throws ConfigurationValidationException;
499 
500   /**
501    * Adds the given listener as a listener to the given property.
502    *
503    * @param name the name of the property to track changes.
504    * @param listener the listener to add.
505    * @throws NullPointerException if {@code name} or {@code listener} is
506    *           <code>null</code>.
507    */
508   void addPropertyChangeListener(PropertyKey name,
509       PropertyChangeListener listener) throws NullPointerException;
510 
511   /**
512    * Removes the given listener as a listener to the given property.
513    *
514    * @param name the name of the property to stop tracking changes.
515    * @param listener the listener to remove.
516    * @throws NullPointerException if {@code name} or {@code listener} is
517    *           <code>null</code>.
518    */
519   void removePropertyChangeListener(PropertyKey name,
520       PropertyChangeListener listener) throws NullPointerException;
521 
522   /**
523    * Adds the given listener to track any property changes.
524    *
525    * @param listener the listener to add.
526    * @throws NullPointerException if {@code listener} is <code>null</code>.
527    */
528   void addPropertyChangeListener(PropertyChangeListener listener)
529     throws NullPointerException;
530 
531   /**
532    * Removes the given listener to stop tracking property changes.
533    *
534    * @param listener the listener to remove.
535    * @throws NullPointerException if {@code listener} is <code>null</code>.
536    */
537   void removePropertyChangeListener(PropertyChangeListener listener)
538     throws NullPointerException;
539 
540   // --- object basics --------------------------------------------------------
541 
542   /**
543    * Creates a serializable variant of this implementation.
544    *
545    * @return a serializable variant of this implementation.
546    * @see de.smartics.properties.spi.config.domain.ConfigurationPropertiesProxy
547    * @see de.smartics.properties.spi.config.domain.ConfigurationPropertiesManagementProxy
548    */
549   SerializableConfigurationProperties toSerializable();
550 
551   /**
552    * Creates an representative of this configuration. If the configuration
553    * serves for a specific configuration key, this instance will be returned. If
554    * the configuration servers for multiple configuration keys, the
555    * representative is returned. The representative is usually the configuration
556    * that is associated with the full key.
557    *
558    * @return the representative (may be this).
559    */
560   ConfigurationProperties toRepresentative();
561 
562 }