package com.liato.bankdroid.api.configuration;
import java.util.Collections;
import java.util.List;
import java.util.ResourceBundle;
/**
* A builder for building {@link Field} objects.
*/
public class FieldBuilder {
private BasicField field;
/**
* Create a new {@link Field} builder without i18n support.
*/
public FieldBuilder(String reference) {
this(reference, null);
}
/**
* Create a new {@link Field} builder with i18n support for {@link Field#getLabel()} and {@link Field#getPlaceholder()}.
* The following keys needs to be in the ResourceBundle:
* {@code field.{reference}.label} - Locale label value
* {@code field.{reference}.placeholder} - Locale placeholder value.
*
* Setting {@link #placeholder(String)} or {@link #label(String) specifically will override the i18n values.
* Otherwise they will be set to the value specified in the Locale bundle or in the default bundle if not present.
* If a key is not present at all in the ResourceBundle the key will will be returned.
* @param reference Field reference
* @param bundle The ResourceBundle to be used for i18n support.
*/
public FieldBuilder(String reference, ResourceBundle bundle) {
if (reference == null || reference.trim().isEmpty()) {
throw new IllegalArgumentException("reference must be provided.");
}
field = new BasicField(reference, bundle);
}
public Field build() {
return field;
}
public FieldBuilder label(String label) {
field.label = label;
return this;
}
public FieldBuilder placeholder(String placeholder) {
field.placeholder = placeholder;
return this;
}
public FieldBuilder fieldType(FieldType fieldType) {
field.fieldType = fieldType;
return this;
}
public FieldBuilder required(boolean required) {
field.required = required;
return this;
}
public FieldBuilder hidden(boolean hidden) {
field.hidden = hidden;
return this;
}
public FieldBuilder secret(boolean secret) {
field.secret = secret;
return this;
}
public FieldBuilder values(List<Entry> values) {
field.values = values;
return this;
}
public FieldBuilder validator(FieldValidator validator) {
field.validator = validator;
return this;
}
private static class BasicField implements Field {
private ResourceBundle resourceBundle;
private String reference;
private String placeholder;
private String label;
private FieldType fieldType;
private boolean required;
private boolean hidden;
private boolean secret;
private List<Entry> values;
private FieldValidator validator;
BasicField(String reference, ResourceBundle bundle) {
this.reference = reference;
this.resourceBundle = bundle;
}
@Override
public String getReference() {
return reference;
}
@Override
public String getPlaceholder() {
return placeholder == null ? getLocaleString("placeholder") : placeholder;
}
@Override
public String getLabel() {
return label == null ? getLocaleString("label") : label;
}
@Override
public FieldType getFieldType() {
return fieldType;
}
@Override
public boolean isRequired() {
return required;
}
@Override
public boolean isHidden() {
return hidden;
}
@Override
public boolean isSecret() {
return secret;
}
@Override
public List<Entry> getValues() {
if (values == null) {
values = Collections.emptyList();
}
return values;
}
@Override
public void validate(String value) throws IllegalArgumentException {
if (required) {
if (value == null || value.trim().isEmpty()) {
throw new IllegalArgumentException(String.format("%s is required", getLabel()));
}
if (validator != null) {
validator.validate(value);
}
}
}
private String getLocaleString(String key) {
if (!isLocale()) {
return null;
}
String propertyKey = String.format("field.%s.%s", reference, key);
return resourceBundle.containsKey(propertyKey) ? resourceBundle.getString(propertyKey)
: propertyKey;
}
private boolean isLocale() {
return resourceBundle != null;
}
}
}