├── .github └── workflows │ └── build.yml ├── .gitignore ├── COPYRIGHT.txt ├── LICENSE.txt ├── README.md ├── pom.xml └── src ├── main └── java │ └── com │ └── gabstudios │ └── cmdline │ ├── CmdLine.java │ ├── Command.java │ ├── CommandDefinition.java │ ├── CommandLineTokenizer.java │ ├── CommandListener.java │ ├── DefinedCommandTokenizer.java │ ├── DuplicateException.java │ ├── MatchException.java │ ├── MissingException.java │ ├── Token.java │ └── UnsupportedException.java └── test ├── java └── com │ └── gabstudios │ └── cmdline │ ├── CmdLineNegativeTest.java │ ├── CmdLineTest.java │ ├── CmdlineNegativeWordSuggestionTest.java │ ├── CommandLineTokenizerTest.java │ └── DefinedCommandTokenizerTest.java └── resources └── logging.properties /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | types: [opened, synchronize, reopened] 8 | jobs: 9 | build: 10 | name: Build 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | with: 15 | fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis 16 | - name: Set up JDK 11 17 | uses: actions/setup-java@v1 18 | with: 19 | java-version: 11 20 | - name: Cache SonarCloud packages 21 | uses: actions/cache@v1 22 | with: 23 | path: ~/.sonar/cache 24 | key: ${{ runner.os }}-sonar 25 | restore-keys: ${{ runner.os }}-sonar 26 | - name: Cache Maven packages 27 | uses: actions/cache@v1 28 | with: 29 | path: ~/.m2 30 | key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} 31 | restore-keys: ${{ runner.os }}-m2 32 | - name: Build and analyze 33 | env: 34 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any 35 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 36 | run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=gab-studios_gab-cmdline 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | 8 | *.war 9 | *.ear 10 | 11 | # backup temp files # 12 | *.bak 13 | 14 | 15 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 16 | hs_err_pid* 17 | /bin 18 | /.classpath 19 | /.project 20 | /target 21 | /.settings 22 | /bak/ 23 | **/.DS_Store 24 | .vscode 25 | -------------------------------------------------------------------------------- /COPYRIGHT.txt: -------------------------------------------------------------------------------- 1 | 2 | Copyright 2016 Gregory Brown 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | GAB-CmdLine 4 | ======= 5 | 6 | The GAB Social Command Line Parser for Java. The purpose of this project is to analyze and examine how I would create a command line parser for Java. Comments are welcome. Thank you. 7 | 8 | 9 | Required 10 | --------- 11 | This project requires the following: 12 | 13 | * Java 8 or 11 14 | * Maven 15 | 16 | 17 | Maven Dependency 18 | --------- 19 | ```java 20 | 21 | com.gabstudios 22 | gab-cmdline 23 | 1.0.0-SNAPSHOT 24 | 25 | 26 | 27 | com.gabstudios 28 | gab-collection 29 | 1.0.0-SNAPSHOT 30 | 31 | 32 | com.gabstudios 33 | gab-logging 34 | 1.0.0-SNAPSHOT 35 | 36 | 37 | com.gabstudios 38 | gab-validate 39 | 1.0.0 40 | 41 | ``` 42 | 43 | 44 | 45 | Build 46 | --------- 47 | Use Maven to build - `mvn package`. 48 | 49 | Usage 50 | --------- 51 | 52 | In order to parse the command line, you need to define what the commands are by calling `Cmdline.defineCommand("xxx");` 53 | 54 | ```java 55 | CmdLine.defineCommand("-help, #print this message") 56 | ``` 57 | 58 | The string used in the defineCommand() method, contains tokens that must use one of these symbols in order for it to be recognized as that type: 59 | 60 | \# = The description of the command. There may be zero to one defined. 61 | 62 | ! = A required value for the command name. There can be zero to many defined. 63 | 64 | ? = An optional value for the command name. There can be zero to many defined. 65 | 66 | : = The regex value to match on for any values that are defined. There can be zero to one defined. 67 | 68 | ... = A value ends with ... and is a list for the command name. There can be zero to one defined. This can be used with the ! and ? symbols 69 | 70 | If a token does not start with one of these tokens, then it is considered a command name. There can be one to many names that represent a single command, such as: 'f', 'file', 'filename' or '-f', '--file', '--filename'. 71 | 72 | Example 73 | --------- 74 | 75 | ```text 76 | myApp [commands] [option1 [option2 [option3] ...]] 77 | Commands: 78 | -help print this message 79 | -version print the version information and exit 80 | -quiet be extra quiet 81 | -verbose be extra verbose 82 | -debug print debugging information 83 | -logfile use given file for log 84 | -logger the class which is to perform logging 85 | -listener add an instance of class as a project listener 86 | -D= use value for given property 87 | -find search for file towards the root of the 88 | filesystem and use it 89 | ``` 90 | 91 | ```java 92 | // define a listener implementation of the CommandListener interface. 93 | private class CmdLineListener implements CommandListener 94 | { 95 | @Override 96 | public void handle(final Command command) 97 | { 98 | System.out.println( command ); 99 | } 100 | } 101 | // create an instance of the listener. 102 | final CmdLineListener listener = new CmdLineListener(); 103 | 104 | // define/declare the commands the parser should parse. 105 | // command names can start with any character that is not reserved. reserved are !?#: 106 | // the commands listed below use the - (dash) to denote a command, but this is not required. 107 | CmdLine.defineCommand("-help, #print this message") 108 | .defineCommand("-version, #print the version information and exit") 109 | .defineCommand("-quiet, #be extra quiet") 110 | .defineCommand("-verbose, #be extra verbose") 111 | .defineCommand("-debug, #print debugging information") 112 | .defineCommand("-logfile, !logFile, #use given file for log") 113 | .defineCommand("-logger, !logClass, #the class which is to perform logging") 114 | .defineCommand("-listener, !listenerClass, #add an instance of class as a project listener") 115 | .defineCommand("-find, !buildFile, #search for file towards the root of the file system and use it"); 116 | 117 | Note: The format of "-D=" is automatically supported and doesnt need to be defined. 118 | If a -D= is seen on the command line, it is parsed and set 119 | in the System properties. In addition, a command is created and sent to the listener. 120 | 121 | // parse the command line args and pass matching commands to the listener for processing. 122 | final List = CmdLine.parse( args, listener ); 123 | ``` 124 | Click for more [examples]. 125 | 126 | 127 | More Documentation 128 | ------------------ 129 | Check the project [wiki]. 130 | 131 | 132 | Copyright 133 | ------- 134 | [Copyright 2016 Gregory Brown] 135 | 136 | 137 | License 138 | ------- 139 | This codebase is licensed under the [Apache v2.0 License]. 140 | 141 | 142 | Feedback 143 | --------- 144 | Comments and feedback are greatly appreciated!!! 145 | 146 | 147 | [Copyright 2016 2021 Gregory Brown]: https://github.com/gab-studios/gab-cmdline/tree/master/COPYRIGHT.txt 148 | [Apache v2.0 License]: https://github.com/gab-studios/gab-cmdline/tree/master/LICENSE.txt 149 | [wiki]: https://github.com/gab-studios/gab-cmdline/wiki 150 | [examples]: https://github.com/gab-studios/gab-cmdline/wiki/Examples 151 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | com.gabstudios 7 | gab-cmdline 8 | 1.0.0-SNAPSHOT 9 | jar 10 | 11 | GAB Studios Command Line Argument Parser 12 | The GAB Studios Command Line Parser 13 | https://github.com/gab-studios/gab-cmdline 14 | 15 | 16 | 17 | Apache v2.0 18 | https://github.com/gab-gabstudios/gab-cmdline/blob/master/LICENSE.txt 19 | 20 | 21 | 22 | 23 | 24 | Gregory Brown 25 | gab@gabstudios.com 26 | GAB Studios 27 | http://www.gabstudios.com 28 | 29 | 30 | 31 | 32 | scm:http://github.com/gab-gabstudios/gab-cmdline.git 33 | scm:http://github.com/gab-gabstudios/gab-cmdline.git 34 | http://github.com/gab-gabstudios/gab-cmdline.git 35 | v@{project.version} 36 | 37 | 38 | 39 | 40 | ossrh 41 | https://oss.sonatype.org/content/repositories/snapshots 42 | 43 | 44 | ossrh 45 | https://oss.sonatype.org/service/local/staging/deploy/maven2 46 | 47 | 48 | 49 | 50 | github 51 | UTF-8 52 | yyyyMMddhhmm 53 | gab-studios 54 | https://sonarcloud.io 55 | 56 | 57 | 58 | 59 | com.gabstudios 60 | gab-validate 61 | 1.0.0 62 | 63 | 64 | com.gabstudios 65 | gab-logging 66 | 1.0.1-SNAPSHOT 67 | 68 | 69 | com.gabstudios 70 | gab-collection 71 | 1.0.0-SNAPSHOT 72 | 73 | 74 | junit 75 | junit 76 | 4.13.1 77 | test 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | org.apache.maven.plugins 87 | maven-repository-plugin 88 | 2.4 89 | 90 | 91 | 92 | 93 | 94 | 95 | org.apache.maven.plugins 96 | maven-repository-plugin 97 | 2.4 98 | 99 | 100 | 101 | org.apache.maven.plugins 102 | maven-source-plugin 103 | 3.2.0 104 | 105 | 106 | attach-sources 107 | 108 | jar-no-fork 109 | 110 | 111 | 112 | 113 | 114 | org.apache.maven.plugins 115 | maven-javadoc-plugin 116 | 3.3.1 117 | 118 | 8 119 | 120 | 121 | 122 | attach-javadocs 123 | 124 | jar 125 | 126 | 127 | 128 | 129 | 130 | org.apache.maven.plugins 131 | maven-gpg-plugin 132 | 1.6 133 | 134 | 135 | sign-artifacts 136 | deploy 137 | 138 | sign 139 | 140 | 141 | 142 | 143 | 144 | 145 | org.apache.maven.plugins 146 | maven-release-plugin 147 | 2.5.3 148 | 149 | v@{project.version} 150 | 151 | 152 | 153 | org.apache.maven.plugins 154 | maven-compiler-plugin 155 | 3.7.0 156 | 157 | 1.8 158 | 1.8 159 | UTF-8 160 | 161 | 162 | 163 | org.apache.maven.plugins 164 | maven-surefire-plugin 165 | 3.0.0-M5 166 | 167 | 168 | 169 | java.util.logging.config.file 170 | src/test/resources/logging.properties 171 | 172 | 173 | 174 | 175 | 176 | com.github.spotbugs 177 | spotbugs-maven-plugin 178 | 3.1.3 179 | 180 | 181 | org.jacoco 182 | jacoco-maven-plugin 183 | 0.8.5 184 | 185 | 186 | prepare-agent 187 | 188 | prepare-agent 189 | 190 | 191 | 192 | report 193 | test 194 | 195 | report 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | -------------------------------------------------------------------------------- /src/main/java/com/gabstudios/cmdline/CmdLine.java: -------------------------------------------------------------------------------- 1 | /***************************************************************************************** 2 | * 3 | * Copyright 2016 Gregory Brown. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | * use this file except in compliance with the License. You may obtain a copy of 7 | * 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, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations under 15 | * the License. 16 | * 17 | ***************************************************************************************** 18 | */ 19 | 20 | package com.gabstudios.cmdline; 21 | 22 | import java.util.ArrayList; 23 | import java.util.HashMap; 24 | import java.util.HashSet; 25 | import java.util.List; 26 | import java.util.Map; 27 | import java.util.Set; 28 | import java.util.regex.Matcher; 29 | import java.util.regex.Pattern; 30 | 31 | import com.gabstudios.cmdline.Token.Type; 32 | import com.gabstudios.collection.LinkedHashMapTrie; 33 | import com.gabstudios.collection.Trie; 34 | import com.gabstudios.logging.LogProvider; 35 | import com.gabstudios.validate.Validate; 36 | 37 | /** 38 | * This class is the main command line parser. 39 | * 40 | * Steps to use parser. 41 | * 42 | * 1. Define your command definitions. 43 | * 44 | * CmdLine.defineCommand("-l, --load, !fileName, #Load a files into the system") 45 | * .defineCommand("-s, --save, #Save the application"); .defineCommand("-q, 46 | * --quit, #Quit the application"); 47 | * 48 | * 2. parse the command line arguments and assign a listener for command 49 | * definitions 50 | * 51 | * CmdLine.parse( args, listener ); 52 | * 53 | * or parse the command line arguments and get the returned List of Command 54 | * instances. 55 | * 56 | * List commands = CmdLine.parse( args ); 57 | * 58 | * 3. clear parser to release resources. 59 | * 60 | * CmdLine.clear(); 61 | * 62 | * CmdLine.defineCommand("xxxx") uses a token based on the first char. 63 | * 64 | * If a String uses one of these symbols then it is recognized as that type: 65 | * 66 | * # = The description of the command. There may be zero to one defined. 67 | * 68 | * ! = A required value for the command name. There can be zero to many defined. 69 | * 70 | * ? = An optional value for the command name. There can be zero to many 71 | * defined. 72 | * 73 | * : = The regex value to match on for any values that are defined. There can be 74 | * zero to one defined. 75 | * 76 | * If a String does not use one of the above char, then it is considered a 77 | * command. 78 | * 79 | * @see setCommandListener 80 | * @see defineCommand 81 | * @see parse 82 | * 83 | * @author Gregory Brown (sysdevone) 84 | * 85 | */ 86 | public class CmdLine { 87 | 88 | /* 89 | * A map that holds the key of a command string and a value of a command 90 | * definition. 91 | */ 92 | private static final Map COMMAND_DEFINITION_MAP; 93 | 94 | /* 95 | * The command line tokenizer 96 | */ 97 | private static final CommandLineTokenizer COMMNAND_LINE_TOKENIZER; 98 | 99 | /* 100 | * The listener that will handle commands as they are processed, to the main 101 | * cmdline class. 102 | */ 103 | private static final List DEFAULT_COMMAND_LIST; 104 | 105 | /* 106 | * Regex to split the define command method 107 | */ 108 | private static final String DEFINED_COMMAND_REGEX_PARSE_PATTERN = "\\s*,\\s*"; 109 | 110 | /* 111 | * The tokenizer that handles the defineCommand(xxxx) method. 112 | */ 113 | private static final DefinedCommandTokenizer DEFINED_COMMAND_TOKENIZER; 114 | 115 | /* 116 | * Support method chaining. 117 | */ 118 | private static final CmdLine INSTANCE; 119 | 120 | /* 121 | * The maximum length allowed for any size - String, tokens, etc. 122 | */ 123 | private static final int MAX_LENGTH = 256; 124 | 125 | /* 126 | * The application name. 127 | */ 128 | private static String s_applicationName; 129 | 130 | /* 131 | * The listener that will handle commands as they are processed, if it is set. 132 | * May be 0 to 1. 133 | */ 134 | private static CommandListener s_commandListener; 135 | 136 | /* 137 | * The application version. 138 | */ 139 | private static String s_version; 140 | 141 | /* 142 | * Holds the variable names assigned to commands. Variable names are unique 143 | * across commands. One a variable is used by a command, another command *may 144 | * not use* that same variable name. 145 | */ 146 | private static final Set VARIABLE_NAME_SET; 147 | 148 | /* 149 | * A Trie that holds the command names. This data structure is used for word 150 | * suggestion if the command is not found. 151 | */ 152 | private static final Trie WORD_SUGGESTION_TRIE; 153 | 154 | /** 155 | * The CmdLine constructor. 156 | */ 157 | static { 158 | WORD_SUGGESTION_TRIE = new LinkedHashMapTrie(); 159 | COMMAND_DEFINITION_MAP = new HashMap(); 160 | VARIABLE_NAME_SET = new HashSet(); 161 | DEFINED_COMMAND_TOKENIZER = new DefinedCommandTokenizer(); 162 | COMMNAND_LINE_TOKENIZER = new CommandLineTokenizer(); 163 | DEFAULT_COMMAND_LIST = new ArrayList(); 164 | INSTANCE = new CmdLine(); 165 | } 166 | 167 | /* 168 | * Adds variable name to existing set. If the name already exists, then the 169 | * DuplicateException is thrown. 170 | */ 171 | private static void addVariableName(final String name) { 172 | assert ((name != null) && (name.length() > 0)) : "The parameter 'name' must not be null or empty"; 173 | assert (name.length() <= CmdLine.MAX_LENGTH) : "The parameter 'name' must be less than or equal to " 174 | + CmdLine.MAX_LENGTH; 175 | 176 | if (!CmdLine.VARIABLE_NAME_SET.add(name)) { 177 | throw (new DuplicateException( 178 | "Error: The variable '" + name + "' has already been defined. Define a new variable name.")); 179 | } 180 | } 181 | 182 | /** 183 | * Clears the CmdLine and releases resources. 184 | * 185 | * @return The CmdLine instance. Used for chaining calls. 186 | */ 187 | public static CmdLine clear() { 188 | CmdLine.s_commandListener = null; 189 | CmdLine.COMMAND_DEFINITION_MAP.clear(); 190 | CmdLine.VARIABLE_NAME_SET.clear(); 191 | CmdLine.WORD_SUGGESTION_TRIE.clear(); 192 | CmdLine.DEFAULT_COMMAND_LIST.clear(); 193 | return (CmdLine.INSTANCE); 194 | } 195 | 196 | /* 197 | * Creates the Command if a CommandDefinition exists. 198 | */ 199 | private static Command createCommand(final String commandName, final List tokens) { 200 | 201 | assert ((commandName != null) 202 | && (commandName.length() > 0)) : "The parameter 'commandName' must not be null or empty"; 203 | assert (commandName.length() <= CmdLine.MAX_LENGTH) : "The parameter 'name' must be less than or equal to " 204 | + CmdLine.MAX_LENGTH; 205 | 206 | assert (tokens != null) : "The parameter 'tokens' must not be null"; 207 | assert (tokens.size() <= CmdLine.MAX_LENGTH) : "The parameter 'name' must be less than or equal to " 208 | + CmdLine.MAX_LENGTH; 209 | 210 | final Command command = new Command(commandName); 211 | if (!tokens.isEmpty()) { 212 | final CommandDefinition commandDefinition = CmdLine.COMMAND_DEFINITION_MAP.get(commandName); 213 | 214 | final String regex = commandDefinition.getRegexValue(); 215 | Pattern pattern = null; 216 | if ((regex != null) && (regex.length() > 0)) { 217 | pattern = Pattern.compile(regex); 218 | } 219 | 220 | if (commandDefinition.hasRequiredVariables()) { 221 | final List names = commandDefinition.getRequiredVariableNames(); 222 | CmdLine.processVariable(pattern, tokens, names, command, true); 223 | } 224 | 225 | if (commandDefinition.hasRequiredVariableLists()) { 226 | final String name = commandDefinition.getRequiredVariableListName(); 227 | CmdLine.processVariableList(pattern, tokens, name, command, true); 228 | } 229 | 230 | if (commandDefinition.hasOptionalVariables()) { 231 | final List names = commandDefinition.getOptionalVariableNames(); 232 | CmdLine.processVariable(pattern, tokens, names, command, false); 233 | } 234 | 235 | if (commandDefinition.hasOptionalVariableLists()) { 236 | final String name = commandDefinition.getOptionalVariableListName(); 237 | CmdLine.processVariableList(pattern, tokens, name, command, false); 238 | } 239 | } 240 | 241 | return (command); 242 | } 243 | 244 | /* 245 | * Creates a CommandDefinition. 246 | */ 247 | private static CommandDefinition createCommandDefinition(final List tokens) { 248 | 249 | assert ((tokens != null) && (tokens.size() > 0)) : "The parameter 'tokens' must not be null or empty"; 250 | assert (tokens.size() <= CmdLine.MAX_LENGTH) : "The parameter 'name' must be less than or equal to " 251 | + CmdLine.MAX_LENGTH; 252 | 253 | final CommandDefinition command = new CommandDefinition(); 254 | 255 | // a list flag. Only one list can exist. 256 | boolean doesListExist = false; 257 | 258 | // a flag to mark if an optional var was created. If this is true and an 259 | // attempt to create a required var is made, then an exception will be 260 | // thrown. 261 | boolean isOptionalVarDefined = false; 262 | for (final Token token : tokens) { 263 | 264 | final Type type = token.getType(); 265 | final String name = token.getValue(); 266 | switch (type) { 267 | case COMMAND: { 268 | if (name.contains(" ")) { 269 | throw (new UnsupportedException("Error: The command name '" + name 270 | + "' contains spaces which is not supported. " + "The definition may need a comma.")); 271 | } else { 272 | command.addName(name); 273 | CmdLine.WORD_SUGGESTION_TRIE.add(name); 274 | } 275 | break; 276 | } 277 | case DESCRIPTION: { 278 | 279 | final String description = command.getDescription(); 280 | if ((description != null) && (description.length() > 0)) { 281 | throw (new DuplicateException("Error: The description '" + name + "' has already been defined.")); 282 | } else { 283 | command.setDescription(name); 284 | } 285 | 286 | break; 287 | } 288 | case REGEX_VALUE: { 289 | final String existingRegex = command.getRegexValue(); 290 | if ((existingRegex != null) && (existingRegex.length() > 0)) { 291 | throw (new DuplicateException("Error: The regex '" + name + "' has already been defined.")); 292 | } else { 293 | command.setRegexValue(name); 294 | } 295 | break; 296 | } 297 | case REQUIRED_VALUE: { 298 | if (isOptionalVarDefined) { 299 | throw (new UnsupportedException( 300 | "Error: An optional variable has already been defined before this required variable. " 301 | + "Required variables must be defined before optional variables.'")); 302 | } else { 303 | CmdLine.addVariableName(name); 304 | command.addRequiredVariable(name); 305 | } 306 | break; 307 | } 308 | case REQUIRED_LIST_VALUE: { 309 | if (isOptionalVarDefined) { 310 | throw (new UnsupportedException( 311 | "Error: An optional variable has already been defined before this required variable. " 312 | + "Required variables must be defined before optional variables.'")); 313 | } else if (doesListExist) { 314 | throw (new UnsupportedException("Error: A List has already been defined for '" + name 315 | + "'. A command can only have one list defined. ")); 316 | } else { 317 | doesListExist = true; 318 | CmdLine.addVariableName(name); 319 | command.setRequiredVariableList(name); 320 | } 321 | break; 322 | } 323 | case OPTIONAL_VALUE: { 324 | CmdLine.addVariableName(name); 325 | command.addOptionalVariable(name); 326 | isOptionalVarDefined = true; 327 | break; 328 | } 329 | case OPTIONAL_LIST_VALUE: { 330 | if (doesListExist) { 331 | throw (new UnsupportedException("Error: A List has already been defined for '" + name 332 | + "'. A command can only have one list defined. ")); 333 | } else { 334 | doesListExist = true; 335 | CmdLine.addVariableName(name); 336 | command.setOptionalVariableList(name); 337 | isOptionalVarDefined = true; 338 | } 339 | break; 340 | } 341 | default: { 342 | throw (new UnsupportedException( 343 | "Error: Unknown token '" + name + "' is an unknown type ='" + type.name() + "').")); 344 | } 345 | } 346 | } 347 | 348 | if (command.getNames().isEmpty()) { 349 | throw (new MissingException("Error: The command name was not defined and is missing.")); 350 | } 351 | 352 | return (command); 353 | } 354 | 355 | /** 356 | * This method defines the command definitions expected in the parser. Call this 357 | * method for each command that will be defined. 358 | * 359 | * A token must use one of these symbols in order for it to be recognized as 360 | * that type: 361 | * 362 | * # = The description of the command. There may be zero to one defined. 363 | * 364 | * ! = A required value for the command name. There can be zero to many defined. 365 | * 366 | * ? = An optional value for the command name. There can be zero to many 367 | * defined. 368 | * 369 | * : = The regex value to match on for any values that are defined. There can be 370 | * zero to one defined. 371 | * 372 | * ... = A value ends with ... and is a list for the command name. There can be 373 | * zero to one defined. This can be used with the ! and ? symbols 374 | * 375 | * If a token does not start with one of these tokens, then it is considered a 376 | * command name. 377 | * 378 | * Exmaples: 379 | * 380 | * "file, !fileName1, :file\\d.txt, #Load a files into the system" "-f, --file, 381 | * !fileName1, ?fileName2, ?fileName3, :file\\d.txt, #Load a files into the 382 | * system" "-f, --file, !fileName1, ?fileNames..., #Load a files into the 383 | * system" 384 | * 385 | * @param nameArgs 386 | * An array of String containing values. 387 | * @return The CmdLine instance. Used for chaining calls. 388 | */ 389 | public static CmdLine defineCommand(final String... nameArgs) { 390 | Validate.defineBoolean((nameArgs != null) && (nameArgs.length > 0) && (nameArgs.length <= CmdLine.MAX_LENGTH)) 391 | .testTrue().throwValidationExceptionOnFail().validate(); 392 | 393 | final List tokens = CmdLine.DEFINED_COMMAND_TOKENIZER.tokenize(nameArgs); 394 | 395 | final CommandDefinition command = CmdLine.createCommandDefinition(tokens); 396 | final List names = command.getNames(); 397 | 398 | for (final String name : names) { 399 | final CommandDefinition existingCommand = CmdLine.COMMAND_DEFINITION_MAP.put(name, command); 400 | if (existingCommand != null) { 401 | throw (new DuplicateException( 402 | "Error: The command '" + name + "' has already been defined. Define a new command name.")); 403 | } 404 | } 405 | 406 | return (CmdLine.INSTANCE); 407 | } 408 | 409 | /** 410 | * This method defines the command definitions expected in the parser. Call this 411 | * method for each command that will be defined. 412 | * 413 | * A token must use one of these symbols in order for it to be recognized as 414 | * that type: 415 | * 416 | * # = The description of the command. There may be zero to one defined. 417 | * 418 | * ! = A required value for the command name. There can be zero to many defined. 419 | * 420 | * ? = An optional value for the command name. There can be zero to many 421 | * defined. 422 | * 423 | * : = The regex value to match on for any values that are defined. There can be 424 | * zero to one defined. 425 | * 426 | * ... = A value ends with ... and is a list for the command name. There can be 427 | * zero to one defined. This can be used with the ! and ? symbols 428 | * 429 | * If a token does not start with one of these tokens, then it is considered a 430 | * command name. 431 | * 432 | * Exmaples: 433 | * 434 | * "file, !fileName1, :file\\d.txt, #Load a files into the system" "-f, --file, 435 | * !fileName1, ?fileName2, ?fileName3, :file\\d.txt, #Load a files into the 436 | * system" "-f, --file, !fileName1, ?fileNames..., #Load a files into the 437 | * system" 438 | * 439 | * @param nameArgs 440 | * A comma delimited String containing values. 441 | * @return The CmdLine instance. Used for chaining calls. 442 | */ 443 | public static CmdLine defineCommand(final String nameArgs) { 444 | Validate.defineString(nameArgs).testNotNullEmpty().testMaxLength(CmdLine.MAX_LENGTH) 445 | .throwValidationExceptionOnFail().validate(); 446 | 447 | final String[] nameArgTokens = nameArgs.split(CmdLine.DEFINED_COMMAND_REGEX_PARSE_PATTERN); 448 | CmdLine.defineCommand(nameArgTokens); 449 | return (CmdLine.INSTANCE); 450 | } 451 | 452 | /** 453 | * Gets the application name that was defined. 454 | * 455 | * @return A String. May be null or empty if the application name was not 456 | * defined. 457 | */ 458 | public static String getApplicationName() { 459 | return (CmdLine.s_applicationName); 460 | } 461 | 462 | /** 463 | * Gets the version String that was defined. 464 | * 465 | * @return A String. May be null or empty if the version was not defined. 466 | */ 467 | public static String getVersion() { 468 | return (CmdLine.s_version); 469 | } 470 | 471 | /** 472 | * Parse the command line arguments. 473 | * 474 | * @param args 475 | * The arguments from the command line. 476 | * @return The CmdLine instance. Used for chaining calls. 477 | */ 478 | public static List parse(final String[] args) { 479 | Validate.defineBoolean((args != null) && (args.length > 0) && (args.length <= CmdLine.MAX_LENGTH)).testTrue() 480 | .throwValidationExceptionOnFail().validate(); 481 | 482 | final List tokens = CmdLine.tokenizeCmdLineArgs(args); 483 | CmdLine.processCmdLineTokens(tokens); 484 | 485 | final List commands = new ArrayList(CmdLine.DEFAULT_COMMAND_LIST); 486 | return (commands); 487 | } 488 | 489 | /** 490 | * Parse the command line arguments. 491 | * 492 | * @param args 493 | * The arguments from the command line. 494 | * @param commandListener 495 | * A listener that will handle the callbacks. 496 | * @return The CmdLine instance. Used for chaining calls. 497 | */ 498 | public static List parse(final String[] args, final CommandListener commandListener) { 499 | CmdLine.setCommandListener(commandListener); 500 | return (CmdLine.parse(args)); 501 | } 502 | 503 | /* 504 | * Processes the String tokens and creates Command. 505 | */ 506 | private static void processCmdLineTokens(final List tokens) { 507 | 508 | assert ((tokens != null) && (tokens.size() > 0)) : "The parameter 'tokens' must not be null or empty"; 509 | assert (tokens.size() <= CmdLine.MAX_LENGTH) : "The parameter 'tokens' must be less than or equal to " 510 | + CmdLine.MAX_LENGTH; 511 | 512 | final String tokenValue = tokens.remove(0); 513 | 514 | // check to see that a command definition exists for the current token. 515 | if (CmdLine.COMMAND_DEFINITION_MAP.containsKey(tokenValue)) { 516 | // if defined, then create a command. 517 | final Command command = CmdLine.createCommand(tokenValue, tokens); 518 | 519 | CmdLine.DEFAULT_COMMAND_LIST.add(command); 520 | 521 | // if the listener was set, then notify the listener of the created 522 | // command. 523 | if (CmdLine.s_commandListener != null) { 524 | // TODO - thread call to remove from main thread. add timeout 525 | // for processing. 526 | CmdLine.s_commandListener.handle(command); 527 | } 528 | 529 | // Have all tokens been consumed? 530 | if (tokens.size() > 0) { 531 | // Reclusive call and process the remaining 532 | // tokens. 533 | CmdLine.processCmdLineTokens(tokens); 534 | } 535 | 536 | } else { 537 | // Process -D= if it exists. 538 | final boolean processForSystemProperty = CmdLine.processSystemProperty(tokenValue, tokens); 539 | 540 | // if not processed, then the token is not supported. 541 | if (!processForSystemProperty) { 542 | // if tokenvalue and not a system property then it is not 543 | // defined. 544 | final List suggestedWords = CmdLine.WORD_SUGGESTION_TRIE.getWords(tokenValue); 545 | 546 | throw (new UnsupportedException("Error: The command name '" + tokenValue + "' is not defined.", 547 | suggestedWords)); 548 | } else if (!tokens.isEmpty()) { 549 | // if the token is supported, recursive call and process the 550 | // remaining tokens. 551 | CmdLine.processCmdLineTokens(tokens); 552 | } 553 | } 554 | } 555 | 556 | /* 557 | * Processes the -D= and adds it to the System property. 558 | */ 559 | private static boolean processSystemProperty(final String valueString, final List tokens) { 560 | 561 | boolean isSystemPropertyProcessed = false; 562 | if ((valueString != null) && (tokens != null) && (tokens.size() > 0)) { 563 | final int indexOfSystemProperty = valueString.indexOf("-D"); 564 | 565 | if (indexOfSystemProperty > -1) { 566 | final String systemPropertyKey = valueString.substring(indexOfSystemProperty + 2); 567 | 568 | final String systemPropertyValue = tokens.remove(0); 569 | 570 | LogProvider.getProvider().getService().logDebug(CmdLine.class, "parseSystemProperty", 571 | "Setting System Property: " + systemPropertyKey + "=" + systemPropertyValue); 572 | 573 | isSystemPropertyProcessed = true; 574 | System.setProperty(systemPropertyKey, systemPropertyValue); 575 | 576 | final Command command = new Command(valueString); 577 | command.addVariable(systemPropertyKey, systemPropertyValue); 578 | 579 | CmdLine.DEFAULT_COMMAND_LIST.add(command); 580 | 581 | if (CmdLine.s_commandListener != null) { 582 | // TODO - thread call to remove from main thread. add 583 | // timeout for processing. 584 | CmdLine.s_commandListener.handle(command); 585 | } 586 | } 587 | } 588 | return (isSystemPropertyProcessed); 589 | } 590 | 591 | /* 592 | * Process the required and optional variables that are associated with a 593 | * command. 594 | */ 595 | private static void processVariable(final Pattern pattern, final List tokens, 596 | final List definedVariableNames, final Command command, final boolean required) { 597 | 598 | // pattern can be null. 599 | 600 | assert (tokens != null) : "The parameter 'tokens' must not be null."; 601 | assert (tokens.size() <= CmdLine.MAX_LENGTH) : "The parameter 'tokens' must be less than or equal to " 602 | + CmdLine.MAX_LENGTH; 603 | 604 | assert (definedVariableNames != null) : "The parameter 'definedVariableNames' must not be null."; 605 | assert (definedVariableNames 606 | .size() <= CmdLine.MAX_LENGTH) : "The parameter 'definedVariableNames' must be less than or equal to " 607 | + CmdLine.MAX_LENGTH; 608 | 609 | assert (command != null) : "The parameter 'command' must not be null."; 610 | 611 | for (final String varName : definedVariableNames) { 612 | // A varName must not start with a space, otherwise an exception is 613 | // thrown. 614 | if (varName.contains(" ")) { 615 | throw (new UnsupportedException("Error: The variable name '" + varName 616 | + "' contains spaces which is not supported. The definition may need a comma.")); 617 | } else if ((tokens.size() == 0) && !required) { 618 | // if there isnt any info from the command line and this 619 | // variable is not required then break and exit. 620 | break; 621 | } else if ((tokens.size() == 0) && required) { 622 | // if there isnt any info from the command line but this 623 | // variable is required then throw exception. 624 | throw (new MissingException( 625 | "Error: The value for the required variable '" + varName + "' is missing.")); 626 | } else { 627 | 628 | final String argToken = tokens.remove(0); 629 | 630 | // System.out.println("processVariable: " + name + " : " 631 | // + argToken + " = " + _variableNameSet); 632 | 633 | boolean isMatch = true; 634 | if (pattern != null) { 635 | final Matcher matcher = pattern.matcher(argToken); 636 | isMatch = matcher.matches(); 637 | if (!isMatch) { 638 | throw (new MatchException("Error: The value '" + argToken 639 | + "' does not match the expected pattern '" + pattern.toString() + "'.")); 640 | } 641 | } 642 | 643 | if (CmdLine.VARIABLE_NAME_SET.contains(varName)) { 644 | command.addVariable(varName, argToken); 645 | } 646 | } 647 | } 648 | } 649 | 650 | /* 651 | * Process the required and optional variable lists that are associated with a 652 | * command. 653 | */ 654 | private static void processVariableList(final Pattern pattern, final List tokens, final String varName, 655 | final Command command, final boolean required) { 656 | // pattern can be null. 657 | 658 | assert (tokens != null) : "The parameter 'tokens' must not be null."; 659 | assert (tokens.size() <= CmdLine.MAX_LENGTH) : "The parameter 'tokens' must be less than or equal to " 660 | + CmdLine.MAX_LENGTH; 661 | 662 | assert ((varName != null) && (varName.length() > 0)) : "The parameter 'varName' must not be null or empty."; 663 | assert (varName.length() <= CmdLine.MAX_LENGTH) : "The parameter 'varName' must be less than or equal to " 664 | + CmdLine.MAX_LENGTH; 665 | 666 | assert (command != null) : "The parameter 'command' must not be null."; 667 | 668 | if (varName.contains(" ")) { 669 | throw (new UnsupportedException("Error: The variable name '" + varName 670 | + "' contains spaces which is not supported. The definition may need a comma.")); 671 | } else if ((tokens.size() == 0) && required) { 672 | // if there isnt any info from the command line but this 673 | // variable is required then throw exception. 674 | throw (new MissingException("Error: The value for the required variable '" + varName + "' is missing.")); 675 | } else { 676 | while (!tokens.isEmpty() && !CmdLine.COMMAND_DEFINITION_MAP.containsKey(tokens.get(0))) { 677 | 678 | final String argToken = tokens.remove(0); 679 | 680 | // Process -Dsystem.properties=true if on command line. 681 | final boolean processedSystemProperty = CmdLine.processSystemProperty(argToken, tokens); 682 | 683 | if (!processedSystemProperty && CmdLine.VARIABLE_NAME_SET.contains(varName)) { 684 | 685 | if (pattern != null) { 686 | final Matcher matcher = pattern.matcher(argToken); 687 | final boolean isMatch = matcher.matches(); 688 | if (!isMatch) { 689 | throw (new MatchException("Error: The value '" + argToken 690 | + "' does not match the expected pattern '" + pattern.toString() + "'.")); 691 | } 692 | } 693 | 694 | command.addVariable(varName, argToken); 695 | 696 | } 697 | } 698 | } 699 | } 700 | 701 | /** 702 | * Sets the application name in the cmdline. To be used in the help menu - 703 | * (future release). 704 | * 705 | * @param name 706 | * The name of the application. 707 | * @return The CmdLine instance. Used for chaining calls. 708 | */ 709 | public static CmdLine setApplicationName(final String name) { 710 | Validate.defineString(name).testNotNullEmpty().testMaxLength(CmdLine.MAX_LENGTH) 711 | .throwValidationExceptionOnFail().validate(); 712 | 713 | CmdLine.s_applicationName = name; 714 | return (CmdLine.INSTANCE); 715 | } 716 | 717 | /** 718 | * Sets the listener that will handle the Commands that are created by the 719 | * parser. 720 | * 721 | * @param commandListener 722 | * A listener that will handle the callbacks. 723 | * @return The CmdLine instance. Used for chaining calls. 724 | */ 725 | public static CmdLine setCommandListener(final CommandListener commandListener) { 726 | Validate.defineObject(commandListener).testNotNull().throwValidationExceptionOnFail().validate(); 727 | 728 | CmdLine.s_commandListener = commandListener; 729 | return (CmdLine.INSTANCE); 730 | } 731 | 732 | /** 733 | * The version number of the application using the cmdline. To be used in the 734 | * help menu - (future release). 735 | * 736 | * @param version 737 | * A String value. Must not be null or empty. 738 | * @return The CmdLine instance. Used for chaining calls. 739 | */ 740 | public static CmdLine setVersion(final String version) { 741 | Validate.defineString(version).testNotNullEmpty().throwValidationExceptionOnFail().validate(); 742 | 743 | CmdLine.s_version = version; 744 | return (CmdLine.INSTANCE); 745 | } 746 | 747 | /* 748 | * Converts the command line args.into String tokens. 749 | */ 750 | private static List tokenizeCmdLineArgs(final String[] args) { 751 | assert ((args != null) && (args.length > 0)) : "The parameter 'args' must not be null or empty"; 752 | assert (args.length <= CmdLine.MAX_LENGTH) : "The parameter 'args' must be less than or equal to " 753 | + CmdLine.MAX_LENGTH; 754 | 755 | final List tokens = CmdLine.COMMNAND_LINE_TOKENIZER.tokenize(args); 756 | return (tokens); 757 | } 758 | 759 | private CmdLine() { 760 | // block direct instance 761 | } 762 | 763 | } 764 | -------------------------------------------------------------------------------- /src/main/java/com/gabstudios/cmdline/Command.java: -------------------------------------------------------------------------------- 1 | /***************************************************************************************** 2 | * 3 | * Copyright 2016 Gregory Brown. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | * use this file except in compliance with the License. You may obtain a copy of 7 | * 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, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations under 15 | * the License. 16 | * 17 | ***************************************************************************************** 18 | */ 19 | 20 | package com.gabstudios.cmdline; 21 | 22 | import java.util.ArrayList; 23 | import java.util.HashMap; 24 | import java.util.LinkedList; 25 | import java.util.List; 26 | import java.util.Map; 27 | 28 | 29 | /** 30 | * This class is the command that is created when the command line is parsed. It 31 | * is sent to the CommandListener.handle(Command command) method. 32 | * 33 | * It holds the name and variables of the command. 34 | * 35 | * @author Gregory Brown (sysdevone) 36 | * 37 | */ 38 | public class Command 39 | { 40 | /* 41 | * The name of the command 42 | */ 43 | protected String _name; 44 | 45 | /* 46 | * The variables associated with the command. A variable has a name and 47 | * value. The value is held in a List instance. 48 | */ 49 | protected Map _variables; 50 | 51 | /** 52 | * A Command POJO. Associates a name and creates the data structure that 53 | * holds the variables.F 54 | * 55 | * @param name 56 | * The name of the command. 57 | */ 58 | protected Command(final String name) 59 | { 60 | assert ((name != null) && (name.length() > 0)) : "The parameter 'name' must not be null or empty"; 61 | 62 | this._name = name; 63 | this._variables = new HashMap(); 64 | } 65 | 66 | /** 67 | * Adds a variable to the Command. The value is added to a List 68 | * . 69 | * 70 | * @param name 71 | * The name of the Variable. Must be unique. 72 | * @param value 73 | * The value associated with the name. 74 | */ 75 | public void addVariable(final String name, final String value) 76 | { 77 | assert ((name != null) && (name.length() > 0)) : "The parameter 'name' must not be null or empty"; 78 | assert ((value != null) && (value.length() > 0)) : "The parameter 'value' must not be null or empty"; 79 | 80 | List variables; 81 | if (!this._variables.containsKey(name)) 82 | { 83 | // create list 84 | variables = new LinkedList(); 85 | this._variables.put(name, variables); 86 | 87 | } 88 | else 89 | { 90 | variables = this._variables.get(name); 91 | } 92 | variables.add(value); 93 | } 94 | 95 | /* 96 | * (non-Javadoc) 97 | * 98 | * @see java.lang.Object#equals(java.lang.Object) 99 | */ 100 | @Override 101 | public boolean equals(final Object obj) 102 | { 103 | if (this == obj) { return true; } 104 | if (obj == null) { return false; } 105 | if (this.getClass() != obj.getClass()) { return false; } 106 | final Command other = (Command) obj; 107 | if (this._name == null) 108 | { 109 | if (other._name != null) { return false; } 110 | } 111 | else if (!this._name.equals(other._name)) { return false; } 112 | return true; 113 | } 114 | 115 | /** 116 | * Gets the name 117 | * 118 | * @return A String name. 119 | */ 120 | public String getName() 121 | { 122 | return (this._name); 123 | } 124 | 125 | /** 126 | * Gets the values associated with the variable name. 127 | * 128 | * @param name 129 | * The name of the variable to get the values for. 130 | * @return A new List instance holding one to many Strings. 131 | */ 132 | public List getValues(final String name) 133 | { 134 | final List commandValues = this._variables.get(name); 135 | 136 | // wrap the values into another container so that it is immutable. 137 | final List values = (commandValues != null ? new ArrayList( 138 | commandValues) : new ArrayList()); 139 | return (values); 140 | } 141 | 142 | /* 143 | * (non-Javadoc) 144 | * 145 | * @see java.lang.Object#hashCode() 146 | */ 147 | @Override 148 | public int hashCode() 149 | { 150 | final int prime = 31; 151 | int result = 1; 152 | result = (prime * result) 153 | + ((this._name == null) ? 0 : this._name.hashCode()); 154 | return result; 155 | } 156 | 157 | /** 158 | * A test to see if the Command has any variables associated with it. 159 | * 160 | * @return A boolean value. True if the Command has variables, otherwise it 161 | * is false.F 162 | */ 163 | public boolean hasVariables() 164 | { 165 | return (this._variables.size() > 0); 166 | } 167 | 168 | /* 169 | * (non-Javadoc) 170 | * 171 | * @see java.lang.Object#toString() 172 | */ 173 | @Override 174 | public String toString() 175 | { 176 | return String.format("Command [_name=%s, _variables=%s]", this._name, 177 | this._variables); 178 | } 179 | 180 | } 181 | -------------------------------------------------------------------------------- /src/main/java/com/gabstudios/cmdline/CommandDefinition.java: -------------------------------------------------------------------------------- 1 | /***************************************************************************************** 2 | * 3 | * Copyright 2016 Gregory Brown. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | * use this file except in compliance with the License. You may obtain a copy of 7 | * 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, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations under 15 | * the License. 16 | * 17 | ***************************************************************************************** 18 | */ 19 | 20 | package com.gabstudios.cmdline; 21 | 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | import com.gabstudios.validate.Validate; 26 | 27 | 28 | /** 29 | * This class is a command definition. It is created when the 30 | * CmdLine.defineCommand() is called. 31 | * 32 | * @author Gregory Brown (sysdevone) 33 | * 34 | */ 35 | public class CommandDefinition 36 | { 37 | protected String _description; 38 | protected List _names; 39 | protected String _optionalVariableListName; 40 | protected List _optionalVariables; 41 | protected String _regexValue; 42 | protected String _requiredVariableListName; 43 | protected List _requiredVariables; 44 | 45 | /* 46 | * Constructor 47 | * 48 | */ 49 | protected CommandDefinition() 50 | { 51 | this._names = new ArrayList(); 52 | this._requiredVariables = new ArrayList(); 53 | this._optionalVariables = new ArrayList(); 54 | } 55 | 56 | protected String getDescription() 57 | { 58 | return (this._description); 59 | } 60 | 61 | protected String getRegexValue() 62 | { 63 | return (this._regexValue); 64 | } 65 | 66 | protected void addName(final String name) 67 | { 68 | Validate.defineString(name).testNotNullEmpty() 69 | .throwValidationExceptionOnFail().validate(); 70 | 71 | this._names.add(name); 72 | } 73 | 74 | protected void addOptionalVariable(final String name) 75 | { 76 | this._optionalVariables.add(name); 77 | } 78 | 79 | protected void setOptionalVariableList(final String name) 80 | { 81 | this._optionalVariableListName = name; 82 | } 83 | 84 | protected void addRequiredVariable(final String name) 85 | { 86 | this._requiredVariables.add(name); 87 | } 88 | 89 | protected void setRequiredVariableList(final String name) 90 | { 91 | this._requiredVariableListName = name; 92 | } 93 | 94 | protected List getOptionalVariableNames() 95 | { 96 | return (this._optionalVariables); 97 | } 98 | 99 | protected String getOptionalVariableListName() 100 | { 101 | return (this._optionalVariableListName); 102 | } 103 | 104 | protected List getRequiredVariableNames() 105 | { 106 | return (this._requiredVariables); 107 | } 108 | 109 | protected String getRequiredVariableListName() 110 | { 111 | return (this._requiredVariableListName); 112 | } 113 | 114 | /* 115 | * (non-Javadoc) 116 | * 117 | * @see java.lang.Object#equals(java.lang.Object) 118 | */ 119 | @Override 120 | public boolean equals(final Object obj) 121 | { 122 | if (this == obj) { return true; } 123 | if (obj == null) { return false; } 124 | if (this.getClass() != obj.getClass()) { return false; } 125 | final CommandDefinition other = (CommandDefinition) obj; 126 | if (this._names == null) 127 | { 128 | if (other._names != null) { return false; } 129 | } 130 | else if (!this._names.equals(other._names)) { return false; } 131 | return true; 132 | } 133 | 134 | protected List getNames() 135 | { 136 | return (this._names); 137 | } 138 | 139 | /* 140 | * (non-Javadoc) 141 | * 142 | * @see java.lang.Object#hashCode() 143 | */ 144 | @Override 145 | public int hashCode() 146 | { 147 | final int prime = 31; 148 | int result = 1; 149 | result = (prime * result) 150 | + ((this._names == null) ? 0 : this._names.hashCode()); 151 | return result; 152 | } 153 | 154 | protected boolean hasOptionalVariableLists() 155 | { 156 | return (this._optionalVariableListName != null && this._optionalVariableListName 157 | .length() > 0); 158 | } 159 | protected boolean hasOptionalVariables() 160 | { 161 | return (this._optionalVariables.size() > 0); 162 | } 163 | 164 | protected boolean hasRequiredVariableLists() 165 | { 166 | return (this._requiredVariableListName != null && this._requiredVariableListName 167 | .length() > 0); 168 | } 169 | 170 | protected boolean hasRequiredVariables() 171 | { 172 | return (this._requiredVariables.size() > 0); 173 | } 174 | 175 | protected void setDescription(final String description) 176 | { 177 | Validate.defineString(description).testNotNullEmpty() 178 | .throwValidationExceptionOnFail().validate(); 179 | 180 | this._description = description; 181 | } 182 | 183 | protected void setRegexValue(final String regexValue) 184 | { 185 | Validate.defineString(regexValue).testNotNullEmpty() 186 | .throwValidationExceptionOnFail().validate(); 187 | 188 | this._regexValue = regexValue; 189 | } 190 | 191 | /* 192 | * (non-Javadoc) 193 | * 194 | * @see java.lang.Object#toString() 195 | */ 196 | @Override 197 | public String toString() 198 | { 199 | return String 200 | .format("CommandDefinition [_description=%s, _names=%s, _optionalVariableListName=%s, _optionalVariables=%s, _regexValue=%s, _requiredVariableListName=%s, _requiredVariables=%s]", 201 | this._description, this._names, 202 | this._optionalVariableListName, 203 | this._optionalVariables, this._regexValue, 204 | this._requiredVariableListName, this._requiredVariables); 205 | } 206 | 207 | } 208 | -------------------------------------------------------------------------------- /src/main/java/com/gabstudios/cmdline/CommandLineTokenizer.java: -------------------------------------------------------------------------------- 1 | /***************************************************************************************** 2 | * 3 | * Copyright 2016 Gregory Brown. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | * use this file except in compliance with the License. You may obtain a copy of 7 | * 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, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations under 15 | * the License. 16 | * 17 | ***************************************************************************************** 18 | */ 19 | 20 | package com.gabstudios.cmdline; 21 | 22 | import java.util.LinkedList; 23 | import java.util.List; 24 | 25 | import com.gabstudios.logging.LogProvider; 26 | import com.gabstudios.logging.LogService; 27 | 28 | 29 | /* 30 | * This class is used to tokenize the values from the command line. 31 | * 32 | * This parser is able to handle equals, commas and a value. 33 | * 34 | * The order of priority is: equals, commas and value. 35 | * 36 | * It will produce a List of String values. 37 | * 38 | * @author Gregory Brown (sysdevone) 39 | * 40 | */ 41 | public class CommandLineTokenizer 42 | { 43 | 44 | /* 45 | * Constructor. 46 | */ 47 | protected CommandLineTokenizer() 48 | { 49 | // void do nothing. 50 | } 51 | 52 | /* 53 | * Tokenize the command line arguments. 54 | * 55 | * @param args An array of String 56 | * 57 | * @return A new List instance. 58 | */ 59 | protected List tokenize(final String[] args) 60 | { 61 | assert( args != null && args.length > 0 ) : "The parameter 'args' must not be null or empty"; 62 | 63 | //TODO - add assert for max length. 64 | 65 | final LogService logService = LogProvider.getProvider().getService(); 66 | 67 | // process spaces - taken care of by command line. 68 | final LinkedList tokenList = new LinkedList(); 69 | 70 | // 71 | // Loop through all of the args. 72 | // --------------------------- 73 | for( String argString : args ) 74 | { 75 | 76 | logService.logDebug(this.getClass(), "tokenize", 77 | "Before equals split: " + argString); 78 | 79 | // 80 | // Tokenize the values using the EQUALS as a delimiter and process. 81 | // --------------------------- 82 | final String[] argsAfterEquals = argString.split("="); 83 | 84 | logService.logDebug(this.getClass(), "tokenize", 85 | "After equals split length: " + argsAfterEquals.length); 86 | 87 | // 88 | // Process tokens after using EQUALS as a delimiter. 89 | // --------------------------- 90 | for( String argAfterEqual :argsAfterEquals) 91 | { 92 | 93 | logService.logDebug(this.getClass(), "tokenize", 94 | "Before comma split: " + argAfterEqual); 95 | 96 | // 97 | // Tokenize the values using the COMMA as a delimiter and process. 98 | // --------------------------- 99 | final String[] argsAfterCommas = argAfterEqual.split(","); 100 | 101 | logService.logDebug(this.getClass(), "tokenize", 102 | "After comma split length: " + argsAfterCommas.length); 103 | 104 | // 105 | // Process tokens after using COMMA as a delimiter. 106 | // --------------------------- 107 | for( String argAfterComma : argsAfterCommas) 108 | { 109 | // Add tokens within the commas. 110 | // values 111 | if (argAfterComma.length() > 0) 112 | { 113 | tokenList.add(argAfterComma.trim()); 114 | } 115 | } 116 | 117 | // 118 | // After processing args for commas, add the previous token if it is not a comma. 119 | // --------------------------- 120 | if (argsAfterCommas.length == 0) 121 | { 122 | if (argAfterEqual.equals(",")) 123 | { 124 | // ignore. 125 | } 126 | else if (argAfterEqual.length() > 0) 127 | { 128 | tokenList.add(argAfterEqual.trim()); 129 | } 130 | } 131 | 132 | } 133 | 134 | // 135 | // After processing args for equals, add the previous token if it is not a equal. 136 | // --------------------------- 137 | if (argsAfterEquals.length == 0) 138 | { 139 | if (argString.equals("=")) 140 | { 141 | // ignore. 142 | } 143 | else if (argString.length() > 0) 144 | { 145 | // values if no equals found. 146 | // is the value a java system property key: -DsetSomthing? 147 | // 148 | tokenList.add(argString.trim()); 149 | 150 | } 151 | } 152 | 153 | } 154 | 155 | return (tokenList); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/main/java/com/gabstudios/cmdline/CommandListener.java: -------------------------------------------------------------------------------- 1 | /***************************************************************************************** 2 | * 3 | * Copyright 2016 Gregory Brown. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | * use this file except in compliance with the License. You may obtain a copy of 7 | * 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, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations under 15 | * the License. 16 | * 17 | ***************************************************************************************** 18 | */ 19 | 20 | package com.gabstudios.cmdline; 21 | 22 | /** 23 | * This interface handles the Command instances that are processed 24 | * when the parse(...) method is called. 25 | * 26 | * 27 | * @author Gregory Brown (sysdevone) 28 | * 29 | */ 30 | public interface CommandListener 31 | { 32 | /** 33 | * Handles the parser callbacks when a Command is created. 34 | * @param command A Command instance. 35 | */ 36 | public void handle(Command command); 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/gabstudios/cmdline/DefinedCommandTokenizer.java: -------------------------------------------------------------------------------- 1 | /***************************************************************************************** 2 | * 3 | * Copyright 2016 Gregory Brown. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | * use this file except in compliance with the License. You may obtain a copy of 7 | * 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, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations under 15 | * the License. 16 | * 17 | ***************************************************************************************** 18 | */ 19 | 20 | package com.gabstudios.cmdline; 21 | 22 | import java.util.LinkedList; 23 | import java.util.List; 24 | 25 | import com.gabstudios.logging.LogProvider; 26 | import com.gabstudios.logging.LogService; 27 | 28 | 29 | /** 30 | * This class is used to tokenize the values from the command line. 31 | * 32 | * This parser is able to handle equals, commas and a value. 33 | * 34 | * The order of priority is: equals, commas and value. 35 | * 36 | * It will produce a List of String values. 37 | * 38 | * @author Gregory Brown (sysdevone) 39 | * 40 | */ 41 | public class DefinedCommandTokenizer 42 | { 43 | /* 44 | * Constructor. 45 | */ 46 | protected DefinedCommandTokenizer() 47 | { 48 | // void - do nothing. 49 | } 50 | 51 | /* 52 | * Creates a token based on the first char. 53 | * 54 | * A String must use one of these symbols in order for it to be recognized 55 | * as that type: 56 | * 57 | * # = The description of the command. There may be zero to one defined. 58 | * 59 | * ! = A required value for the command name. There can be zero to many 60 | * defined. 61 | * 62 | * ? = An optional value for the command name. There can be zero to many 63 | * defined. 64 | * 65 | * : = The regex value to match on for any values that are defined. There 66 | * can be zero to one defined. 67 | * 68 | * 69 | * @param inputString 70 | * @param tokenList 71 | */ 72 | private static void createToken(final String inputString, 73 | final List tokenList) 74 | { 75 | 76 | assert( inputString != null && inputString.length() > 0 ) : "The parameter 'inputString' must not be null or empty"; 77 | assert( tokenList != null) : "The parameter 'tokenList' must not be null"; 78 | //TODO - add assert for max length. 79 | 80 | if (inputString.startsWith("#")) 81 | { 82 | tokenList.add(new Token(Token.Type.DESCRIPTION, inputString 83 | .substring(1))); 84 | } 85 | else if (inputString.startsWith("!") || inputString.startsWith("?")) 86 | { 87 | DefinedCommandTokenizer.handleListValue(inputString, tokenList); 88 | } 89 | else if (inputString.startsWith(":")) 90 | { 91 | tokenList.add(new Token(Token.Type.REGEX_VALUE, inputString 92 | .substring(1))); 93 | } 94 | else 95 | { 96 | tokenList.add(new Token(Token.Type.COMMAND, inputString)); 97 | } 98 | } 99 | 100 | /* 101 | * Creates a token based on the first char. 102 | * 103 | * A String must use one of these symbols in order for it to be recognized 104 | * as that type: 105 | * 106 | * ! = A required value for the command name. There can be zero to many 107 | * defined. 108 | * 109 | * ? = An optional value for the command name. There can be zero to many 110 | * defined. 111 | * 112 | * ... = A value ends with ... and is a list for the command name. There can 113 | * be zero to one defined. This can be used with the ! and ? symbols 114 | * 115 | * 116 | * @param inputString 117 | * @param tokenList 118 | */ 119 | 120 | private static void handleListValue(final String inputString, 121 | final List tokenList) 122 | { 123 | 124 | assert( inputString != null && inputString.length() > 0 ) : "The parameter 'inputString' must not be null or empty"; 125 | assert( tokenList != null) : "The parameter 'tokenList' must not be null"; 126 | //TODO - add assert for max length. 127 | 128 | if (inputString.startsWith("!") && inputString.endsWith("...")) 129 | { 130 | int length = inputString.length() - 3; 131 | tokenList.add(new Token(Token.Type.REQUIRED_LIST_VALUE, inputString 132 | .substring(1, length))); 133 | } 134 | else if (inputString.startsWith("!")) 135 | { 136 | tokenList.add(new Token(Token.Type.REQUIRED_VALUE, inputString 137 | .substring(1))); 138 | } 139 | else if (inputString.startsWith("?") && inputString.endsWith("...")) 140 | { 141 | int length = inputString.length() - 3; 142 | tokenList.add(new Token(Token.Type.OPTIONAL_LIST_VALUE, inputString 143 | .substring(1, length))); 144 | } 145 | else if (inputString.startsWith("?")) 146 | { 147 | tokenList.add(new Token(Token.Type.OPTIONAL_VALUE, inputString 148 | .substring(1))); 149 | } 150 | } 151 | 152 | /* 153 | * Tokenize the values that were defined. 154 | * 155 | * @param args 156 | * An array of String containing one to many values. 157 | * @return A List instance. May return an empty List if input is empty or nothing is processed. 158 | */ 159 | protected List tokenize(final String[] args) 160 | { 161 | //assert( args != null && args.length > 0 ) : "The parameter 'args' must not be null or empty"; 162 | //TODO - add assert for max length. 163 | 164 | // process spaces - taken care of by command line. 165 | final LinkedList tokenList = new LinkedList(); 166 | 167 | if (args != null && args.length > 0) 168 | { 169 | final LogService logService = LogProvider.getProvider() 170 | .getService(); 171 | 172 | // 173 | // Tokenize the values using the EQUALS as a delimiter and process. 174 | // --------------------------- 175 | for (String argString : args) 176 | { 177 | // equals 178 | logService.logDebug(this.getClass(), "tokenize", 179 | "Before equals split: " + argString); 180 | 181 | // 182 | // Tokenize the values using the EQUALS as a delimiter and process. 183 | // --------------------------- 184 | final String[] argsAfterEquals = argString.split("="); 185 | 186 | logService.logDebug(this.getClass(), "tokenize", 187 | "After equals split length: " + argsAfterEquals.length); 188 | 189 | // 190 | // Process tokens after using EQUALS as a delimiter. 191 | // --------------------------- 192 | for (String argAfterEquals : argsAfterEquals) 193 | { 194 | 195 | // commas 196 | 197 | logService.logDebug(this.getClass(), "tokenize", 198 | "Before comma split: " + argAfterEquals); 199 | 200 | // 201 | // Tokenize the values using the COMMA as a delimiter and process. 202 | // --------------------------- 203 | final String[] argsAfterCommas = argAfterEquals.split(","); 204 | 205 | logService.logDebug(this.getClass(), "tokenize", 206 | "After comma split length: " 207 | + argsAfterCommas.length); 208 | // 209 | // Process tokens after using COMMA as a delimiter. 210 | // --------------------------- 211 | for (String argAfterComma : argsAfterCommas) 212 | { 213 | 214 | // values 215 | if (argAfterComma.length() > 0) 216 | { 217 | DefinedCommandTokenizer.createToken(argAfterComma, 218 | tokenList); 219 | } 220 | } 221 | // 222 | // After processing args for commas, add the previous token if it is not a comma. 223 | // --------------------------- 224 | if (argsAfterCommas.length == 0) 225 | { 226 | if (argAfterEquals.equals(",")) 227 | { 228 | // ignore. 229 | } 230 | else if (argAfterEquals.length() > 0) 231 | { 232 | DefinedCommandTokenizer.createToken(argAfterEquals, 233 | tokenList); 234 | } 235 | } 236 | 237 | } 238 | 239 | // 240 | // After processing args for equals, add the previous token if it is not a equal. 241 | // --------------------------- 242 | if (argsAfterEquals.length == 0) 243 | { 244 | if (argString.equals("=")) 245 | { 246 | // ignore. 247 | } 248 | else if (argString.length() > 0) 249 | { 250 | tokenList.add(new Token(Token.Type.COMMAND, argString)); 251 | } 252 | } 253 | 254 | } 255 | } 256 | return (tokenList); 257 | } 258 | } 259 | -------------------------------------------------------------------------------- /src/main/java/com/gabstudios/cmdline/DuplicateException.java: -------------------------------------------------------------------------------- 1 | /***************************************************************************************** 2 | * 3 | * Copyright 2016 Gregory Brown. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | * use this file except in compliance with the License. You may obtain a copy of 7 | * 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, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations under 15 | * the License. 16 | * 17 | ***************************************************************************************** 18 | */ 19 | 20 | package com.gabstudios.cmdline; 21 | 22 | /** 23 | * An exception that is used if a command or variable are already defined. 24 | * 25 | * 26 | * @author Gregory Brown (sysdevone) 27 | * 28 | */ 29 | public class DuplicateException extends RuntimeException 30 | { 31 | 32 | /** 33 | * Serialized version number. 34 | */ 35 | private static final long serialVersionUID = -195256277725680146L; 36 | 37 | /** 38 | * Constructor that takes a message. 39 | * 40 | * @param message 41 | * A String message. 42 | */ 43 | protected DuplicateException(final String message) 44 | { 45 | super(message); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/gabstudios/cmdline/MatchException.java: -------------------------------------------------------------------------------- 1 | /***************************************************************************************** 2 | * 3 | * Copyright 2016 Gregory Brown. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | * use this file except in compliance with the License. You may obtain a copy of 7 | * 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, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations under 15 | * the License. 16 | * 17 | ***************************************************************************************** 18 | */ 19 | 20 | package com.gabstudios.cmdline; 21 | 22 | /** 23 | * An exception that is used if a match fails when the regex value has been defined. 24 | * 25 | * 26 | * @author Gregory Brown (sysdevone) 27 | * 28 | */ 29 | public class MatchException extends RuntimeException 30 | { 31 | 32 | /** 33 | * Serialized version number. 34 | */ 35 | private static final long serialVersionUID = 2425601012570939723L; 36 | 37 | /** 38 | * Constructor that takes a message. 39 | * 40 | * @param message 41 | * A String message. 42 | */ 43 | protected MatchException(final String message) 44 | { 45 | super(message); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/gabstudios/cmdline/MissingException.java: -------------------------------------------------------------------------------- 1 | /***************************************************************************************** 2 | * 3 | * Copyright 2016 Gregory Brown. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | * use this file except in compliance with the License. You may obtain a copy of 7 | * 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, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations under 15 | * the License. 16 | * 17 | ***************************************************************************************** 18 | */ 19 | 20 | package com.gabstudios.cmdline; 21 | 22 | /** 23 | * An exception that is used if a required token or arg is missing. 24 | * 25 | * 26 | * @author Gregory Brown (sysdevone) 27 | * 28 | */ 29 | public class MissingException extends RuntimeException 30 | { 31 | 32 | /** 33 | * Serialized version number. 34 | */ 35 | private static final long serialVersionUID = 1339875153427052412L; 36 | 37 | /** 38 | * Constructor that takes a message. 39 | * 40 | * @param message 41 | * A String message. 42 | */ 43 | protected MissingException(final String message) 44 | { 45 | super(message); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/gabstudios/cmdline/Token.java: -------------------------------------------------------------------------------- 1 | /***************************************************************************************** 2 | * 3 | * Copyright 2016 Gregory Brown. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | * use this file except in compliance with the License. You may obtain a copy of 7 | * 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, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations under 15 | * the License. 16 | * 17 | ***************************************************************************************** 18 | */ 19 | 20 | package com.gabstudios.cmdline; 21 | 22 | /** 23 | * This is used by the DefinedCommandTokenizer to represent the different types of settings. 24 | * 25 | * The types are: 26 | * 27 | * COMMAND - The command that will have variables. 28 | * DESCRIPTION - A description of what the command does. 29 | * REQUIRED_VALUE = A required variable of the command. 30 | * OPTIONAL_VALUE = An optional variable of the command. 31 | * REGEX_VALUE = A regex that will be used to validate the data within a VALUE 32 | * REQUIRED_LIST_VALUE = A required variable that will have one to many values. 33 | * OPTIONAL_LIST_VALUE = An optional variable that will have zero to many values. 34 | * 35 | * @author Gregory Brown (sysdevone) 36 | * 37 | */ 38 | public class Token 39 | { 40 | /* 41 | * The type of token. 42 | */ 43 | protected enum Type 44 | { 45 | COMMAND, DESCRIPTION, REQUIRED_VALUE, OPTIONAL_VALUE, REGEX_VALUE, REQUIRED_LIST_VALUE, OPTIONAL_LIST_VALUE 46 | } 47 | 48 | /* 49 | * The type of token. 50 | */ 51 | private final Type _type; 52 | 53 | /* 54 | * The String value of the token. 55 | */ 56 | private final String _value; 57 | 58 | /* 59 | * Constructor. 60 | */ 61 | protected Token(final Type type) 62 | { 63 | assert (type != null) : "The parameter 'type' must not be null"; 64 | 65 | this._type = type; 66 | this._value = null; 67 | } 68 | 69 | /* 70 | * Constructor. 71 | */ 72 | protected Token(final Type type, final String value) 73 | { 74 | assert (type != null) : "The parameter 'type' must not be null"; 75 | assert (value != null && value.length() > 0) : "The parameter 'value' must not be null or empty"; 76 | 77 | this._type = type; 78 | this._value = value; 79 | } 80 | 81 | /* 82 | * (non-Javadoc) 83 | * 84 | * @see java.lang.Object#equals(java.lang.Object) 85 | */ 86 | @Override 87 | public boolean equals(final Object obj) 88 | { 89 | if (this == obj) { return true; } 90 | if (obj == null) { return false; } 91 | if (this.getClass() != obj.getClass()) { return false; } 92 | final Token other = (Token) obj; 93 | if (this._type != other._type) { return false; } 94 | if (this._value == null) 95 | { 96 | if (other._value != null) { return false; } 97 | } 98 | else if (!this._value.equals(other._value)) { return false; } 99 | return true; 100 | } 101 | 102 | /* 103 | * Get the type. 104 | * @return The Type of token. 105 | */ 106 | protected Type getType() 107 | { 108 | return (this._type); 109 | } 110 | 111 | /* 112 | * Get the value of the token. 113 | * @return A String instance. May not be null or empty. 114 | */ 115 | protected String getValue() 116 | { 117 | return (this._value); 118 | } 119 | 120 | /* 121 | * (non-Javadoc) 122 | * 123 | * @see java.lang.Object#hashCode() 124 | */ 125 | @Override 126 | public int hashCode() 127 | { 128 | final int prime = 31; 129 | int result = 1; 130 | result = (prime * result) 131 | + ((this._type == null) ? 0 : this._type.hashCode()); 132 | result = (prime * result) 133 | + ((this._value == null) ? 0 : this._value.hashCode()); 134 | return result; 135 | } 136 | 137 | /* 138 | * (non-Javadoc) 139 | * 140 | * @see java.lang.Object#toString() 141 | */ 142 | @Override 143 | public String toString() 144 | { 145 | return String.format("Token [_value='%s', _type='%s']", this._value, 146 | this._type); 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /src/main/java/com/gabstudios/cmdline/UnsupportedException.java: -------------------------------------------------------------------------------- 1 | /***************************************************************************************** 2 | * 3 | * Copyright 2016 Gregory Brown. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | * use this file except in compliance with the License. You may obtain a copy of 7 | * 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, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations under 15 | * the License. 16 | * 17 | ***************************************************************************************** 18 | */ 19 | 20 | package com.gabstudios.cmdline; 21 | 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | 26 | /** 27 | * An exception that is used if an action is not supported. 28 | * 29 | * 30 | * @author Gregory Brown (sysdevone) 31 | * 32 | */ 33 | public class UnsupportedException extends RuntimeException 34 | { 35 | 36 | /** 37 | * Serialized version number. 38 | */ 39 | private static final long serialVersionUID = 2473729829921263263L; 40 | 41 | /** 42 | * Holds possible suggestions to return to the user. 43 | */ 44 | private List _suggestionList; 45 | 46 | /** 47 | * Constructor that takes a message. 48 | * 49 | * @param message 50 | * A String message. 51 | */ 52 | protected UnsupportedException(final String message) 53 | { 54 | super(message); 55 | } 56 | 57 | /** 58 | * Constructor that takes a message. 59 | * 60 | * @param message 61 | * A String message. 62 | * @param suggestionList 63 | * A List of possible suggestions to return to the 64 | * user if the command was misspelled 65 | */ 66 | public UnsupportedException(final String message, 67 | final List suggestionList) 68 | { 69 | super(message); 70 | this._suggestionList = new ArrayList(suggestionList); 71 | } 72 | 73 | /** 74 | * Gets a List of suggestion alternatives. 75 | * 76 | * @return A List instance containing zero to many 77 | * Stringinstances. 78 | */ 79 | public List getSuggestionList() 80 | { 81 | return (this._suggestionList); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/test/java/com/gabstudios/cmdline/CmdLineNegativeTest.java: -------------------------------------------------------------------------------- 1 | /***************************************************************************************** 2 | * 3 | * Copyright 2015 Gregory Brown. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | * use this file except in compliance with the License. You may obtain a copy of 7 | * 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, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations under 15 | * the License. 16 | * 17 | ***************************************************************************************** 18 | */ 19 | 20 | package com.gabstudios.cmdline; 21 | 22 | import com.gabstudios.validate.ValidateException; 23 | import org.junit.After; 24 | import org.junit.Assert; 25 | import org.junit.Before; 26 | import org.junit.Test; 27 | 28 | 29 | /** 30 | * 31 | * 32 | * @author Gregory Brown (sysdevone) 33 | * 34 | */ 35 | public class CmdLineNegativeTest 36 | { 37 | 38 | @Before 39 | public void setUp() 40 | { 41 | } 42 | 43 | @After 44 | public void tearDown() 45 | { 46 | CmdLine.clear(); 47 | } 48 | 49 | 50 | @Test 51 | public void testDefineNoCommand() 52 | { 53 | 54 | try 55 | { 56 | 57 | CmdLine.defineCommand("!fileName, ?fileName1, :file\\d.txt, #Load files into the system"); 58 | 59 | Assert.fail(); 60 | } 61 | catch (MissingException e) 62 | { 63 | Assert.assertTrue(true); 64 | } 65 | } 66 | 67 | @Test 68 | public void testDefineCommand() 69 | { 70 | 71 | try 72 | { 73 | 74 | CmdLine.defineCommand("file, !fileName, ?fileName, :file\\d.txt, #Load files into the system"); 75 | 76 | Assert.fail(); 77 | } 78 | catch (DuplicateException e) 79 | { 80 | Assert.assertTrue(true); 81 | } 82 | } 83 | 84 | @Test 85 | public void testDefineCommand2() 86 | { 87 | 88 | try 89 | { 90 | 91 | CmdLine.defineCommand("file, file, !fileName, :file\\d.txt, #Load files into the system"); 92 | 93 | Assert.fail(); 94 | } 95 | catch (DuplicateException e) 96 | { 97 | Assert.assertTrue(true); 98 | } 99 | } 100 | 101 | @Test 102 | public void testDefineCommand3() 103 | { 104 | 105 | try 106 | { 107 | 108 | CmdLine.defineCommand("file, !fileName, :file\\d.txt, :file\\d.txt, #Load files into the system"); 109 | 110 | Assert.fail(); 111 | } 112 | catch (DuplicateException e) 113 | { 114 | Assert.assertTrue(true); 115 | } 116 | } 117 | 118 | @Test 119 | public void testDefineCommand4() 120 | { 121 | 122 | try 123 | { 124 | 125 | CmdLine.defineCommand("file, !fileName, :file\\d.txt, #Load files into the system, #Load files into the system"); 126 | 127 | Assert.fail(); 128 | } 129 | catch (DuplicateException e) 130 | { 131 | Assert.assertTrue(true); 132 | } 133 | } 134 | 135 | @Test 136 | public void testDefineCommand5() 137 | { 138 | 139 | try 140 | { 141 | 142 | CmdLine.defineCommand("file !fileName :file\\d.txt #Load files into the system"); 143 | 144 | Assert.fail(); 145 | } 146 | catch (UnsupportedException e) 147 | { 148 | Assert.assertTrue(true); 149 | } 150 | } 151 | 152 | @Test 153 | public void testDefineCommand6() 154 | { 155 | 156 | try 157 | { 158 | 159 | CmdLine.defineCommand("file, !fileNames..., ?fileNames..."); 160 | 161 | Assert.fail(); 162 | } 163 | catch (UnsupportedException e) 164 | { 165 | Assert.assertTrue(true); 166 | } 167 | 168 | } 169 | 170 | @Test 171 | public void testDefineCommand7() 172 | { 173 | 174 | try 175 | { 176 | 177 | CmdLine.defineCommand("file, ?fileNames..., !fileNames2..."); 178 | 179 | Assert.fail(); 180 | } 181 | catch (UnsupportedException e) 182 | { 183 | Assert.assertTrue(true); 184 | } 185 | } 186 | 187 | @Test 188 | public void testDefineCommand8() 189 | { 190 | 191 | CmdLine.defineCommand("file, !file1, !file2"); 192 | 193 | final String[] args = new String[3]; 194 | args[0] = "file"; 195 | args[1] = "="; 196 | args[2] = "file1.txt"; 197 | 198 | try 199 | { 200 | CmdLine.parse(args); 201 | 202 | Assert.fail(); 203 | } 204 | catch (MissingException e) 205 | { 206 | Assert.assertTrue(true); 207 | } 208 | } 209 | 210 | @Test 211 | public void testDefineCommand9() 212 | { 213 | 214 | CmdLine.defineCommand("file, !file, !files..."); 215 | 216 | final String[] args = new String[3]; 217 | args[0] = "file"; 218 | args[1] = "="; 219 | args[2] = "file1.txt"; 220 | 221 | try 222 | { 223 | CmdLine.parse(args); 224 | 225 | Assert.fail(); 226 | } 227 | catch (MissingException e) 228 | { 229 | Assert.assertTrue(true); 230 | } 231 | } 232 | 233 | @Test 234 | public void testDefineCommand10() 235 | { 236 | 237 | CmdLine.defineCommand("file, !file"); 238 | 239 | final String[] args = new String[3]; 240 | args[0] = "install"; 241 | args[1] = "="; 242 | args[2] = "file1.txt"; 243 | 244 | try 245 | { 246 | CmdLine.parse(args); 247 | 248 | Assert.fail(); 249 | } 250 | catch (UnsupportedException e) 251 | { 252 | Assert.assertTrue(true); 253 | } 254 | } 255 | 256 | @Test 257 | public void testDefineCommand11() 258 | { 259 | 260 | try 261 | { 262 | 263 | CmdLine.defineCommand("file, ?fileName1, !fileNames2"); 264 | 265 | Assert.fail(); 266 | } 267 | catch (UnsupportedException e) 268 | { 269 | Assert.assertTrue(true); 270 | } 271 | } 272 | 273 | @Test 274 | public void testDefineCommand12() 275 | { 276 | 277 | try 278 | { 279 | 280 | CmdLine.defineCommand(""); 281 | 282 | Assert.fail(); 283 | } 284 | catch (ValidateException e) 285 | { 286 | Assert.assertTrue(true); 287 | } 288 | } 289 | 290 | @Test 291 | public void testDefineCommand13() 292 | { 293 | 294 | try 295 | { 296 | 297 | CmdLine.defineCommand(); 298 | 299 | Assert.fail(); 300 | } 301 | catch (ValidateException e) 302 | { 303 | Assert.assertTrue(true); 304 | } 305 | } 306 | 307 | @Test 308 | public void testDefineCommand14() 309 | { 310 | 311 | try 312 | { 313 | 314 | CmdLine.defineCommand(" "); 315 | 316 | Assert.fail(); 317 | } 318 | catch (UnsupportedException e) 319 | { 320 | Assert.assertTrue(true); 321 | } 322 | } 323 | 324 | } 325 | -------------------------------------------------------------------------------- /src/test/java/com/gabstudios/cmdline/CmdLineTest.java: -------------------------------------------------------------------------------- 1 | /***************************************************************************************** 2 | * 3 | * Copyright 2015 Gregory Brown. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | * use this file except in compliance with the License. You may obtain a copy of 7 | * 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, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations under 15 | * the License. 16 | * 17 | ***************************************************************************************** 18 | */ 19 | 20 | package com.gabstudios.cmdline; 21 | 22 | import java.util.HashMap; 23 | import java.util.List; 24 | import java.util.Map; 25 | 26 | import org.junit.After; 27 | import org.junit.Assert; 28 | import org.junit.Before; 29 | import org.junit.Test; 30 | 31 | 32 | /** 33 | * 34 | * 35 | * @author Gregory Brown (sysdevone) 36 | * 37 | */ 38 | public class CmdLineTest 39 | { 40 | private class CmdLineListener implements CommandListener 41 | { 42 | 43 | private final Map _commandMap = new HashMap(); 44 | 45 | public Command getCommand(final String name) 46 | { 47 | return (this._commandMap.get(name)); 48 | } 49 | 50 | public int getCount() 51 | { 52 | return (this._commandMap.size()); 53 | } 54 | 55 | @Override 56 | public void handle(final Command command) 57 | { 58 | this._commandMap.put(command.getName(), command); 59 | 60 | // System.out.println( command ); 61 | } 62 | } 63 | 64 | @Before 65 | public void setUp() 66 | { 67 | // void 68 | } 69 | 70 | @After 71 | public void tearDown() 72 | { 73 | CmdLine.clear(); 74 | } 75 | 76 | @Test 77 | public void testDefineCommand() 78 | { 79 | 80 | final CmdLineListener listener = new CmdLineListener(); 81 | CmdLine.setCommandListener(listener); 82 | 83 | CmdLine.defineCommand("file , !fileName1,:file\\d.txt, #Load files into the system"); 84 | 85 | final String[] args = new String[1]; 86 | args[0] = "file=file1.txt"; 87 | 88 | try 89 | { 90 | CmdLine.parse(args); 91 | 92 | Assert.assertTrue(listener.getCount() == 1); 93 | 94 | final Command command = listener.getCommand("file"); 95 | Assert.assertTrue(command != null); 96 | 97 | final List values = command.getValues("fileName1"); 98 | Assert.assertTrue(values != null); 99 | Assert.assertTrue(values.size() > 0); 100 | 101 | final String value = values.get(0); 102 | Assert.assertTrue(value != null); 103 | Assert.assertTrue(value.length() > 0); 104 | Assert.assertTrue(value.equals("file1.txt")); 105 | 106 | Assert.assertTrue(true); 107 | } 108 | catch (final Exception e) 109 | { 110 | Assert.fail(e.toString()); 111 | } 112 | 113 | } 114 | 115 | @Test 116 | public void testDefineCommand1() 117 | { 118 | final CmdLineListener listener = new CmdLineListener(); 119 | CmdLine.setCommandListener(listener); 120 | 121 | CmdLine.defineCommand("file, !fileName1, :file\\d.txt, #Load a files into the system"); 122 | 123 | final String[] args = new String[1]; 124 | args[0] = "file = file1.txt"; 125 | 126 | try 127 | { 128 | CmdLine.parse(args); 129 | 130 | Assert.assertTrue(listener.getCount() == 1); 131 | 132 | final Command command = listener.getCommand("file"); 133 | Assert.assertTrue(command != null); 134 | Assert.assertTrue(command.hasVariables()); 135 | 136 | final List values = command.getValues("fileName1"); 137 | Assert.assertTrue(values != null); 138 | Assert.assertTrue(values.size() > 0); 139 | 140 | final String value = values.get(0); 141 | Assert.assertTrue(value != null); 142 | Assert.assertTrue(value.length() > 0); 143 | Assert.assertTrue(value.equals("file1.txt")); 144 | 145 | Assert.assertTrue(true); 146 | } 147 | catch (final Exception e) 148 | { 149 | Assert.fail(e.toString()); 150 | } 151 | 152 | } 153 | 154 | @Test 155 | public void testDefineCommand1a() 156 | { 157 | final CmdLineListener listener = new CmdLineListener(); 158 | CmdLine.setCommandListener(listener); 159 | 160 | CmdLine.defineCommand("-f, --file, !fileName1, ?fileName2, ?fileName3, :file\\d.txt, #Load a files into the system"); 161 | 162 | final String[] args = new String[1]; 163 | args[0] = "-f=file1.txt, file2.txt, file3.txt"; 164 | 165 | try 166 | { 167 | CmdLine.parse(args); 168 | 169 | Assert.assertTrue(listener.getCount() == 1); 170 | 171 | final Command command = listener.getCommand("-f"); 172 | Assert.assertTrue(command != null); 173 | Assert.assertTrue(command.hasVariables()); 174 | 175 | List values = command.getValues("fileName1"); 176 | Assert.assertTrue(values != null); 177 | Assert.assertTrue(values.size() == 1); 178 | 179 | String value = values.get(0); 180 | Assert.assertTrue(value != null); 181 | Assert.assertTrue(value.length() > 0); 182 | Assert.assertTrue(value.equals("file1.txt")); 183 | 184 | values = command.getValues("fileName2"); 185 | Assert.assertTrue(values != null); 186 | Assert.assertTrue(values.size() == 1); 187 | 188 | value = values.get(0); 189 | Assert.assertTrue(value != null); 190 | Assert.assertTrue(value.length() > 0); 191 | Assert.assertTrue(value.equals("file2.txt")); 192 | 193 | values = command.getValues("fileName3"); 194 | Assert.assertTrue(values != null); 195 | Assert.assertTrue(values.size() == 1); 196 | 197 | value = values.get(0); 198 | Assert.assertTrue(value != null); 199 | Assert.assertTrue(value.length() > 0); 200 | Assert.assertTrue(value.equals("file3.txt")); 201 | 202 | Assert.assertTrue(true); 203 | } 204 | catch (final Exception e) 205 | { 206 | Assert.fail(e.toString()); 207 | } 208 | } 209 | 210 | @Test 211 | public void testDefineCommand1b() 212 | { 213 | final CmdLineListener listener = new CmdLineListener(); 214 | CmdLine.setCommandListener(listener); 215 | 216 | CmdLine.defineCommand("-f, --file, !fileName1, ?fileName2, ?fileName3, :file\\d.txt, #Load a files into the system"); 217 | 218 | final String[] args = new String[3]; 219 | args[0] = "-f"; 220 | args[1] = "="; 221 | args[2] = "file1.txt"; 222 | 223 | try 224 | { 225 | CmdLine.parse(args); 226 | 227 | Assert.assertTrue(listener.getCount() == 1); 228 | 229 | final Command command = listener.getCommand("-f"); 230 | Assert.assertTrue(command != null); 231 | Assert.assertTrue(command.hasVariables()); 232 | 233 | final List values = command.getValues("fileName1"); 234 | Assert.assertTrue(values != null); 235 | Assert.assertTrue(values.size() > 0); 236 | 237 | final String value = values.get(0); 238 | Assert.assertTrue(value != null); 239 | Assert.assertTrue(value.length() > 0); 240 | Assert.assertTrue(value.equals("file1.txt")); 241 | 242 | Assert.assertTrue(true); 243 | } 244 | catch (final Exception e) 245 | { 246 | Assert.fail(e.toString()); 247 | } 248 | } 249 | 250 | @Test 251 | public void testDefineCommand1c() 252 | { 253 | final CmdLineListener listener = new CmdLineListener(); 254 | CmdLine.setCommandListener(listener); 255 | 256 | CmdLine.defineCommand("-f, --file, !fileName1, ?fileName2, ?fileName3, #Load a files into the system"); 257 | 258 | final String[] args = new String[3]; 259 | args[0] = "-f"; 260 | args[1] = "="; 261 | args[2] = "file1.txt"; 262 | 263 | try 264 | { 265 | CmdLine.parse(args); 266 | 267 | Assert.assertTrue(listener.getCount() == 1); 268 | 269 | final Command command = listener.getCommand("-f"); 270 | Assert.assertTrue(command != null); 271 | Assert.assertTrue(command.hasVariables()); 272 | 273 | final List values = command.getValues("fileName1"); 274 | Assert.assertTrue(values != null); 275 | Assert.assertTrue(values.size() == 1); 276 | 277 | final String value = values.get(0); 278 | Assert.assertTrue(value != null); 279 | Assert.assertTrue(value.length() > 0); 280 | Assert.assertTrue(value.equals("file1.txt")); 281 | 282 | Assert.assertTrue(true); 283 | } 284 | catch (final Exception e) 285 | { 286 | Assert.fail(e.toString()); 287 | } 288 | } 289 | 290 | @Test 291 | public void testDefineCommand1d() 292 | { 293 | final CmdLineListener listener = new CmdLineListener(); 294 | CmdLine.setCommandListener(listener); 295 | 296 | CmdLine.defineCommand("-f, --file, !fileName1, ?fileNames..., #Load a files into the system"); 297 | 298 | final String[] args = new String[7]; 299 | args[0] = "-f"; 300 | args[1] = "="; 301 | args[2] = "file1.txt"; 302 | args[3] = ","; 303 | args[4] = "file2.txt"; 304 | args[5] = ","; 305 | args[6] = "file3.txt"; 306 | 307 | try 308 | { 309 | CmdLine.parse(args); 310 | 311 | Assert.assertTrue(listener.getCount() == 1); 312 | 313 | final Command command = listener.getCommand("-f"); 314 | Assert.assertTrue(command != null); 315 | Assert.assertTrue(command.hasVariables()); 316 | 317 | List values = command.getValues("fileName1"); 318 | Assert.assertTrue(values != null); 319 | Assert.assertTrue(values.size() == 1); 320 | 321 | String value = values.get(0); 322 | Assert.assertTrue(value != null); 323 | Assert.assertTrue(value.length() > 0); 324 | Assert.assertTrue(value.equals("file1.txt")); 325 | 326 | values = command.getValues("fileNames"); 327 | Assert.assertTrue(values != null); 328 | Assert.assertTrue(values.size() == 2); 329 | 330 | value = values.get(0); 331 | Assert.assertTrue(value != null); 332 | Assert.assertTrue(value.length() > 0); 333 | Assert.assertTrue(value.equals("file2.txt")); 334 | 335 | value = values.get(1); 336 | Assert.assertTrue(value != null); 337 | Assert.assertTrue(value.length() > 0); 338 | Assert.assertTrue(value.equals("file3.txt")); 339 | 340 | Assert.assertTrue(true); 341 | } 342 | catch (final Exception e) 343 | { 344 | Assert.fail(e.toString()); 345 | } 346 | } 347 | 348 | @Test 349 | public void testDefineCommand1e() 350 | { 351 | final CmdLineListener listener = new CmdLineListener(); 352 | CmdLine.setCommandListener(listener); 353 | 354 | CmdLine.defineCommand("-f, --file, !fileName1, ?fileNames..., #Load a files into the system, file"); 355 | 356 | final String[] args = new String[7]; 357 | args[0] = "file"; 358 | args[1] = "="; 359 | args[2] = "file1.txt"; 360 | args[3] = ","; 361 | args[4] = "file2.txt"; 362 | args[5] = ","; 363 | args[6] = "file3.txt"; 364 | 365 | try 366 | { 367 | CmdLine.parse(args); 368 | 369 | Assert.assertTrue(listener.getCount() == 1); 370 | 371 | final Command command = listener.getCommand("file"); 372 | Assert.assertTrue(command != null); 373 | Assert.assertTrue(command.hasVariables()); 374 | 375 | List values = command.getValues("fileName1"); 376 | Assert.assertTrue(values != null); 377 | Assert.assertTrue(values.size() == 1); 378 | 379 | String value = values.get(0); 380 | Assert.assertTrue(value != null); 381 | Assert.assertTrue(value.length() > 0); 382 | Assert.assertTrue(value.equals("file1.txt")); 383 | 384 | values = command.getValues("fileNames"); 385 | Assert.assertTrue(values != null); 386 | Assert.assertTrue(values.size() == 2); 387 | 388 | value = values.get(0); 389 | Assert.assertTrue(value != null); 390 | Assert.assertTrue(value.length() > 0); 391 | Assert.assertTrue(value.equals("file2.txt")); 392 | 393 | value = values.get(1); 394 | Assert.assertTrue(value != null); 395 | Assert.assertTrue(value.length() > 0); 396 | Assert.assertTrue(value.equals("file3.txt")); 397 | 398 | Assert.assertTrue(true); 399 | } 400 | catch (final Exception e) 401 | { 402 | Assert.fail(e.toString()); 403 | } 404 | } 405 | 406 | @Test 407 | public void testDefineCommand1f() 408 | { 409 | final CmdLineListener listener = new CmdLineListener(); 410 | CmdLine.setCommandListener(listener); 411 | 412 | CmdLine.defineCommand("file, !file"); 413 | 414 | final String[] args = new String[3]; 415 | args[0] = "file"; 416 | args[1] = "="; 417 | args[2] = "file1.txt"; 418 | 419 | try 420 | { 421 | CmdLine.parse(args); 422 | 423 | Assert.assertTrue(listener.getCount() == 1); 424 | 425 | final Command command = listener.getCommand("file"); 426 | Assert.assertTrue(command != null); 427 | Assert.assertTrue(command.hasVariables()); 428 | 429 | List values = command.getValues("file"); 430 | Assert.assertTrue(values != null); 431 | Assert.assertTrue(values.size() == 1); 432 | 433 | String value = values.get(0); 434 | Assert.assertTrue(value != null); 435 | Assert.assertTrue(value.length() > 0); 436 | Assert.assertTrue(value.equals("file1.txt")); 437 | 438 | Assert.assertTrue(true); 439 | } 440 | catch (final Exception e) 441 | { 442 | Assert.fail(e.toString()); 443 | } 444 | } 445 | 446 | @Test 447 | public void testDefineCommand1g() 448 | { 449 | final CmdLineListener listener = new CmdLineListener(); 450 | CmdLine.setCommandListener(listener); 451 | 452 | CmdLine.defineCommand("file, !file, !files..."); 453 | 454 | final String[] args = new String[5]; 455 | args[0] = "file"; 456 | args[1] = "="; 457 | args[2] = "file1.txt"; 458 | args[3] = ","; 459 | args[4] = "file2.txt"; 460 | 461 | try 462 | { 463 | CmdLine.parse(args); 464 | 465 | Assert.assertTrue(listener.getCount() == 1); 466 | 467 | final Command command = listener.getCommand("file"); 468 | Assert.assertTrue(command != null); 469 | Assert.assertTrue(command.hasVariables()); 470 | 471 | List values = command.getValues("file"); 472 | Assert.assertTrue(values != null); 473 | Assert.assertTrue(values.size() == 1); 474 | 475 | String value = values.get(0); 476 | Assert.assertTrue(value != null); 477 | Assert.assertTrue(value.length() > 0); 478 | Assert.assertTrue(value.equals("file1.txt")); 479 | 480 | Assert.assertTrue(true); 481 | } 482 | catch (final Exception e) 483 | { 484 | Assert.fail(e.toString()); 485 | } 486 | } 487 | 488 | @Test 489 | public void testParseWithListener() 490 | { 491 | final CmdLineListener listener = new CmdLineListener(); 492 | 493 | CmdLine.defineCommand("file, !file, !files..."); 494 | 495 | final String[] args = new String[5]; 496 | args[0] = "file"; 497 | args[1] = "="; 498 | args[2] = "file1.txt"; 499 | args[3] = ","; 500 | args[4] = "file2.txt"; 501 | 502 | try 503 | { 504 | CmdLine.parse(args, listener); 505 | 506 | Assert.assertTrue(listener.getCount() == 1); 507 | 508 | final Command command = listener.getCommand("file"); 509 | Assert.assertTrue(command != null); 510 | Assert.assertTrue(command.hasVariables()); 511 | 512 | List values = command.getValues("file"); 513 | Assert.assertTrue(values != null); 514 | Assert.assertTrue(values.size() == 1); 515 | 516 | String value = values.get(0); 517 | Assert.assertTrue(value != null); 518 | Assert.assertTrue(value.length() > 0); 519 | Assert.assertTrue(value.equals("file1.txt")); 520 | 521 | Assert.assertTrue(true); 522 | } 523 | catch (final Exception e) 524 | { 525 | Assert.fail(e.toString()); 526 | } 527 | } 528 | 529 | @Test 530 | public void testChainingCommand() 531 | { 532 | final CmdLineListener listener = new CmdLineListener(); 533 | 534 | final String[] args = new String[5]; 535 | args[0] = "file"; 536 | args[1] = "="; 537 | args[2] = "file1.txt"; 538 | args[3] = ","; 539 | args[4] = "file2.txt"; 540 | 541 | try 542 | { 543 | CmdLine.defineCommand("file, !file, !files...").parse(args, 544 | listener); 545 | 546 | Assert.assertTrue(listener.getCount() == 1); 547 | 548 | final Command command = listener.getCommand("file"); 549 | Assert.assertTrue(command != null); 550 | Assert.assertTrue(command.hasVariables()); 551 | 552 | List values = command.getValues("file"); 553 | Assert.assertTrue(values != null); 554 | Assert.assertTrue(values.size() == 1); 555 | 556 | String value = values.get(0); 557 | Assert.assertTrue(value != null); 558 | Assert.assertTrue(value.length() > 0); 559 | Assert.assertTrue(value.equals("file1.txt")); 560 | 561 | Assert.assertTrue(true); 562 | } 563 | catch (final Exception e) 564 | { 565 | Assert.fail(e.toString()); 566 | } 567 | } 568 | 569 | @Test 570 | public void testDefineMultipleCommand1() 571 | { 572 | final CmdLineListener listener = new CmdLineListener(); 573 | CmdLine.setCommandListener(listener); 574 | 575 | CmdLine.setVersion("1.1.0"); 576 | CmdLine.defineCommand("-f", "--file", "!fileNames...", ":file\\d.txt", 577 | "#Load files into the system"); 578 | CmdLine.defineCommand("-l", "--list", 579 | "#List the files loaded into the system"); 580 | CmdLine.defineCommand("-q", "--quit", "#Quit the application"); 581 | 582 | final String[] args = new String[4]; 583 | args[0] = "-f"; 584 | args[1] = "="; 585 | args[2] = "file1.txt"; 586 | args[3] = "--list"; 587 | 588 | try 589 | { 590 | CmdLine.parse(args); 591 | 592 | Assert.assertTrue(listener.getCount() == 2); 593 | 594 | Command command = listener.getCommand("-f"); 595 | Assert.assertTrue(command != null); 596 | Assert.assertTrue(command.hasVariables()); 597 | 598 | final List values = command.getValues("fileNames"); 599 | Assert.assertTrue(values != null); 600 | Assert.assertTrue(values.size() == 1); 601 | 602 | final String value = values.get(0); 603 | Assert.assertTrue(value != null); 604 | Assert.assertTrue(value.length() > 0); 605 | Assert.assertTrue(value.equals("file1.txt")); 606 | 607 | command = listener.getCommand("--list"); 608 | Assert.assertTrue(command != null); 609 | Assert.assertTrue(!command.hasVariables()); 610 | 611 | Assert.assertTrue(true); 612 | } 613 | catch (final Exception e) 614 | { 615 | Assert.fail(e.toString()); 616 | } 617 | } 618 | 619 | @Test 620 | public void testDefineMultipleCommand2() 621 | { 622 | final CmdLineListener listener = new CmdLineListener(); 623 | CmdLine.setApplicationName("myApp") 624 | .setVersion("1.1.0") 625 | .defineCommand("-f", "--file", "!fileNames...", ":file\\d.txt", 626 | "#Load files into the system") 627 | .defineCommand("-l", "--list", 628 | "#List the files loaded into the system") 629 | .defineCommand("-q", "--quit", "#Quit the application"); 630 | 631 | final String[] args = new String[5]; 632 | args[0] = "-f"; 633 | args[1] = "="; 634 | args[2] = "file1.txt"; 635 | args[3] = "-Dcom.gabsocial.cmdline.debug=true"; 636 | args[4] = "--list"; 637 | 638 | try 639 | { 640 | CmdLine.parse(args, listener); 641 | 642 | Assert.assertTrue(listener.getCount() == 3); 643 | 644 | Command command = listener.getCommand("-f"); 645 | Assert.assertTrue(command != null); 646 | Assert.assertTrue(command.hasVariables()); 647 | 648 | List values = command.getValues("fileNames"); 649 | Assert.assertTrue(values != null); 650 | Assert.assertTrue(values.size() == 1); 651 | 652 | String value = values.get(0); 653 | Assert.assertTrue(value != null); 654 | Assert.assertTrue(value.length() > 0); 655 | Assert.assertTrue(value.equals("file1.txt")); 656 | 657 | command = listener.getCommand("-Dcom.gabsocial.cmdline.debug"); 658 | Assert.assertTrue(command != null); 659 | Assert.assertTrue(command.hasVariables()); 660 | 661 | values = command.getValues("com.gabsocial.cmdline.debug"); 662 | Assert.assertTrue(values != null); 663 | Assert.assertTrue(values.size() == 1); 664 | 665 | value = values.get(0); 666 | Assert.assertTrue(value != null); 667 | Assert.assertTrue(value.length() > 0); 668 | Assert.assertTrue(value.equals("true")); 669 | 670 | command = listener.getCommand("--list"); 671 | Assert.assertTrue(command != null); 672 | Assert.assertTrue(!command.hasVariables()); 673 | 674 | Assert.assertTrue(true); 675 | } 676 | catch (final Exception e) 677 | { 678 | Assert.fail(e.toString()); 679 | } 680 | } 681 | 682 | @Test 683 | public void testDefineMultipleCommandWithDefaultListener() 684 | { 685 | CmdLine.setApplicationName("myApp") 686 | .setVersion("1.1.0") 687 | .defineCommand("-f", "--file", "!fileNames...", ":file\\d.txt", 688 | "#Load files into the system") 689 | .defineCommand("-l", "--list", 690 | "#List the files loaded into the system") 691 | .defineCommand("-q", "--quit", "#Quit the application"); 692 | 693 | final String[] args = new String[5]; 694 | args[0] = "-f"; 695 | args[1] = "="; 696 | args[2] = "file1.txt"; 697 | args[3] = "-Dcom.gabsocial.cmdline.debug=true"; 698 | args[4] = "--list"; 699 | 700 | try 701 | { 702 | List commands = CmdLine.parse(args); 703 | Assert.assertTrue(commands.size() == 3); 704 | 705 | for (Command command : commands) 706 | { 707 | final String name = command.getName(); 708 | // System.out.println( "'" + command + "'"); 709 | 710 | if (name.equals("-f")) 711 | { 712 | Assert.assertTrue(command != null); 713 | Assert.assertTrue(command.hasVariables()); 714 | 715 | List values = command.getValues("fileNames"); 716 | Assert.assertTrue(values != null); 717 | Assert.assertTrue(values.size() == 1); 718 | 719 | String value = values.get(0); 720 | Assert.assertTrue(value != null); 721 | Assert.assertTrue(value.length() > 0); 722 | Assert.assertTrue(value.equals("file1.txt")); 723 | } 724 | else if (name.equals("-Dcom.gabsocial.cmdline.debug")) 725 | { 726 | Assert.assertTrue(command != null); 727 | Assert.assertTrue(command.hasVariables()); 728 | 729 | List values = command 730 | .getValues("com.gabsocial.cmdline.debug"); 731 | Assert.assertTrue(values != null); 732 | Assert.assertTrue(values.size() == 1); 733 | 734 | String value = values.get(0); 735 | Assert.assertTrue(value != null); 736 | Assert.assertTrue(value.length() > 0); 737 | Assert.assertTrue(value.equals("true")); 738 | } 739 | else if (name.equals("--list")) 740 | { 741 | Assert.assertTrue(command != null); 742 | Assert.assertTrue(!command.hasVariables()); 743 | } 744 | } 745 | Assert.assertTrue(true); 746 | } 747 | catch (final Exception e) 748 | { 749 | e.printStackTrace(); 750 | Assert.fail(e.toString()); 751 | } 752 | } 753 | 754 | @Test 755 | public void testDefineMultipleCommandWithDefaultListenerAndSecondListener() 756 | { 757 | final CmdLineListener listener = new CmdLineListener(); 758 | CmdLine.setApplicationName("myApp") 759 | .setVersion("1.1.0") 760 | .defineCommand("-f", "--file", "!fileNames...", ":file\\d.txt", 761 | "#Load files into the system") 762 | .defineCommand("-l", "--list", 763 | "#List the files loaded into the system") 764 | .defineCommand("-q", "--quit", "#Quit the application"); 765 | 766 | final String[] args = new String[5]; 767 | args[0] = "-f"; 768 | args[1] = "="; 769 | args[2] = "file1.txt"; 770 | args[3] = "-Dcom.gabsocial.cmdline.debug=true"; 771 | args[4] = "--list"; 772 | 773 | try 774 | { 775 | List commands = CmdLine.parse(args, listener); 776 | Assert.assertTrue(commands.size() == 3); 777 | 778 | for (Command command : commands) 779 | { 780 | final String name = command.getName(); 781 | // System.out.println( "'" + command + "'"); 782 | 783 | if (name.equals("-f")) 784 | { 785 | Assert.assertTrue(command != null); 786 | Assert.assertTrue(command.hasVariables()); 787 | 788 | List values = command.getValues("fileNames"); 789 | Assert.assertTrue(values != null); 790 | Assert.assertTrue(values.size() == 1); 791 | 792 | String value = values.get(0); 793 | Assert.assertTrue(value != null); 794 | Assert.assertTrue(value.length() > 0); 795 | Assert.assertTrue(value.equals("file1.txt")); 796 | } 797 | else if (name.equals("-Dcom.gabsocial.cmdline.debug")) 798 | { 799 | Assert.assertTrue(command != null); 800 | Assert.assertTrue(command.hasVariables()); 801 | 802 | List values = command 803 | .getValues("com.gabsocial.cmdline.debug"); 804 | Assert.assertTrue(values != null); 805 | Assert.assertTrue(values.size() == 1); 806 | 807 | String value = values.get(0); 808 | Assert.assertTrue(value != null); 809 | Assert.assertTrue(value.length() > 0); 810 | Assert.assertTrue(value.equals("true")); 811 | } 812 | else if (name.equals("--list")) 813 | { 814 | Assert.assertTrue(command != null); 815 | Assert.assertTrue(!command.hasVariables()); 816 | } 817 | } 818 | 819 | Assert.assertTrue(listener.getCount() == 3); 820 | 821 | Command command = listener.getCommand("-f"); 822 | Assert.assertTrue(command != null); 823 | Assert.assertTrue(command.hasVariables()); 824 | 825 | List values = command.getValues("fileNames"); 826 | Assert.assertTrue(values != null); 827 | Assert.assertTrue(values.size() == 1); 828 | 829 | String value = values.get(0); 830 | Assert.assertTrue(value != null); 831 | Assert.assertTrue(value.length() > 0); 832 | Assert.assertTrue(value.equals("file1.txt")); 833 | 834 | command = listener.getCommand("-Dcom.gabsocial.cmdline.debug"); 835 | Assert.assertTrue(command != null); 836 | Assert.assertTrue(command.hasVariables()); 837 | 838 | values = command.getValues("com.gabsocial.cmdline.debug"); 839 | Assert.assertTrue(values != null); 840 | Assert.assertTrue(values.size() == 1); 841 | 842 | value = values.get(0); 843 | Assert.assertTrue(value != null); 844 | Assert.assertTrue(value.length() > 0); 845 | Assert.assertTrue(value.equals("true")); 846 | 847 | command = listener.getCommand("--list"); 848 | Assert.assertTrue(command != null); 849 | Assert.assertTrue(!command.hasVariables()); 850 | 851 | Assert.assertTrue(true); 852 | } 853 | catch (final Exception e) 854 | { 855 | e.printStackTrace(); 856 | Assert.fail(e.toString()); 857 | } 858 | } 859 | 860 | @Test 861 | public void testSystemPropertyCommand1() 862 | { 863 | final CmdLineListener listener = new CmdLineListener(); 864 | CmdLine.setCommandListener(listener); 865 | 866 | CmdLine.setVersion("1.1.0"); 867 | 868 | final String[] args = new String[1]; 869 | args[0] = "-Dcom.gabsocial.cmdline.debug=true"; 870 | 871 | try 872 | { 873 | CmdLine.parse(args); 874 | 875 | final Command command = listener 876 | .getCommand("-Dcom.gabsocial.cmdline.debug"); 877 | 878 | Assert.assertTrue(listener.getCount() == 1); 879 | Assert.assertTrue(command != null); 880 | Assert.assertTrue(command.hasVariables()); 881 | 882 | final List values = command 883 | .getValues("com.gabsocial.cmdline.debug"); 884 | Assert.assertTrue(values != null); 885 | Assert.assertTrue(values.size() == 1); 886 | 887 | final String value = values.get(0); 888 | Assert.assertTrue(value != null); 889 | Assert.assertTrue(value.length() > 0); 890 | Assert.assertTrue(value.equals("true")); 891 | 892 | Assert.assertTrue(true); 893 | } 894 | catch (final Exception e) 895 | { 896 | Assert.fail(e.toString()); 897 | } 898 | } 899 | 900 | @Test 901 | public void testSystemPropertyCommand2() 902 | { 903 | final CmdLineListener listener = new CmdLineListener(); 904 | CmdLine.setCommandListener(listener); 905 | 906 | CmdLine.setVersion("1.1.0"); 907 | 908 | final String[] args = new String[4]; 909 | args[0] = "-Dcom.gabsocial.cmdline.debug=true"; 910 | args[1] = "-Dcom.gabsocial.cmdline.screen=true"; 911 | args[2] = "-Dcom.gabsocial.cmdline.gfx=true"; 912 | args[3] = "-Dcom.gabsocial.cmdline.load=true"; 913 | 914 | try 915 | { 916 | CmdLine.parse(args); 917 | 918 | Assert.assertTrue(listener.getCount() == 4); 919 | 920 | final Command command = listener 921 | .getCommand("-Dcom.gabsocial.cmdline.debug"); 922 | 923 | Assert.assertTrue(command != null); 924 | Assert.assertTrue(command.hasVariables()); 925 | 926 | final List values = command 927 | .getValues("com.gabsocial.cmdline.debug"); 928 | Assert.assertTrue(values != null); 929 | Assert.assertTrue(values.size() == 1); 930 | 931 | final String value = values.get(0); 932 | Assert.assertTrue(value != null); 933 | Assert.assertTrue(value.length() > 0); 934 | Assert.assertTrue(value.equals("true")); 935 | 936 | Assert.assertTrue(true); 937 | } 938 | catch (final Exception e) 939 | { 940 | Assert.fail(e.toString()); 941 | } 942 | }; 943 | 944 | @Test 945 | public void testSystemPropertyCommand3() 946 | { 947 | final CmdLineListener listener = new CmdLineListener(); 948 | CmdLine.setCommandListener(listener); 949 | 950 | CmdLine.defineCommand("file, !file, !files..., :file\\d.txt"); 951 | 952 | CmdLine.setVersion("1.1.0"); 953 | 954 | final String[] args = new String[4]; 955 | args[0] = "-Dcom.gabsocial.cmdline.debug=true"; 956 | args[1] = "file"; 957 | args[2] = "file1.txt"; 958 | args[3] = "file2.txt"; 959 | 960 | try 961 | { 962 | CmdLine.parse(args); 963 | 964 | Assert.assertTrue(listener.getCount() == 2); 965 | 966 | Command command = listener 967 | .getCommand("-Dcom.gabsocial.cmdline.debug"); 968 | 969 | Assert.assertTrue(command != null); 970 | Assert.assertTrue(command.hasVariables()); 971 | 972 | List values = command 973 | .getValues("com.gabsocial.cmdline.debug"); 974 | Assert.assertTrue(values != null); 975 | Assert.assertTrue(values.size() == 1); 976 | 977 | String value = values.get(0); 978 | Assert.assertTrue(value != null); 979 | Assert.assertTrue(value.length() > 0); 980 | Assert.assertTrue(value.equals("true")); 981 | 982 | command = listener.getCommand("file"); 983 | 984 | Assert.assertTrue(command != null); 985 | Assert.assertTrue(command.hasVariables()); 986 | 987 | values = command.getValues("file"); 988 | Assert.assertTrue(values != null); 989 | Assert.assertTrue(values.size() == 1); 990 | 991 | value = values.get(0); 992 | Assert.assertTrue(value != null); 993 | Assert.assertTrue(value.length() > 0); 994 | Assert.assertTrue(value.equals("file1.txt")); 995 | 996 | values = command.getValues("files"); 997 | Assert.assertTrue(values != null); 998 | Assert.assertTrue(values.size() == 1); 999 | 1000 | value = values.get(0); 1001 | Assert.assertTrue(value != null); 1002 | Assert.assertTrue(value.length() > 0); 1003 | Assert.assertTrue(value.equals("file2.txt")); 1004 | 1005 | Assert.assertTrue(true); 1006 | } 1007 | catch (final Exception e) 1008 | { 1009 | Assert.fail(e.toString()); 1010 | } 1011 | } 1012 | 1013 | @Test 1014 | public void testSystemPropertyCommand4() 1015 | { 1016 | final CmdLineListener listener = new CmdLineListener(); 1017 | 1018 | CmdLine.defineCommand("file, !file, !files..., :file\\d.txt") 1019 | .setApplicationName("myApp").setVersion("1.1.0"); 1020 | 1021 | final String[] args = new String[5]; 1022 | args[0] = "-Dcom.gabsocial.cmdline.debug=true"; 1023 | args[1] = "file"; 1024 | args[2] = "file1.txt"; 1025 | args[3] = "file2.txt"; 1026 | args[4] = "-Dcom.gabsocial.cmdline.load=true"; 1027 | 1028 | try 1029 | { 1030 | CmdLine.parse(args, listener); 1031 | 1032 | Assert.assertTrue(listener.getCount() == 3); 1033 | 1034 | Command command = listener 1035 | .getCommand("-Dcom.gabsocial.cmdline.debug"); 1036 | 1037 | Assert.assertTrue(command != null); 1038 | Assert.assertTrue(command.hasVariables()); 1039 | 1040 | List values = command 1041 | .getValues("com.gabsocial.cmdline.debug"); 1042 | Assert.assertTrue(values != null); 1043 | Assert.assertTrue(values.size() == 1); 1044 | 1045 | String value = values.get(0); 1046 | Assert.assertTrue(value != null); 1047 | Assert.assertTrue(value.length() > 0); 1048 | Assert.assertTrue(value.equals("true")); 1049 | 1050 | command = listener.getCommand("file"); 1051 | 1052 | Assert.assertTrue(command != null); 1053 | Assert.assertTrue(command.hasVariables()); 1054 | 1055 | values = command.getValues("file"); 1056 | Assert.assertTrue(values != null); 1057 | Assert.assertTrue(values.size() == 1); 1058 | 1059 | value = values.get(0); 1060 | Assert.assertTrue(value != null); 1061 | Assert.assertTrue(value.length() > 0); 1062 | Assert.assertTrue(value.equals("file1.txt")); 1063 | 1064 | values = command.getValues("files"); 1065 | Assert.assertTrue(values != null); 1066 | Assert.assertTrue(values.size() == 1); 1067 | 1068 | value = values.get(0); 1069 | Assert.assertTrue(value != null); 1070 | Assert.assertTrue(value.length() > 0); 1071 | Assert.assertTrue(value.equals("file2.txt")); 1072 | 1073 | command = listener.getCommand("-Dcom.gabsocial.cmdline.load"); 1074 | 1075 | Assert.assertTrue(command != null); 1076 | Assert.assertTrue(command.hasVariables()); 1077 | 1078 | values = command.getValues("com.gabsocial.cmdline.load"); 1079 | Assert.assertTrue(values != null); 1080 | Assert.assertTrue(values.size() == 1); 1081 | 1082 | value = values.get(0); 1083 | Assert.assertTrue(value != null); 1084 | Assert.assertTrue(value.length() > 0); 1085 | Assert.assertTrue(value.equals("true")); 1086 | 1087 | Assert.assertTrue(true); 1088 | } 1089 | catch (final Exception e) 1090 | { 1091 | Assert.fail(e.toString()); 1092 | } 1093 | } 1094 | } 1095 | -------------------------------------------------------------------------------- /src/test/java/com/gabstudios/cmdline/CmdlineNegativeWordSuggestionTest.java: -------------------------------------------------------------------------------- 1 | /***************************************************************************************** 2 | * 3 | * Copyright 2016 Gregory Brown. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * 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 | ***************************************************************************************** 18 | */ 19 | package com.gabstudios.cmdline; 20 | 21 | import java.util.HashMap; 22 | import java.util.List; 23 | import java.util.Map; 24 | 25 | import org.junit.After; 26 | import org.junit.Assert; 27 | import org.junit.Before; 28 | import org.junit.Test; 29 | 30 | /** 31 | * 32 | * 33 | * @author Gregory Brown (sysdevone) 34 | * 35 | */ 36 | public class CmdlineNegativeWordSuggestionTest 37 | { 38 | private class CmdLineListener implements CommandListener 39 | { 40 | 41 | private final Map _commandMap = new HashMap(); 42 | 43 | public Command getCommand(final String name) 44 | { 45 | return (this._commandMap.get(name)); 46 | } 47 | 48 | public int getCount() 49 | { 50 | return (this._commandMap.size()); 51 | } 52 | 53 | @Override 54 | public void handle(final Command command) 55 | { 56 | this._commandMap.put(command.getName(), command); 57 | 58 | // System.out.println( command ); 59 | } 60 | } 61 | 62 | @Before 63 | public void setUp() 64 | { 65 | } 66 | 67 | @After 68 | public void tearDown() 69 | { 70 | CmdLine.clear(); 71 | } 72 | 73 | @Test 74 | public void testWordSuggestion() 75 | { 76 | 77 | final CmdLineListener listener = new CmdLineListener(); 78 | 79 | CmdLine 80 | .setApplicationName("myApp") 81 | .setVersion("1.1.0") 82 | .defineCommand("file, !file, !files..., :file\\d.txt") 83 | .defineCommand("help") 84 | .defineCommand("quit") 85 | .defineCommand("install, !installOption") 86 | .defineCommand("info"); 87 | 88 | final String[] args = new String[1]; 89 | args[0] = "inztolll"; 90 | 91 | try 92 | { 93 | CmdLine.parse(args, listener); 94 | 95 | Assert.fail(); 96 | } 97 | catch (final UnsupportedException e) 98 | { 99 | final List words = e.getSuggestionList(); 100 | org.junit.Assert.assertEquals(2, words.size()); 101 | org.junit.Assert.assertTrue(words.contains("install")); 102 | org.junit.Assert.assertTrue(words.contains("info")); 103 | } 104 | catch (final Exception e) 105 | { 106 | Assert.fail(e.toString()); 107 | } 108 | } 109 | 110 | @Test 111 | public void testWordSuggestion2() 112 | { 113 | 114 | final CmdLineListener listener = new CmdLineListener(); 115 | 116 | CmdLine 117 | .setApplicationName("myApp") 118 | .setVersion("1.1.0") 119 | .defineCommand("file, !file, !files..., :file\\d.txt") 120 | .defineCommand("help") 121 | .defineCommand("quit") 122 | .defineCommand("install, !installOption") 123 | .defineCommand("info"); 124 | 125 | final String[] args = new String[1]; 126 | args[0] = "instolll"; 127 | 128 | try 129 | { 130 | CmdLine.parse(args, listener); 131 | 132 | Assert.fail(); 133 | } 134 | catch (final UnsupportedException e) 135 | { 136 | final List words = e.getSuggestionList(); 137 | org.junit.Assert.assertEquals(1, words.size()); 138 | org.junit.Assert.assertTrue(words.contains("install")); 139 | } 140 | catch (final Exception e) 141 | { 142 | Assert.fail(e.toString()); 143 | } 144 | } 145 | 146 | @Test 147 | public void testWordSuggestion3() 148 | { 149 | 150 | final CmdLineListener listener = new CmdLineListener(); 151 | 152 | CmdLine 153 | .setApplicationName("myApp") 154 | .setVersion("1.1.0") 155 | .defineCommand("file, !file, !files..., :file\\d.txt") 156 | .defineCommand("help") 157 | .defineCommand("quit") 158 | .defineCommand("install, !installOption") 159 | .defineCommand("info"); 160 | 161 | final String[] args = new String[1]; 162 | args[0] = "znstolll"; 163 | 164 | try 165 | { 166 | CmdLine.parse(args, listener); 167 | 168 | Assert.fail(); 169 | } 170 | catch (final UnsupportedException e) 171 | { 172 | final List words = e.getSuggestionList(); 173 | org.junit.Assert.assertEquals(5, words.size()); 174 | org.junit.Assert.assertTrue(words.contains("file")); 175 | org.junit.Assert.assertTrue(words.contains("help")); 176 | org.junit.Assert.assertTrue(words.contains("quit")); 177 | org.junit.Assert.assertTrue(words.contains("install")); 178 | org.junit.Assert.assertTrue(words.contains("info")); 179 | } 180 | catch (final Exception e) 181 | { 182 | Assert.fail(e.toString()); 183 | } 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /src/test/java/com/gabstudios/cmdline/CommandLineTokenizerTest.java: -------------------------------------------------------------------------------- 1 | /***************************************************************************************** 2 | * 3 | * Copyright 2016 Gregory Brown. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | * use this file except in compliance with the License. You may obtain a copy of 7 | * 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, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations under 15 | * the License. 16 | * 17 | ***************************************************************************************** 18 | */ 19 | 20 | package com.gabstudios.cmdline; 21 | 22 | import java.util.List; 23 | 24 | import org.junit.After; 25 | import org.junit.Assert; 26 | import org.junit.Before; 27 | import org.junit.Test; 28 | 29 | 30 | /** 31 | * 32 | * 33 | * @author Gregory Brown (sysdevone) 34 | * 35 | */ 36 | public class CommandLineTokenizerTest 37 | { 38 | 39 | CommandLineTokenizer _tokenizer; 40 | 41 | @Before 42 | public void setUp() 43 | { 44 | this._tokenizer = new CommandLineTokenizer(); 45 | } 46 | 47 | @After 48 | public void tearDown() 49 | { 50 | this._tokenizer = null; 51 | } 52 | 53 | @Test 54 | public void testTokenizer() 55 | { 56 | // file=file1.txt 57 | final String[] inputTokens = 58 | { "file=file1.txt" }; 59 | 60 | final List tokens = this._tokenizer.tokenize(inputTokens); 61 | 62 | Assert.assertTrue(tokens.size() == 2); 63 | Assert.assertTrue(tokens.get(0).equals("file")); 64 | Assert.assertTrue(tokens.get(1).equals("file1.txt")); 65 | 66 | } 67 | 68 | @Test 69 | public void testTokenizer2() 70 | { 71 | // -file=file1,txt, file2.txt 72 | final String[] inputTokens = 73 | { "-file=file1.txt,", "file2.txt" }; 74 | 75 | final List tokens = this._tokenizer.tokenize(inputTokens); 76 | 77 | Assert.assertTrue(tokens.size() == 3); 78 | Assert.assertTrue(tokens.get(0).equals("-file")); 79 | Assert.assertTrue(tokens.get(1).equals("file1.txt")); 80 | Assert.assertTrue(tokens.get(2).equals("file2.txt")); 81 | 82 | } 83 | 84 | @Test 85 | public void testTokenizer3() 86 | { 87 | // -file=file1,txt, file2.txt -Dorg.gabsocial.cmdline.debug=true 88 | final String[] inputTokens = 89 | { "-file", "file1.txt", "file2.txt", 90 | "-Dorg.gabsocial.cmdline.debug=true" }; 91 | 92 | final List tokens = this._tokenizer.tokenize(inputTokens); 93 | 94 | Assert.assertTrue(tokens.size() == 5); 95 | Assert.assertTrue(tokens.get(0).equals("-file")); 96 | Assert.assertTrue(tokens.get(1).equals("file1.txt")); 97 | Assert.assertTrue(tokens.get(2).equals("file2.txt")); 98 | Assert.assertTrue(tokens.get(3).equals("-Dorg.gabsocial.cmdline.debug")); 99 | Assert.assertTrue(tokens.get(4).equals("true")); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/test/java/com/gabstudios/cmdline/DefinedCommandTokenizerTest.java: -------------------------------------------------------------------------------- 1 | /***************************************************************************************** 2 | * 3 | * Copyright 2016 Gregory Brown. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | * use this file except in compliance with the License. You may obtain a copy of 7 | * 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, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations under 15 | * the License. 16 | * 17 | ***************************************************************************************** 18 | */ 19 | 20 | package com.gabstudios.cmdline; 21 | 22 | import java.util.List; 23 | 24 | import org.junit.After; 25 | import org.junit.Assert; 26 | import org.junit.Before; 27 | import org.junit.Test; 28 | 29 | 30 | /** 31 | * 32 | * 33 | * @author Gregory Brown (sysdevone) 34 | * 35 | */ 36 | public class DefinedCommandTokenizerTest 37 | { 38 | 39 | DefinedCommandTokenizer _tokenizer; 40 | 41 | @Before 42 | public void setUp() 43 | { 44 | this._tokenizer = new DefinedCommandTokenizer(); 45 | } 46 | 47 | @After 48 | public void tearDown() 49 | { 50 | this._tokenizer = null; 51 | } 52 | 53 | @Test 54 | public void testTokenizer() 55 | { 56 | final String inputString = "file , !fileName1,:file\\d.txt, #Load a files into the system"; 57 | final String[] inputTokens = inputString.split("\\s*,\\s*"); 58 | 59 | List tokens = this._tokenizer.tokenize(inputTokens); 60 | 61 | Assert.assertTrue(tokens.size() == 4); 62 | Assert.assertTrue(tokens.get(0).getValue().equals("file")); 63 | Assert.assertTrue(tokens.get(1).getValue().equals("fileName1")); 64 | Assert.assertTrue(tokens.get(2).getValue().equals("file\\d.txt")); 65 | Assert.assertTrue(tokens.get(3).getValue().equals("Load a files into the system")); 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/test/resources/logging.properties: -------------------------------------------------------------------------------- 1 | # Add handlers to the root logger. 2 | # These are inherited by all other loggers. 3 | #handlers=java.util.logging.ConsoleHandler, java.util.logging.FileHandler 4 | handlers=java.util.logging.ConsoleHandler 5 | 6 | # Set the logging level of the root logger. 7 | # Levels from lowest to highest are 8 | # FINEST, FINER, FINE, CONFIG, INFO, WARNING and SEVERE. 9 | # The default level for all loggers and handlers is INFO. 10 | .level=FINER 11 | 12 | 13 | # Configure the ConsoleHandler. 14 | # ConsoleHandler uses java.util.logging.SimpleFormatter by default. 15 | # Even though the root logger has the same level as this, 16 | # the next line is still needed because we're configuring a handler, 17 | # not a logger, and handlers don't inherit properties from the root logger. 18 | java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter 19 | java.util.logging.ConsoleHandler.level=FINEST 20 | 21 | # Configure the FileHandler. 22 | # FileHandler uses java.util.logging.XMLFormatter by default. 23 | java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter 24 | java.util.logging.FileHandler.level=FINEST 25 | 26 | # The following special tokens can be used in the pattern property 27 | # which specifies the location and name of the log file. 28 | # / - standard path separator 29 | # %t - system temporary directory 30 | # %h - value of the user.home system property 31 | # %g - generation number for rotating logs 32 | # %u - unique number to avoid conflicts 33 | # FileHandler writes to %h/demo0.log by default. 34 | java.util.logging.FileHandler.pattern=/%t/gab-cmdline/gab-line-log%u%g.log 35 | 36 | #java.util.logging.SimpleFormatter.format=%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS %1$Tp %2$s%n%4$s: %5$s%n 37 | 38 | java.util.logging.SimpleFormatter.format=%1$tY-%1tm-%1$td|%1$tl:%1$tM:%1$tS %1$Tp|%4$s|%2$s|%5$s%n --------------------------------------------------------------------------------