KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > api > sendopts > CommandLine


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.api.sendopts;
21
22 import java.io.File JavaDoc;
23 import java.io.InputStream JavaDoc;
24 import java.io.OutputStream JavaDoc;
25 import java.io.PrintWriter JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Collections JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.HashSet JavaDoc;
30 import java.util.LinkedHashMap JavaDoc;
31 import java.util.LinkedHashSet JavaDoc;
32 import java.util.Locale JavaDoc;
33 import java.util.Map JavaDoc;
34 import org.netbeans.modules.sendopts.OptionImpl;
35 import org.netbeans.spi.sendopts.Env;
36 import org.netbeans.spi.sendopts.Option;
37 import org.netbeans.spi.sendopts.OptionProcessor;
38 import org.openide.util.Lookup;
39 import org.openide.util.NbBundle;
40
41 /**
42  * A class for clients that have an array of strings and want to process
43  * it - e.g. parse it and also invoke registered {@link OptionProcessor}s.
44  *
45  * @author Jaroslav Tulach
46  */

47 public final class CommandLine {
48     /** internal errors of CommandLine start here and end here + 100 */
49     private static final int ERROR_BASE = 50345;
50     
51     /** Use factory methods to create the line. */
52     CommandLine() {
53     }
54     
55     /** Getter for the default command line processor in the system. List
56      * of {@link OptionProcessor}s is taken from default
57      * <a HREF="@org-openide-util@/org/openide/util/Lookup.html">Lookup.getDefault</code>.
58      */

59     public static CommandLine getDefault() {
60         return new CommandLine();
61     }
62     
63     /** Process the array of arguments and invoke associated {@link OptionProcessor}s.
64      *
65      * @param args the array of strings to process
66      * @exception CommandException if processing is not possible or failed
67      */

68     public void process(String JavaDoc[] args) throws CommandException {
69         process(args, null, null, null, null);
70     }
71     
72     /** Process the array of arguments and invoke associated {@link OptionProcessor}s.
73      *
74      * @param args the array of strings to process
75      * @param is the input stream that processors can read
76      * @param os the output stream that processors can write to
77      * @param err the output stream that processors can send error messages to
78      * @param currentDir directory that processors should use as current user dir
79      * @exception CommandException if processing is not possible or failed
80      */

81     public void process(String JavaDoc[] args, InputStream JavaDoc is, OutputStream JavaDoc os, OutputStream JavaDoc err, File JavaDoc currentDir) throws CommandException {
82         if (is == null) {
83             is = System.in;
84         }
85         if (os == null) {
86             os = System.out;
87         }
88         if (err == null) {
89             err = System.err;
90         }
91         if (currentDir == null) {
92             currentDir = new File JavaDoc(System.getProperty("user.dir")); // NOI18N
93
}
94         Env env = OptionImpl.Trampoline.DEFAULT.create(is, os, err, currentDir);
95         
96         
97         ArrayList JavaDoc<String JavaDoc> additionalParams = new ArrayList JavaDoc<String JavaDoc>();
98         ArrayList JavaDoc<OptionImpl> opts = new ArrayList JavaDoc<OptionImpl>();
99         OptionImpl acceptsAdons = null;
100         
101         OptionImpl[] mainOptions = getOptions();
102         LinkedHashSet JavaDoc<OptionImpl> allOptions = new LinkedHashSet JavaDoc<OptionImpl>();
103         for (int i = 0; i < mainOptions.length; i++) {
104             mainOptions[i] = mainOptions[i].addWorkingCopy(allOptions);
105         }
106         OptionImpl[] arr = allOptions.toArray(new OptionImpl[0]);
107         
108         boolean optionMode = true;
109         ARGS: for (int i = 0; i < args.length; i++) {
110             if (args[i] == null) {
111                 continue ARGS;
112             }
113
114             if (optionMode) {
115                 if (args[i].startsWith("--")) {
116                     if (args[i].length() == 2) {
117                         optionMode = false;
118                         continue ARGS;
119                     }
120
121                     String JavaDoc text = args[i].substring(2);
122                     String JavaDoc value = null;
123                     int textEqual = text.indexOf('=');
124                     if (textEqual >= 0) {
125                         // strip the name of the option
126
value = text.substring(textEqual + 1);
127                         text = text.substring(0, textEqual);
128                     }
129                     OptionImpl opt = findByLongName (text, arr);
130                     if (opt == null) {
131                         throw new CommandException(args[i], ERROR_BASE + 1);
132                     }
133                     if (opt.getArgumentType() == 1 && value == null) {
134                         // read next value from the argument
135
for(;;) {
136                             if (++i == args.length) {
137                                 throw new CommandException(NbBundle.getMessage(CommandLine.class, "MSG_MissingArgument", "--" + opt.getLongName()), ERROR_BASE + 2); // NOI18N
138
}
139                             
140                             if (args[i].equals("--")) {
141                                 optionMode = false;
142                                 continue;
143                             }
144                             
145                             if (optionMode && args[i].startsWith("-")) {
146                                 throw new CommandException(NbBundle.getMessage(CommandLine.class, "MSG_MissingArgument", "--" + opt.getLongName()), ERROR_BASE + 2); // NOI18N
147
}
148
149                             break;
150                         }
151                         
152                         
153                         
154                         value = args[i];
155                     }
156
157
158                     if (value != null) {
159                         if (opt.getArgumentType() != 1 && opt.getArgumentType() != 2) {
160                             throw new CommandException("Option " + opt + " cannot have value " + value, ERROR_BASE + 2);
161                         }
162
163                         opt.associateValue(value);
164                     }
165
166                     if (opt.getArgumentType() == 3) {
167                         if (acceptsAdons != null) {
168                             String JavaDoc oName1 = findOptionName(acceptsAdons, args);
169                             String JavaDoc oName2 = findOptionName(opt, args);
170                             String JavaDoc msg = NbBundle.getMessage(CommandLine.class, "MSG_CannotTogether", oName1, oName2); // NOI18N
171
throw new CommandException(msg, ERROR_BASE + 3);
172                         }
173                         acceptsAdons = opt;
174                     }
175
176                     opts.add(opt);
177                     continue ARGS;
178                 } else if (args[i].startsWith("-") && args[i].length() > 1) {
179                     for (int j = 1; j < args[i].length(); j++) {
180                         char ch = args[i].charAt(j);
181                         OptionImpl opt = findByShortName(ch, arr);
182                         if (opt == null) {
183                             throw new CommandException("Unknown option " + args[i], ERROR_BASE + 1);
184                         }
185                         if (args[i].length() == j + 1 && opt.getArgumentType() == 1) {
186                             throw new CommandException(NbBundle.getMessage(CommandLine.class, "MSG_MissingArgument", args[i]), ERROR_BASE + 2);
187                         }
188
189                         if (args[i].length() > j && (opt.getArgumentType() == 1 || opt.getArgumentType() == 2)) {
190                             opt.associateValue(args[i].substring(j + 1));
191                             j = args[i].length();
192                         }
193                         if (opt.getArgumentType() == 3) {
194                             if (acceptsAdons != null) {
195                                 String JavaDoc oName1 = findOptionName(acceptsAdons, args);
196                                 String JavaDoc oName2 = findOptionName(opt, args);
197                                 String JavaDoc msg = NbBundle.getMessage(CommandLine.class, "MSG_CannotTogether", oName1, oName2); // NOI18N
198
throw new CommandException(msg, ERROR_BASE + 3);
199                             }
200                             acceptsAdons = opt;
201                         }
202                         opts.add(opt);
203                     }
204                     continue ARGS;
205                 }
206             }
207             
208             additionalParams.add(args[i]);
209         }
210         
211         if (acceptsAdons == null && !additionalParams.isEmpty()) {
212             for (int i = 0; i < arr.length; i++) {
213                 if (arr[i].getArgumentType() == 4) {
214                     if (acceptsAdons != null) {
215                         throw new CommandException("There cannot be two default options: " + acceptsAdons + " and " + arr[i], ERROR_BASE + 3);
216                     }
217                     acceptsAdons = arr[i];
218                     opts.add(acceptsAdons);
219                 }
220             }
221             if (acceptsAdons == null) {
222                 throw new CommandException("There are params but noone wants to proces them: " + additionalParams, ERROR_BASE + 2);
223             }
224             
225         }
226         
227         OptionImpl.Appearance[] postProcess = new OptionImpl.Appearance[mainOptions.length];
228         {
229             HashSet JavaDoc<OptionImpl> used = new HashSet JavaDoc<OptionImpl>(opts);
230             for (int i = 0; i < mainOptions.length; i++) {
231                 OptionImpl.Appearance res = mainOptions[i].checkConsistent(used);
232                 postProcess[i] = res;
233                 if (res.isThere()) {
234                     mainOptions[i].markConsistent(res);
235                 }
236 /*
237                 if (res.isError()) {
238                     throw new CommandException(res.errorMessage(args), ERROR_BASE + 4);
239                 }
240  */

241             }
242         }
243         
244         
245         {
246             HashSet JavaDoc<OptionImpl> used = new HashSet JavaDoc<OptionImpl>(opts);
247             for (int i = 0; i < mainOptions.length; i++) {
248                 if (postProcess[i].isError()) {
249                     OptionImpl error = mainOptions[i].findNotUsedOption(used);
250                     if (error != null) {
251                         throw new CommandException(postProcess[i].errorMessage(args), ERROR_BASE + 4);
252                     }
253                 }
254             }
255         }
256
257         Map JavaDoc<OptionProcessor,Map JavaDoc<Option,String JavaDoc[]>> providers = new LinkedHashMap JavaDoc<OptionProcessor,Map JavaDoc<Option,String JavaDoc[]>>();
258         {
259             for (int i = 0; i < mainOptions.length; i++) {
260                 if (postProcess[i].isThere()) {
261                     Map JavaDoc<Option,String JavaDoc[]> param = providers.get(mainOptions[i].getProvider());
262                     if (param == null) {
263                         param = new HashMap JavaDoc<Option,String JavaDoc[]>();
264                         providers.put(mainOptions[i].getProvider(), param);
265                     }
266                     mainOptions[i].process(additionalParams.toArray(new String JavaDoc[0]), param);
267                 }
268             }
269         }
270         
271         for (Map.Entry JavaDoc<OptionProcessor, Map JavaDoc<Option, String JavaDoc[]>> pair : providers.entrySet()) {
272             OptionImpl.Trampoline.DEFAULT.process(pair.getKey(), env, pair.getValue());
273         }
274     }
275
276     /** Prints the usage information about options provided by associated
277      * {@link OptionProcessor}s.
278      *
279      * @param w the writer to output usage info to
280      * @since 1.7
281      */

282     public void usage(PrintWriter JavaDoc w) {
283         OptionImpl[] mainOptions = getOptions();
284         LinkedHashSet JavaDoc<OptionImpl> allOptions = new LinkedHashSet JavaDoc<OptionImpl>();
285         for (int i = 0; i < mainOptions.length; i++) {
286             mainOptions[i].addWorkingCopy(allOptions);
287         }
288         OptionImpl[] arr = allOptions.toArray(new OptionImpl[0]);
289
290         int max = 25;
291         String JavaDoc[] prefixes = new String JavaDoc[arr.length];
292         for (int i = 0; i < arr.length; i++) {
293             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
294             
295             String JavaDoc ownDisplay = OptionImpl.Trampoline.DEFAULT.getDisplayName(arr[i].getOption(), Locale.getDefault());
296             if (ownDisplay != null) {
297                 sb.append(ownDisplay);
298             } else {
299                 String JavaDoc sep = "";
300                 if (arr[i].getShortName() != -1) {
301                     sb.append('-');
302                     sb.append((char)arr[i].getShortName());
303                     sep = ", ";
304                 }
305                 if (arr[i].getLongName() != null) {
306                     sb.append(sep);
307                     sb.append("--"); // NOI18N
308
sb.append(arr[i].getLongName());
309                 } else {
310                     if (sep.length() == 0) {
311                         continue;
312                     }
313                 }
314
315                 switch (arr[i].getArgumentType()) {
316                     case 0: break;
317                     case 1:
318                         sb.append(' ');
319                         sb.append(NbBundle.getMessage(CommandLine.class, "MSG_OneArg")); // NOI18N
320
break;
321                     case 2:
322                         sb.append(' ');
323                         sb.append(NbBundle.getMessage(CommandLine.class, "MSG_OptionalArg")); // NOI18N
324
break;
325                     case 3:
326                         sb.append(' ');
327                         sb.append(NbBundle.getMessage(CommandLine.class, "MSG_AddionalArgs")); // NOI18N
328
break;
329                     default:
330                         assert false;
331                 }
332             }
333
334             if (sb.length() > max) {
335                 max = sb.length();
336             }
337
338             prefixes[i] = sb.toString();
339         }
340
341         for (int i = 0; i < arr.length; i++) {
342             if (prefixes[i] != null) {
343                 w.print(" "); // NOI18N
344
w.print(prefixes[i]);
345                 for (int j = prefixes[i].length(); j < max; j++) {
346                     w.print(' ');
347                 }
348                 w.print(' ');
349                 arr[i].usage(w, max);
350                 w.println();
351             }
352         }
353
354         w.flush();
355     }
356
357     private OptionImpl[] getOptions() {
358         ArrayList JavaDoc<OptionImpl> arr = new ArrayList JavaDoc<OptionImpl>();
359         
360         for (OptionProcessor p : Lookup.getDefault().lookupAll(OptionProcessor.class)) {
361             org.netbeans.spi.sendopts.Option[] all = OptionImpl.Trampoline.DEFAULT.getOptions(p);
362             for (int i = 0; i < all.length; i++) {
363                 arr.add(OptionImpl.cloneImpl(OptionImpl.find(all[i]), all[i], p));
364             }
365         }
366         
367         return arr.toArray(new OptionImpl[0]);
368     }
369     
370     private OptionImpl findByLongName(String JavaDoc lng, OptionImpl[] arr) {
371         boolean abbrev = false;
372         OptionImpl best = null;
373         for (int i = 0; i < arr.length; i++) {
374             String JavaDoc on = arr[i].getLongName();
375             if (on == null) {
376                 continue;
377             }
378             if (lng.equals(on)) {
379                 return arr[i];
380             }
381             if (on.startsWith(lng)) {
382                 abbrev = best == null;
383                 best = arr[i];
384             }
385         }
386         
387         return abbrev ? best : null;
388     }
389     
390     private OptionImpl findByShortName(char ch, OptionImpl[] arr) {
391         for (int i = 0; i < arr.length; i++) {
392             if (ch == arr[i].getShortName()) {
393                 return arr[i];
394             }
395         }
396         return null;
397     }
398
399     private static String JavaDoc findOptionName(OptionImpl opt, String JavaDoc[] args) {
400         for(int i = 0; i < args.length; i++) {
401             if (!args[i].startsWith("-")) {
402                 continue;
403             }
404             
405             if (args[i].startsWith("--")) {
406                 String JavaDoc text = args[i].substring(2);
407                 int textEqual = text.indexOf('=');
408                 if (textEqual >= 0) {
409                     // strip the name of the option
410
text = text.substring(0, textEqual);
411                 }
412                 if (text.startsWith(opt.getLongName())) {
413                     return args[i];
414                 }
415             } else {
416                 if (opt.getShortName() == args[i].charAt(1)) {
417                     return "-" + (char)opt.getShortName();
418                 }
419             }
420         }
421         
422         return opt.toString();
423     }
424
425 }
426
Popular Tags