All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.methylene.args.ArgParser Maven / Gradle / Ivy
package com.github.methylene.args;
import com.github.methylene.args.predicate.IntegerPredicates;
import com.github.methylene.args.predicate.ListPredicates;
import com.github.methylene.args.predicate.Predicates;
import java.util.*;
public class ArgParser {
public enum RejectionCondition {
UNDECLARED_FLAG, UNDECLARED_PARAMETER
}
public enum ArityRule {
ZERO_OR_MORE(ListPredicates.hasCardinality(IntegerPredicates.geq(0))),
ZERO_OR_ONE(Predicates.or(
ListPredicates.hasCardinality(IntegerPredicates.exactly(0)),
ListPredicates.hasCardinality(IntegerPredicates.exactly(1)))),
ONE_OR_MORE(ListPredicates.hasCardinality(IntegerPredicates.geq(1))),
EXACTLY_ONE(ListPredicates.hasCardinality(IntegerPredicates.exactly(1)));
private final Predicate> predicate;
ArityRule(Predicate> predicate) {this.predicate = predicate;}
public Predicate> getPredicate() {
return predicate;
}
}
private final Set rejectionConditions;
private static final class Expectation {
private final TokenValue.ValType type;
private final String field;
private final Predicate> predicate;
private final String message;
private Expectation(TokenValue.ValType type, String field, String message, Predicate> predicate) {
this.type = type;
this.field = field;
this.predicate = predicate;
this.message = message;
}
private static Expectation parameter(String field, ArityRule mult) {
return new Expectation(TokenValue.ValType.PARAMETER, field, "expected parameter with arity " + mult,
Predicates.and(TokenValue.ValType.PARAMETER.getPredicate(), mult.getPredicate()));
}
private static Expectation flag(String field, ArityRule mult) {
return new Expectation(TokenValue.ValType.FLAG, field, "expected flag with arity " + mult,
Predicates.and(TokenValue.ValType.FLAG.getPredicate(), mult.getPredicate()));
}
private boolean isFlag() {
return type == TokenValue.ValType.FLAG;
}
private String getField() {
return field;
}
}
public static class ParserBuilder {
private final Mapper mapper;
private final List expectations = new ArrayList();
private final Set rejectionConditions = new HashSet(RejectionCondition.values().length);
private ParserBuilder(Mapper mapper) {
this.mapper = mapper;
}
private ParserBuilder parameter(String field, ArityRule mult) {
expectations.add(Expectation.parameter(field, mult));
return this;
}
public ParserBuilder required(String field) {
return parameter(field, ArityRule.EXACTLY_ONE);
}
public ParserBuilder optional(String field) {
return parameter(field, ArityRule.ZERO_OR_ONE);
}
public ParserBuilder list(String field) {
return parameter(field, ArityRule.ZERO_OR_MORE);
}
public ParserBuilder flag(String field, ArityRule mult) {
expectations.add(Expectation.flag(field, mult));
return this;
}
public ParserBuilder flag(String field) {
return flag(field, ArityRule.ZERO_OR_ONE);
}
public ParserBuilder rejectUndeclared() {
rejectionConditions.addAll(Arrays.asList(RejectionCondition.UNDECLARED_FLAG, RejectionCondition.UNDECLARED_PARAMETER));
return this;
}
public ArgParser build() {
return new ArgParser(modifiedMapper(expectations, mapper), expectations,
rejectionConditions.isEmpty() ? Collections.emptySet() : EnumSet.copyOf(rejectionConditions));
}
}
public static ParserBuilder builder() {
return new ParserBuilder(Mapper.builder().build());
}
public static ParserBuilder builder(Mapper mapper) {
return new ParserBuilder(mapper);
}
private final Mapper mapper;
private final List expectations;
private ArgParser(Mapper mapper, List expectations, Set rejectionConditions) {
this.mapper = mapper;
this.rejectionConditions = rejectionConditions;
this.expectations = expectations;
}
static Mapper modifiedMapper(List expectations, Mapper mapper) {
if (expectations.isEmpty())
return mapper;
Set atoms = new HashSet(expectations.size());
Set strongBindings = new HashSet(expectations.size());
for (Expectation expectation : expectations) {
if (expectation.isFlag())
atoms.add(expectation.getField());
else
strongBindings.add(expectation.getField());
}
return Mapper.builder()
.setExpanders(mapper.getExpanders())
.setAtomic(Predicates.or(mapper.getTokenizer().getAtomic(), Predicates.in(atoms)))
.setStrongBinding(Predicates.or(mapper.getTokenizer().getStrongBinding(), Predicates.in(strongBindings)))
.setWeakBinding(mapper.getTokenizer().getWeakBinding())
.build();
}
private static boolean isMixed(List tokens) {
if (tokens.isEmpty())
return false;
TokenValue.ValType type = tokens.get(0).getToken().getValue().getType();
for (Token val : tokens)
if (val.getType() != type)
return true;
return false;
}
public ParseResult parse(String... args) {
Map> map = mapper.build(args);
List messages = new ArrayList();
for (Expectation expectation : expectations) {
if (!expectation.predicate.matches(map.get(expectation.field))) {
messages.add(String.format("%s: %s", expectation.field, expectation.message));
}
}
if (!messages.isEmpty())
return ParseResult.failure(messages);
for (String key : map.keySet()) {
if (isMixed(map.get(key))) {
messages.add("mixing flags and parameters: " + key);
}
}
if (!messages.isEmpty())
return ParseResult.failure(messages);
ParsedArgs parsedArgs = new ParsedArgs(mapper.build(args));
Map declared = new HashMap(expectations.size());
for (Expectation expectation : expectations) {
declared.put(expectation.getField(), expectation.type);
}
if (rejectionConditions.contains(RejectionCondition.UNDECLARED_FLAG)) {
for (String key : parsedArgs.getKeys()) {
if (parsedArgs.get(key).isFlag()) {
if (declared.get(key) == null || declared.get(key) != TokenValue.ValType.FLAG) {
messages.add("undeclared flag: " + key);
}
}
}
}
if (rejectionConditions.contains(RejectionCondition.UNDECLARED_PARAMETER)) {
for (String key : parsedArgs.getKeys()) {
if (parsedArgs.get(key).isParameter()) {
if (declared.get(key) == null || declared.get(key) != TokenValue.ValType.PARAMETER) {
messages.add("undeclared parameter: " + key + " = " + parsedArgs.get(key).getValues());
}
}
}
}
if (!messages.isEmpty())
return ParseResult.failure(messages);
return ParseResult.success(parsedArgs);
}
}