001: /*
002: * Copyright 2006 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.util.tools;
017:
018: import com.google.gwt.dev.About;
019:
020: import java.io.File;
021: import java.io.IOException;
022: import java.util.ArrayList;
023: import java.util.HashSet;
024: import java.util.Iterator;
025: import java.util.List;
026: import java.util.Map;
027: import java.util.Set;
028: import java.util.TreeMap;
029:
030: /**
031: * A base class for a GWT related command-line application. To use this:
032: * <ol>
033: * <li>Derive a class for this class.</li>
034: * <li>In your constructor, call {@link #registerHandler(ArgHandler)}
035: * repeatedly to register particular command line arguments and options.</li>
036: * <li>Write a main that looks like this:
037: *
038: * <pre>
039: * public static void main(String[] args) {
040: * MyShell myShell = new MyShell();
041: * if (myShell.processArgs(args)) {
042: * // main program operation
043: * }
044: * System.exit(1);
045: * }
046: * </pre>
047: *
048: * </li>
049: * <li>Create launch config whose main class is MyShell.</li>
050: * </ol>
051: */
052: public abstract class ToolBase {
053:
054: static {
055: String installPath = Utility.getInstallPath();
056: try {
057: // try to make absolute
058: installPath = new File(installPath).getCanonicalPath();
059: } catch (IOException e) {
060: // ignore problems, failures will occur when the libs try to load
061: }
062: System.setProperty("swt.library.path", installPath + '/');
063: }
064:
065: // Use a tree map to sort the order.
066: //
067: private final Map argHandlers = new TreeMap();
068:
069: // Use a list to preserve the declared order for help printing.
070: //
071: private final List orderedArgHandlers = new ArrayList();
072:
073: protected void printHelp() {
074: System.err.println(About.GWT_VERSION);
075:
076: ArgHandler nullHandler = null;
077: int widest = 0;
078: for (Iterator iter = orderedArgHandlers.iterator(); iter
079: .hasNext();) {
080: ArgHandler handler = (ArgHandler) iter.next();
081: if (handler.isUndocumented()) {
082: continue;
083: }
084: String tag = handler.getTag();
085: if (tag != null) {
086: if (tag.length() > widest) {
087: widest = tag.length();
088: }
089: } else {
090: nullHandler = handler;
091: int len = nullHandler.getTagArgs()[0].length();
092: if (len > widest) {
093: widest = len;
094: }
095: }
096: }
097:
098: // Print the name.
099: //
100: String name = getClass().getName();
101: int i = name.lastIndexOf('.');
102: if (i != -1) {
103: name = name.substring(i + 1);
104: }
105: System.err.print(name);
106:
107: // Print the command-line template.
108: //
109: for (Iterator iter = orderedArgHandlers.iterator(); iter
110: .hasNext();) {
111: ArgHandler handler = (ArgHandler) iter.next();
112: if (handler.isUndocumented()) {
113: continue;
114: }
115: String tag = handler.getTag();
116: if (tag != null) {
117: System.err.print(handler.isRequired() ? " " : " [");
118: System.err.print(tag);
119: String[] tagArgs = handler.getTagArgs();
120: for (int j = 0; j < tagArgs.length; j++) {
121: if (handler.isRequired()) {
122: System.err.print(" " + tagArgs[j]);
123: } else {
124: System.err.print(" " + tagArgs[j]);
125: }
126: }
127: System.err.print(handler.isRequired() ? "" : "]");
128: }
129: }
130:
131: // Print the flagless args.
132: //
133: if (nullHandler != null && !nullHandler.isUndocumented()) {
134: String[] tagArgs = nullHandler.getTagArgs();
135: for (int j = 0; j < tagArgs.length; j++) {
136: System.err.print(nullHandler.isRequired() ? " " : " [");
137: System.err.print(tagArgs[j]);
138: System.err.print(nullHandler.isRequired() ? " " : "]");
139: }
140: System.err.println();
141: }
142:
143: System.err.println();
144:
145: System.err.println("where ");
146:
147: // Print the details.
148: //
149: for (Iterator iter = orderedArgHandlers.iterator(); iter
150: .hasNext();) {
151: ArgHandler handler = (ArgHandler) iter.next();
152: if (handler.isUndocumented()) {
153: continue;
154: }
155: String tag = handler.getTag();
156: if (tag != null) {
157: int len = tag.length();
158: System.err.print(" ");
159: System.err.print(tag);
160: for (i = len; i < widest; ++i) {
161: System.err.print(' ');
162: }
163: System.err.print(" ");
164: System.err.print(handler.getPurpose());
165: System.err.println();
166: }
167: }
168:
169: // And details for the "extra" args, if any.
170: //
171: if (nullHandler != null && !nullHandler.isUndocumented()) {
172: System.err.println("and ");
173: String tagArg = nullHandler.getTagArgs()[0];
174: int len = tagArg.length();
175: System.err.print(" ");
176: System.err.print(tagArg);
177: for (i = len; i < widest; ++i) {
178: System.err.print(' ');
179: }
180: System.err.print(" ");
181: System.err.print(nullHandler.getPurpose());
182: System.err.println();
183: }
184: }
185:
186: protected boolean processArgs(String[] args) {
187: if (args.length > 0) {
188: boolean help = false;
189: if ("-help".equalsIgnoreCase(args[0])) {
190: help = true;
191: } else if ("-?".equals(args[0])) {
192: help = true;
193: }
194:
195: if (help) {
196: printHelp();
197: return false;
198: }
199: }
200:
201: Set defs = new HashSet(argHandlers.values());
202: int extraArgCount = 0;
203:
204: Set receivedArg = new HashSet();
205:
206: // Let the args drive the handlers.
207: //
208: ArgHandler nullHandler = (ArgHandler) argHandlers.get("");
209: for (int i = 0; i < args.length; i++) {
210: String arg = args[i];
211: ArgHandler handler;
212: if (arg.startsWith("-")) {
213: // Use the handler registered for this flag.
214: //
215: handler = (ArgHandler) argHandlers.get(arg);
216: } else {
217: // Use the handler that doesn't have a leading flag.
218: //
219: handler = nullHandler;
220: ++extraArgCount;
221: }
222:
223: if (handler == null) {
224: System.err.println("Unknown argument: " + arg);
225: printHelp();
226: return false;
227: }
228:
229: int addtlConsumed = handler.handle(args, i);
230: if (addtlConsumed == -1) {
231: printHelp();
232: return false;
233: }
234:
235: i += addtlConsumed;
236:
237: // We don't need to use this as a default handler.
238: //
239: defs.remove(handler);
240:
241: // Record that this handler saw a value
242: //
243: receivedArg.add(handler);
244: }
245:
246: // See if any handler didn't get its required argument(s).
247: //
248: for (Iterator iter = argHandlers.values().iterator(); iter
249: .hasNext();) {
250: ArgHandler argHandler = (ArgHandler) iter.next();
251: if (argHandler.isRequired()
252: && !receivedArg.contains(argHandler)) {
253: System.err.print("Missing required argument '");
254: String tag = argHandler.getTag();
255: if (tag != null) {
256: System.err.print(tag);
257: System.err.print(" ");
258: }
259:
260: String tagArg = argHandler.getTagArgs()[0];
261: System.err.print(tagArg);
262: System.err.println("'");
263:
264: printHelp();
265: return false;
266: }
267: }
268: if (extraArgCount == 0 && nullHandler != null
269: && nullHandler.isRequired()) {
270: System.err.print("Missing required argument '");
271: String tagArg = nullHandler.getTagArgs()[0];
272: System.err.print(tagArg);
273: System.err.println("'");
274: printHelp();
275: return false;
276: }
277:
278: // Set if there are any remaining unused handlers with default arguments.
279: // Allow the default handlers to pretend there were other arguments.
280: //
281: for (Iterator iter = defs.iterator(); iter.hasNext();) {
282: ArgHandler def = (ArgHandler) iter.next();
283: String[] defArgs = def.getDefaultArgs();
284: if (defArgs != null) {
285: if (def.handle(defArgs, 0) == -1) {
286: return false;
287: }
288: }
289: }
290:
291: return true;
292: }
293:
294: protected void registerHandler(ArgHandler handler) {
295: String tag = handler.getTag();
296: orderedArgHandlers.add(handler);
297: argHandlers.put(tag != null ? tag : "", handler);
298: }
299: }
|