GenerationConfig.java

/*
 * Copyright (C) 2019 sw4j.org
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.sw4j.tool.barcode.random.config;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * This class configures the generation and presentation.
 * </p>
 * <p>
 * To create a new instance programmatically use the
 * {@link org.sw4j.tool.barcode.random.config.OutputConfig.Builder Builder} which can be obtained by the method
 * {@link #builder()}.
 * </p>
 * <p>
 * This class is immutable.
 * </p>
 * @author Uwe Plonus &lt;u.plonus@gmail.com&gt;
 */
public class GenerationConfig {

    /**
     * <p>
     * The size (in bits) of the random number to create.
     * </p>
     */
    private final int size;

    /**
     * <p>
     * The encoding of the predefined codes.
     * </p>
     */
    private final EncodingConfig encoding;

    /**
     * <p>
     * The configurations of the generated barcodes.
     * </p>
     */
    private final List<CodeConfig> codes;

    /**
     * <p>
     * The configuration of the additional encoded random numbers.
     * </p>
     */
    private final List<EncodingConfig> encodings;

    /**
     * <p>
     * Create a new {@code GenerationConfig} with the given random size (in bits) or source encoding, barcode formats
     * and additional representations. If the encoding is set the random size is ignored.
     * </p>
     * <p>
     * This constructor is annotated so that a YAML or JSON parsed with jackson fasterxml can create an instance
     * directly.
     * </p>
     * @param size the size of the random number generated (must be positive and a multiple of 8).
     * @param encoding the encoding of the predefined codes.
     * @param codes the configuration of the barcodes generated.
     * @param encodings the configuration of the additional encodings generated.
     * @throws IllegalArgumentException if {@code size} is either negative or not a multiple of 8, or {@code code} and
     *   {@code encodings} is both {@code null}.
     */
    @JsonCreator
    public GenerationConfig(
            @JsonProperty("size") final int size,
            @JsonProperty("encoding") final EncodingConfig encoding,
            @JsonProperty("codes") final List<CodeConfig> codes,
            @JsonProperty("encodings") final List<EncodingConfig> encodings) {
        if (encoding == null) {
            if (size < 0) {
                throw new IllegalArgumentException(String.format("%s: size is negative",
                        getClass().getSimpleName()));
            }
            if (size % 8 != 0) {
                throw new IllegalArgumentException(String.format("%s: size is not a multiple of 8",
                        getClass().getSimpleName()));
            }
        }
        if ((codes == null || codes.isEmpty()) && (encodings == null || encodings.isEmpty())) {
            throw new IllegalArgumentException(String.format("%s: either codes or encodings is needed",
                    getClass().getSimpleName()));
        }
        this.size = size;
        this.codes = codes;
        this.encodings = encodings;
        this.encoding = encoding;
    }

    /**
     * <p>
     * Return the size of the random number to be created.
     * </p>
     * @return the size of the random number.
     */
    public int getSize() {
        return size;
    }

    /**
     * <p>
     * Return the encoding of the predefined values.
     * </p>
     * @return the encoding.
     */
    public EncodingConfig getEncoding() {
        return encoding;
    }

    /**
     * <p>
     * Return the configurations of the barcodes to create.
     * </p>
     * @return the configuration of the barcodes to create.
     */
    public List<CodeConfig> getCodes() {
        return Collections.unmodifiableList(codes);
    }

    /**
     * <p>
     * Return the configurations of the additional encoding of the random number to create.
     * </p>
     * @return the configuration of the additional encodings.
     */
    public List<EncodingConfig> getEncodings() {
        return Collections.unmodifiableList(encodings);
    }

    /**
     * <p>
     * Return a {@link org.sw4j.tool.barcode.random.config.RandomConfig.Builder Builder} that can be used to build a
     * config.
     * </p>
     * @return a {@link org.sw4j.tool.barcode.random.config.RandomConfig.Builder Builder}.
     */
    public static Builder builder() {
        return new Builder();
    }


    /**
     * <p>
     * This class is a Builder to build a {@link org.sw4j.tool.barcode.random.config.GenerationConfig RandomConfig}
     * programmatically. All methods to set the values are fluent to ease the building of a configuration.
     * <p>
     * This class is not thread save.
     */
    public static class Builder {

        /**
         * <p>
         * The size (in bits) of the random number to create.
         * </p>
         */
        private int size;

        /**
         * <p>
         * The encoding of the predefined values.
         * </p>
         */
        private EncodingConfig encoding;

        /**
         * <p>
         * The configurations of the generated barcodes.
         * </p>
         */
        private List<CodeConfig> codes;

        /**
         * <p>
         * The configuration of the additional encoded random numbers.
         * </p>
         */
        private List<EncodingConfig> encodings;

        /**
         * <p>
         * Create a new {@code Builder}.
         * </p>
         */
        public Builder() {
        }

        /**
         * <p>
         * Set the size (in bits) of the random number generator.
         * </p>
         * @param size the size of the random number generator.
         * @return the builder for a fluent interface.
         */
        public Builder setSize(final int size) {
            this.size = size;
            return this;
        }

        /**
         * <p>
         * Set the encoding of the predefined values.
         * </p>
         * @param encoding the encoding.
         * @return the builder for a fluent interface.
         */
        public Builder setEncoding(EncodingConfig encoding) {
            this.encoding = encoding;
            return this;
        }

        /**
         * <p>
         * Set the configurations of the barcodes generated.
         * </p>
         * @param codes the configuration of the barcodes.
         * @return the builder for a fluent interface.
         */
        public Builder setCodes(final List<CodeConfig> codes) {
            this.codes = codes;
            return this;
        }

        /**
         * <p>
         * Set the configurations of the additional encodings generated.
         * </p>
         * @param encodings  the configuration of the encodings.
         * @return the builder for a fluent interface.
         */
        public Builder setEncodings(final List<EncodingConfig> encodings) {
            this.encodings = encodings;
            return this;
        }

        /**
         * <p>
         * Build a new {@link org.sw4j.tool.barcode.random.config.GenerationConfig RandomConfig} with the parameters set.
         * </p>
         * @return the new created {@link org.sw4j.tool.barcode.random.config.GenerationConfig RandomConfig}.
         * @throws IllegalArgumentException if {@code size} is either negative or not a multiple of 8, or {@code code}
         *   and {@code encodings} is both {@code null}.
         */
        public GenerationConfig build() {
            return new GenerationConfig(size, encoding, codes, encodings);
        }

    }

}