Source Code Cross Referenced for OptionParser.java in  » Development » JOpt-Simple » joptsimple » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Development » JOpt Simple » joptsimple 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         Copyright 2004-2007 Paul R. Holser, Jr.  All rights reserved.
003:         Licensed under the Academic Free License version 3.0
004:         */
005:
006:        package joptsimple;
007:
008:        import java.io.IOException;
009:        import java.io.OutputStream;
010:        import java.io.OutputStreamWriter;
011:        import java.io.Writer;
012:
013:        /**
014:         * <p>Parses command line arguments according to GNU's conventions.</p>
015:         *
016:         * <p>This parser supports both <dfn>short options</dfn> and <dfn>long options</dfn>.</p>
017:         *
018:         * <ul>
019:         *   <li><dfn>Short options</dfn> begin with a single hyphen ("<code>-</code>") followed
020:         *   by a single letter or digit.</li>
021:         *
022:         *   <li>Short options can accept single arguments.  The argument can be made required or
023:         *   optional.  The option can occur in:
024:         *     <ul>
025:         *       <li>the argument after the option, as in <code>-d /tmp</code></li>
026:         *       <li>right up against it, as in <code>-d/tmp</code></li>
027:         *       <li>right up against it separated by an equals sign (<code>"="</code>), as in
028:         *         <code>-d=/tmp</code>
029:         *     </ul>
030:         *   </li>
031:         *
032:         *   <li>Short options can be clustered, so that <code>-abc</code> is treated as <code>-a
033:         *   -b -c</code>, if none of those options can accept arguments.</li>
034:         *
035:         *   <li>An argument consisting only of two hyphens (<code>"--"</code>) signals that the
036:         *   remaining arguments are to be treated as non-options.</li>
037:         *
038:         *   <li>An argument consisting only of a single hyphen is considered a non-option
039:         *   argument (though it can be an argument of an option).  Many Unix programs treat
040:         *   single hyphens as stand-ins for the standard input or standard output streams.</li>
041:         *
042:         *   <li><dfn>Long options</dfn> generally begin with two hyphens (<code>"--"</code>),
043:         *   followed by multiple letters and/or digits.</li>
044:         *
045:         *   <li>You can abbreviate long options, so long as the abbreviation is unique.</li>
046:         *
047:         *   <li>Long options can accept single arguments.  The argument can be made required or
048:         *   optional.  The option can occur in:
049:         *     <ul>
050:         *       <li>the argument after the option, as in <code>--directory /tmp</code></li>
051:         *       <li>right up against it separated by an equals sign (<code>"="</code>), as in
052:         *         <code>--directory=/tmp</code>
053:         *     </ul>
054:         *   </li>
055:         *
056:         *   <li>You can use a single hyphen (<code>"-"</code>) instead of a double hyphen
057:         *   (<code>"--"</code>) for a long option.</li>
058:         *
059:         *   <li>The option <code>-W</code> is reserved.  If you tell the parser to {@linkplain
060:         *   #recognizeAlternativeLongOptions(boolean) recognize alternative long options}, then
061:         *   it will treat, for example, <code>-W foo=bar</code> as the long option
062:         *   <code>foo</code> with argument <code>bar</code>, as though you had written
063:         *   <code>--foo=bar</code>.</li>
064:         *
065:         *   <li>You can specify <code>-W</code> as a valid short option, or use it as an
066:         *   abbreviation for a long option, but {@linkplain
067:         *   #recognizeAlternativeLongOptions(boolean) recognizing alternative long options} will
068:         *   always supersede this behavior.</li>
069:         *
070:         *   <li>You can specify a given short or long option multiple times on a single command
071:         *   line.  The parser collects any arguments specified for those options as a list.</li>
072:         *
073:         *   <li>If the parser detects an option whose argument is optional, and the next argument
074:         *   "looks like" an option, that argument is not treated as the argument to the option,
075:         *   but as a potentially valid option.  If, on the other hand, the optional argument is
076:         *   typed as a derivative of {@link Number}, then that argument is treated as the
077:         *   negative number argument of the option, even if the parser recognizes the
078:         *   corresponding numeric option.  For example:
079:         *   <pre>
080:         *     parser.accepts( "a" ).withOptionalArg().ofType( Integer.class );
081:         *     parser.accepts( "1" );
082:         *     OptionSet options = parser.parse( new String[] { "-a", "-1" } );
083:         *   </pre>
084:         *   In this case, the option set contains <code>"a"</code> with argument <code>-1</code>,
085:         *   not both <code>"a"</code> and <code>"1"</code>.  Swapping the elements in the
086:         *   <var>args</var> array gives the latter.</li>
087:         * </ul>
088:         *
089:         * <p>There are two ways to tell the parser what options to recognize:</p>
090:         *
091:         * <ol>
092:         *   <li>A "domain-specific language"-style API for specifying options, available since
093:         *   version 2.  Sentences in this domain-specific language begin with a call to
094:         *   {@link #accepts(String) accepts}; methods on the ensuing chain of objects describe
095:         *   whether the option passed to {@link #accepts(String) accepts} can take an argument,
096:         *   whether the argument is required or optional, and to what type arguments of the
097:         *   option should be converted.</li>
098:         *
099:         *   <li>Since version 1, a more concise way of specifying short options to recognize has
100:         *   been to use the special {@linkplain #OptionParser(String) constructor}.  Arguments
101:         *   of options specified in this manner will be of type {@link String}.  Here are the
102:         *   rules for the format of the specification strings this constructor accepts:
103:         *
104:         *     <ul>
105:         *         <li>Any letter or digit is treated as an option character.</li>
106:         *
107:         *         <li>If an option character is followed by a single colon (<code>":"</code>),
108:         *         then the option requires an argument.</li>
109:         *
110:         *         <li>If an option character is followed by two colons (<code>"::"</code>), then
111:         *         the option accepts an optional argument.</li>
112:         *
113:         *         <li>Otherwise, the option character accepts no argument.</li>
114:         *
115:         *         <li>If the option specification string begins with a plus sign
116:         *         (<code>"+"</code>), the parser will behave "POSIX-ly correct".</li>
117:         *
118:         *         <li>If the option specification string contains the sequence <code>"W;"</code>
119:         *         (capital W followed by a semicolon), the parser will recognize the alternative
120:         *         form of long options.</li>
121:         *     </ul>
122:         *   </li>
123:         * </ol>
124:         *
125:         * <p>By default, as with GNU <code>getopt()</code>, the parser allows intermixing of
126:         * options and non-options.  If, however, the parser has been created to be "POSIX-ly
127:         * correct", then the first argument that does not look lexically like an option, and
128:         * is not a required argument of a preceding option, signals the end of options.
129:         * You can still bind optional arguments to their options using the abutting (for short
130:         * options) or <code>=</code> syntax.</p>
131:         *
132:         * <p>
133:         * Unlike GNU <code>getopt()</code>, this parser does not honor the
134:         * environment variable <code>POSIXLY_CORRECT</code>.  "POSIX-ly correct" parsers are
135:         * configured by either:</p>
136:         *
137:         * <ol>
138:         *   <li>using the method {@link #setPosixlyCorrect(boolean)}, or</li>
139:         *
140:         *   <li>using the {@linkplain #OptionParser(String) constructor} with an argument whose
141:         *   first character is a plus sign (<code>"+"</code>)</li>
142:         * </ol>
143:         *
144:         * @since 1.0
145:         * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
146:         * @version $Id: OptionParser.java,v 1.42 2007/04/21 22:24:58 pholser Exp $
147:         * @see <a href="http://www.gnu.org/software/libc/manual">The GNU C Library </a>
148:         */
149:        public class OptionParser {
150:            private final AbbreviationMap recognizedOptions;
151:            private OptionParserState state;
152:            private boolean posixlyCorrect;
153:
154:            /**
155:             * Creates an option parser that initially recognizes no options, and does not exhibit
156:             * "POSIX-ly correct" behavior.
157:             *
158:             * @since 1.0
159:             */
160:            public OptionParser() {
161:                recognizedOptions = new AbbreviationMap();
162:                state = new MoreOptionsParserState(false);
163:            }
164:
165:            /**
166:             * Creates an option parser and configures it to recognize the short options specified
167:             * in the given string.
168:             * <p/>
169:             * Arguments of options specified this way will be of type {@link String}.
170:             *
171:             * @since 1.0
172:             * @param optionSpecification an option specification
173:             * @throws NullPointerException if <code>optionSpecification</code> is
174:             * <code>null</code>
175:             */
176:            public OptionParser(String optionSpecification) {
177:                this ();
178:
179:                new OptionSpecTokenizer(optionSpecification).configure(this );
180:            }
181:
182:            /**
183:             * Tells the parser to recognize the given option.
184:             * <p/>
185:             * This method returns an instance of {@link OptionSpecBuilder} to allow the
186:             * formation of parser directives as sentences in a domain-specific language.
187:             * For example:
188:             * <pre>
189:             *   OptionParser parser = new OptionParser();
190:             *   parser.<strong>accepts( "c" )</strong>.withRequiredArg().ofType( Integer.class );
191:             * </pre>
192:             * If no methods are invoked on the returned {@link OptionSpecBuilder}, then the
193:             * parser treats the option as accepting no argument.
194:             *
195:             * @since 2.0
196:             * @param option the option to recognize
197:             * @return an object that can be used to flesh out more detail about the option
198:             * @throws OptionException if the option contains illegal characters
199:             * @throws NullPointerException if the option is <code>null</code>
200:             */
201:            public OptionSpecBuilder accepts(String option) {
202:                return accepts(option, "");
203:            }
204:
205:            /**
206:             * Tells the parser to recognize the given option.
207:             *
208:             * @since 2.1
209:             * @see #accepts(String)
210:             * @param option the option to recognize
211:             * @param description a string that describes the purpose of the option.  This is
212:             * used when generating help information about the parser.
213:             * @return an object that can be used to flesh out more detail about the option
214:             * @throws OptionException if the option contains illegal characters
215:             * @throws NullPointerException if the option is <code>null</code>
216:             */
217:            public OptionSpecBuilder accepts(String option, String description) {
218:                ParserRules.checkLegalOption(option);
219:
220:                return new OptionSpecBuilder(this , option, description);
221:            }
222:
223:            /**
224:             * Tells the parser whether or not to behave "POSIX-ly correct"-ly.
225:             *
226:             * @since 1.0
227:             * @param posixlyCorrect <code>true</code> if the parser should behave "POSIX-ly
228:             * correct"-ly
229:             */
230:            public void setPosixlyCorrect(boolean posixlyCorrect) {
231:                this .posixlyCorrect = posixlyCorrect;
232:                state = new MoreOptionsParserState(posixlyCorrect);
233:            }
234:
235:            boolean isPosixlyCorrect() {
236:                return posixlyCorrect;
237:            }
238:
239:            /**
240:             * Tells the parser either to recognize or ignore <code>"-W"</code>-style long
241:             * options.
242:             *
243:             * @since 1.0
244:             * @param recognize <code>true</code> if the parser is to recognize the special style
245:             * of long options
246:             */
247:            public void recognizeAlternativeLongOptions(boolean recognize) {
248:                if (recognize)
249:                    recognize(new AlternativeLongOptionSpec());
250:                else
251:                    recognizedOptions.remove(String
252:                            .valueOf(ParserRules.RESERVED_FOR_EXTENSIONS));
253:            }
254:
255:            void recognize(OptionSpec spec) {
256:                recognizedOptions.put(spec.option(), spec);
257:            }
258:
259:            /**
260:             * Writes information about the options this parser recognizes to the given output
261:             * sink.
262:             *
263:             * @since 2.1
264:             * @param sink the sink to write information to
265:             * @throws IOException if there is a problem writing to the sink
266:             * @throws NullPointerException if <code>sink</code> is <code>null</code>
267:             */
268:            public void printHelpOn(OutputStream sink) throws IOException {
269:                OutputStreamWriter writer = null;
270:
271:                try {
272:                    writer = new OutputStreamWriter(sink);
273:                    printHelpOn(writer);
274:                } finally {
275:                    if (writer != null)
276:                        writer.close();
277:                }
278:            }
279:
280:            /**
281:             * Writes information about the options this parser recognizes to the given output
282:             * sink.
283:             *
284:             * @since 2.1
285:             * @param sink the sink to write information to
286:             * @throws IOException if there is a problem writing to the sink
287:             * @throws NullPointerException if <code>sink</code> is <code>null</code>
288:             */
289:            public void printHelpOn(Writer sink) throws IOException {
290:                sink.write(new OptionParserHelpFormatter()
291:                        .format(recognizedOptions.toJavaUtilMap()));
292:            }
293:
294:            /**
295:             * Parses the given command line arguments according to the option specifications
296:             * given to the parser.
297:             *
298:             * @since 1.0
299:             * @param arguments arguments to parse
300:             * @return an {@link OptionSet} describing the parsed options, their arguments, and
301:             * any non-option arguments found
302:             * @throws OptionException if problems are detected while parsing
303:             * @throws NullPointerException if the argument list is <code>null</code>
304:             */
305:            public OptionSet parse(String[] arguments) {
306:                ArgumentList argumentList = new ArgumentList(arguments);
307:                OptionSet detected = new OptionSet();
308:
309:                while (argumentList.hasMore())
310:                    state.handleArgument(this , argumentList, detected);
311:
312:                reset();
313:                return detected;
314:            }
315:
316:            void handleLongOptionToken(String candidate,
317:                    ArgumentList arguments, OptionSet detected) {
318:
319:                KeyValuePair optionAndArgument = parseLongOptionWithArgument(candidate);
320:
321:                if (!isRecognized(optionAndArgument.key))
322:                    throw new UnrecognizedOptionException(optionAndArgument.key);
323:
324:                OptionSpec optionSpec = specFor(optionAndArgument.key);
325:                optionSpec.handleOption(this , arguments, detected,
326:                        optionAndArgument.value);
327:            }
328:
329:            void handleShortOptionToken(String candidate,
330:                    ArgumentList arguments, OptionSet detected) {
331:
332:                KeyValuePair optionAndArgument = parseShortOptionWithArgument(candidate);
333:
334:                if (isRecognized(optionAndArgument.key)) {
335:                    specFor(optionAndArgument.key).handleOption(this ,
336:                            arguments, detected, optionAndArgument.value);
337:                } else
338:                    handleShortOptionCluster(candidate, arguments, detected);
339:            }
340:
341:            private void handleShortOptionCluster(String candidate,
342:                    ArgumentList arguments, OptionSet detected) {
343:
344:                char[] options = extractShortOptionsFrom(candidate);
345:                validateOptionCharacters(options);
346:
347:                OptionSpec optionSpec = specFor(options[0]);
348:
349:                if (optionSpec.acceptsArguments() && options.length > 1) {
350:                    String detectedArgument = String.valueOf(options, 1,
351:                            options.length - 1);
352:                    optionSpec.handleOption(this , arguments, detected,
353:                            detectedArgument);
354:                } else {
355:                    for (int i = 0; i < options.length; ++i)
356:                        specFor(options[i]).handleOption(this , arguments,
357:                                detected, null);
358:                }
359:            }
360:
361:            void noMoreOptions() {
362:                state = new NoMoreOptionsParserState();
363:            }
364:
365:            boolean looksLikeAnOption(String argument) {
366:                return ParserRules.isShortOptionToken(argument)
367:                        || ParserRules.isLongOptionToken(argument);
368:            }
369:
370:            private boolean isRecognized(String option) {
371:                return recognizedOptions.contains(option);
372:            }
373:
374:            private OptionSpec specFor(char option) {
375:                return specFor(String.valueOf(option));
376:            }
377:
378:            private OptionSpec specFor(String option) {
379:                return (OptionSpec) recognizedOptions.get(option);
380:            }
381:
382:            private void reset() {
383:                state = new MoreOptionsParserState(posixlyCorrect);
384:            }
385:
386:            private static char[] extractShortOptionsFrom(String argument) {
387:                char[] options = new char[argument.length() - 1];
388:                argument.getChars(1, argument.length(), options, 0);
389:
390:                return options;
391:            }
392:
393:            private void validateOptionCharacters(char[] options) {
394:                for (int i = 0; i < options.length; ++i) {
395:                    String option = String.valueOf(options[i]);
396:
397:                    if (!isRecognized(option))
398:                        throw new UnrecognizedOptionException(option);
399:
400:                    if (specFor(option).acceptsArguments()) {
401:                        if (i > 0)
402:                            throw new IllegalOptionClusterException(option);
403:
404:                        // remainder of chars are the argument to the option at char 0
405:                        return;
406:                    }
407:                }
408:            }
409:
410:            private static KeyValuePair parseLongOptionWithArgument(
411:                    String argument) {
412:                return KeyValuePair.parse(argument.substring(2));
413:            }
414:
415:            private static KeyValuePair parseShortOptionWithArgument(
416:                    String argument) {
417:                return KeyValuePair.parse(argument.substring(1));
418:            }
419:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.