PatternEncoderBuilder.java

package io.jstach.rainbowgum.pattern.format;

import io.jstach.rainbowgum.LogProperties;
import io.jstach.rainbowgum.LogProperty;

/**
 * Builder to create {@link io.jstach.rainbowgum.LogProvider<io.jstach.rainbowgum.LogEncoder> }.
 * <table class="table">
 * <caption><strong>Properties retrieved from LogProperties</strong></caption>
 * <tr>
 * <th>Property Pattern</th>
 * <th>Type</th>
 * <th>Required</th>
 * <th>Default</th>
 * <th>Description</th>
 * </tr>
 * <tr>
 * <td><code>{@value PROPERTY_pattern }</code></td>
 * <td><code>String</code></td>
 * <td><code>true</code></td>
 * <td><code>null</code></td>
 * <td></td>
 * </tr>
 * <tr>
 * <td><code>{@value PROPERTY_charset }</code></td>
 * <td><code>String (converted)</code></td>
 * <td><code>false</code></td>
 * <td><code>null</code></td>
 * <td></td>
 * </tr>
 * <tr>
 * <td><code>{@value PROPERTY_maxBufferSize }</code></td>
 * <td><code>Integer</code></td>
 * <td><code>false</code></td>
 * <td><code>null</code></td>
 * <td></td>
 * </tr>
 * </table>
 */
public final class PatternEncoderBuilder implements io.jstach.rainbowgum.LogBuilder<PatternEncoderBuilder,io.jstach.rainbowgum.LogProvider<io.jstach.rainbowgum.LogEncoder>> {

	/**
	 * The properties to be retrieved from config will have
	 * this prefix.
	 */
	static final String PROPERTY_PREFIX = "logging.appender.{name}.encoder.pattern.";
	
	/**
	 * <code>{@value #PROPERTY_pattern } = java.lang.String</code> 
	 */
	static final String PROPERTY_pattern = PROPERTY_PREFIX + "pattern";
	/**
	 * <code>{@value #PROPERTY_charset } = java.nio.charset.Charset</code> 
	 */
	static final String PROPERTY_charset = PROPERTY_PREFIX + "charset";
	/**
	 * <code>{@value #PROPERTY_maxBufferSize } = java.lang.Integer</code> 
	 */
	static final String PROPERTY_maxBufferSize = PROPERTY_PREFIX + "maxBufferSize";
	
	private final String propertyPrefix;
	final String property_pattern;
	final String property_charset;
	final String property_maxBufferSize;
	
	private final java.lang.String name;
	private java.lang.@org.jspecify.annotations.Nullable String pattern = null;
	private io.jstach.rainbowgum.pattern.format.@org.jspecify.annotations.Nullable PatternCompiler patternCompiler;
	private java.nio.charset.@org.jspecify.annotations.Nullable Charset charset = null;
	private java.lang.@org.jspecify.annotations.Nullable Integer maxBufferSize = null;
	
	/**
	 * Create a builder for {@code io.jstach.rainbowgum.LogProvider<io.jstach.rainbowgum.LogEncoder> }.
	 * @param name will fill <code>{name}</code> in <code>logging.appender.{name}.encoder.pattern.</code>. 
	 */
	public PatternEncoderBuilder(
			java.lang.String name
			) {
		try {
			java.util.Map<String,String> prefixParameters = java.util.Map.of(
					"name", name
				);
			this.propertyPrefix = LogProperties.interpolateKey(PROPERTY_PREFIX, prefixParameters);
			this.name = name;
			property_pattern = LogProperties.interpolateKey(PROPERTY_pattern, prefixParameters);
			property_charset = LogProperties.interpolateKey(PROPERTY_charset, prefixParameters);
			property_maxBufferSize = LogProperties.interpolateKey(PROPERTY_maxBufferSize, prefixParameters);
		}
		catch (IllegalArgumentException e) {
			throw LogProperty.ValidationException.of(this.getClass(), e);
		}
	}


	/**
	 * Sets patternCompiler.
	 * 
	 * Default is <code>null</code>.
	 * @param patternCompiler not configurable through properties 
	 * @return this builder.
	 */
	public PatternEncoderBuilder patternCompiler(io.jstach.rainbowgum.pattern.format.@org.jspecify.annotations.Nullable PatternCompiler patternCompiler) {
		this.patternCompiler = patternCompiler;
		return this;
	}

	
	/**
	 * Sets <strong>required</strong> pattern.
	 * 
	 * Default is <code>null</code>.
	 * @param pattern <code>{@value #PROPERTY_pattern } = java.lang.String</code> 
	 * @return this builder.
	 */
	public PatternEncoderBuilder pattern(java.lang.String pattern) {
		this.pattern = pattern;
		return this;
	}
	
	/**
	 * Sets charset.
	 * 
	 * Default is <code>null</code>.
	 * @param charset <code>{@value #PROPERTY_charset } = java.nio.charset.Charset</code> 
	 * @return this builder.
	 */
	public PatternEncoderBuilder charset(java.nio.charset.@org.jspecify.annotations.Nullable Charset charset) {
		this.charset = charset;
		return this;
	}
	
	/**
	 * Sets maxBufferSize.
	 * 
	 * Default is <code>null</code>.
	 * @param maxBufferSize <code>{@value #PROPERTY_maxBufferSize } = java.lang.Integer</code> 
	 * @return this builder.
	 */
	public PatternEncoderBuilder maxBufferSize(java.lang.@org.jspecify.annotations.Nullable Integer maxBufferSize) {
		this.maxBufferSize = maxBufferSize;
		return this;
	}
	
	/**
	 * Creates {@code io.jstach.rainbowgum.LogProvider<io.jstach.rainbowgum.LogEncoder> } from this builder.
	 * @return {@code io.jstach.rainbowgum.LogProvider<io.jstach.rainbowgum.LogEncoder> }.
	 */
	public io.jstach.rainbowgum.LogProvider<io.jstach.rainbowgum.LogEncoder> build() {
		try {
			return io.jstach.rainbowgum.pattern.format.PatternConfigurator.provideEncoder(
					this.name
					, io.jstach.rainbowgum.LogProperty.require(property_pattern, this.pattern)
					, this.patternCompiler
					, this.charset
					, this.maxBufferSize
					);
		}
		catch (IllegalArgumentException | LogProperty.PropertyMissingException e) {
			throw LogProperty.ValidationException.of(this.getClass(), e);
		}
	}
	
	@Override
	public PatternEncoderBuilder fromProperties(LogProperties properties) {
		var __v = LogProperty.Validator.of(this.getClass());
		var _pattern = properties.forKey(property_pattern).ofString().or(this.pattern).validate(__v);
		var _charset = properties.forKey(property_charset).ofString().map(_v -> io.jstach.rainbowgum.pattern.format.PatternConfigurator.convertCharset(_v)).or(this.charset).validateIfError(__v);
		var _maxBufferSize = properties.forKey(property_maxBufferSize).ofInt().or(this.maxBufferSize).validateIfError(__v);
		__v.validate();
		this.pattern = _pattern.value();
		this.charset = _charset.valueOrNull();
		this.maxBufferSize = _maxBufferSize.valueOrNull();
		return this;
	}
	
	/**
	 * The interpolated property prefix: {@value #PROPERTY_PREFIX}.
	 * @return resolved prefix which should end with a "<code>.</code>".
	 */
	@Override
	public String propertyPrefix() {
		return this.propertyPrefix;
	}
	
}