View Javadoc

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.cli2.builder;
18  
19  import java.util.Iterator;
20  import java.util.LinkedHashSet;
21  import java.util.Set;
22  
23  import org.apache.commons.cli2.Argument;
24  import org.apache.commons.cli2.Option;
25  import org.apache.commons.cli2.validation.ClassValidator;
26  import org.apache.commons.cli2.validation.DateValidator;
27  import org.apache.commons.cli2.validation.FileValidator;
28  import org.apache.commons.cli2.validation.NumberValidator;
29  import org.apache.commons.cli2.validation.UrlValidator;
30  import org.apache.commons.cli2.validation.Validator;
31  
32  /**
33   * Builds Options using a String pattern
34   */
35  //TODO Document and link to the acceptable patterns
36  public class PatternBuilder {
37  
38      private final GroupBuilder gbuilder;
39      private final DefaultOptionBuilder obuilder;
40      private final ArgumentBuilder abuilder;
41  
42      /**
43       * Creates a new PatternBuilder
44       */
45      public PatternBuilder() {
46          this(
47              new GroupBuilder(),
48              new DefaultOptionBuilder(),
49              new ArgumentBuilder());
50      }
51  
52      /**
53       * Creates a new PatternBuilder
54       * @param gbuilder the GroupBuilder to use
55       * @param obuilder the DefaultOptionBuilder to use
56       * @param abuilder the ArgumentBuilder to use
57       */
58      public PatternBuilder(
59          final GroupBuilder gbuilder,
60          final DefaultOptionBuilder obuilder,
61          final ArgumentBuilder abuilder) {
62          this.gbuilder = gbuilder;
63          this.obuilder = obuilder;
64          this.abuilder = abuilder;
65      }
66  
67      private final Set options = new LinkedHashSet();
68  
69      /**
70       * Creates a new Option instance.
71       * @return a new Option instance
72       */
73      public Option create() {
74          final Option option;
75  
76          if (options.size() == 1) {
77              option = (Option)options.iterator().next();
78          }
79          else {
80              gbuilder.reset();
81              for (final Iterator i = options.iterator(); i.hasNext();) {
82                  gbuilder.withOption((Option)i.next());
83              }
84              option = gbuilder.create();
85          }
86  
87          reset();
88  
89          return option;
90      }
91  
92      /**
93       * Resets this builder.
94       * @return this builder
95       */
96      public PatternBuilder reset() {
97          options.clear();
98          return this;
99      }
100 
101     private void createOption(
102         final char type,
103         final boolean required,
104         final char opt) {
105         final Argument argument;
106         if (type != ' ') {
107             abuilder.reset();
108             abuilder.withValidator(validator(type));
109             if (required) {
110                 abuilder.withMinimum(1);
111             }
112             if (type != '*') {
113                 abuilder.withMaximum(1);
114             }
115             argument = abuilder.create();
116         }
117         else {
118             argument = null;
119         }
120 
121         obuilder.reset();
122         obuilder.withArgument(argument);
123         obuilder.withShortName(String.valueOf(opt));
124         obuilder.withRequired(required);
125 
126         options.add(obuilder.create());
127     }
128 
129     /**
130      * Builds an Option using a pattern string.
131      * @param pattern the pattern to build from
132      */
133     public void withPattern(final String pattern) {
134         int sz = pattern.length();
135 
136         char opt = ' ';
137         char ch = ' ';
138         char type = ' ';
139         boolean required = false;
140 
141         for (int i = 0; i < sz; i++) {
142             ch = pattern.charAt(i);
143 
144             switch (ch) {
145                 case '!' :
146                     required = true;
147                     break;
148                 case '@' :
149                 case ':' :
150                 case '%' :
151                 case '+' :
152                 case '#' :
153                 case '<' :
154                 case '>' :
155                 case '*' :
156                 case '/' :
157                     type = ch;
158                     break;
159                 default :
160                     if (opt != ' ') {
161                         createOption(type, required, opt);
162                         required = false;
163                         type = ' ';
164                     }
165 
166                     opt = ch;
167             }
168         }
169 
170         if (opt != ' ') {
171             createOption(type, required, opt);
172         }
173     }
174 
175     private static Validator validator(final char c) {
176         switch (c) {
177             case '@' :
178                 final ClassValidator classv = new ClassValidator();
179                 classv.setInstance(true);
180                 return classv;
181             case '+' :
182                 final ClassValidator instancev = new ClassValidator();
183                 return instancev;
184                 //case ':':// no validator needed for a string
185             case '%' :
186                 return NumberValidator.getNumberInstance();
187             case '#' :
188                 return DateValidator.getDateInstance();
189             case '<' :
190                 final FileValidator existingv = new FileValidator();
191                 existingv.setExisting(true);
192                 existingv.setFile(true);
193                 return existingv;
194             case '>' :
195             case '*' :
196                 return new FileValidator();
197             case '/' :
198                 return new UrlValidator();
199             default :
200                 return null;
201         }
202     }
203 }