import java.
util.
Map;
import java.
util.
HashMap;
import java.
io.
File;
public class CommandLineProcessor
{
public static final String ARG_PREFIX1 =
"--";
public static final String ARG_PREFIX2 =
"//";
protected Map m_optionExtractors =
new HashMap();
protected FileOption m_fileSetter =
null;
protected int m_fileIndex =
0;
public void registerOption
(String optionName,
Option handler
) {
addExtractor
(optionName,
new OptionExtractor
(handler
));
}
public void registerOption
(String optionName, StringOption handler
) {
addExtractor
(optionName,
new StringOptionExtractor
(handler
));
}
public void registerFiles
(FileOption handler
) {
m_fileSetter = handler;
}
public void registerOption
(String optionName, IntOption handler
) {
addExtractor
(optionName,
new IntOptionExtractor
(handler
));
}
public void execute
(String[] args
) {
boolean optionsAllowed =
true;
int argIndex =
0;
while (argIndex < args.
length) {
String arg = args
[argIndex++
];
if (optionsAllowed
) {
if (ARG_PREFIX1.
equals(arg
) || ARG_PREFIX2.
equals(arg
)) {
optionsAllowed =
false;
continue;
}
String optionName;
if (arg.
startsWith(ARG_PREFIX1
)) {
optionName = arg.
substring(ARG_PREFIX1.
length());
} else if (arg.
startsWith(ARG_PREFIX2
)) {
optionName = arg.
substring(ARG_PREFIX2.
length());
} else {
optionName =
null;
}
if (optionName ==
null) {
setFile
(arg
);
} else {
Extractor extractor =
(Extractor
) m_optionExtractors.
get(optionName
);
if (extractor ==
null) {
throw new Exception("Unexpected option '" + optionName +
"'");
}
argIndex = extractor.
execute(optionName, args, argIndex
);
}
} else {
setFile
(arg
);
}
}
}
protected void setFile
(String value
) {
if (m_fileSetter ==
null) {
throw new Exception("Unexpected file name: '" + value +
"'");
}
m_fileSetter.
execute(++m_fileIndex,
new File(value
));
}
protected void addExtractor
(String optionName, Extractor extractor
) {
if (m_optionExtractors.
containsKey(optionName
)) {
throw new Exception("Duplicated option name: '" + optionName +
"'");
}
m_optionExtractors.
put(optionName, extractor
);
}
public static class Exception extends java.
lang.
RuntimeException {
public Exception (String message
) {
super(message
);
}
public Exception (String message,
Throwable nested
) {
super(message,nested
);
}
}
public interface Option {
void execute
(String option
) throws Exception;
}
public interface StringOption
{
void execute
(String option,
String value
) throws Exception;
}
public interface IntOption
{
void execute
(String option,
int value
) throws Exception;
}
public interface FileOption
{
void execute
(int fileNo,
File value
) throws Exception;
}
protected abstract class Extractor
{
public abstract int execute
(String optionName,
String[] args,
int argIndex
) throws Exception;
protected String getArg
(String optionName,
String[] args,
int argIndex,
String errorMessage
) {
if (argIndex >= args.
length) {
throw newException
(optionName, errorMessage
);
}
return args
[argIndex
];
}
protected Exception newException
(String optionName,
String errorMessage
) {
return new Exception("Invalid option '" + optionName +
"': " + errorMessage
);
}
}
protected class OptionExtractor
extends Extractor
{
protected Option m_handler;
public OptionExtractor
(Option handler
) {
m_handler = handler;
}
public int execute
(String optionName,
String[] args,
int argIndex
) {
m_handler.
execute(optionName
);
return argIndex;
}
}
protected class StringOptionExtractor
extends Extractor
{
protected StringOption m_handler;
public StringOptionExtractor
(StringOption handler
) {
m_handler = handler;
}
public int execute
(String optionName,
String[] args,
int argIndex
) {
m_handler.
execute(optionName, getArg
(optionName, args, argIndex,
"string value expected"));
return argIndex +
1;
}
}
protected class IntOptionExtractor
extends Extractor
{
protected IntOption m_handler;
public IntOptionExtractor
(IntOption handler
) {
m_handler = handler;
}
public int execute
(String optionName,
String[] args,
int argIndex
) {
String textValue = getArg
(optionName, args, argIndex,
"integer value expected");
int value;
try {
value =
Integer.
parseInt(textValue
);
} catch (Throwable t
) {
throw newException
(optionName,
"Invalid int argument");
}
m_handler.
execute(optionName, value
);
return argIndex +
1;
}
}
} java -cp . Test --host localhost Foobar.txt
java -cp . Test --host localhost Foobar.txt --append
java -cp . Test --host localhost Foobar.txt --append --maxSize 1024
java -cp . Test --host localhost --append --maxSize 1024 -- --Foo--