AbstractAutofillDefaultValueBuilder.java
package fr.sii.ogham.core.builder.filler;
import fr.sii.ogham.core.builder.configuration.ConfigurationValueBuilder;
import fr.sii.ogham.core.builder.configuration.ConfigurationValueBuilderHelper;
import fr.sii.ogham.core.builder.configurer.Configurer;
import fr.sii.ogham.core.builder.context.BuildContext;
import fr.sii.ogham.core.fluent.AbstractParent;
/**
* Base class to configure a property key that will be used to automatically
* fill a message. It registers the property keys only (no direct value).
*
* @author Aurélien Baudet
*
* @param <MYSELF>
* The type of this instance. This is needed to have the right return
* type for fluent chaining with inheritance
* @param <P>
* the type of the parent builder (when calling {@link #and()}
* method)
* @param <V>
* The type of the value
*/
@SuppressWarnings("squid:S00119")
public abstract class AbstractAutofillDefaultValueBuilder<MYSELF, P, V> extends AbstractParent<P> {
protected final MYSELF myself;
protected final BuildContext buildContext;
protected final ConfigurationValueBuilderHelper<MYSELF, V> defaultValueBuilder;
/**
* Initializes the builder with the explicit type of this instance for
* chaining. This is mandatory in order to have a fluent chaining that
* doesn't loose sub-types. If we were using directly {@code this}, chaining
* would only give methods statically defined by
* {@link AbstractAutofillDefaultValueBuilder}. All methods defined by any
* specialized implementation that would add other methods won't be
* accessible directly.
*
* The parent is used by the {@link #and()} method for chaining.
*
* @param selfType
* the real implementation class that helps compiler to chain
* calls
* @param parent
* the parent builder
* @param valueClass
* the type of the value
* @param buildContext
* for registering instances and property evaluation
*/
@SuppressWarnings("unchecked")
public AbstractAutofillDefaultValueBuilder(Class<?> selfType, P parent, Class<V> valueClass, BuildContext buildContext) {
super(parent);
myself = (MYSELF) selfType.cast(this);
this.buildContext = buildContext;
defaultValueBuilder = buildContext.newConfigurationValueBuilder(myself, valueClass);
}
/**
* Register a default value to use if no value is specified on the message.
*
* <p>
* The value set using this method takes precedence over any property and
* default value configured using {@link #defaultValue()}.
*
* <pre>
* .defaultValue("my-value")
* .defaultValue()
* .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
* .defaultValue("default")
* </pre>
*
* <pre>
* .defaultValue("my-value")
* .defaultValue()
* .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
* .defaultValue("default")
* </pre>
*
* In both cases, {@code defaultValue("my-value")} is used.
*
* <p>
* If this method is called several times, only the last value is used.
*
* <p>
* If {@code null} value is set, it is like not setting a value at all. The
* property/default value configuration is applied.
*
* @param value
* the default value if no value is defined
* @return this instance for fluent chaining
*/
public MYSELF defaultValue(V value) {
defaultValueBuilder.setValue(value);
return myself;
}
/**
* Register a default value to use if no value is specified on the message.
*
* <p>
* This method is mainly used by {@link Configurer}s to register some
* property keys and/or a default value. The aim is to let developer be able
* to externalize its configuration (using system properties, configuration
* file or anything else). If the developer doesn't configure any value for
* the registered properties, the default value is used (if set).
*
* <pre>
* .defaultValue()
* .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
* .defaultValue("default")
* </pre>
*
* <p>
* Non-null value set using {@link #defaultValue(Object)} takes precedence
* over property values and default value.
*
* <pre>
* .defaultValue("my-value")
* .defaultValue()
* .properties("${custom.property.high-priority}", "${custom.property.low-priority}")
* .defaultValue("default")
* </pre>
*
* The value {@code "my-value"} is used regardless of the value of the
* properties and default value.
*
* <p>
* See {@link ConfigurationValueBuilder} for more information.
*
*
* @return the builder to configure property keys/default value
*/
public ConfigurationValueBuilder<MYSELF, V> defaultValue() {
return defaultValueBuilder;
}
}