
fi.evolver.utils.arg.Arg Maven / Gradle / Ivy
package fi.evolver.utils.arg;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fi.evolver.utils.GzipUtils;
public abstract class Arg {
protected static final Logger LOG = LoggerFactory.getLogger(Arg.class);
private final Class type;
private final String name;
private final boolean required;
private final T defaultValue;
protected Arg(Class type, String name, boolean required, T defaultValue) {
this.type = type;
this.name = name;
this.required = required;
this.defaultValue = defaultValue;
}
public String getType() {
return type.getName();
}
public String getName() {
return name;
}
public boolean isRequired() {
return required;
}
protected List> getSubArgs() {
return Collections.emptyList();
}
/**
* Converts the given input stream contents to the Arg's value type.
*
* @param in Input data.
* @return Converted value.
* @throws IOException Thrown in case there are issues with the input stream.
*/
protected abstract T convert(InputStream in) throws IOException;
/**
* Validates the given value.
*
* @param value The value to validate.
*/
protected void validate(T value) { }
public T get(Map args) {
return checkValue(args.get(getName()));
}
public T remove(Map args) {
return checkValue(args.remove(getName()));
}
private T checkValue(Object value) {
if (value == null) {
if (isRequired())
throw new IllegalArgumentException(getName() + ": missing required parameter");
else
return defaultValue;
}
if (!type.isInstance(value))
throw new IllegalArgumentException(getName() + ": value " + value + " is not an instance of " + getType());
T result = type.cast(value);
if (result != null)
validate(result);
return result;
}
/**
* Parses a map of String values into the formats of the corresponding argument.
*
* @param argList List of supported arguments.
* @param values Values by argument name.
* @return Converted argument values by argument name.
*/
public static Map parseStringValues(List> argList, Map values) {
Map data = new LinkedHashMap<>();
for (Arg> arg: argList) {
String value = values.get(arg.getName());
if (value != null) {
Charset charset = StandardCharsets.UTF_8;
if (arg instanceof FileReaderArg)
charset = ((FileReaderArg)arg).getCharset();
data.put(arg.getName(), GzipUtils.zip(value, charset));
}
}
return parseZipValues(argList, data);
}
/**
* Parses a map of gzip compressed values into the formats of the corresponding argument.
*
* @param argList List of supported arguments.
* @param values gzip compressed values by argument name.
* @return Converted argument values by argument name.
*/
public static Map parseZipValues(List> argList, Map values) {
Map results = new LinkedHashMap<>();
for (Arg> arg: argList)
parseArg(arg, values, results);
return results;
}
private static void parseArg(Arg> arg, Map values, Map results) {
byte[] value = values.get(arg.getName());
for (Arg> subArg: arg.getSubArgs())
parseArg(subArg, values, results);
if (value == null) {
arg.checkValue(null);
return;
}
try {
Object converted = arg.convert(new GZIPInputStream(new ByteArrayInputStream(value)));
results.put(arg.getName(), arg.checkValue(converted));
}
catch (IOException e) {
LOG.error("Unexpected I/O issues while parsing arg {}", arg.name, e);
throw new IllegalArgumentException(arg.getName() + ": could not parse value as " + arg.getType());
}
}
protected static String readUtf8Value(InputStream in) throws IOException {
return IOUtils.toString(in, StandardCharsets.UTF_8);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy