Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 107 additions & 72 deletions src/main/java/chapter14/args/Args.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ public class Args {
private String[] args;
private boolean valid = true;
private Set<Character> unexpectedArguments = new TreeSet<>();
private Map<Character, Boolean> booleanArgs = new HashMap<>();
private Map<Character, String> stringArgs = new HashMap<>();
private Map<Character, Integer> intArgs = new HashMap<>();
private Map<Character, ArgumentMarshaler> marshalers = new HashMap<>();
private Set<Character> argsFound = new HashSet<>();
private int currentArgument;
private char errorArgumentId = '\0';
Expand Down Expand Up @@ -52,13 +50,13 @@ private void parseSchemaElement(String element) throws ParseException {
char elementId = element.charAt(0);
String elementTail = element.substring(1);
validateSchemaElementId(elementId);
if (isBooleanSchemaElement(elementTail))
parseBooleanSchemaElement(elementId);
else if (isStringSchemaElement(elementTail))
parseStringSchemaElement(elementId);
else if (isIntegerSchemaElement(elementTail))
parseIntegerSchemaElement(elementId);
else {
if (isBooleanSchemaElement(elementTail)) {
marshalers.put(elementId, new BooleanArgumentMarshaler());
} else if (isStringSchemaElement(elementTail)) {
marshalers.put(elementId, new StringArgumentMarshaler());
} else if (isIntegerSchemaElement(elementTail)) {
marshalers.put(elementId, new IntegerArgumentMarshaler());
} else {
throw new ParseException(
String.format("Argument: %c has invalid format: %s.",
elementId, elementTail), 0);
Expand All @@ -72,18 +70,6 @@ private void validateSchemaElementId(char elementId) throws ParseException {
}
}

private void parseBooleanSchemaElement(char elementId) {
booleanArgs.put(elementId, false);
}

private void parseIntegerSchemaElement(char elementId) {
intArgs.put(elementId, 0);
}

private void parseStringSchemaElement(char elementId) {
stringArgs.put(elementId, "");
}

private boolean isStringSchemaElement(String elementTail) {
return elementTail.equals("*");
}
Expand Down Expand Up @@ -126,63 +112,55 @@ private void parseElement(char argChar) throws ArgsException {
}

private boolean setArgument(char argChar) throws ArgsException {
if (isBooleanArg(argChar))
setBooleanArg(argChar, true);
else if (isStringArg(argChar))
setStringArg(argChar);
else if (isIntArg(argChar))
setIntArg(argChar);
else
return false;

ArgumentMarshaler m = marshalers.get(argChar);
try {
if (m instanceof BooleanArgumentMarshaler)
setBooleanArg(m);
else if (m instanceof StringArgumentMarshaler)
setStringArg(m);
else if (m instanceof IntegerArgumentMarshaler)
setIntArg(m);
else
return false;
} catch (ArgsException e) {
valid = false;
errorArgumentId = argChar;
throw e;
}
return true;
}

private boolean isIntArg(char argChar) {
return intArgs.containsKey(argChar);
}

private void setIntArg(char argChar) throws ArgsException {
private void setIntArg(ArgumentMarshaler m) throws ArgsException {
currentArgument++;
String parameter = null;
try {
parameter = args[currentArgument];
intArgs.put(argChar, new Integer(parameter));
m.set(parameter);
} catch (ArrayIndexOutOfBoundsException e) {
valid = false;
errorArgumentId = argChar;
errorCode = ErrorCode.MISSING_INTEGER;
throw new ArgsException();
} catch (NumberFormatException e) {
valid = false;
errorArgumentId = argChar;
} catch (ArgsException e) {
errorParameter = parameter;
errorCode = ErrorCode.INVALID_INTEGER;
throw new ArgsException();
throw e;
}
}

private void setStringArg(char argChar) {
private void setStringArg(ArgumentMarshaler m) throws ArgsException {
currentArgument++;
try {
stringArgs.put(argChar, args[currentArgument]);
m.set(args[currentArgument]);
} catch (ArrayIndexOutOfBoundsException e) {
valid = false;
errorArgumentId = argChar;
errorCode = ErrorCode.MISSING_STRING;
throw new ArgsException();
}
}

private boolean isStringArg(char argChar) {
return stringArgs.containsKey(argChar);
}

private void setBooleanArg(char argChar, boolean value) {
booleanArgs.put(argChar, value);
}

private boolean isBooleanArg(char argChar) {
return booleanArgs.containsKey(argChar);
private void setBooleanArg(ArgumentMarshaler m) {
try {
m.set("true");
} catch (ArgsException e) {
}
}

public int cardinality() {
Expand Down Expand Up @@ -226,28 +204,33 @@ private String unexpectedArgumentMessage() {
return message.toString();
}

private boolean falseIfNull(Boolean b) {
return b == null ? false : b;
}

private int zeroIfNull(Integer i) {
return i == null ? 0 : i;
}

private String blankIfNull(String s) {
return s == null ? "" : s;
}

public String getString(char arg) {
return blankIfNull(stringArgs.get(arg));
ArgumentMarshaler am = marshalers.get(arg);
try {
return am == null ? "" : (String) am.get();
} catch (ClassCastException e) {
return "";
}
}

public int getInt(char arg) {
return zeroIfNull(intArgs.get(arg));
ArgumentMarshaler am = marshalers.get(arg);
try {
return am == null ? 0 : (Integer) am.get();
} catch (ClassCastException e) {
return 0;
}
}

public boolean getBoolean(char arg) {
return falseIfNull(booleanArgs.get(arg));
ArgumentMarshaler am = marshalers.get(arg);
boolean b = false;
try {
b = am != null && (Boolean) am.get();
} catch (ClassCastException e) {
b = false;
}
return b;
}

public boolean has(char arg) {
Expand All @@ -260,4 +243,56 @@ public boolean isValid() {

private class ArgsException extends Exception {
}

private abstract class ArgumentMarshaler {
public abstract void set(String s) throws ArgsException;

public abstract Object get();
}

private class BooleanArgumentMarshaler extends ArgumentMarshaler {
private boolean booleanValue = false;

@Override
public void set(String s) {
booleanValue = true;
}

@Override
public Object get() {
return booleanValue;
}
}

private class StringArgumentMarshaler extends ArgumentMarshaler {
private String stringValue = "";

@Override
public void set(String s) {
stringValue = s;
}

@Override
public Object get() {
return stringValue;
}
}

private class IntegerArgumentMarshaler extends ArgumentMarshaler {
private int intValue = 0;

@Override
public void set(String s) throws ArgsException {
try {
intValue = Integer.parseInt(s);
} catch (NumberFormatException e) {
throw new ArgsException();
}
}

@Override
public Object get() {
return intValue;
}
}
}