Skip to content
Merged
Show file tree
Hide file tree
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
7 changes: 3 additions & 4 deletions src/main/java/chapter14/Application.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package chapter14;

import chapter14.args.Args;

import java.text.ParseException;
import chapter14.args.ArgsException;

class Application {

Expand All @@ -13,8 +12,8 @@ public static void main(String[] args) {
int port = arg.getInt('p');
String directory = arg.getString('d');
executeApplication(logging, port, directory);
} catch (ParseException e) {
System.out.printf("Parse error: %s\n", e.getMessage());
} catch (ArgsException e) {
System.out.printf("Argument error: %s\n", e.getMessage());
}
}

Expand Down
202 changes: 24 additions & 178 deletions src/main/java/chapter14/args/Args.java
Original file line number Diff line number Diff line change
@@ -1,53 +1,35 @@
package chapter14.args;

import java.text.ParseException;
import java.util.*;

public class Args {
private String schema;
private boolean valid = true;
private Set<Character> unexpectedArguments = new TreeSet<>();
private Map<Character, ArgumentMarshaler> marshalers = new HashMap<>();
private Set<Character> argsFound = new HashSet<>();
private Iterator<String> currentArgument;
private char errorArgumentId = '\0';
private String errorParameter = "TILT";
private ErrorCode errorCode = ErrorCode.OK;
private List<String> argsList;

enum ErrorCode {
OK, MISSING_STRING, MISSING_INTEGER, INVALID_INTEGER,
UNEXPECTED_ARGUMENT, MISSING_DOUBLE, INVALID_DOUBLE
}

public Args(String schema, String[] args) throws ParseException {
public Args(String schema, String[] args) throws ArgsException {
this.schema = schema;
argsList = Arrays.asList(args);
valid = parse();
parse();
}

private boolean parse() throws ParseException {
if (schema.length() == 0 && argsList.size() == 0)
return true;
private void parse() throws ArgsException {
parseSchema();
try {
parseArguments();
} catch (ArgsException e) {
}
return valid;
parseArguments();
}

private boolean parseSchema() throws ParseException {
private boolean parseSchema() throws ArgsException {
for (String element : schema.split(",")) {
if (element.length() > 0) {
String trimmedElement = element.trim();
parseSchemaElement(trimmedElement);
parseSchemaElement(element.trim());
}
}
return true;
}

private void parseSchemaElement(String element) throws ParseException {
private void parseSchemaElement(String element) throws ArgsException {
char elementId = element.charAt(0);
String elementTail = element.substring(1);
validateSchemaElementId(elementId);
Expand All @@ -60,25 +42,23 @@ private void parseSchemaElement(String element) throws ParseException {
} else if (elementTail.equals("##")) {
marshalers.put(elementId, new DoubleArgumentMarshaler());
} else {
throw new ParseException(
String.format("Argument: %c has invalid format: %s.",
elementId, elementTail), 0);
throw new ArgsException(ArgsException.ErrorCode.INVALID_ARGUMENT_FORMAT,
elementId, elementTail);
}
}

private void validateSchemaElementId(char elementId) throws ParseException {
private void validateSchemaElementId(char elementId) throws ArgsException {
if (!Character.isLetter(elementId)) {
throw new ParseException(
"Bad character: " + elementId + " in Args format: " + schema, 0);
throw new ArgsException(ArgsException.ErrorCode.INVALID_ARGUMENT_NAME,
elementId, null);
}
}

private boolean parseArguments() throws ArgsException {
private void parseArguments() throws ArgsException {
for (currentArgument = argsList.iterator(); currentArgument.hasNext(); ) {
String arg = currentArgument.next();
parseArgument(arg);
}
return true;
}

private void parseArgument(String arg) throws ArgsException {
Expand All @@ -96,9 +76,8 @@ private void parseElement(char argChar) throws ArgsException {
if (setArgument(argChar))
argsFound.add(argChar);
else {
unexpectedArguments.add(argChar);
errorCode = ErrorCode.UNEXPECTED_ARGUMENT;
valid = false;
throw new ArgsException(ArgsException.ErrorCode.UNEXPECTED_ARGUMENT,
argChar, null);
}
}

Expand All @@ -110,8 +89,7 @@ private boolean setArgument(char argChar) throws ArgsException {
m.set(currentArgument);
return true;
} catch (ArgsException e) {
valid = false;
errorArgumentId = argChar;
e.setErrorArgumentId(argChar);
throw e;
}
}
Expand All @@ -127,40 +105,15 @@ public String usage() {
return "";
}

public String errorMessage() throws Exception {
switch (errorCode) {
case OK:
throw new Exception("TILT: Should not get here.");
case UNEXPECTED_ARGUMENT:
return unexpectedArgumentMessage();
case MISSING_STRING:
return String.format("Could not find string parameter for -%c.",
errorArgumentId);
case INVALID_INTEGER:
return String.format("Argument -%c expects an integer but was '%s'.",
errorArgumentId, errorParameter);
case MISSING_INTEGER:
return String.format("Could not find integer parameter for -%c.",
errorArgumentId);
case INVALID_DOUBLE:
return String.format("Argument -%c expects an double but was '%s'.",
errorArgumentId, errorParameter);
case MISSING_DOUBLE:
return String.format("Could not find double parameter for -%c.",
errorArgumentId);
}
return "";

}

private String unexpectedArgumentMessage() {
StringBuffer message = new StringBuffer("Argument(s) -");
for (char c : unexpectedArguments) {
message.append(c);
public boolean getBoolean(char arg) {
ArgumentMarshaler am = marshalers.get(arg);
boolean b = false;
try {
b = am != null && (Boolean) am.get();
} catch (ClassCastException e) {
b = false;
}
message.append(" unexpected.");

return message.toString();
return b;
}

public String getString(char arg) {
Expand All @@ -181,17 +134,6 @@ public int getInt(char arg) {
}
}

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

public double getDouble(char arg) {
ArgumentMarshaler am = marshalers.get(arg);
try {
Expand All @@ -204,100 +146,4 @@ public double getDouble(char arg) {
public boolean has(char arg) {
return argsFound.contains(arg);
}

public boolean isValid() {
return valid;
}

private class ArgsException extends Exception {
}

private interface ArgumentMarshaler {
void set(Iterator<String> currentArgument) throws ArgsException;

Object get();
}

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

@Override
public void set(Iterator<String> currentArgument) throws ArgsException {
booleanValue = true;
}

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

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

@Override
public void set(Iterator<String> currentArgument) throws ArgsException {
try {
stringValue = currentArgument.next();
} catch (NoSuchElementException e) {
errorCode = ErrorCode.MISSING_STRING;
throw new ArgsException();
}
}

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

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

@Override
public void set(Iterator<String> currentArgument) throws ArgsException {
String parameter = null;
try {
parameter = currentArgument.next();
intValue = Integer.parseInt(parameter);
} catch (NoSuchElementException e) {
errorCode = ErrorCode.MISSING_INTEGER;
throw new ArgsException();
} catch (NumberFormatException e) {
errorParameter = parameter;
errorCode = ErrorCode.INVALID_INTEGER;
throw new ArgsException();
}
}

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

private class DoubleArgumentMarshaler implements ArgumentMarshaler {
private double doubleValue = 0;

@Override
public void set(Iterator<String> currentArgument) throws ArgsException {
String parameter = null;
try {
parameter = currentArgument.next();
doubleValue = Double.parseDouble(parameter);
} catch (NoSuchElementException e) {
errorCode = ErrorCode.MISSING_DOUBLE;
throw new ArgsException();
} catch (NumberFormatException e) {
errorParameter = parameter;
errorCode = ErrorCode.INVALID_DOUBLE;
throw new ArgsException();
}
}

@Override
public Object get() {
return doubleValue;
}
}
}
92 changes: 92 additions & 0 deletions src/main/java/chapter14/args/ArgsException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package chapter14.args;

public class ArgsException extends Exception {
private char errorArgumentId = '\0';
private String errorParameter = "TILT";
private ErrorCode errorCode = ErrorCode.OK;

public ArgsException() {
}

public ArgsException(String message) {
super(message);
}

public ArgsException(ErrorCode errorCode) {
this.errorCode = errorCode;
}

public ArgsException(ErrorCode errorCode, String errorParameter) {
this.errorCode = errorCode;
this.errorParameter = errorParameter;
}

public ArgsException(ErrorCode errorCode, char errorArgumentId, String errorParameter) {
this.errorCode = errorCode;
this.errorArgumentId = errorArgumentId;
this.errorParameter = errorParameter;
}

public char getErrorArgumentId() {
return errorArgumentId;
}

public void setErrorArgumentId(char errorArgumentId) {
this.errorArgumentId = errorArgumentId;
}

public String getErrorParameter() {
return errorParameter;
}

public void setErrorParameter(String errorParameter) {
this.errorParameter = errorParameter;
}

public ErrorCode getErrorCode() {
return errorCode;
}

public void setErrorCode(ErrorCode errorCode) {
this.errorCode = errorCode;
}

public String errorMessage() throws Exception {
switch (errorCode) {
case OK:
throw new Exception("TILT: Should not get here.");
case UNEXPECTED_ARGUMENT:
return String.format("Argument(s) -%c unexpected.", errorArgumentId);
case MISSING_STRING:
return String.format("Could not find string parameter for -%c.",
errorArgumentId);
case INVALID_INTEGER:
return String.format("Argument -%c expects an integer but was '%s'.",
errorArgumentId, errorParameter);
case MISSING_INTEGER:
return String.format("Could not find integer parameter for -%c.",
errorArgumentId);
case INVALID_DOUBLE:
return String.format("Argument -%c expects an double but was '%s'.",
errorArgumentId, errorParameter);
case MISSING_DOUBLE:
return String.format("Could not find double parameter for -%c.",
errorArgumentId);
case INVALID_ARGUMENT_NAME:
return String.format("'%c' is not a valid argument name.",
errorArgumentId);
case INVALID_ARGUMENT_FORMAT:
return String.format("'%s' is not a valid argument format.",
errorParameter);
}
return "";
}

public enum ErrorCode {
OK, INVALID_ARGUMENT_FORMAT, UNEXPECTED_ARGUMENT,
INVALID_ARGUMENT_NAME,
MISSING_STRING,
MISSING_INTEGER, INVALID_INTEGER,
MISSING_DOUBLE, INVALID_DOUBLE
}
}
Loading