1 mike 1.1 //BEGIN_LICENSE
2 //
3 // Copyright (c) 2000 The Open Group, BMC Software, Tivoli Systems, IBM
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a
6 // copy of this software and associated documentation files (the "Software"),
7 // to deal in the Software without restriction, including without limitation
8 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 // and/or sell copies of the Software, and to permit persons to whom the
10 // Software is furnished to do so, subject to the following conditions:
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
15 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18 // DEALINGS IN THE SOFTWARE.
19 //
20 //END_LICENSE
21 //BEGIN_HISTORY
22 mike 1.1 //
23 // Author: Michael E. Brasher
24 //
|
25 mike 1.2 // $Log: OptionManager.h,v $
26 // Revision 1.1 2001/04/14 01:52:45 mike
27 // New option management class.
28 //
|
29 mike 1.1 //
30 //END_HISTORY
31
32 #ifndef Pegasus_OptionManager_h
33 #define Pegasus_OptionManager_h
34
35 #include <Pegasus/Common/Config.h>
36 #include <Pegasus/Common/String.h>
37 #include <Pegasus/Common/Array.h>
38
39 PEGASUS_NAMESPACE_BEGIN
40
41 class Option;
42
43 /** The OptionManager class manages a collection of program options.
44
45 <h4>Overview</h4>
46
47 A program option may be specified in one of three ways:
48
49 <ul>
50 mike 1.1 <li>As an environment variable</li>
51 <li>In a configuration file</li>
52 <li>On the command line</li>
53 </ul>
54
55 This class provides methods for merging options from all three of these
56 sources into a single unified collection. The following example showss
57 how to merge options from a command line into the option manager.
58
59 <pre>
60 int main(int argc, char** argv)
61 {
62 OptionManager om;
63
64 ...
65
66 // Merge options from the command line into the option manager's
67 // option list. Remove arguments from command line.
68
69 om.mergeCommandLine(argc, argv);
70
71 mike 1.1 ...
72 }
73 </pre>
74
75 Methods are also provided for merging options from files and the environment
76 (see OptionManager::mergeFile(), OptionManager::mergeEnvironment()).
77
78 Before options are merged into the option manager, information on each
79 option must be registered with the option manager so that the following
80 can be resolved:
81
82 <ul>
83 <li>The option's name</li>
84 <li>The default value (to be used if not specified elsewhere)</li>
85 <li>Whether the option is required</li>
|
86 mike 1.2 <li>The option's type (e.g., boolean, integer or string)</li>
|
87 mike 1.1 <li>The domain of the option if any (set of legal values)</li>
88 <li>The name the option as it appears as an environment variable</li>
89 <li>The name the option as it appears in a configuration file</li>
90 <li>The name the option as it appears on the command line</li>
91 </ul>
92
93 Here is how to regsiter an option:
94
95 <pre>
96 OptionManager om;
97
98 Option* option = new Option("port", "80", false, Option::INTEGER,
|
99 mike 1.2 Array<String>(), "PEGASUS_PORT", "PORT", "p");
|
100 mike 1.1
101 om.registerOption(option);
102 </pre>
103
104 The arguments of the Option constructor are the same (and in the same
|
105 mike 1.2 order) as the list just above. Notice that option name is "port", Whereas
106 the environment variable is named "PEGASUS_PORT" and the option name
107 in the configuration file is "port" and the command line option argument
108 name is "p" (will appear as -p on the command line).
|
109 mike 1.1
110 Once options have been registered, the option values may be obtained using
111 the merge methods described earlier. During merging, certain validation is
112 done using the corresponding Option instance described above.
113
114 Once options have been merged, they may obtained by calling the
115 lookupOption() method like this:
116
117 <pre>
118 Option* option = om.lookupOption("port");
119
120 String port = option->getValue();
121 </pre>
122
123 <h4>Command Line Options</h4>
124
125 To merge option values from the command line argument, call
126 mergeCommandLine() like this:
127
128 <pre>
129 om.mergeCommandLine(argc, argv);
130 mike 1.1 </pre>
131
132 This method searches the command line for options that match the registered
133 ones. It will extract those options from the command line (argc and argv
134 will be modified accordingly).
135
136 <h4>Configuration File Otpions</h4>
137
138 Options from a configuration file may be merged by calling the mergeFile()
139 method like this:
140
141 <pre>
142 om.mergeFile(fileName);
143 </pre>
144
145 This searches the file for options matching registered ones. Exceptions
146 are thrown for any unrecognized option names that are encountered.
147
148 <h4>Environment Variable Options</h4>
149
150 The mergeEnvironment() method merges options from the enviroment space of
151 mike 1.1 the process.
152
153 <h4>Merge Validation</h4>
154
155 During merging, the option manager validates the following (using the
156 information optatined during option registration).
157
158 <ul>
159 <li>The type of the option - whether integer, positive integer,
160 or string.</li>
161 <li>The domain of the option - whether the supplied option is a legal
162 value for that otpion</li>
163 <li>User extended validation - whether the user overriden
164 Option::isValid() returns true when the value is passed to it</li>
165 </ul>
|
166 mike 1.2
167 <h4>Typcial Usage</h4>
168
169 The OptionManager is typically used in the following way. First, options
170 are registered to establish the valid set of options. Next, values are
171 merged from the various sources by calling the merge functions. Finally,
172 checkRequiredOptions() is called to see if any required option values were
173 not provided.
|
174 mike 1.1 */
|
175 mike 1.2 class PEGASUS_COMMON_LINKAGE OptionManager
|
176 mike 1.1 {
177 public:
178
179 /** Constructor. */
180 OptionManager();
181
182 /** Destructor. Deletes all contained Options. */
183 ~OptionManager();
184
185 /** Registers an option. The OptionManager is responsible for disposing
186 of the option; the caller must not delete this object.
187
188 @param option - option to be registerd.
189 @return false if an option with same name already registered.
190 */
191 Boolean registerOption(Option* option);
192
193 /** Merge option values from the command line. Searches the command
194 line for registered options whose names are given by the
195 Option::getCommandLineOptionName() method. Validation is performed
196 on each option value obtained by calling Option::isValid(). Valid
197 mike 1.1 option values are set by calling Option::setValue(). The argc and
198 argv arguments are modified: the option and its argument are
199 stripped from the command line. The option and its argument have the
200 following form: -option-name argument. A space must be supplied
201 between the two. Boolean option arguments are an exception. They
202 must have the form -option. If they are present, then they are
203 taken to be true.
204
205 ¶m argc - number of argument on the command line.
206 ¶m argv - list of command line arguments.
207 &throw BadCommandLineOption when validation fails.
208 */
209 void mergeCommandLine(int& argc, char**& argv);
210
211 /** Merge option values from the environment. Searches the environment
212 for registered options whose names are given by the
213 Option::getEnvironmentVariableName() method. Validation is performed
214 on each option value obtained by calling Option::isValid(). Valid
215 option values are set by calling Option::setValue().
216
217 &throw BadEnvironmentOption when validation fails.
218 mike 1.1 */
219 void mergeEnvironment();
220
221 /** Merge option values from a file. Searches file for registered options
222 whose names are given by the Option::getEnvironmentVariableName()
223 method. Validation is performed on each option value by calling
224 Option::isValid(). Valid option values are set by calling
225 Option::setValue().
226
227 ¶m fileName - name of file to be merged.
228 &throw NoSuchFile
229 &throw BadConfigFileOption
230 */
231 void mergeFile(const String& fileName);
232
233 /** After merging, this method is called to check for required options
234 that were not merged (specified).
235
236 &throw UnspecifiedRequiredOption
237 */
238 void checkRequiredOptions() const;
239 mike 1.1
|
240 mike 1.2 /** Lookup the option with the given name.
241 */
242 const Option* lookupOption(const String& optionName) const;
243
|
244 mike 1.1 private:
245
246 Array<Option*> _options;
247 };
248
249 /** The Option class is used to specify information about an Option.
250
251 See the OptionManager class for more details.
252 */
|
253 mike 1.2 class PEGASUS_COMMON_LINKAGE Option
|
254 mike 1.1 {
255 public:
256
257 /** Valid value types. */
258 enum Type { BOOLEAN, INTEGER, POSITIVE_INTEGER, STRING };
259
260 // Hack to fix bug in MSVC.
261 typedef Array<String> StringArray;
262
263 /** Constructor.
264
265 @param optionName - the name of this option.
266
267 @param defaultValue - the default value of this option.
268
269 @param required - whether the value of this option is required.
270
271 @param type - type of the value. This is used to validate the value.
272
273 @param domain - list of legal value for this option. If this list
274 is empty, then no domain is enforced.
275 mike 1.1
276 @param environmentVariableName - name of the corresponding environment
277 variable (which may be different from the option name).
278
279 @param configFileVariableName - name of the corresponding variable
280 in the config file (which may be different from the option name).
281
282 @param commandLineOptionName - name of the corresponding command line
283 option (which may be different from the option name).
284 */
285 Option(
286 const String& optionName,
287 const String& defaultValue,
288 Boolean required,
289 Type type,
290 const StringArray& domain = StringArray(),
291 const String& environmentVariableName = String(),
292 const String& configFileVariableName = String(),
|
293 mike 1.2 const String& commandLineOptionName = String());
294
295 Option(const Option& x);
|
296 mike 1.1
297 virtual ~Option();
298
|
299 mike 1.2 Option& operator=(const Option& x);
|
300 mike 1.1
301 /** Accessor */
302 const String& getOptionName() const
303 {
304 return _optionName;
305 }
306
307 /** Modifier */
308 void setOptionName(const String& optionName)
309 {
310 _optionName = optionName;
311 }
312
313 /** Accessor */
314 const String& getDefaultValue() const
315 {
316 return _defaultValue;
317 }
318
319 /** Modifier. */
320 void setDefaultValue(const String& defaultValue)
321 mike 1.1 {
322 _defaultValue = defaultValue;
323 }
324
325 /** Accessor */
326 const String& getValue() const
327 {
328 return _value;
329 }
330
331 /** Modifier */
332 void setValue(const String& value)
333 {
334 _value = value;
335 }
336
337 /** Accessor */
338 Boolean getRequired() const
339 {
340 return _required;
341 }
342 mike 1.1
343 /** Modifier */
344 void setRequired(Boolean required)
345 {
346 _required = required;
347 }
348
349 /** Accessor */
350 Type getType() const
351 {
352 return _type;
353 }
354
355 /** Modifier */
356 void setType(Type type)
357 {
358 _type = type;
359 }
360
361 /** Accessor */
362 const StringArray& getDomain() const
363 mike 1.1 {
364 return _domain;
365 }
366
367 /** Modifier */
368 void setDomain(const StringArray& domain)
369 {
370 _domain = domain;
371 }
372
373 /** Accessor */
374 const String& getEnvironmentVariableName() const
375 {
376 return _environmentVariableName;
377 }
378
379 /** Modifier */
380 void setEnvironmentVariableName(const String& environmentVariableName)
381 {
382 _environmentVariableName = environmentVariableName;
383 }
384 mike 1.1
385 /** Accessor */
386 const String& getConfigFileVariableName() const
387 {
388 return _configFileVariableName;
389 }
390
391 /** Modifier */
392 void setConfigFileVariableName(const String& configFileVariableName)
393 {
394 _configFileVariableName = configFileVariableName;
395 }
396
397 /** Accessor */
398 const String& getCommandLineOptionName() const
399 {
400 return _commandLineOptionName;
401 }
402
403 /** Modifier */
404 void setCommandLineOptionName(const String& commandLineOptionName)
405 mike 1.1 {
406 _commandLineOptionName = commandLineOptionName;
407 }
408
409 /** Accesor. Returns true if an option value was ever obtained for
410 this option.
411 */
412 Boolean foundValue() const
413 {
414 return _foundValue;
415 }
416
417 /** Checks to see if the given value is valid or not. This method may be
418 overriden by derived classes to do special purpose validation of the
419 value. This implementation just checks the domain and type.
420 */
421 virtual Boolean isValid(const String& value) const;
422
423 private:
424 String _optionName;
425 String _defaultValue;
426 mike 1.1 String _value;
427 Boolean _required;
428 Type _type;
429 StringArray _domain;
430 String _environmentVariableName;
431 String _configFileVariableName;
432 String _commandLineOptionName;
433 Boolean _foundValue;
434 };
435
436 PEGASUS_NAMESPACE_END
437
438 #endif /* Pegasus_OptionManager_h */
|