Skip to content

Commit 53fbebe

Browse files
author
unclebob
committed
initial commit
0 parents  commit 53fbebe

15 files changed

Lines changed: 627 additions & 0 deletions

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
classes
2+
getopts.i*
3+

README

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
This is the java version of the Args program described in: http://butunclebob.com/ArticleS.UncleBob.CleanCodeArgs
2+
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package com.objectmentor.utilities.args;
2+
3+
import static com.objectmentor.utilities.args.ArgsException.ErrorCode.*;
4+
5+
import java.util.*;
6+
7+
public class Args {
8+
private Map<Character, ArgumentMarshaler> marshalers;
9+
private Set<Character> argsFound;
10+
private ListIterator<String> currentArgument;
11+
12+
public Args(String schema, String[] args) throws ArgsException {
13+
marshalers = new HashMap<Character, ArgumentMarshaler>();
14+
argsFound = new HashSet<Character>();
15+
16+
parseSchema(schema);
17+
parseArgumentStrings(Arrays.asList(args));
18+
}
19+
20+
private void parseSchema(String schema) throws ArgsException {
21+
for (String element : schema.split(","))
22+
if (element.length() > 0)
23+
parseSchemaElement(element.trim());
24+
}
25+
26+
private void parseSchemaElement(String element) throws ArgsException {
27+
char elementId = element.charAt(0);
28+
String elementTail = element.substring(1);
29+
validateSchemaElementId(elementId);
30+
if (elementTail.length() == 0)
31+
marshalers.put(elementId, new BooleanArgumentMarshaler());
32+
else if (elementTail.equals("*"))
33+
marshalers.put(elementId, new StringArgumentMarshaler());
34+
else if (elementTail.equals("#"))
35+
marshalers.put(elementId, new IntegerArgumentMarshaler());
36+
else if (elementTail.equals("##"))
37+
marshalers.put(elementId, new DoubleArgumentMarshaler());
38+
else if (elementTail.equals("[*]"))
39+
marshalers.put(elementId, new StringArrayArgumentMarshaler());
40+
else
41+
throw new ArgsException(INVALID_ARGUMENT_FORMAT, elementId, elementTail);
42+
}
43+
44+
private void validateSchemaElementId(char elementId) throws ArgsException {
45+
if (!Character.isLetter(elementId))
46+
throw new ArgsException(INVALID_ARGUMENT_NAME, elementId, null);
47+
}
48+
49+
private void parseArgumentStrings(List<String> argsList) throws ArgsException {
50+
for (currentArgument = argsList.listIterator(); currentArgument.hasNext();) {
51+
String argString = currentArgument.next();
52+
if (argString.startsWith("-")) {
53+
parseArgumentCharacters(argString.substring(1));
54+
} else {
55+
currentArgument.previous();
56+
break;
57+
}
58+
}
59+
}
60+
61+
private void parseArgumentCharacters(String argChars) throws ArgsException {
62+
for (int i = 0; i < argChars.length(); i++)
63+
parseArgumentCharacter(argChars.charAt(i));
64+
}
65+
66+
private void parseArgumentCharacter(char argChar) throws ArgsException {
67+
ArgumentMarshaler m = marshalers.get(argChar);
68+
if (m == null) {
69+
throw new ArgsException(UNEXPECTED_ARGUMENT, argChar, null);
70+
} else {
71+
argsFound.add(argChar);
72+
try {
73+
m.set(currentArgument);
74+
} catch (ArgsException e) {
75+
e.setErrorArgumentId(argChar);
76+
throw e;
77+
}
78+
}
79+
}
80+
81+
public boolean has(char arg) {
82+
return argsFound.contains(arg);
83+
}
84+
85+
public int nextArgument() {
86+
return currentArgument.nextIndex();
87+
}
88+
89+
public boolean getBoolean(char arg) {
90+
return BooleanArgumentMarshaler.getValue(marshalers.get(arg));
91+
}
92+
93+
public String getString(char arg) {
94+
return StringArgumentMarshaler.getValue(marshalers.get(arg));
95+
}
96+
97+
public int getInt(char arg) {
98+
return IntegerArgumentMarshaler.getValue(marshalers.get(arg));
99+
}
100+
101+
public double getDouble(char arg) {
102+
return DoubleArgumentMarshaler.getValue(marshalers.get(arg));
103+
}
104+
105+
public String[] getStringArray(char arg) {
106+
return StringArrayArgumentMarshaler.getValue(marshalers.get(arg));
107+
}
108+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.objectmentor.utilities.args;
2+
3+
import static com.objectmentor.utilities.args.ArgsException.ErrorCode.*;
4+
5+
public class ArgsException extends Exception {
6+
private char errorArgumentId = '\0';
7+
private String errorParameter = null;
8+
private ErrorCode errorCode = OK;
9+
10+
public ArgsException() {}
11+
12+
public ArgsException(String message) {super(message);}
13+
14+
public ArgsException(ErrorCode errorCode) {
15+
this.errorCode = errorCode;
16+
}
17+
18+
public ArgsException(ErrorCode errorCode, String errorParameter) {
19+
this.errorCode = errorCode;
20+
this.errorParameter = errorParameter;
21+
}
22+
23+
public ArgsException(ErrorCode errorCode, char errorArgumentId, String errorParameter) {
24+
this.errorCode = errorCode;
25+
this.errorParameter = errorParameter;
26+
this.errorArgumentId = errorArgumentId;
27+
}
28+
29+
public char getErrorArgumentId() {
30+
return errorArgumentId;
31+
}
32+
33+
public void setErrorArgumentId(char errorArgumentId) {
34+
this.errorArgumentId = errorArgumentId;
35+
}
36+
37+
public String getErrorParameter() {
38+
return errorParameter;
39+
}
40+
41+
public void setErrorParameter(String errorParameter) {
42+
this.errorParameter = errorParameter;
43+
}
44+
45+
public ErrorCode getErrorCode() {
46+
return errorCode;
47+
}
48+
49+
public void setErrorCode(ErrorCode errorCode) {
50+
this.errorCode = errorCode;
51+
}
52+
53+
public String errorMessage() {
54+
switch (errorCode) {
55+
case OK:
56+
return "TILT: Should not get here.";
57+
case UNEXPECTED_ARGUMENT:
58+
return String.format("Argument -%c unexpected.", errorArgumentId);
59+
case MISSING_STRING:
60+
return String.format("Could not find string parameter for -%c.", errorArgumentId);
61+
case INVALID_INTEGER:
62+
return String.format("Argument -%c expects an integer but was '%s'.", errorArgumentId, errorParameter);
63+
case MISSING_INTEGER:
64+
return String.format("Could not find integer parameter for -%c.", errorArgumentId);
65+
case INVALID_DOUBLE:
66+
return String.format("Argument -%c expects a double but was '%s'.", errorArgumentId, errorParameter);
67+
case MISSING_DOUBLE:
68+
return String.format("Could not find double parameter for -%c.", errorArgumentId);
69+
case INVALID_ARGUMENT_NAME:
70+
return String.format("'%c' is not a valid argument name.", errorArgumentId);
71+
case INVALID_ARGUMENT_FORMAT:
72+
return String.format("'%s' is not a valid argument format.", errorParameter);
73+
}
74+
return "";
75+
}
76+
77+
public enum ErrorCode {
78+
OK, INVALID_ARGUMENT_FORMAT, UNEXPECTED_ARGUMENT, INVALID_ARGUMENT_NAME,
79+
MISSING_STRING,
80+
MISSING_INTEGER, INVALID_INTEGER,
81+
MISSING_DOUBLE, INVALID_DOUBLE}
82+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.objectmentor.utilities.args;
2+
3+
import static com.objectmentor.utilities.args.ArgsException.ErrorCode.*;
4+
5+
import junit.framework.TestCase;
6+
7+
public class ArgsExceptionTest extends TestCase {
8+
public void testUnexpectedMessage() throws Exception {
9+
ArgsException e = new ArgsException(UNEXPECTED_ARGUMENT, 'x', null);
10+
assertEquals("Argument -x unexpected.", e.errorMessage());
11+
}
12+
13+
public void testMissingStringMessage() throws Exception {
14+
ArgsException e = new ArgsException(MISSING_STRING, 'x', null);
15+
assertEquals("Could not find string parameter for -x.", e.errorMessage());
16+
}
17+
18+
public void testInvalidIntegerMessage() throws Exception {
19+
ArgsException e = new ArgsException(INVALID_INTEGER, 'x', "Forty two");
20+
assertEquals("Argument -x expects an integer but was 'Forty two'.", e.errorMessage());
21+
}
22+
23+
public void testMissingIntegerMessage() throws Exception {
24+
ArgsException e = new ArgsException(MISSING_INTEGER, 'x', null);
25+
assertEquals("Could not find integer parameter for -x.", e.errorMessage());
26+
}
27+
28+
public void testInvalidDoubleMessage() throws Exception {
29+
ArgsException e = new ArgsException(INVALID_DOUBLE, 'x', "Forty two");
30+
assertEquals("Argument -x expects a double but was 'Forty two'.", e.errorMessage());
31+
}
32+
33+
public void testMissingDoubleMessage() throws Exception {
34+
ArgsException e = new ArgsException(MISSING_DOUBLE, 'x', null);
35+
assertEquals("Could not find double parameter for -x.", e.errorMessage());
36+
}
37+
38+
public void testInvalidArgumentName() throws Exception {
39+
ArgsException e = new ArgsException(INVALID_ARGUMENT_NAME, '#', null);
40+
assertEquals("'#' is not a valid argument name.", e.errorMessage());
41+
}
42+
43+
public void testInvalidFormat() throws Exception {
44+
ArgsException e = new ArgsException(INVALID_ARGUMENT_FORMAT, 'x', "$");
45+
assertEquals("'$' is not a valid argument format.", e.errorMessage());
46+
}
47+
}
48+

0 commit comments

Comments
 (0)