All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fi.evolver.utils.arg.Arg Maven / Gradle / Ivy

There is a newer version: 3.5.0
Show newest version
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