package org.infinispan.commons.configuration.attributes; import org.infinispan.commons.CacheConfigurationException; import org.infinispan.commons.util.Util; /** * * AttributeDefinition. Defines the characteristics of a configuration attribute. It is used to * construct an actual {@link Attribute} holder. * * An attribute definition has the following characteristics: * <ul> * <li>A name</li> * <li>A default value or a value initializer</li> * <li>A type, which needs to be specified if it cannot be inferred from the default value, i.e. * when it is null</li> * <li>Whether an attribute is immutable or not, i.e. whether its value is constant after * initialization or it can be changed</li> * <li>A validator which intercepts invalid values</li> * </ul> * * @author Tristan Tarrant * @since 7.2 */ public final class AttributeDefinition<T> { private final String name; private final String xmlName; private final T defaultValue; private final boolean immutable; private final boolean autoPersist; private final AttributeCopier copier; private final AttributeInitializer<? extends T> initializer; private final AttributeValidator<? super T> validator; private final Class<T> type; AttributeDefinition(String name, String xmlName, T initialValue, Class<T> type, boolean immutable, boolean autoPersist, AttributeCopier copier, AttributeValidator<? super T> validator, AttributeInitializer<? extends T> initializer) { this.name = name; this.xmlName = xmlName; this.defaultValue = initialValue; this.immutable = immutable; this.autoPersist = autoPersist; this.copier = copier; this.initializer = initializer; this.validator = validator; this.type = type; } public String name() { return name; } public String xmlName() { return xmlName; } public Class<T> getType() { return type; } public T getDefaultValue() { return initializer != null ? initializer().initialize() : defaultValue; } public boolean isImmutable() { return immutable; } public boolean isAutoPersist() { return autoPersist; } public AttributeCopier copier() { return copier; } public AttributeInitializer<? extends T> initializer() { return initializer; } AttributeValidator<? super T> validator() { return validator; } public Attribute<T> toAttribute() { return new Attribute<T>(this); } public void validate(T value) { if (validator != null) { validator.validate(value); } } public static <T> Builder<T> builder(String name, T defaultValue) { if (defaultValue != null) { return new Builder<T>(name, defaultValue, (Class<T>) defaultValue.getClass()); } else { throw new CacheConfigurationException("Must specify type when passing null for AttributeDefinition " + name); } } public static <T> Builder<T> builder(String name, T defaultValue, Class<T> klass) { return new Builder<>(name, defaultValue, klass); } public static final class Builder<T> { private final String name; private final T defaultValue; private final Class<T> type; private boolean immutable = false; private boolean autoPersist = true; private String xmlName; private AttributeCopier copier = null; private AttributeInitializer<? extends T> initializer; private AttributeValidator<? super T> validator; private Builder(String name, T defaultValue, Class<T> type) { this.name = name; this.defaultValue = defaultValue; this.type = type; } public Builder<T> immutable() { this.immutable = true; return this; } public Builder<T> copier(AttributeCopier copier) { this.copier = copier; return this; } public Builder<T> initializer(AttributeInitializer<? extends T> initializer) { this.initializer = initializer; return this; } public Builder<T> autoPersist(boolean autoPersist) { this.autoPersist = autoPersist; return this; } public Builder<T> validator(AttributeValidator<? super T> validator) { this.validator = validator; return this; } public Builder<T> xmlName(String xmlName) { this.xmlName = xmlName; return this; } public AttributeDefinition<T> build() { return new AttributeDefinition<T>(name, xmlName == null ? Util.xmlify(name) : xmlName, defaultValue, type, immutable, autoPersist, copier, validator, initializer); } } }