Terms of Service | Privacy Policy | Cookie Policy

...
 
Commits (7)
......@@ -6,7 +6,7 @@ output:
name: output.csv
random:
size: 128
code:
codes:
-
type: qrcode
size: 120x120
......
......@@ -105,7 +105,7 @@ public class Main {
String configFileName = "etc/barcode.yaml";
configFile = new File(appHome, configFileName);
}
Config config = Config.readConfig(configFile);
Config config = Config.readYamlConfig(configFile);
CodeGenerator generator = new CodeGenerator(config.getRandom(), new FileCodeData(config));
......
......@@ -118,6 +118,10 @@ public class CodeConfig {
* <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.
......@@ -125,7 +129,8 @@ public class CodeConfig {
* @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 the type or encoding is {@code null} or the type is unknown.
* @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,
......
......@@ -21,40 +21,93 @@ import java.util.HashMap;
import java.util.Map;
/**
*
* <p>
* This enum enumerates all available barcode types that are usable in the application.
* </p>
* @author Uwe Plonus &lt;u.plonus@gmail.com&gt;
*/
public enum CodeType {
/**
* <p>
* Barcode type QR code.
* </p>
*/
QRCODE("qrcode", BarcodeFormat.QR_CODE);
/**
* <p>
* A lookup table to resolve a type name (e.g. qrcode) to the corresponding enum (e.g. QRCODE).
* </p>
*/
private static final Map<String, CodeType> CODE_TYPES = new HashMap<>();
/**
* <p>
* The name of the type. Can be used for lookup by name.
* </p>
*/
private final String type;
/**
* <p>
* A mapping to the ZXing barcode format.
* </p>
*/
private final BarcodeFormat format;
private static final Map<String, CodeType> codeTypes = new HashMap<>();
/**
* <p>
* Static initializer to fill the lookup table {@link #CODE_TYPES}.
* </p>
*/
static {
for (CodeType codeType: CodeType.values()) {
codeTypes.put(codeType.getType(), codeType);
CODE_TYPES.put(codeType.getType(), codeType);
}
}
private CodeType(String type, BarcodeFormat format) {
/**
* <p>
* The constructor for a concrete enum value.
* </p>
* @param type the type of the barcode format (e.g. qrcode).
* @param format the ZXing format of the barcode (e.g. QR_CODE).
*/
CodeType(final String type, final BarcodeFormat format) {
this.type = type;
this.format = format;
}
/**
* <p>
* Return the type of the barcode (e.g. qrcode).
* </p>
* @return the type of the barcode.
*/
public String getType() {
return type;
}
/**
* <p>
* Return the ZXing barcode format of the barcode (e.g. QR_CODE).
* </p>
* @return the ZXing barcode format.
*/
public BarcodeFormat getFormat() {
return format;
}
public static CodeType lookup(String type) {
return codeTypes.get(type);
/**
* <p>
* Return an enum by doing a lookup with the type string (e.g. qrcode).
* </p>
* @param type the type string to look up (e.g. qrcode).
* @return the enum with the given type string.
*/
public static CodeType lookup(final String type) {
return CODE_TYPES.get(type);
}
}
......@@ -19,26 +19,64 @@ package org.sw4j.tool.barcode.random.config;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import java.io.File;
import java.io.IOException;
/**
*
* <p>
* The top level class for configuring the whole application. This class includes the configuration for the input file,
* the output file(s) and the random number generation and presentation.
* </p>
* <p>
* To create a new instance programmatically use the {@link org.sw4j.tool.barcode.random.config.Config.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 Config {
/**
* <p>
* The configuration for the input file.
* </p>
*/
private final FileConfig input;
/**
* <p>
* The configuration for the output file(s).
* </p>
*/
private final OutputConfig output;
/**
* <p>
* The configuration for the random number generation and presentation.
* </p>
*/
private final RandomConfig random;
/**
* <p>
* Create a new {@code Config} with the given part configurations.
* </p>
* <p>
* This constructor is annotated so that a YAML or JSON parsed with jackson fasterxml can create an instance
* directly.
* </p>
* @param input the input file configuration.
* @param output the output file(s) configuration.
* @param random the random generation and presentation configuration.
* @throws IllegalArgumentException if either {@code input}, {@code output} or {@code random} is {@code null}.
*/
@JsonCreator
public Config(
@JsonProperty("input") FileConfig input,
@JsonProperty("output") OutputConfig output,
@JsonProperty("random") RandomConfig random
) {
@JsonProperty("input") final FileConfig input,
@JsonProperty("output") final OutputConfig output,
@JsonProperty("random") final RandomConfig random) {
if (input == null) {
throw new IllegalArgumentException(String.format("%s: Missing input", getClass().getSimpleName()));
}
......@@ -53,54 +91,144 @@ public class Config {
this.random = random;
}
/**
* <p>
* Return the input file configuration.
* </p>
* @return the input file configuration.
*/
public FileConfig getInput() {
return input;
}
/**
* <p>
* Return the output file(s) configuration.
* </p>
* @return the output file(s) configuration.
*/
public OutputConfig getOutput() {
return output;
}
/**
* <p>
* Return the random generation and presentation configuration.
* </p>
* @return the random generation and presentation configuration.
*/
public RandomConfig getRandom() {
return random;
}
public static Config readConfig(java.io.File configFile) throws IOException {
/**
* <p>
* A factory method to create a configuration from a YAML file.
* </p>
* @param configFile the YAML file to read.
* @return the parsed configuration.
* @throws IOException if the reading of the file fails.
*/
public static Config readYamlConfig(final File configFile) throws IOException {
YAMLMapper mapper = new YAMLMapper();
return mapper.readValue(configFile, Config.class);
}
/**
* <p>
* Return a {@link org.sw4j.tool.barcode.random.config.Config.Builder Builder} that can be used to build a config.
* </p>
* @return a {@link org.sw4j.tool.barcode.random.config.Config.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.Config Config} 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 &lt;u.plonus@gmail.com&gt;
*/
public static class Builder {
/**
* <p>
* The input file configuration.
* </p>
*/
private FileConfig input;
/**
* <p>
* The output file(s) configuration.
* </p>
*/
private OutputConfig output;
/**
* <p>
* The random number generation and presentation configuration.
* </p>
*/
private RandomConfig random;
/**
* <p>
* Create a new {@code Builder}.
* </p>
*/
public Builder() {
}
public Builder setInput(FileConfig input) {
/**
* <p>
* Set the input file configuration.
* </p>
* @param input the input file configuration.
* @return the builder for a fluent interface.
*/
public Builder setInput(final FileConfig input) {
this.input = input;
return this;
}
public Builder setOutput(OutputConfig output) {
/**
* <p>
* Set the output file(s) configuration.
* </p>
* @param output the output file(s) configuration.
* @return the builder for a fluent interface.
*/
public Builder setOutput(final OutputConfig output) {
this.output = output;
return this;
}
public Builder setRandom(RandomConfig random) {
/**
* <p>
* Set the random generation and presentation configuration.
* </p>
* @param random the random generation and presentation configuration.
* @return the builder for a fluent interface.
*/
public Builder setRandom(final RandomConfig random) {
this.random = random;
return this;
}
/**
* <p>
* Build a new {@link org.sw4j.tool.barcode.random.config.Config Config} with the parameters set.
* </p>
* @return the new created {@link org.sw4j.tool.barcode.random.config.Config Config}.
* @throws IllegalArgumentException if either {@code input}, {@code output} or {@code random} is {@code null}.
*/
public Config build() {
return new Config(input, output, random);
}
......
......@@ -20,44 +20,116 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
*
* @author uwe
* <p>
* This class configures a file.
* </p>
* <p>
* To create a new instance programmatically use the
* {@link org.sw4j.tool.barcode.random.config.FileConfig.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 FileConfig {
/**
* <p>
* The name of the file.
* </p>
*/
private final String name;
/**
* <p>
* Create a new {@code FileConfig} with the given file name.
* </p>
* <p>
* This constructor is annotated so that a YAML or JSON parsed with jackson fasterxml can create an instance
* directly.
* </p>
* @param name the name of the file configuration.
* @throws IllegalArgumentException if {@code name} is {@code null}.
*/
@JsonCreator
public FileConfig(
@JsonProperty("name") String name
) {
@JsonProperty("name") final String name) {
if (name == null || "".equals(name.trim())) {
throw new IllegalArgumentException(String.format("%s: Missing name", getClass().getSimpleName()));
}
this.name = name;
}
/**
* <p>
* The name of the file configured.
* </p>
* @return the name of the file.
*/
public String getName() {
return name;
}
/**
* <p>
* Return a {@link org.sw4j.tool.barcode.random.config.FileConfig.Builder Builder} that can be used to build a
* config.
* </p>
* @return a {@link org.sw4j.tool.barcode.random.config.FileConfig.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.FileConfig FileConfig}
* 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 &lt;u.plonus@gmail.com&gt;
*/
public static class Builder {
/**
* <p>
* The name of the file.
* </p>
*/
private String name;
/**
* <p>
* Create a new {@code Builder}.
* </p>
*/
public Builder() {
}
public Builder setName(String name) {
/**
* <p>
* Set the name of the file.
* </p>
* @param name the name of the file.
* @return the builder for a fluent interface.
*/
public Builder setName(final String name) {
this.name = name;
return this;
}
/**
* <p>
* Build a new {@link org.sw4j.tool.barcode.random.config.FileConfig FileConfig} with the parameters set.
* </p>
* @return the new created {@link org.sw4j.tool.barcode.random.config.FileConfig FileConfig}.
* @throws IllegalArgumentException if {@code name} is {@code null}.
*/
public FileConfig build() {
return new FileConfig(name);
}
......
......@@ -20,20 +20,51 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
*
* @author uwe
* <p>
* This class configures the output file(s).
* </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 OutputConfig {
/**
* <p>
* The folder for the output files.
* </p>
*/
private final String folder;
/**
* <p>
* The output file for the output csv file.
* </p>
*/
private final FileConfig file;
/**
* <p>
* Create a new {@code OutputConfig} with the given file name.
* </p>
* <p>
* This constructor is annotated so that a YAML or JSON parsed with jackson fasterxml can create an instance
* directly.
* </p>
* @param folder the name of the file configuration.
* @param file the name of the output csv file.
* @throws IllegalArgumentException if either {@code folder} or {@code file} is {@code null}.
*/
@JsonCreator
public OutputConfig(
@JsonProperty("folder") String folder,
@JsonProperty("file") FileConfig file
) {
@JsonProperty("folder") final String folder,
@JsonProperty("file") final FileConfig file) {
if (folder == null) {
throw new IllegalArgumentException(String.format("%s: Missing folder", getClass().getSimpleName()));
}
......@@ -44,38 +75,103 @@ public class OutputConfig {
this.file = file;
}
/**
* <p>
* Return the folder of the output files.
* </p>
* @return the folder of the output files.
*/
public String getFolder() {
return folder;
}
/**
* <p>
* Return the output csv file.
* </p>
* @return the output csv file.
*/
public FileConfig getFile() {
return file;
}
/**
* <p>
* Return a {@link org.sw4j.tool.barcode.random.config.OutputConfig.Builder Builder} that can be used to build a
* config.
* </p>
* @return a {@link org.sw4j.tool.barcode.random.config.OutputConfig.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.OutputConfig OutputConfig}
* 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 &lt;u.plonus@gmail.com&gt;
*/
public static class Builder {
/**
* <p>
* The folder for the output files.
* </p>
*/
private String folder;
/**
* <p>
* The file of the csv output.
* </p>
*/
private FileConfig file;
/**
* <p>
* Create a new {@code Builder}.
* </p>
*/
public Builder() {
}
public Builder setFolder(String folder) {
/**
* <p>
* Set the folder of the output files.
* </p>
* @param folder the folder of the output files.
* @return the builder for a fluent interface.
*/
public Builder setFolder(final String folder) {
this.folder = folder;
return this;
}
public Builder setFile(FileConfig file) {
/**
* <p>
* Set the file of the output csv file.
* </p>
* @param file the file of the output csv file.
* @return the builder for a fluent interface.
*/
public Builder setFile(final FileConfig file) {
this.file = file;
return this;
}
/**
* <p>
* Build a new {@link org.sw4j.tool.barcode.random.config.OutputConfig OutputConfig} with the parameters set.
* </p>
* @return the new created {@link org.sw4j.tool.barcode.random.config.OutputConfig OutputConfig}.
* @throws IllegalArgumentException if either {@code folder} or {@code file} is {@code null}.
*/
public OutputConfig build() {
return new OutputConfig(folder, file);
}
......
......@@ -18,26 +18,66 @@ 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;
/**
*
* @author uwe
* <p>
* This class configures the random 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 RandomConfig {
/**
* <p>
* The size (in bits) of the random number to create.
* </p>
*/
private final int size;
private final List<CodeConfig> code;
/**
* <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<String> encodings;
/**
* <p>
* Create a new {@code RandomConfig} with the given random size (in bits), barcode formats and additional random
* representations.
* </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 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 RandomConfig(
@JsonProperty("size") int size,
@JsonProperty("code") List<CodeConfig> code,
@JsonProperty("encodings") List<String> encodings
) {
@JsonProperty("size") final int size,
@JsonProperty("codes") final List<CodeConfig> codes,
@JsonProperty("encodings") final List<String> encodings) {
if (size < 0) {
throw new IllegalArgumentException(String.format("%s: size is negative",
getClass().getSimpleName()));
......@@ -46,60 +86,144 @@ public class RandomConfig {
throw new IllegalArgumentException(String.format("%s: size is not a multiple of 8",
getClass().getSimpleName()));
}
if ((code == null || code.isEmpty()) && (encodings == null || encodings.isEmpty())) {
throw new IllegalArgumentException(String.format("%s: either qrcodes or encodings is needed",
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.code = code;
this.codes = codes;
this.encodings = encodings;
}
/**
* <p>
* Return the size of the random number to be created.
* </p>
* @return the size of the random number.
*/
public int getSize() {
return size;
}
public List<CodeConfig> getCode() {
return code;
/**
* <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<String> getEncodings() {
return encodings;
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.RandomConfig RandomConfig}
* 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 &lt;u.plonus@gmail.com&gt;
*/
public static class Builder {
/**
* <p>
* The size (in bits) of the random number to create.
* </p>
*/
private int size;
private List<CodeConfig> qrcodes;
/**
* <p>
* The configurations of the generated barcodes.
* </p>
*/
private List<CodeConfig> codes;
/**
* <p>
* The configuration of the additional encoded random numbers.
* </p>
*/
private List<String> encodings;
/**
* <p>
* Create a new {@code Builder}.
* </p>
*/
public Builder() {
}
public Builder setSize(int size) {
/**
* <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;
}
public Builder setQrcodes(List<CodeConfig> qrcodes) {
this.qrcodes = qrcodes;
/**
* <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;
}
public Builder setEncodings(List<String> encodings) {
/**
* <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<String> encodings) {
this.encodings = encodings;
return this;
}
/**
* <p>
* Build a new {@link org.sw4j.tool.barcode.random.config.RandomConfig RandomConfig} with the parameters set.
* </p>
* @return the new created {@link org.sw4j.tool.barcode.random.config.RandomConfig 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 RandomConfig build() {
return new RandomConfig(size, qrcodes, encodings);
return new RandomConfig(size, codes, encodings);
}
}
......
......@@ -20,16 +20,40 @@ import java.util.Iterator;
import java.util.ServiceLoader;
/**
*
* <p>
* This class is an interface for new Encoders (e.g. {@link org.sw4j.tool.barcode.random.encoder.impl.Base58Encoder})
* and a factory for such encoders.
* </p>
* @author Uwe Plonus &lt;u.plonus@gmail.com&gt;
*/
public abstract class ByteArrayEncoder {
/**
* <p>
* For concrete encoders this method should return {@code true} if the given encoding is supported.
* </p>
* @param encoding the encoding to check for.
* @return {@code true} if the encoding is supported by the encoder.
*/
public abstract boolean supports(String encoding);
/**
* <p>
* Encode the given byte array data into the encoding that is supported by the encoder.
* </p>
* @param data the data to encode.
* @return the encoded data.
*/
public abstract String encode(byte[] data);
public static ByteArrayEncoder forEncoding(String encoding) {
/**
* <p>
* Return an encoder for the given encoding (e.g. {@code base58}).
* </p>
* @param encoding the encoding for which an encoder should be created.
* @return the encoder for the encoding or {@code null} if no encoder is available.
*/
public static ByteArrayEncoder forEncoding(final String encoding) {
ServiceLoader<ByteArrayEncoder> loader = ServiceLoader.load(ByteArrayEncoder.class);
Iterator<ByteArrayEncoder> iterator = loader.iterator();
ByteArrayEncoder encoder = null;
......
......@@ -21,20 +21,49 @@ import org.sw4j.tool.barcode.random.coder.Base58;
import org.sw4j.tool.barcode.random.encoder.ByteArrayEncoder;
/**
*
* <p>
* This class encodes a byte array as base58 string.
* </p>
* @author Uwe Plonus &lt;u.plonus@gmail.com&gt;
*/
public class Base58Encoder extends ByteArrayEncoder {
/**
* <p>
* The encoding name as constant.
* </p>
*/
public static final String TYPE = "base58";
/**
* <p>
* The default constructor.
* </p>
*/
public Base58Encoder() {
}
/**
* <p>
* Return {@code true} if the {@code encoding} is base58 (case insensitive).
* </p>
* @param encoding the encoding name to check.
* @return {@code true} if the name is base58.
*/
@Override
public boolean supports(String encoding) {
return TYPE.equals(encoding.toLowerCase(Locale.ROOT));
public boolean supports(final String encoding) {
return encoding != null && TYPE.equals(encoding.toLowerCase(Locale.ROOT));
}
/**
* <p>
* Return the byte array encoded as base58.
* </p>
* @param data the byte array to encode.
* @return the encoded data.
*/
@Override
public String encode(byte[] data) {
public String encode(final byte[] data) {
return Base58.encode(data);
}
......
......@@ -21,20 +21,49 @@ import javax.xml.bind.DatatypeConverter;
import org.sw4j.tool.barcode.random.encoder.ByteArrayEncoder;
/**
*
* <p>
* This class encodes a byte array as hex string.
* </p>
* @author Uwe Plonus &lt;u.plonus@gmail.com&gt;
*/
public class HexEncoder extends ByteArrayEncoder {
/**
* <p>
* The encoding name as constant.
* </p>
*/
public static final String TYPE = "hex";
/**
* <p>
* The default constructor.
* </p>
*/
public HexEncoder() {
}
/**
* <p>
* Return {@code true} if the {@code encoding} is hex (case insensitive).
* </p>
* @param encoding the encoding name to check.
* @return {@code true} if the name is hex.
*/
@Override
public boolean supports(String encoding) {
return TYPE.equals(encoding.toLowerCase(Locale.ROOT));
public boolean supports(final String encoding) {
return encoding != null && TYPE.equals(encoding.toLowerCase(Locale.ROOT));
}
/**
* <p>
* Return the byte array encoded as hex.
* </p>
* @param data the byte array to encode.
* @return the encoded data.
*/
@Override
public String encode(byte[] data) {
public String encode(final byte[] data) {
return DatatypeConverter.printHexBinary(data).toLowerCase(Locale.ROOT);
}
......
/*
* 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/>.
*/
/**
* <p>
* This package defines some implementations for the {@link org.sw4j.tool.barcode.random.encoder.ByteArrayEncoder}.
* </p>
* @see org.sw4j.tool.barcode.random.encoder
* @see org.sw4j.tool.barcode.random.encoder.ByteArrayEncoder
*/
package org.sw4j.tool.barcode.random.encoder.impl;
/*
* 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/>.
*/
/**
* <p>
* This package is the base for a pluggable encoder architecture.
* </p>
* <p>
* This architecture uses the Java {@link java.util.ServiceLoader} to load additional encoders.
* </p>
* <p>
* To add a new encoder extend the abstract class {@link org.sw4j.tool.barcode.random.encoder.ByteArrayEncoder} and add
* a file named {@code org.sw4j.tool.barcode.random.encoder.ByteArrayEncoder} in your {@code META-INF/services} folder
* with your fully qualified classname as content.
* </p>
* <p>
* In your class you have to override the methods
* {@link org.sw4j.tool.barcode.random.encoder.ByteArrayEncoder#supports(String) ByteArrayEncoder#supports(String)} and
* {@link org.sw4j.tool.barcode.random.encoder.ByteArrayEncoder#encode(byte[]) ByteArrayEncoder#encode(byte[])} to add
* a new encoder which then can be referenced by the config.
* </p>
*/
package org.sw4j.tool.barcode.random.encoder;
......@@ -85,7 +85,7 @@ public class CodeGenerator {
*/
public void createCodes() throws IOException {
Set<String> encodings = new HashSet<>();
config.getCode().forEach((codeConfig) -> {
config.getCodes().forEach((codeConfig) -> {
encodings.add(codeConfig.getEncoding());
});
config.getEncodings().forEach((encoding) -> {
......@@ -106,7 +106,7 @@ public class CodeGenerator {
Set<RandomIdent> randomValues = createCodes(inputValues, encodings);
randomValues.parallelStream()
.forEach(randomIdent -> {
config.getCode().forEach(code -> {
config.getCodes().forEach(code -> {
CodeType codeType = code.getType();
String codeEncoding = code.getEncoding();
String codeUrl = code.getUrl();
......
......@@ -6,7 +6,7 @@ output:
name: output
random:
size: 128
code:
codes:
-
type: qrcode
encoding: hex
......
......@@ -185,13 +185,13 @@ public class ConfigNGTest {
@Test
public void testReadingConfig() throws IOException {
Config config = Config.readConfig(new File("src/test", "etc/test.yaml"));
Config config = Config.readYamlConfig(new File("src/test", "etc/test.yaml"));
assertNotNull(config, "Expected the config to be read.");
assertEquals(config.getInput().getName(), "input");
assertEquals(config.getOutput().getFolder(), "folder");
assertEquals(config.getOutput().getFile().getName(), "output");
assertEquals(config.getRandom().getSize(), 128);
assertEquals(config.getRandom().getCode().size(), 1);
assertEquals(config.getRandom().getCodes().size(), 1);
assertEquals(config.getRandom().getEncodings().size(), 1);
}
......
......@@ -61,7 +61,7 @@ public class RandomConfigNGTest {
@Test
public void testSetQrcodesIsFuild() {
RandomConfig.Builder builder = RandomConfig.builder();
RandomConfig.Builder b = builder.setQrcodes(Collections.EMPTY_LIST);
RandomConfig.Builder b = builder.setCodes(Collections.EMPTY_LIST);
assertNotNull(b, "Expected a builder to be returned by setQrcodes.");
}
......@@ -76,7 +76,7 @@ public class RandomConfigNGTest {
public void testBuildingWithNegativeSizeFails() {
RandomConfig.Builder builder = RandomConfig.builder();
RandomConfig.Builder b = builder.setSize(-8);
b = b.setQrcodes(Collections.singletonList(CodeConfig.builder()
b = b.setCodes(Collections.singletonList(CodeConfig.builder()
.setType("qrcode")
.setEncoding("hex")
.setUrl("https://example.org/{code}")
......@@ -90,7 +90,7 @@ public class RandomConfigNGTest {
public void testBuildingWithSizeNotDivisibleBy8Fails() {
RandomConfig.Builder builder = RandomConfig.builder();
RandomConfig.Builder b = builder.setSize(7);
b = b.setQrcodes(Collections.singletonList(CodeConfig.builder()
b = b.setCodes(Collections.singletonList(CodeConfig.builder()
.setType("qrcode")
.setEncoding("hex")
.setUrl("https://example.org/{code}")
......@@ -104,7 +104,7 @@ public class RandomConfigNGTest {
public void testBuildingWithQrcodesNullEncodingsNullFails() {
RandomConfig.Builder builder = RandomConfig.builder();
RandomConfig.Builder b = builder.setSize(8);
b = b.setQrcodes(null);
b = b.setCodes(null);
b = b.setEncodings(null);
b.build();
fail("Expected an exception to be thrown when qrcodes is null and encodings is null.");
......@@ -114,7 +114,7 @@ public class RandomConfigNGTest {
public void testBuildingWithQrcodesEmptyEncodingsNullFails() {
RandomConfig.Builder builder = RandomConfig.builder();
RandomConfig.Builder b = builder.setSize(8);
b = b.setQrcodes(Collections.EMPTY_LIST);
b = b.setCodes(Collections.EMPTY_LIST);
b = b.setEncodings(null);
b.build();
fail("Expected an exception to be thrown when qrcodes is empty and encodings is null.");
......@@ -124,7 +124,7 @@ public class RandomConfigNGTest {
public void testBuildingWithQrcodesNullEncodingsEmptyFails() {
RandomConfig.Builder builder = RandomConfig.builder();
RandomConfig.Builder b = builder.setSize(8);
b = b.setQrcodes(null);
b = b.setCodes(null);
b = b.setEncodings(Collections.EMPTY_LIST);
b.build();
fail("Expected an exception to be thrown when qrcodes is null and encodings is empty.");
......@@ -134,7 +134,7 @@ public class RandomConfigNGTest {
public void testBuildingWithQrcodesEmptyEncodingsEmptyFails() {
RandomConfig.Builder builder = RandomConfig.builder();
RandomConfig.Builder b = builder.setSize(8);
b = b.setQrcodes(Collections.EMPTY_LIST);
b = b.setCodes(Collections.EMPTY_LIST);
b = b.setEncodings(Collections.EMPTY_LIST);
b.build();
fail("Expected an exception to be thrown when qrcodes is empty and encodings is empty.");
......@@ -144,7 +144,7 @@ public class RandomConfigNGTest {
public void testBuildingWithQrcodesSucceeds() {
RandomConfig.Builder builder = RandomConfig.builder();
RandomConfig.Builder b = builder.setSize(8);
b = b.setQrcodes(Collections.singletonList(CodeConfig.builder()
b = b.setCodes(Collections.singletonList(CodeConfig.builder()
.setType("qrcode")
.setEncoding("hex")
.setUrl("https://example.org/{code}")
......@@ -158,7 +158,7 @@ public class RandomConfigNGTest {
public void testBuildingWithEncodingsSucceeds() {
RandomConfig.Builder builder = RandomConfig.builder();
RandomConfig.Builder b = builder.setSize(8);
b = b.setQrcodes(Collections.EMPTY_LIST);
b = b.setCodes(Collections.EMPTY_LIST);
b = b.setEncodings(Collections.singletonList("hex"));
RandomConfig config = b.build();
assertNotNull(config, "Expected a config to be built.");
......@@ -168,7 +168,7 @@ public class RandomConfigNGTest {
public void testBuildingWithQrcodesEncodingsSucceeds() {
RandomConfig.Builder builder = RandomConfig.builder();
RandomConfig.Builder b = builder.setSize(8);
b = b.setQrcodes(Collections.singletonList(CodeConfig.builder()
b = b.setCodes(Collections.singletonList(CodeConfig.builder()
.setType("qrcode")
.setEncoding("hex")
.setUrl("https://example.org/{code}")
......@@ -182,7 +182,7 @@ public class RandomConfigNGTest {
public void testBuildingSetsSize() {
RandomConfig.Builder builder = RandomConfig.builder();
RandomConfig.Builder b = builder.setSize(8);
b = b.setQrcodes(Collections.singletonList(CodeConfig.builder()
b = b.setCodes(Collections.singletonList(CodeConfig.builder()
.setType("qrcode")
.setEncoding("hex")
.setUrl("https://example.org/{code}")
......@@ -196,21 +196,21 @@ public class RandomConfigNGTest {
public void testBuildingSetsQrcodes() {
RandomConfig.Builder builder = RandomConfig.builder();
RandomConfig.Builder b = builder.setSize(8);
b = b.setQrcodes(Collections.singletonList(CodeConfig.builder()
b = b.setCodes(Collections.singletonList(CodeConfig.builder()
.setType("qrcode")
.setEncoding("hex")
.setUrl("https://example.org/{code}")
.build()));
b = b.setEncodings(Collections.singletonList("base58"));
RandomConfig config = b.build();
assertFalse(config.getCode().isEmpty(), "Expected the qrcodes not to be empty.");
assertFalse(config.getCodes().isEmpty(), "Expected the qrcodes not to be empty.");
}
@Test
public void testBuildingSetsEncodings() {
RandomConfig.Builder builder = RandomConfig.builder();
RandomConfig.Builder b = builder.setSize(8);
b = b.setQrcodes(Collections.singletonList(CodeConfig.builder()
b = b.setCodes(Collections.singletonList(CodeConfig.builder()
.setType("qrcode")
.setEncoding("hex")
.setUrl("https://example.org/{code}")
......
......@@ -45,6 +45,12 @@ public class ByteArrayEncoderNGTest {
public void tearDownMethod() throws Exception {
}
@Test
public void testLoadNullEncoder() {
ByteArrayEncoder encoder = ByteArrayEncoder.forEncoding(null);
assertNull(encoder, "Expected to find no encoder for encoding null.");
}
@Test
public void testLoadHexEncoder() {
ByteArrayEncoder encoder = ByteArrayEncoder.forEncoding("hex");
......