CodeConfig.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.JsonProperty;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* <p>
* This class configures a concrete code to generate. A code is determined by the encoding (e.g. hex), the file type
* (e.g. png), the url (or text) with {@code {code}} as placeholder for the random code, and the barcode parameters
* (type, width, height and error correction).
* </p>
* <p>
* To create a new instance programmatically use the
* {@link org.sw4j.tool.barcode.random.config.CodeConfig.Builder Builder} which can be obtained with the method
* {@link #builder()}.
* </p>
* <p>
* Supported barcode types:
* <ul>
* <li>qrcode</li>
* </ul>
* </p>
* <p>
* Supported file types: All types supported by Image IO.
* </p>
* <p>
* This class is immutable.
* </p>
* @author Uwe Plonus <u.plonus@gmail.com>
*/
public class CodeConfig {
/**
* <p>
* The default width of a barcode.
* </p>
*/
private static final int DEFAULT_WIDTH = 200;
/**
* <p>
* The default height of a barcode.
* </p>
*/
private static final int DEFAULT_HEIGHT = 200;
/**
* <p>
* The barcode type to create (e.g. qrcode).
* </p>
*/
private final CodeType type;
/**
* <p>
* The width of the barcode. Defaults to 200.
* </p>
*/
private final int width;
/**
* <p>
* The height of the barcode. Defaults to 200.
* </p>
*/
private final int height;
/**
* <p>
* The error correction parameter of the barcode (if applicable) (e.g. M for QRCode).
* </p>
*/
private final String errorCorrection;
/**
* <p>
* The file type of the barcode to generate. Defaults to png.
* </p>
*/
private final String filetype;
/**
* <p>
* The encoding of the random number (e.g. hex).
* </p>
*/
private final EncodingConfig encoding;
/**
* <p>
* The URL (or text) that should be encoded in the barcode. The random number is placed at the {@code {code}}
* placeholder.
* </p>
*/
private final String url;
/**
* <p>
* Create a new {@code CodeConfig} object with the given parameters.
* </p>
* <p>
* If the size cannot be parsed then the default size will be used.
* </p>
* <p>
* This constructor is annotated so that a YAML or JSON parsed with jackson fasterxml can create an instance
* directly.
* </p>
* @param type the type of the barcode to create (e.g. qrcode). May not be null.
* @param size the size of the barcode, given in the format "(width)x(height)", e.g. 120x150 for with 120 and height
* 150. If only a single number is given a square with the given number as width and height is configured.
* @param errorCorrection the error correction of the barcode (if applicable), e.g. "M" for QRCode.
* @param filetype the file type for the final barcode image.
* @param encoding the encoding to use for encoding the random number. May not be null.
* @param url the URL (or text) to encode in the barcode.
* @throws IllegalArgumentException if either {@code type} or {@code encoding} is {@code null} or the {@code type}
* is unknown.
*/
public CodeConfig(
@JsonProperty("type") final String type,
@JsonProperty("size") final String size,
@JsonProperty("errorcorrection") final String errorCorrection,
@JsonProperty("filetype") final String filetype,
@JsonProperty("encoding") final EncodingConfig encoding,
@JsonProperty("url") final String url) {
if (type == null) {
throw new IllegalArgumentException(String.format("%s: Missing type", getClass().getSimpleName()));
}
if (encoding == null) {
throw new IllegalArgumentException(String.format("%s: Missing encoding", getClass().getSimpleName()));
}
this.type = CodeType.lookup(type);
if (this.type == null) {
throw new IllegalArgumentException(
String.format("%s: Unknown type '%s'", getClass().getSimpleName(), type));
}
if (size == null || !size.matches("\\d+(x\\d+)?")) {
width = DEFAULT_WIDTH;
height = DEFAULT_HEIGHT;
} else {
Pattern p = Pattern.compile("(\\d+)(x(\\d+))?");
Matcher m = p.matcher(size);
m.matches();
width = Integer.parseInt(m.group(1));
if (m.group(2) == null) {
height = width;
} else {
height = Integer.parseInt(m.group(3));
}
}
this.errorCorrection = errorCorrection;
this.filetype = filetype == null ? "png" : filetype;
this.encoding = encoding;
this.url = url;
}
/**
* <p>
* Return the type of the barcode (e.g. qrcode).
* </p>
* @return the type of the barcode. Is never {@code null}.
*/
public CodeType getType() {
return type;
}
/**
* <p>
* Return the width of the barcode. Defaults to 200.
* </p>
* @return the width of the barcode.
*/
public int getWidth() {
return width;
}
/**
* <p>
* Return the height of the barcode. Defaults to 200.
* </p>
* @return the width of the barcode.
*/
public int getHeight() {
return height;
}
/**
* <p>
* Return the error correction of the barcode. May be {@code null} or empty.
* </p>
* @return the error correction of the barcode.
*/
public String getErrorCorrection() {
return errorCorrection;
}
/**
* <p>
* Return the file type of the barcode. Defaults to png.
* </p>
* @return the file type of the barcode.
*/
public String getFiletype() {
return filetype;
}
/**
* <p>
* Return the encoding of the random number in the barcode. Is never {@code null}.
* </p>
* @return the encoding of the random number.
*/
public EncodingConfig getEncoding() {
return encoding;
}
/**
* <p>
* Return the URL (or text) of the barcode with the placeholder {@code {code}} replaced by the encoded random
* number.
* </p>
* @return the URL of the barcode.
*/
public String getUrl() {
return url;
}
/**
* <p>
* Return a {@link org.sw4j.tool.barcode.random.config.CodeConfig.Builder Builder} that can be used to build a
* config.
* </p>
* @return a {@link org.sw4j.tool.barcode.random.config.CodeConfig.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.CodeConfig CodeConfig}
* programmatically. All methods to set the values are fluent to ease the building of a configuration.
* </p>
* <p>
* This class is not thread save.
* </p>
* @author Uwe Plonus <u.plonus@gmail.com>
*/
public static class Builder {
/**
* <p>
* The type of the barcode.
* </p>
*/
private String type;
/**
* <p>
* The width of the barcode.
* </p>
*/
private int width;
/**
* <p>
* The height of the barcode.
* </p>
*/
private int height;
/**
* <p>
* The error correction of the barcode.
* </p>
*/
private String errorCorrection;
/**
* <p>
* The file type of the barcode.
* </p>
*/
private String filetype;
/**
* <p>
* The encoding for the random number.
* </p>
*/
private EncodingConfig encoding;
/**
* <p>
* The URL (or text) for the barcode.
* </p>
*/
private String url;
/**
* <p>
* Create a new {@code Builder}.
* </p>
*/
public Builder() {
}
/**
* <p>
* Set the type of the barcode.
* </p>
* @param type the type of the barcode.
* @return the builder for a fluent interface.
*/
public Builder setType(final String type) {
this.type = type;
return this;
}
/**
* <p>
* Set the width of the barcode.
* </p>
* @param width the width of the barcode.
* @return the builder for a fluent interface.
*/
public Builder setWidth(final int width) {
this.width = width;
return this;
}
/**
* <p>
* Set the height of the barcode.
* </p>
* @param height the height of the barcode.
* @return the builder for a fluent interface.
*/
public Builder setHeight(final int height) {
this.height = height;
return this;
}
/**
* <p>
* Set the error correction of the barcode.
* </p>
* @param errorCorrection the error correction of the barcode.
* @return the builder for a fluent interface.
*/
public Builder setErrorCorrection(final String errorCorrection) {
this.errorCorrection = errorCorrection;
return this;
}
/**
* <p>
* Set the file type of the barcode.
* </p>
* @param filetype the file type of the barcode.
* @return the builder for a fluent interface.
*/
public Builder setFiletype(final String filetype) {
this.filetype = filetype;
return this;
}
/**
* <p>
* Set the encoding of the random number in the barcode.
* </p>
* @param encoding the encoding of the random number in the barcode.
* @return the builder for a fluent interface.
*/
public Builder setEncoding(final EncodingConfig encoding) {
this.encoding = encoding;
return this;
}
/**
* <p>
* Set the URL (or text) of the barcode.
* </p>
* @param url the URL (or text) of the barcode.
* @return the builder for a fluent interface.
*/
public Builder setUrl(final String url) {
this.url = url;
return this;
}
/**
* <p>
* Build a new {@link org.sw4j.tool.barcode.random.config.CodeConfig CodeConfig} with the parameters set.
* </p>
* @return the new created {@link org.sw4j.tool.barcode.random.config.CodeConfig CodeConfig}.
* @throws IllegalArgumentException if either the type or encoding is {@code null} or the type is unknown.
*/
public CodeConfig build() {
String size = null;
if (width > 0) {
StringBuilder sb = new StringBuilder();
sb.append(String.valueOf(width));
if (height > 0) {
sb.append("x");
sb.append(String.valueOf(height));
}
size = sb.toString();
}
return new CodeConfig(type, size, errorCorrection, filetype, encoding, url);
}
}
}