001: package org.incava.jagol;
002:
003: import java.io.*;
004: import java.util.*;
005:
006: /**
007: * A group of options.
008: */
009: public class OptionSet {
010: private List options = new ArrayList();
011:
012: private List rcFiles = new ArrayList();
013:
014: private String appName;
015:
016: private String description;
017:
018: public OptionSet(String appName, String description) {
019: this .appName = appName;
020: this .description = description;
021: }
022:
023: /**
024: * Returns the application name.
025: */
026: public String getAppName() {
027: return appName;
028: }
029:
030: /**
031: * Returns the description.
032: */
033: public String getDescription() {
034: return description;
035: }
036:
037: /**
038: * Adds an options to this set.
039: */
040: public void add(Option opt) {
041: options.add(opt);
042: }
043:
044: /**
045: * Adds a run control file to be processed.
046: */
047: public void addRunControlFile(String name) {
048: tr.Ace.log("adding rc file: " + name);
049: rcFiles.add(name);
050: }
051:
052: /**
053: * Processes the run control files and command line arguments. Returns the
054: * arguments that were not consumed by option processing.
055: */
056: public String[] process(String[] args) {
057: tr.Ace.log("args: " + args);
058:
059: processRunControlFiles();
060:
061: return processCommandLine(args);
062: }
063:
064: /**
065: * Processes the run control files, if any.
066: */
067: protected void processRunControlFiles() {
068: tr.Ace.log("");
069: Iterator it = rcFiles.iterator();
070: while (it.hasNext()) {
071: String rcFileName = (String) it.next();
072: tr.Ace.log("processing: " + rcFileName);
073: try {
074: Properties props = new Properties();
075:
076: int tildePos = rcFileName.indexOf('~');
077: if (tildePos != -1) {
078: rcFileName = rcFileName.substring(0, tildePos)
079: + System.getProperty("user.home")
080: + rcFileName.substring(tildePos + 1);
081: }
082:
083: props.load(new FileInputStream(rcFileName));
084:
085: tr.Ace.log("properties: " + props);
086: Iterator pit = props.keySet().iterator();
087: while (pit.hasNext()) {
088: String key = (String) pit.next();
089: String value = (String) props.get(key);
090: tr.Ace.log(key + " => " + value);
091: Iterator oit = options.iterator();
092: boolean processed = false;
093: while (!processed && oit.hasNext()) {
094: Option opt = (Option) oit.next();
095: tr.Ace.log("option: " + opt.getLongName());
096: if (opt.getLongName().equals(key)) {
097: tr.Ace.log("option matches: " + opt);
098: processed = true;
099: try {
100: opt.setValue(value);
101: } catch (OptionException oe) {
102: tr.Ace.log("option exception: " + oe);
103: System.err.println("error: "
104: + oe.getMessage());
105: }
106: }
107: }
108: }
109: } catch (IOException ioe) {
110: tr.Ace.log("exception: " + ioe);
111: // ioe.printStackTrace();
112: }
113: }
114: }
115:
116: /**
117: * Processes the command line arguments. Returns the arguments that were not
118: * consumed by option processing.
119: */
120: protected String[] processCommandLine(String[] args) {
121: tr.Ace.log("args: " + args);
122:
123: List argList = new ArrayList();
124: for (int i = 0; i < args.length; ++i) {
125: argList.add(args[i]);
126: }
127:
128: tr.Ace.log("arg list: " + argList);
129:
130: while (argList.size() > 0) {
131: String arg = (String) argList.get(0);
132:
133: tr.Ace.log("arg: " + arg);
134:
135: if (arg.equals("--")) {
136: argList.remove(0);
137: break;
138: } else if (arg.charAt(0) == '-') {
139: tr.Ace.log("got leading dash");
140: argList.remove(0);
141:
142: Iterator oit = options.iterator();
143: boolean processed = false;
144: while (!processed && oit.hasNext()) {
145: Option opt = (Option) oit.next();
146: tr.Ace.log("option: " + opt);
147: try {
148: processed = opt.set(arg, argList);
149: tr.Ace.log("processed: " + processed);
150: } catch (OptionException oe) {
151: tr.Ace.log("option exception: " + oe);
152: System.err.println("error: " + oe.getMessage());
153: }
154: }
155:
156: if (!processed) {
157: tr.Ace.log("argument not processed: '" + arg + "'");
158: if (arg.equals("--help") || arg.equals("-h")) {
159: showUsage();
160: } else if (rcFiles.size() > 0
161: && arg.equals("--help-config")) {
162: showConfig();
163: } else {
164: System.err.println("invalid option: " + arg
165: + " (-h will show valid options)");
166: }
167:
168: break;
169: }
170: } else {
171: break;
172: }
173: }
174:
175: String[] unprocessed = (String[]) argList
176: .toArray(new String[0]);
177:
178: tr.Ace.log("args", args);
179: tr.Ace.log("unprocessed", unprocessed);
180:
181: return unprocessed;
182: }
183:
184: protected void showUsage() {
185: tr.Ace.log("generating help");
186:
187: System.out.println("Usage: " + appName + " [options] file...");
188: System.out.println(description);
189: System.out.println();
190: System.out.println("Options:");
191:
192: tr.Ace.log("options: " + options);
193:
194: List tags = new ArrayList();
195:
196: Iterator it = options.iterator();
197: while (it.hasNext()) {
198: Option opt = (Option) it.next();
199: tr.Ace.log("opt: " + opt);
200: StringBuffer buf = new StringBuffer(" ");
201:
202: if (opt.getShortName() == 0) {
203: buf.append(" ");
204: } else {
205: buf.append("-" + opt.getShortName() + ", ");
206: }
207:
208: buf.append("--" + opt.getLongName());
209:
210: tags.add(buf.toString());
211: }
212:
213: int widest = -1;
214: Iterator tit = tags.iterator();
215: while (tit.hasNext()) {
216: String tag = (String) tit.next();
217: widest = Math.max(tag.length(), widest);
218: }
219:
220: it = options.iterator();
221: tit = tags.iterator();
222: while (it.hasNext()) {
223: Option opt = (Option) it.next();
224: String tag = (String) tit.next();
225: tr.Ace.log("opt: " + opt);
226:
227: System.out.print(tag);
228: for (int i = tag.length(); i < widest + 2; ++i) {
229: System.out.print(" ");
230: }
231:
232: System.out.println(opt.getDescription());
233: }
234:
235: if (rcFiles.size() > 0) {
236: System.out
237: .println("For an example configure file, run --help-config");
238: System.out.println();
239: System.out.println("Configuration File"
240: + (rcFiles.size() > 1 ? "s" : "") + ":");
241: Iterator rit = rcFiles.iterator();
242: while (rit.hasNext()) {
243: String rcFileName = (String) rit.next();
244: System.out.println(" " + rcFileName);
245: }
246: }
247: }
248:
249: protected void showConfig() {
250: tr.Ace.log("generating config");
251:
252: Iterator it = options.iterator();
253: while (it.hasNext()) {
254: Option opt = (Option) it.next();
255: System.out.println("# " + opt.getDescription());
256: System.out.println(opt.getLongName() + " = "
257: + opt.toString());
258: System.out.println();
259: }
260: }
261: }
|