Class BasicConfigurationBuilder<T extends ImmutableConfiguration>

  • Type Parameters:
    T - the concrete type of ImmutableConfiguration objects created by this builder
    All Implemented Interfaces:
    ConfigurationBuilder<T>, EventSource
    Direct Known Subclasses:
    CombinedConfigurationBuilder, FileBasedConfigurationBuilder, MultiFileConfigurationBuilder

    public class BasicConfigurationBuilder<T extends ImmutableConfiguration>
    extends java.lang.Object
    implements ConfigurationBuilder<T>

    An implementation of the ConfigurationBuilder interface which is able to create different concrete ImmutableConfiguration implementations based on reflection.

    When constructing an instance of this class the concrete ImmutableConfiguration implementation class has to be provided. Then properties for the new ImmutableConfiguration instance can be set. The first call to getConfiguration() creates and initializes the new ImmutableConfiguration object. It is cached and returned by subsequent calls. This cache - and also the initialization properties set so far - can be flushed by calling one of the reset() methods. That way other ImmutableConfiguration instances with different properties can be created.

    If the newly created ImmutableConfiguration object implements the Initializable interface, its initialize() method is called after all initialization properties have been set. This way a concrete implementation class can perform arbitrary initialization steps.

    There are multiple options for setting up a BasicConfigurationBuilder instance:

    • All initialization properties can be set in one or multiple calls of the configure() method. In each call an arbitrary number of BuilderParameters objects can be passed. The API allows method chaining and is intended to be used from Java code.
    • If builder instances are created by other means - e.g. using a dependency injection framework -, the fluent API approach may not be suitable. For those use cases it is also possible to pass in all initialization parameters as a map. The keys of the map have to match initialization properties of the ImmutableConfiguration object to be created, the values are the corresponding property values. For instance, the key throwExceptionOnMissing in the map will cause the method setThrowExceptionOnMissing() on the ImmutableConfiguration object to be called with the corresponding value as parameter.

    A builder instance can be constructed with an allowFailOnInit flag. If set to true, exceptions during initialization of the configuration are ignored; in such a case an empty configuration object is returned. A use case for this flag is a scenario in which a configuration is optional and created on demand the first time configuration data is to be stored. Consider an application that stores user-specific configuration data in the user's home directory: When started for the first time by a new user there is no configuration file; so it makes sense to start with an empty configuration object. On application exit, settings can be stored in this object and written to the associated file. Then they are available on next application start.

    This class is thread-safe. Multiple threads can modify initialization properties and call getConfiguration(). However, the intended use case is that the builder is configured by a single thread first. Then getConfiguration() can be called concurrently, and it is guaranteed that always the same ImmutableConfiguration instance is returned until the builder is reset.

    Since:
    2.0
    • Field Detail

      • resultClass

        private final java.lang.Class<? extends T extends ImmutableConfiguration> resultClass
        The class of the objects produced by this builder instance.
      • eventListeners

        private final EventListenerList eventListeners
        An object managing the event listeners registered at this builder.
      • allowFailOnInit

        private final boolean allowFailOnInit
        A flag whether exceptions on initializing configurations are allowed.
      • parameters

        private java.util.Map<java.lang.String,​java.lang.Object> parameters
        The map with current initialization parameters.
      • resultDeclaration

        private BeanDeclaration resultDeclaration
        The current bean declaration.
    • Constructor Detail

      • BasicConfigurationBuilder

        public BasicConfigurationBuilder​(java.lang.Class<? extends T> resCls)
        Creates a new instance of BasicConfigurationBuilder and initializes it with the given result class. No initialization properties are set.
        Parameters:
        resCls - the result class (must not be null)
        Throws:
        java.lang.IllegalArgumentException - if the result class is null
      • BasicConfigurationBuilder

        public BasicConfigurationBuilder​(java.lang.Class<? extends T> resCls,
                                         java.util.Map<java.lang.String,​java.lang.Object> params)
        Creates a new instance of BasicConfigurationBuilder and initializes it with the given result class and an initial set of builder parameters. The allowFailOnInit flag is set to false.
        Parameters:
        resCls - the result class (must not be null)
        params - a map with initialization parameters
        Throws:
        java.lang.IllegalArgumentException - if the result class is null
      • BasicConfigurationBuilder

        public BasicConfigurationBuilder​(java.lang.Class<? extends T> resCls,
                                         java.util.Map<java.lang.String,​java.lang.Object> params,
                                         boolean allowFailOnInit)
        Creates a new instance of BasicConfigurationBuilder and initializes it with the given result class, an initial set of builder parameters, and the allowFailOnInit flag. The map with parameters may be null, in this case no initialization parameters are set.
        Parameters:
        resCls - the result class (must not be null)
        params - a map with initialization parameters
        allowFailOnInit - a flag whether exceptions on initializing a newly created ImmutableConfiguration object are allowed
        Throws:
        java.lang.IllegalArgumentException - if the result class is null
    • Method Detail

      • registerListener

        private static <E extends Event> void registerListener​(EventSource evSrc,
                                                               EventListenerRegistrationData<E> regData)
        Registers an event listener at an event source object.
        Type Parameters:
        E - the type of the event listener
        Parameters:
        evSrc - the event source
        regData - the registration data object
      • removeListener

        private static <E extends Event> void removeListener​(EventSource evSrc,
                                                             EventListenerRegistrationData<E> regData)
        Removes an event listener from an event source object.
        Type Parameters:
        E - the type of the event listener
        Parameters:
        evSrc - the event source
        regData - the registration data object
      • addEventListener

        public <E extends Event> void addEventListener​(EventType<E> eventType,
                                                       EventListener<? super E> listener)
        Adds an event listener for the specified event type. This listener is notified about events of this type and all its sub types. This implementation also takes care that the event listener is added to the managed configuration object.
        Specified by:
        addEventListener in interface EventSource
        Type Parameters:
        E - the type of events processed by this listener
        Parameters:
        eventType - the event type (must not be null)
        listener - the listener to be registered (must not be null)
        Throws:
        java.lang.IllegalArgumentException - if the event type or the listener is null
      • addParameters

        public BasicConfigurationBuilder<T> addParameters​(java.util.Map<java.lang.String,​java.lang.Object> params)
        Adds the content of the given map to the already existing initialization parameters.
        Parameters:
        params - the map with additional initialization parameters; may be null, then this call has no effect
        Returns:
        a reference to this builder for method chaining
      • checkResultInstance

        private void checkResultInstance​(java.lang.Object inst)
        Checks whether the class of the result configuration is compatible with this builder's result class. This is done to ensure that only objects of the expected result class are created.
        Parameters:
        inst - the result instance to be checked
        Throws:
        ConfigurationRuntimeException - if an invalid result class is detected
      • configure

        public BasicConfigurationBuilder<T> configure​(BuilderParameters... params)
        Appends the content of the specified BuilderParameters objects to the current initialization parameters. Calling this method multiple times will create a union of the parameters provided.
        Parameters:
        params - an arbitrary number of objects with builder parameters
        Returns:
        a reference to this builder for method chaining
        Throws:
        java.lang.NullPointerException - if a null array is passed
      • connectToReloadingController

        public final void connectToReloadingController​(ReloadingController controller)
        Connects this builder with a ReloadingController. With this method support for reloading can be added to an arbitrary builder object. Event listeners are registered at the reloading controller and this builder with connect both objects:
        • When the reloading controller detects that a reload is required, the builder's resetResult() method is called; so the managed result object is invalidated.
        • When a new result object has been created the controller's reloading state is reset, so that new changes can be detected again.
        Parameters:
        controller - the ReloadingController to connect to (must not be null)
        Throws:
        java.lang.IllegalArgumentException - if the controller is null
      • copyEventListeners

        protected void copyEventListeners​(BasicConfigurationBuilder<?> target)
        Copies all EventListener objects registered at this builder to the specified target configuration builder. This method is intended to be used by derived classes which support inheritance of their properties to other builder objects.
        Parameters:
        target - the target configuration builder (must not be null)
        Throws:
        java.lang.NullPointerException - if the target builder is null
      • copyEventListeners

        protected void copyEventListeners​(BasicConfigurationBuilder<?> target,
                                          EventListenerList listeners)
        Copies all event listeners in the specified list to the specified target configuration builder. This method is intended to be used by derived classes which have to deal with managed configuration builders that need to be initialized with event listeners.
        Parameters:
        target - the target configuration builder (must not be null)
        listeners - the event listeners to be copied over
        Throws:
        java.lang.NullPointerException - if the target builder is null
      • createResult

        protected T createResult()
                          throws ConfigurationException
        Creates a new, initialized result object. This method is called by getConfiguration() if no valid result object exists. This base implementation performs two steps:
        • createResultInstance() is called to create a new, uninitialized result object.
        • initResultInstance() is called to process all initialization parameters.
        It also evaluates the allowFailOnInit flag, i.e. if initialization causes an exception and this flag is set, the exception is ignored, and the newly created, uninitialized configuration is returned. Note that this method is called in a synchronized block.
        Returns:
        the newly created result object
        Throws:
        ConfigurationException - if an error occurs
      • createResultDeclaration

        protected BeanDeclaration createResultDeclaration​(java.util.Map<java.lang.String,​java.lang.Object> params)
                                                   throws ConfigurationException
        Creates a new BeanDeclaration which is used for creating new result objects dynamically. This implementation creates a specialized BeanDeclaration object that is initialized from the given map of initialization parameters. The BeanDeclaration must be initialized with the result class of this builder, otherwise exceptions will be thrown when the result object is created. Note: This method is invoked in a synchronized block.
        Parameters:
        params - a snapshot of the current initialization parameters
        Returns:
        the BeanDeclaration for creating result objects
        Throws:
        ConfigurationException - if an error occurs
      • createResultInstance

        protected T createResultInstance()
                                  throws ConfigurationException
        Creates the new, uninitialized result object. This is the first step of the process of producing a result object for this builder. This implementation uses the BeanHelper class to create a new object based on the BeanDeclaration returned by getResultDeclaration(). Note: This method is invoked in a synchronized block.
        Returns:
        the newly created, yet uninitialized result object
        Throws:
        ConfigurationException - if an exception occurs
      • fetchBeanHelper

        protected final BeanHelper fetchBeanHelper()
        Obtains the BeanHelper object to be used when dealing with bean declarations. This method checks whether this builder was configured with a specific BeanHelper instance. If so, this instance is used. Otherwise, the default BeanHelper is returned.
        Returns:
        the BeanHelper to be used
      • fetchEventSource

        private EventSource fetchEventSource()
        Returns an EventSource for the current result object. If there is no current result or if it does not extend EventSource, a dummy event source is returned.
        Returns:
        the EventSource for the current result object
      • fireBuilderEvent

        protected void fireBuilderEvent​(ConfigurationBuilderEvent event)
        Sends the specified builder event to all registered listeners.
        Parameters:
        event - the event to be fired
      • getConfiguration

        public T getConfiguration()
                           throws ConfigurationException
        Gets the configuration provided by this builder. An implementation has to perform all necessary steps for creating and initializing a ImmutableConfiguration object. This implementation creates the result configuration on first access. Later invocations return the same object until this builder is reset. The double-check idiom for lazy initialization is used (Bloch, Effective Java, item 71).
        Specified by:
        getConfiguration in interface ConfigurationBuilder<T extends ImmutableConfiguration>
        Returns:
        the configuration
        Throws:
        ConfigurationException - if an error occurs
      • getFilteredParameters

        private java.util.Map<java.lang.String,​java.lang.Object> getFilteredParameters()
        Gets a map with initialization parameters where all parameters starting with the reserved prefix have been filtered out.
        Returns:
        the filtered parameters map
      • getParameters

        protected final java.util.Map<java.lang.String,​java.lang.Object> getParameters()
        Gets a (unmodifiable) map with the current initialization parameters set for this builder. The map is populated with the parameters set using the various configuration options.
        Returns:
        a map with the current set of initialization parameters
      • getResultClass

        public java.lang.Class<? extends T> getResultClass()
        Gets the result class of this builder. The objects produced by this builder have the class returned here.
        Returns:
        the result class of this builder
      • getResultDeclaration

        protected final BeanDeclaration getResultDeclaration()
                                                      throws ConfigurationException
        Gets the BeanDeclaration that is used to create and initialize result objects. The declaration is created on first access (by invoking createResultDeclaration(Map)) based on the current initialization parameters.
        Returns:
        the BeanDeclaration for dynamically creating a result object
        Throws:
        ConfigurationException - if an error occurs
      • handleEventListenerProviders

        private void handleEventListenerProviders​(BuilderParameters params)
        Checks whether the specified parameters object implements the EventListenerProvider interface. If so, the event listeners it provides are added to this builder.
        Parameters:
        params - the parameters object
      • handleInitializable

        private void handleInitializable​(T obj)
        Performs special initialization of the result object. This method is called after parameters have been set on a newly created result instance. If supported by the result class, the initialize() method is now called.
        Parameters:
        obj - the newly created result object
      • initResultInstance

        protected void initResultInstance​(T obj)
                                   throws ConfigurationException
        Initializes a newly created result object. This is the second step of the process of producing a result object for this builder. This implementation uses the BeanHelper class to initialize the object's property based on the BeanDeclaration returned by getResultDeclaration(). Note: This method is invoked in a synchronized block. This is required because internal state is accessed. Sub classes must not call this method without proper synchronization.
        Parameters:
        obj - the object to be initialized
        Throws:
        ConfigurationException - if an error occurs
      • installEventListener

        protected final <E extends Event> void installEventListener​(EventType<E> eventType,
                                                                    EventListener<? super E> listener)
        Adds the specified event listener to this object. This method is called by addEventListener(), it does the actual listener registration. Because it is final it can be called by sub classes in the constructor if there is already the need to register an event listener.
        Type Parameters:
        E - the event type
        Parameters:
        eventType - the event type object
        listener - the listener to be registered
      • isAllowFailOnInit

        public boolean isAllowFailOnInit()
        Returns the allowFailOnInit flag. See the header comment for information about this flag.
        Returns:
        the allowFailOnInit flag
      • registerEventListeners

        private void registerEventListeners​(T obj)
        Registers the available event listeners at the given object. This method is called for each result object created by the builder.
        Parameters:
        obj - the object to initialize
      • removeEventListener

        public <E extends Event> boolean removeEventListener​(EventType<E> eventType,
                                                             EventListener<? super E> listener)
        Removes the event listener registration for the given event type and listener. An event listener instance may be registered multiple times for different event types. Therefore, when removing a listener the event type of the registration in question has to be specified. The return value indicates whether a registration was removed. A value of false means that no such combination of event type and listener was found. This implementation also takes care that the event listener is removed from the managed configuration object.
        Specified by:
        removeEventListener in interface EventSource
        Type Parameters:
        E - the type of events processed by this listener
        Parameters:
        eventType - the event type
        listener - the event listener to be removed
        Returns:
        a flag whether a listener registration was removed
      • removeEventListeners

        private void removeEventListeners​(T obj)
        Removes all available event listeners from the given result object. This method is called when the result of this builder is reset. Then the old managed configuration should no longer generate events.
        Parameters:
        obj - the affected result object
      • resetParameters

        public void resetParameters()
        Removes all initialization parameters of this builder. This method can be called if this builder is to be reused for creating result objects with a different configuration.
      • resetResult

        public void resetResult()
        Clears an existing result object. An invocation of this method causes a new ImmutableConfiguration object to be created the next time getConfiguration() is called.
      • setParameters

        public BasicConfigurationBuilder<T> setParameters​(java.util.Map<java.lang.String,​java.lang.Object> params)
        Sets the initialization parameters of this builder. Already existing parameters are replaced by the content of the given map.
        Parameters:
        params - the new initialization parameters of this builder; can be null, then all initialization parameters are removed
        Returns:
        a reference to this builder for method chaining
      • updateParameters

        private void updateParameters​(java.util.Map<java.lang.String,​java.lang.Object> newParams)
        Replaces the current map with parameters by a new one.
        Parameters:
        newParams - the map with new parameters (may be null)