# Package oracle.dbtools.plugin.api.conf

Services for defining and introspecting Configuration Settings

# About Configuration Settings

Each plugin may contribute zero or more `ConfigurationSetting` values. By declaring discoverable `ConfigurationSetting` values a plugin enables two things:

- The plugin's settings may be managed in the same manner across all plugins. Configuration Tooling can operate on the plugin's settings automatically
- The plugin can inject the setting's value directly into an `javax.inject.Inject` injection site. This reduces coupling to the Plugin API, making it easier to re-use or share code in the plugin in other code bases and it also facilitates easier unit testing. Unit tests can just pass the the required values directly to the class under test, rather than having to pass values via the `Configuration` API

## Declaring a Configuration Setting

Each setting is uniquely defined by it's name. It must have a data-type and may also have the following optional attributes:

- A default value, used when no explicit value for the settings is provided in the `Configuration`
- A flag indicating if the value is sensitive (such as a password) and should be stored/accessed securely
- A flag indicating if the setting is global and applies across the entire application, rather than being configurable per request

Best practice is to define a constant for the setting name and use that constant rather than a literal string. The `ConfigurationSetting` should be defined as a `final static` constant. The field must be annotated with `javax.inject.Named` to indicate the unique name of the setting.

The field or it's enclosing type must be annotated with `Provides` so that the field is discoverable.

### Supported data types

`ConfigurationSetting` data-types must be one of the following:

- `String` - A textual value
- `Integer` - An integer value
- `Long` - A large integer value
- `Boolean` - A boolean value. It is recommended that the default value for a `Boolean` setting is always `Boolean.FALSE`
- A subclass of `Enum` - Where the value of is one of the case insensitive name of enum value names
- `TimeDuration` - A value representing a duration

### Examples

#### Undocumented Integer Setting

     public interface PluginSettings {
            static final String SETTING_FOO = "my.plugin.setting.foo";
     }

     @Provides
     class PluginImpl {
            @Named(PluginSettings.SETTING_FOO)
            static final ConfigurationSetting FOO = ConfigurationSetting.setting(10);
     }

#### Documented Enum Setting

     public interface PluginSettings {
            static final String ACCESS_MODE_SETTING = "my.plugin.accessMode";
     }

     @Provides
     class PluginImpl {
            @Named(PluginSettings.ACCESS_MODE_SETTING)
            @ConfigurationSetting.Description(@TranslatableDescription(type = MyPluginMessages.class, id = MyPluginMessages.ACCESS_MODE_DESCRIPTION))
            static final ConfigurationSetting ACCESS_MODE = ConfigurationSetting.setting(java.nio.AccessMode.class,
                            java.nio.AccessMode.READ);
     }

## Injecting Configuration Settings

When a `ConfigurationSetting` is declared as outlined above, the Dependency Injection runtime is able to map each setting to a concrete value derived from the `Configuration` instance applicable to the current scope. Thus instead of invoking `Configuration.get(String)` (which is strongly discouraged) a plugin service can just declare a dependency on the configuration setting value via an appropriately typed and `javax.inject.Named` parameter in it's constructor

For example to inject the `my.plugin.setting.foo` configuration setting value into some service, one would do:

     @Provides
     class MyPluginService implements SomeService {
       @Inject
       MyPluginService(final @Named(PluginSettings.FOO_SETTING) int foo) {
        ...
       }
     }

### Boxing and Unboxing of Primitive Types

For ease of use, injection sites may use primitive types where applicable.

- Settings of type `Integer` can be injected as `int`
- Settings of type `Long` can be injected as `long`
- Settings of type `Boolean` can be injected as `boolean`

Note in each case if no default value is specified for the setting and the `Configuration` also lacks a value for the setting then a runtime error will occur during creation of the service and likely lead to the application not starting.

Author:
  cdivilly

- Interface Summary
  Interface | Description
  --- | ---
  Configuration | Represents a set of configuration properties.

- Class Summary
  Class | Description
  --- | ---
  ConfigurationSetting | Declares a `ConfigurationSetting`, specifying it's type, and default value.
  ConfigurationSetting.Builder | Builds `ConfigurationSetting` instances
  TimeDuration | Represents a specification of a time duration.

- Enum Summary
  Enum | Description
  --- | ---
  ConfigurationStatus | Enumerates the status of a ConfigurationSettings.

- Annotation Types Summary
  Annotation Type | Description
  --- | ---
  ConfigurationSetting.Description | Deprecated. since 20.3.0.