Package org.tquadrat.foundation.config.cli
The API for the Command Line Interface (CLI) can also be used without the annotation processor, in two different ways, as described below.
Unless otherwise stated, null
argument values will cause methods
and constructors of all classes in this package to throw an
Exception
,
usually a
NullArgumentException
,
but in some rare cases, it could be also a
NullPointerException
.
The Code Approach
The API can be used directly from the code, without any external configuration. This may look like this:
201… 202import static org.tquadrat.foundation.ui.spi.ConfigUtil.parseCommandLine; 203import static org.tquadrat.foundation.ui.spi.ConfigUtil.printUsage; 204 205import java.io.IOException; 206import java.util.ArrayList; 207import java.util.List; 208import java.util.Optional; 209import java.util.function.BiConsumer; 210 211import org.tquadrat.foundation.ui.spi.CLIArgumentDefinition; 212import org.tquadrat.foundation.ui.spi.CLIDefinition; 213import org.tquadrat.foundation.ui.spi.CLIOptionDefinition; 214import org.tquadrat.foundation.ui.spi.CmdLineException; 215import org.tquadrat.foundation.ui.spi.CmdLineValueHandler; 216 217… 218 219/** 220 * The argument value. 221 */ 222private String m_ArgumentValue; 223 224/** 225 * The option value. 226 */ 227private String m_OptionValue; 228 229… 230 231private final boolean execute( final String [] args ) throws IOException 232{ 233 //---* Create the CLI definition *------------------------------------- 234 final BiConsumer<String,String> argumentValueSetter = ($,value) -> m_ArgumentValue = value; 235 final BiConsumer<String,String> optionValueSetter = ($,value) -> m_OptionValue = value; 236 final CmdLineValueHandler<String> argumentHandler = new StringValueHandler( argumentValueSetter ); 237 final CmdLineValueHandler<String> optionHandler = new StringValueHandler( optionValueSetter ); 238 final List<CLIDefinition> cliDefinitions = new ArrayList<>(); 239 cliDefinitions.add( 240 new CLIArgumentDefinition( 241 "argument", // The property name; not used in this context 242 0, // The index for the argument 243 "The value for the argument", // The usage text for the help 244 "MSGKEY_Argument", // The resource bundle key; not used here 245 "ARGUMENT", // The meta variable for the help 246 true, // Arguments are usually required 247 argumentHandler, // The value handler 248 false, // The argument is not multi-value 249 null ) ); // No special format 250 cliDefinitions.add( 251 new CLIOptionDefinition( 252 "option", // The property name; not used in this context 253 List.of( "--option", "-o" ), // The option names 254 "The option", // The usage text for the help 255 "MSGKEY_Option", // The resource bundle key; not used here 256 "VALUE", // The meta variable of the option value for the help 257 false, // Options are usually optional … 258 optionHandler, // The value handler 259 false, // The option value is not multi-value 260 null ) ); // No special format 261 262 //---* Parse the command line *---------------------------------------- 263 var retValue = false; 264 try 265 { 266 parseCommandLine( cliDefinitions, args ); 267 retValue = true; // Success! 268 } 269 catch( final CmdLineException e ) 270 { 271 err.println( e.getLocalizedMessage() ); 272 printUsage( err, Optional.empty(), getClass().getSimpleName(), cliDefinitions ); 273 } 274 275 //---* Done *---------------------------------------------------------- 276 return retValue; 277} // execute() 278 279…
For another sample, refer to the source of { link org.tquadrat.foundation.ui.tools.ShowCLISpec}.
Configuration of the Command Line with XML
The command line can be defined in an XML file that could be provided as
a resource or on the file system; the method
parseCommandLine()
just expects an instance of
InputStream
with the XML. The drawback of this approach is that the value from the
command line will be returned as an instance of
Map<String,Object>
that uses the propertyName
(see the DTD below) as the key, instead
of storing them directly to attributes, making the access less
type-safe.
The XML needs to confirm the DTD below, and it can be validated against the also provided XML Schema file.
Sample code:
201… 201final var cliDefinition = getClass().getResourceAsStream( CLI_DEFINITION_XML ); 202final Map<String,Object> cmdLineData = ConfigUtil.parseCommandLine( cliDefinition, false, args );; 203…
Of course the error handling was omitted here.
The DTD
01<?xml version="1.0" 02 encoding="UTF-8"?> 03 04<!-- 05============================================================================ 06Copyright © 2002-2021 by Thomas Thrien. 07All Rights Reserved. 08============================================================================ 09Licensed to the public under the agreements of the GNU Lesser General Public 10License, version 3.0 (the "License"). You may obtain a copy of the License at 11 12 http://www.gnu.org/licenses/lgpl.html 13 14Unless required by applicable law or agreed to in writing, software distributed 15under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 16CONDITIONS OF ANY KIND, either express or implied. See the License for the 17specific language governing permissions and limitations under the License. 18--> 19<!-- $Id: CLIDefinition.dtd 907 2021-05-05 23:09:17Z tquadrat $ --> 20 21<!-- The definition of a boolean entity --> 22<!ENTITY % boolean "(true|false)"> 23 24<!-- The document definition --> 25<!ELEMENT cliDefinition (option*,argument*)> 26 27<!-- The definition for a CLI Option. 28 29 propertyName The name of the property; this is used to reference the 30 option value inside from the code. 31 type The data type for the option. 32 name The name of the option. 33 handler The fully qualified class name of the value handler for 34 this option; if not provided, it will be inferred from the 35 string converter or the data type itself. 36 isRequired Indicates that the option is required; the default is 37 false. 38 isMultiValue Indicates whether the option may appear multiple times. 39 metaVar A symbolic identifier for the option value that is shown 40 in the help. 41 stringConversion The fully qualified class name of the string converter for 42 this option; if not provided, it will be inferred from the 43 data type. --> 44<!ELEMENT option (alias*,format?,usage?)> 45 <!ATTLIST option 46 propertyName CDATA #REQUIRED 47 type CDATA #REQUIRED 48 name CDATA #REQUIRED 49 handler CDATA #IMPLIED 50 isRequired %boolean; "false" 51 isMultiValue %boolean; "false" 52 metaVar CDATA #IMPLIED 53 stringConversion CDATA #IMPLIED> 54 <!ELEMENT alias EMPTY> 55 <!ATTLIST alias 56 name CDATA #REQUIRED> 57 58<!-- The definition for a CLI Argument. 59 60 propertyName The name of the property; this is used to reference the 61 argument value inside from the code. 62 type The data type for the argument. 63 index The zero based index for the argument on the command line. 64 handler The fully qualified class name of the value handler for 65 this argument; if not provided, it will be inferred from 66 the string converter or the data type itself. 67 isRequired Indicates that the argument is mandatory; the default is 68 true. 69 isMultiValue Indicates that all remaining values on the command line do 70 belong to this argument. 71 metaVar A symbolic identifier for the argument that is shown in 72 the help. 73 stringConversion The fully qualified class name of the string converter for 74 this option; if not provided, it will be inferred from the 75 data type. --> 76<!ELEMENT argument (format?,usage?)> 77 <!ATTLIST argument 78 propertyName CDATA #REQUIRED 79 type CDATA #REQUIRED 80 index CDATA #REQUIRED 81 handler CDATA #IMPLIED 82 isRequired %boolean; "true" 83 isMultiValue %boolean; "false" 84 metaVar CDATA #IMPLIED 85 stringConversion CDATA #IMPLIED> 86 87<!-- The optional format for the argument or option --> 88<!ELEMENT format (#PCDATA)> 89 90<!-- The optional usage message; can be empty. 91 92 key The resource bundle key for the usage message. --> 93<!ELEMENT usage (#PCDATA)> 94 <!ATTLIST usage 95 key CDATA #IMPLIED > 96 97<!-- 98End of file 99-->
The XML Schema
001<?xml version="1.0" encoding="UTF-8"?> 002<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 003 xmlns="http://dtd.tquadrat.org/CLIDefinition" 004 targetNamespace="http://dtd.tquadrat.org/CLIDefinition" 005 elementFormDefault="qualified"> 006 007<!-- 008============================================================================ 009Copyright © 2002-2021 by Thomas Thrien. 010All Rights Reserved. 011============================================================================ 012Licensed to the public under the agreements of the GNU Lesser General Public 013License, version 3.0 (the "License"). You may obtain a copy of the License at 014 015 http://www.gnu.org/licenses/lgpl.html 016 017Unless required by applicable law or agreed to in writing, software distributed 018under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 019CONDITIONS OF ANY KIND, either express or implied. See the License for the 020specific language governing permissions and limitations under the License. 021--> 022<!-- $Id: CLIDefinition.xsd 907 2021-05-05 23:09:17Z tquadrat $ --> 023 024 <!-- The root element --> 025 <xsd:element name="cliDefinition" 026 type="cliDefinitionType" > 027 <xsd:annotation> 028 <xsd:documentation>This is the root element for a CLI Definition</xsd:documentation> 029 </xsd:annotation></xsd:element> 030 031 <!-- The type definitions --> 032 <xsd:complexType name="aliasType"> 033 <xsd:annotation> 034 <xsd:documentation>An optional alias for an option</xsd:documentation> 035 </xsd:annotation> 036 <xsd:attribute ref="name" /> 037 </xsd:complexType> 038 039 <xsd:complexType name="argumentType"> 040 <xsd:annotation> 041 <xsd:documentation>The definition for a CLI Argument</xsd:documentation> 042 </xsd:annotation> 043 <xsd:sequence> 044 <xsd:element name="format" 045 type="formatType" 046 maxOccurs="1" 047 minOccurs="0" /> 048 <xsd:element name="usage" 049 type="usageType" 050 maxOccurs="1" 051 minOccurs="0" /> 052 </xsd:sequence> 053 <xsd:attribute ref="propertyName" /> 054 <xsd:attribute ref="type" /> 055 <xsd:attribute ref="index" /> 056 <xsd:attribute ref="handler" /> 057 <xsd:attribute ref="isRequired" /> 058 <xsd:attribute ref="isMultiValue" /> 059 <xsd:attribute ref="metaVar" /> 060 <xsd:attribute ref="stringConversion" /> 061 </xsd:complexType> 062 063 <xsd:complexType name="cliDefinitionType"> 064 <xsd:annotation> 065 <xsd:documentation>The document definition</xsd:documentation> 066 </xsd:annotation> 067 <xsd:sequence> 068 <xsd:element name="option" 069 type="optionType" 070 maxOccurs="unbounded" 071 minOccurs="0" /> 072 <xsd:element name="argument" 073 type="argumentType" 074 maxOccurs="unbounded" 075 minOccurs="0" /> 076 </xsd:sequence> 077 </xsd:complexType> 078 079 <xsd:simpleType name="formatType"> 080 <xsd:annotation> 081 <xsd:documentation>The optional format for the argument or option</xsd:documentation> 082 </xsd:annotation> 083 <xsd:restriction base="xsd:string"/> 084 </xsd:simpleType> 085 086 <xsd:complexType name="optionType"> 087 <xsd:annotation> 088 <xsd:documentation>The definition for a CLI Option</xsd:documentation> 089 </xsd:annotation> 090 <xsd:sequence> 091 <xsd:element name="alias" 092 type="aliasType" 093 maxOccurs="unbounded" 094 minOccurs="0" /> 095 <xsd:element name="format" 096 type="formatType" 097 maxOccurs="1" 098 minOccurs="0" /> 099 <xsd:element name="usage" 100 type="usageType" 101 maxOccurs="1" 102 minOccurs="0" /> 103 </xsd:sequence> 104 <xsd:attribute ref="propertyName" /> 105 <xsd:attribute ref="type" /> 106 <xsd:attribute ref="name" /> 107 <xsd:attribute ref="handler" /> 108 <xsd:attribute ref="isRequired" /> 109 <xsd:attribute ref="isMultiValue" /> 110 <xsd:attribute ref="metaVar" /> 111 <xsd:attribute ref="stringConversion" /> 112 </xsd:complexType> 113 114 <xsd:complexType name="usageType"> 115 <xsd:annotation> 116 <xsd:documentation>The optional usage message; can be empty</xsd:documentation> 117 </xsd:annotation> 118 <xsd:simpleContent> 119 <xsd:extension base="xsd:string"> 120 <xsd:attribute ref="key" 121 use="optional" /> 122 </xsd:extension> 123 </xsd:simpleContent> 124 </xsd:complexType> 125 126 <!-- The attribute definitions --> 127 <xsd:attribute name="handler"> 128 <xsd:annotation> 129 <xsd:documentation>The fully qualified name of the Java class for the value handler</xsd:documentation> 130 </xsd:annotation> 131 <xsd:simpleType> 132 <xsd:restriction base="xsd:string"> 133 <xsd:whiteSpace value="collapse"/> 134 <xsd:minLength value="1" /> 135 </xsd:restriction> 136 </xsd:simpleType> 137 </xsd:attribute> 138 139 <xsd:attribute name="index"> 140 <xsd:annotation> 141 <xsd:documentation>The zero based index for arguments on the command line</xsd:documentation> 142 </xsd:annotation> 143 <xsd:simpleType> 144 <xsd:restriction base="xsd:int"> 145 <xsd:minInclusive value="0" /> 146 </xsd:restriction> 147 </xsd:simpleType> 148 </xsd:attribute> 149 150 <xsd:attribute name="isMultiValue" 151 type="xsd:boolean" > 152 <xsd:annotation> 153 <xsd:documentation>true if the command line value is multi-valued; usually used for List types</xsd:documentation> 154 </xsd:annotation> 155 </xsd:attribute> 156 157 <xsd:attribute name="isRequired" 158 type="xsd:boolean" > 159 <xsd:annotation> 160 <xsd:documentation>true for a mandatory option or argument. 161The default is true for arguments and false for options.</xsd:documentation> 162 </xsd:annotation> 163 </xsd:attribute> 164 165 <xsd:attribute name="key" 166 type="xsd:string"> 167 <xsd:annotation> 168 <xsd:documentation>The resource bundle key for the usage message</xsd:documentation> 169 </xsd:annotation> 170 </xsd:attribute> 171 172 <xsd:attribute name="metaVar"> 173 <xsd:annotation> 174 <xsd:documentation>The meta variable for the value</xsd:documentation> 175 </xsd:annotation> 176 <xsd:simpleType> 177 <xsd:restriction base="xsd:string"> 178 <xsd:whiteSpace value="collapse" /> 179 </xsd:restriction> 180 </xsd:simpleType> 181 </xsd:attribute> 182 183 <xsd:attribute name="name"> 184 <xsd:annotation> 185 <xsd:documentation>The name for an option</xsd:documentation> 186 </xsd:annotation> 187 <xsd:simpleType> 188 <xsd:restriction base="xsd:string"> 189 <xsd:whiteSpace value="collapse" /> 190 <xsd:minLength value="1" /> 191 </xsd:restriction> 192 </xsd:simpleType> 193 </xsd:attribute> 194 195 <xsd:attribute name="propertyName"> 196 <xsd:annotation> 197 <xsd:documentation>The name of the property; this is how the value is referenced by the program</xsd:documentation> 198 </xsd:annotation> 199 <xsd:simpleType> 200 <xsd:restriction base="xsd:string"> 201 <xsd:minLength value="1" /> 202 <xsd:whiteSpace value="collapse" /> 203 </xsd:restriction> 204 </xsd:simpleType> 205 </xsd:attribute> 206 207 <xsd:attribute name="stringConversion"> 208 <xsd:annotation> 209 <xsd:documentation>The fully qualified name of the Java class for the string converter</xsd:documentation> 210 </xsd:annotation> 211 <xsd:simpleType> 212 <xsd:restriction base="xsd:string"> 213 <xsd:whiteSpace value="collapse"/> 214 <xsd:minLength value="1" /> 215 </xsd:restriction> 216 </xsd:simpleType> 217 </xsd:attribute> 218 219 <xsd:attribute name="type"> 220 <xsd:annotation> 221 <xsd:documentation>The property's data type as a fully qualified Java class name</xsd:documentation> 222 </xsd:annotation> 223 <xsd:simpleType> 224 <xsd:restriction base="xsd:string"> 225 <xsd:minLength value="1" /> 226 <xsd:whiteSpace value="collapse" /> 227 </xsd:restriction> 228 </xsd:simpleType> 229 </xsd:attribute> 230</xsd:schema> 231 232<!-- 233End of file 234-->
The above mentioned class { link org.tquadrat.foundation.ui.tools.ShowCLISpec} can be used to dump both the DTD and the Schema file to load them into a validating XML editor or alike.
-
ClassesClassDescriptionThe abstract base class for the value handler that takes a String value from the command line, translates it to the target type and sets the value to the property.An implementation of
CmdLineValueHandler
forDate
values.An implementation ofCmdLineValueHandler
forDocument
values.
TheDocument
will be identified by the name of the respectiveFile
object that of course has to exist and needs to be accessible.EnumValueHandler<T extends Enum<T>>An implementation ofCmdLineValueHandler
for types that are derived fromEnum
.An implementation ofCmdLineValueHandler
forBufferedImage
values.The implementation ofTimeValueHandler
forInstant
.The implementation ofTimeValueHandler
forLocalDateTime
.The implementation ofTimeValueHandler
forjava.time.LocalDate
.The implementation ofTimeValueHandler
forLocalTime
.The implementation ofCmdLineValueHandler
for all those types for that an implementation ofStringConverter
exists.An implementation ofCmdLineValueHandler
forString
values.TimeValueHandler<T extends Temporal>The abstract base class for implementations ofCmdLineValueHandler
for types that extendTemporal
.The implementation ofTimeValueHandler
forYearMonth
.The implementation ofTimeValueHandler
forYear
.An implementation ofCmdLineValueHandler
forboolean
andBoolean
values that does accept also "yes", "qui", "ja", "sí", "sì", "да", "sim", "tak" and more astrue
.An implementation ofStringConverter
that translates 'yes' in various languages intotrue
.The implementation ofTimeValueHandler
forZonedDateTime
.