/** * Copyright 2011-2017 Asakusa Framework Team. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.asakusafw.runtime.io.text.driver; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.function.Supplier; /** * A definition of field. * @param <T> the property type * @since 0.9.1 */ public final class FieldDefinition<T> { private final String name; private final Supplier<? extends FieldAdapter<? super T>> adapterSupplier; private final Boolean trimInput; private final Boolean skipEmptyInput; private final ErrorAction onMalformedInput; private final ErrorAction onUnmappableOutput; private final Collection<? extends FieldOutput.Option> outputOptions; FieldDefinition( String name, Supplier<? extends FieldAdapter<? super T>> adapterSupplier, Boolean trimInput, Boolean skipEmptyInput, ErrorAction onMalformedInput, ErrorAction onUnmappableOutput, Collection<? extends FieldOutput.Option> outputOptions) { this.name = name; this.adapterSupplier = adapterSupplier; this.trimInput = trimInput; this.skipEmptyInput = skipEmptyInput; this.onMalformedInput = onMalformedInput; this.onUnmappableOutput = onUnmappableOutput; this.outputOptions = Collections.unmodifiableList(new ArrayList<>(outputOptions)); } /** * Creates a new builder. * @param <T> the property type * @param name the field name * @param adapterSupplier the adapter supplier * @return the created builder */ public static <T> Builder<T> builder(String name, Supplier<? extends FieldAdapter<T>> adapterSupplier) { return new Builder<>(name, adapterSupplier); } /** * Returns the field name. * @return the name */ public String getName() { return name; } /** * Returns a supplier of the field adapter. * @return the adapter supplier */ public Supplier<? extends FieldAdapter<? super T>> getAdapterSupplier() { return adapterSupplier; } /** * Returns whether or not leading/trailing white-space characters are trimmed. * @return {@code true} if this trims input, otherwise {@code false} */ public Optional<Boolean> getTrimInput() { return Optional.ofNullable(trimInput); } /** * Returns whether or not this skips empty inputs. * @return {@code true} if this skips empty inputs, otherwise {@code false} */ public Optional<Boolean> getSkipEmptyInput() { return Optional.ofNullable(skipEmptyInput); } /** * Returns the error action for malformed inputs. * @return the error action for malformed inputs */ public Optional<ErrorAction> getOnMalformedInput() { return Optional.ofNullable(onMalformedInput); } /** * Returns the error action for un-mappable outputs. * @return the error action for un-mappable outputs */ public Optional<ErrorAction> getOnUnmappableOutput() { return Optional.ofNullable(onUnmappableOutput); } /** * Returns the output options. * @return the output options */ public Collection<? extends FieldOutput.Option> getOutputOptions() { return outputOptions; } /** * A builder of {@link FieldDefinition}. * @since 0.9.1 * @param <T> the property type */ public static class Builder<T> { private final String name; private final Supplier<? extends FieldAdapter<? super T>> adapterSupplier; private Boolean trimInput = null; private Boolean skipEmptyInput = null; private ErrorAction onMalformedInput = null; private ErrorAction onUnmappableOutput = null; private final List<FieldOutput.Option> outputOptions = new ArrayList<>(); /** * Creates a new instance. * @param name the field name * @param adapterSupplier the adapter supplier */ public Builder(String name, Supplier<? extends FieldAdapter<? super T>> adapterSupplier) { this.name = name; this.adapterSupplier = adapterSupplier; } /** * Sets whether or not leading/trailing white-space characters are trimmed. * @param newValue {@code true} to enable, {@code false} to disable, or {@code null} to inherit the parent * @return this */ public Builder<T> withTrimInput(Boolean newValue) { this.trimInput = newValue; return this; } /** * Sets whether or not this skips empty inputs. * @param newValue {@code true} to enable, {@code false} to disable, or {@code null} to inherit the parent * @return this */ public Builder<T> withSkipEmptyInput(Boolean newValue) { this.skipEmptyInput = newValue; return this; } /** * Sets the error action for malformed inputs. * @param newValue the error action, or {@code null} if inherit the parent setting * @return this */ public Builder<T> withOnMalformedInput(ErrorAction newValue) { this.onMalformedInput = newValue; return this; } /** * Sets the error action for un-mappable outputs. * @param newValue the error action, or {@code null} if inherit the parent setting * @return this */ public Builder<T> withOnUnmappableOutput(ErrorAction newValue) { this.onUnmappableOutput = newValue; return this; } /** * Adds an output option. * @param newValue the output option * @return this */ public Builder<T> withOutputOption(FieldOutput.Option newValue) { this.outputOptions.add(newValue); return this; } /** * Adds output options. * @param newValues the output options * @return this */ public Builder<T> withOutputOptions(FieldOutput.Option... newValues) { Collections.addAll(this.outputOptions, newValues); return this; } /** * Builds a {@link FieldDefinition}. * @return the built object */ public FieldDefinition<T> build() { return new FieldDefinition<>( name, adapterSupplier, trimInput, skipEmptyInput, onMalformedInput, onUnmappableOutput, outputOptions); } } }