1 /***
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.cli;
18
19 /***
20 * <p>
21 * Allows Options to be created from a single String.
22 * The pattern contains various single character flags and via
23 * an optional punctuation character, their expected type.
24 * </p>
25 *
26 * <table border="1">
27 * <tr><td>a</td><td>-a flag</td></tr>
28 * <tr><td>b@</td><td>-b [classname]</td></tr>
29 * <tr><td>c></td><td>-c [filename]</td></tr>
30 * <tr><td>d+</td><td>-d [classname] (creates object via empty contructor)</td></tr>
31 * <tr><td>e%</td><td>-e [number] (creates Double/Long instance depeding on existing of a '.')</td></tr>
32 * <tr><td>f/</td><td>-f [url]</td></tr>
33 * <tr><td>g:</td><td>-g [string]</td></tr>
34 * </table>
35 *
36 * <p>
37 * For example, the following allows command line flags of '-v -p string-value -f /dir/file'.
38 * </p>
39 * <code>Options options = PatternOptionBuilder.parsePattern("vp:f/");</code>
40 *
41 * <p>
42 * TODO These need to break out to OptionType and also
43 * to be pluggable.
44 * </p>
45 *
46 * @author Henri Yandell (bayard @ generationjava.com)
47 * @version $Revision: 542144 $
48 */
49 public class PatternOptionBuilder {
50
51 /*** String class */
52 public static final Class STRING_VALUE = java.lang.String.class;
53
54 /*** Object class */
55 public static final Class OBJECT_VALUE = java.lang.Object.class;
56
57 /*** Number class */
58 public static final Class NUMBER_VALUE = java.lang.Number.class;
59
60 /*** Date class */
61 public static final Class DATE_VALUE = java.util.Date.class;
62
63 /*** Class class */
64 public static final Class CLASS_VALUE = java.lang.Class.class;
65
66
67
68
69
70 /*** FileInputStream class */
71 public static final Class EXISTING_FILE_VALUE =
72 java.io.FileInputStream.class;
73
74 /*** File class */
75 public static final Class FILE_VALUE = java.io.File.class;
76
77 /*** File array class */
78 public static final Class FILES_VALUE = java.io.File[].class;
79
80 /*** URL class */
81 public static final Class URL_VALUE = java.net.URL.class;
82
83 /***
84 * <p>Retrieve the class that <code>ch</code> represents.</p>
85 *
86 * @param ch the specified character
87 * @return The class that <code>ch</code> represents
88 */
89 public static Object getValueClass(char ch)
90 {
91 if (ch == '@')
92 {
93 return PatternOptionBuilder.OBJECT_VALUE;
94 }
95 else if (ch == ':')
96 {
97 return PatternOptionBuilder.STRING_VALUE;
98 }
99 else if (ch == '%')
100 {
101 return PatternOptionBuilder.NUMBER_VALUE;
102 }
103 else if (ch == '+')
104 {
105 return PatternOptionBuilder.CLASS_VALUE;
106 }
107 else if (ch == '#')
108 {
109 return PatternOptionBuilder.DATE_VALUE;
110 }
111 else if (ch == '<')
112 {
113 return PatternOptionBuilder.EXISTING_FILE_VALUE;
114 }
115 else if (ch == '>')
116 {
117 return PatternOptionBuilder.FILE_VALUE;
118 }
119 else if (ch == '*')
120 {
121 return PatternOptionBuilder.FILES_VALUE;
122 }
123 else if (ch == '/')
124 {
125 return PatternOptionBuilder.URL_VALUE;
126 }
127
128 return null;
129 }
130
131 /***
132 * <p>Returns whether <code>ch</code> is a value code, i.e.
133 * whether it represents a class in a pattern.</p>
134 *
135 * @param ch the specified character
136 * @return true if <code>ch</code> is a value code, otherwise false.
137 */
138 public static boolean isValueCode(char ch)
139 {
140 if ((ch != '@') && (ch != ':') && (ch != '%') && (ch != '+')
141 && (ch != '#') && (ch != '<') && (ch != '>') && (ch != '*')
142 && (ch != '/') && (ch != '!'))
143 {
144 return false;
145 }
146
147 return true;
148 }
149
150 /***
151 * <p>Returns the {@link Options} instance represented by
152 * <code>pattern</code>.</p>
153 *
154 * @param pattern the pattern string
155 * @return The {@link Options} instance
156 */
157 public static Options parsePattern(String pattern)
158 {
159 int sz = pattern.length();
160
161 char opt = ' ';
162 char ch = ' ';
163 boolean required = false;
164 Object type = null;
165
166 Options options = new Options();
167
168 for (int i = 0; i < sz; i++)
169 {
170 ch = pattern.charAt(i);
171
172
173
174 if (!isValueCode(ch))
175 {
176 if (opt != ' ')
177 {
178 OptionBuilder.hasArg(type != null);
179 OptionBuilder.isRequired(required);
180 OptionBuilder.withType(type);
181
182
183 options.addOption(OptionBuilder.create(opt));
184 required = false;
185 type = null;
186 opt = ' ';
187 }
188
189 opt = ch;
190 }
191 else if (ch == '!')
192 {
193 required = true;
194 }
195 else
196 {
197 type = getValueClass(ch);
198 }
199 }
200
201 if (opt != ' ')
202 {
203 OptionBuilder.hasArg(type != null);
204 OptionBuilder.isRequired(required);
205 OptionBuilder.withType(type);
206
207
208 options.addOption(OptionBuilder.create(opt));
209 }
210
211 return options;
212 }
213 }