package net.sourceforge.gpstools;
/* gpsdings
* Copyright (C) 2006-2007 Moritz Ringler
* $Id: AbstractCommandLine.java 441 2010-12-13 20:04:20Z ringler $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.awt.Color;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.File;
import java.io.PrintStream;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.Set;
import java.util.TreeSet;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.Parser;
import org.apache.commons.cli.PosixParser;
import org.apache.commons.cli.OptionBuilder;
public abstract class AbstractCommandLine<T extends GPSDings> {
protected final String[] argv;
public final static String OPT_HELP = "help";
public final static String OPT_LICENSE = "license";
public final static String OPT_QUIET = "quiet";
protected final T app;
protected transient String opt;
private String[] inp;
public AbstractCommandLine(T app, String[] args) {
final int narg = args.length;
argv = new String[narg];
System.arraycopy(args, 0, argv, 0, narg);
this.app = app;
}
public void printHelp(PrintStream out) {
out.println(GPSDings.getApplicationInfo());
}
public abstract void execute();
static void cat(String resource, Class<?> klass) throws IOException {
byte[] myBuff = new byte[1024];
String qName = (resource.startsWith("/")) ? resource
: "/net/sourceforge/gpstools/res/" + resource;
InputStream is = klass.getResourceAsStream(qName);
if (is == null) {
throw new IllegalArgumentException("Resource " + resource + "="
+ qName + " not found.");
}
is = new BufferedInputStream(is);
try {
for (int i = 0; i > -1; i = is.read(myBuff)) {
System.out.write(myBuff, 0, i);
System.out.flush();
}
} finally {
is.close();
}
}
protected void cat(String resource) throws IOException {
cat(resource, getClass());
}
public void printLicense() {
try {
cat("gpl");
} catch (IOException ex) {
throw new Error(ex);
}
}
public File[] getInputFiles() throws FileNotFoundException {
if (inp == null) {
return null;
}
return asFiles(inp);
}
public String[] getInput() {
return inp.clone();
}
protected Options createOptions() {
Options options = new Options();
options.addOption(makeOption(OPT_HELP, Boolean.class, 0, null));
options.addOption(makeOption(OPT_LICENSE, Boolean.class, 0, null));
options.addOption(makeOption(OPT_QUIET, Boolean.class, 0, null));
return options;
}
private static Set<String> getColorConstants() {
Class<Color> color = Color.class;
Field[] fields = color.getFields();
Set<String> result = new TreeSet<String>();
for (Field field : fields) {
if (field.getType() == color) {
int m = field.getModifiers();
if (Modifier.isStatic(m) && Modifier.isPublic(m)) {
result.add(field.getName());
}
}
}
return result;
}
protected Color parseColor(String s) {
Color result = null;
final int slen = s.length();
if (slen == 0) {
throw new IllegalArgumentException("Empty string is not allowed.");
}
if (s.charAt(0) == '#') {
switch (slen) {
case 7:
result = new Color(Integer.valueOf(s.substring(1), 16), false);
break;
case 9:
result = new Color(Integer.valueOf(s.substring(1), 16), true);
break;
default:
throw new IllegalArgumentException(
"Numeric color specification must have 6 or 8 digits.");
}
} else if (getColorConstants().contains(s)) {
// Constant of the Color class
try {
result = (Color) Color.class.getField(s).get(null);
} catch (Exception ex) {
throw new IllegalArgumentException(ex);
}
} else {
result = Color.getColor(s);
}
return result;
}
protected void processArguments() {
try {
CommandLine cl = processOptions(createOptions());
opt = null;
inp = cl.getArgs();
} catch (Exception ex) {
if (app == null) {
if (opt != null) {
System.err
.println("An exception occurred while processing the "
+ opt + " option");
}
System.err.println(ex);
if (ex instanceof RuntimeException) {
ex.printStackTrace();
}
} else {
app.handleException(opt, ex);
}
}
}
public static File[] asFiles(String[] fargs) throws FileNotFoundException {
int nf = fargs.length;
File[] input = new File[nf];
for (int i = 0; i < nf; i++) {
input[i] = new File(fargs[i]);
if (!input[i].isFile()) {
input = null;
throw new FileNotFoundException(fargs[i]
+ " is not a regular file.");
}
}
return input;
}
protected CommandLine processOptions(Options options)
throws org.apache.commons.cli.ParseException, IOException,
java.text.ParseException {
if (argv.length == 0) {
printHelp(System.out);
System.exit(1);
}
Parser p = new PosixParser();
CommandLine cl = p.parse(options, argv);
/* help option */
opt = OPT_HELP;
char c = opt.charAt(0);
if (cl.hasOption(c)) {
printHelp(System.out);
System.exit(1);
}
/* license option */
opt = OPT_LICENSE;
c = opt.charAt(0);
if (cl.hasOption(c)) {
printLicense();
System.exit(0);
}
/* quiet option */
if (app != null) {
opt = OPT_QUIET;
c = opt.charAt(0);
app.setQuiet(cl.hasOption(c));
}
return cl;
}
@SuppressWarnings("static-access")
private void configureOptionBuilder(String longOption, Class<?> type,
int args, String argName) {
OptionBuilder.withLongOpt(longOption).isRequired(false);
switch (args) {
case 0:
OptionBuilder.hasArg(false);
break;
case 1:
OptionBuilder.hasArg(true);
break;
default:
OptionBuilder.hasArgs(args);
}
if (argName != null) {
OptionBuilder.withArgName(argName);
}
OptionBuilder.withType(type);
}
protected synchronized Option makeOption(String longOption, Class<?> type,
int args, String argName) {
configureOptionBuilder(longOption, type, args, argName);
return OptionBuilder.create(longOption.charAt(0));
}
protected synchronized Option makeOption(char shortOption,
String longOption, Class<?> type, int args, String argName) {
configureOptionBuilder(longOption, type, args, argName);
return OptionBuilder.create(shortOption);
}
}