├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── library ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── br │ │ └── com │ │ └── ilhasoft │ │ └── support │ │ └── validation │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ ├── br │ │ │ └── com │ │ │ │ └── ilhasoft │ │ │ │ └── support │ │ │ │ └── validation │ │ │ │ ├── Validator.java │ │ │ │ ├── binding │ │ │ │ ├── DateBindings.java │ │ │ │ ├── LengthBindings.java │ │ │ │ ├── PasswordBindings.java │ │ │ │ ├── RegexBindings.java │ │ │ │ └── TypeBindings.java │ │ │ │ ├── rule │ │ │ │ ├── ConfirmPasswordRule.java │ │ │ │ ├── CpfTypeRule.java │ │ │ │ ├── CreditCardTypeRule.java │ │ │ │ ├── DateRule.java │ │ │ │ ├── EmailTypeRule.java │ │ │ │ ├── EmptyRule.java │ │ │ │ ├── MaxLengthRule.java │ │ │ │ ├── MinLengthRule.java │ │ │ │ ├── RegexRule.java │ │ │ │ ├── Rule.java │ │ │ │ ├── TypeRule.java │ │ │ │ ├── UrlTypeRule.java │ │ │ │ └── UsernameRule.java │ │ │ │ └── util │ │ │ │ ├── EditTextHandler.java │ │ │ │ ├── ErrorMessageHelper.java │ │ │ │ └── ViewTagHelper.java │ │ └── org │ │ │ └── apache │ │ │ └── commons │ │ │ └── validator │ │ │ └── routines │ │ │ ├── AbstractCalendarValidator.java │ │ │ ├── AbstractFormatValidator.java │ │ │ ├── CodeValidator.java │ │ │ ├── CreditCardValidator.java │ │ │ ├── DateValidator.java │ │ │ ├── RegexValidator.java │ │ │ └── checkdigit │ │ │ ├── CheckDigit.java │ │ │ ├── CheckDigitException.java │ │ │ ├── LuhnCheckDigit.java │ │ │ └── ModulusCheckDigit.java │ └── res │ │ ├── values-es │ │ └── strings.xml │ │ ├── values-pt │ │ └── strings.xml │ │ └── values │ │ ├── ids.xml │ │ └── strings.xml │ └── test │ └── java │ └── br │ └── com │ └── ilhasoft │ └── support │ └── validation │ └── ExampleUnitTest.java ├── sample ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── br │ │ └── com │ │ └── ilhasoft │ │ └── support │ │ └── validation │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── br │ │ │ └── com │ │ │ └── ilhasoft │ │ │ └── support │ │ │ └── validation │ │ │ └── sample │ │ │ └── MainActivity.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── br │ └── com │ └── ilhasoft │ └── support │ └── validation │ └── ExampleUnitTest.java ├── settings.gradle └── usageSample.gif /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/java,intellij,android,osx,windows,linux,git 3 | 4 | ### Intellij ### 5 | 6 | .idea/ 7 | 8 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 9 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 10 | 11 | # User-specific stuff: 12 | .idea/workspace.xml 13 | .idea/tasks.xml 14 | .idea/dictionaries 15 | .idea/vcs.xml 16 | .idea/jsLibraryMappings.xml 17 | 18 | # Sensitive or high-churn files: 19 | .idea/dataSources.ids 20 | .idea/dataSources.xml 21 | .idea/dataSources.local.xml 22 | .idea/sqlDataSources.xml 23 | .idea/dynamic.xml 24 | .idea/uiDesigner.xml 25 | 26 | # Gradle: 27 | .idea/gradle.xml 28 | .idea/libraries 29 | 30 | # Mongo Explorer plugin: 31 | .idea/mongoSettings.xml 32 | 33 | ## File-based project format: 34 | *.iws 35 | 36 | ## Plugin-specific files: 37 | 38 | # IntelliJ 39 | /out/ 40 | 41 | # mpeltonen/sbt-idea plugin 42 | .idea_modules/ 43 | 44 | # JIRA plugin 45 | atlassian-ide-plugin.xml 46 | 47 | # Crashlytics plugin (for Android Studio and IntelliJ) 48 | com_crashlytics_export_strings.xml 49 | crashlytics.properties 50 | crashlytics-build.properties 51 | fabric.properties 52 | 53 | ### Intellij Patch ### 54 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 55 | 56 | # *.iml 57 | # modules.xml 58 | 59 | 60 | ### Android ### 61 | # Built application files 62 | *.apk 63 | *.ap_ 64 | 65 | # Files for the Dalvik VM 66 | *.dex 67 | 68 | # Java class files 69 | *.class 70 | 71 | # Generated files 72 | bin/ 73 | gen/ 74 | out/ 75 | 76 | # Gradle files 77 | .gradle/ 78 | build/ 79 | 80 | # Local configuration file (sdk path, etc) 81 | local.properties 82 | 83 | # Proguard folder generated by Eclipse 84 | proguard/ 85 | 86 | # Log Files 87 | *.log 88 | 89 | # Android Studio Navigation editor temp files 90 | .navigation/ 91 | 92 | # Android Studio captures folder 93 | captures/ 94 | 95 | # Intellij 96 | *.iml 97 | 98 | # Keystore files 99 | *.jks 100 | 101 | ### Android Patch ### 102 | gen-external-apklibs 103 | 104 | 105 | ### OSX ### 106 | *.DS_Store 107 | .AppleDouble 108 | .LSOverride 109 | 110 | # Icon must end with two \r 111 | Icon 112 | 113 | 114 | # Thumbnails 115 | ._* 116 | 117 | # Files that might appear in the root of a volume 118 | .DocumentRevisions-V100 119 | .fseventsd 120 | .Spotlight-V100 121 | .TemporaryItems 122 | .Trashes 123 | .VolumeIcon.icns 124 | .com.apple.timemachine.donotpresent 125 | 126 | # Directories potentially created on remote AFP share 127 | .AppleDB 128 | .AppleDesktop 129 | Network Trash Folder 130 | Temporary Items 131 | .apdisk 132 | 133 | 134 | ### Windows ### 135 | # Windows image file caches 136 | Thumbs.db 137 | ehthumbs.db 138 | 139 | # Folder config file 140 | Desktop.ini 141 | 142 | # Recycle Bin used on file shares 143 | $RECYCLE.BIN/ 144 | 145 | # Windows Installer files 146 | *.cab 147 | *.msi 148 | *.msm 149 | *.msp 150 | 151 | # Windows shortcuts 152 | *.lnk 153 | 154 | 155 | ### Linux ### 156 | *~ 157 | 158 | # temporary files which can be created if a process still has a handle open of a deleted file 159 | .fuse_hidden* 160 | 161 | # KDE directory preferences 162 | .directory 163 | 164 | # Linux trash folder which might appear on any partition or disk 165 | .Trash-* 166 | 167 | 168 | ### Git ### 169 | *.orig 170 | 171 | 172 | ### Java ### 173 | *.class 174 | 175 | # Mobile Tools for Java (J2ME) 176 | .mtj.tmp/ 177 | 178 | # Package Files # 179 | # *.jar 180 | *.war 181 | *.ear 182 | 183 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 184 | hs_err_pid* 185 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # IlhaSoft Support Validation CHANGELOG 2 | 3 | ## Version 0.5.0 (2016-10-14) 4 | 5 | * Implemented password validation 6 | * Created ES and EN translation 7 | * Updated build tools and support libraries 8 | 9 | ## Version 0.4.5 (2016-10-14) 10 | 11 | * Fix error messages on **TextInputLayout** 12 | ## Version 0.4.4 (2016-10-14) 13 | 14 | * Updated DateRule to don't use apache validator library 15 | * Removed the dependency of the entire Apache validator library 16 | * Fixed implementation of `disableErrorOnChanged` method 17 | 18 | ## Version 0.4.3 (2016-10-14) 19 | 20 | * Fixed problem with CPF validation 21 | 22 | ## Version 0.4.2 (2016-10-03) 23 | 24 | * Remove unused groups on commons validation 25 | 26 | ## Version 0.4.1 (2016-06-16) 27 | 28 | * Fixed credit card validation with white spaces 29 | 30 | ## Version 0.4.0 (2016-06-16) 31 | 32 | * Added validators for date by pattern 33 | * Added credit card type validation 34 | 35 | ## Version 0.3.1 (2016-06-08) 36 | 37 | * Fixed validation order 38 | 39 | ## Version 0.3.0 (2016-06-08) 40 | 41 | * Added empty role for validations; 42 | * Added enable or disable validation for a view; 43 | 44 | ## Version 0.2.0 (2016-05-26) 45 | 46 | * Added TextWatcher to clear error when typing; 47 | * Added CPF rule for validations; 48 | * Added sample of library; 49 | 50 | ## Version 0.1.0 (2016-05-25) 51 | 52 | * **Initial release**; 53 | * Created base of this library; 54 | * Added simple rules for validations; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data Binding Validator by Ilhasoft 2 | 3 | [![Release](https://jitpack.io/v/Ilhasoft/data-binding-validator.svg?style=flag-square?style=flat-square)](https://jitpack.io/#Ilhasoft/data-binding-validator) 4 | 5 | The Data Binding Validator makes it easy and quick to validate fields in forms using data binding framework. 6 | 7 | ## Download 8 | 9 | Step 1: Add it in your root build.gradle at the end of repositories: 10 | 11 | ``` 12 | allprojects { 13 | repositories { 14 | ... 15 | maven { url 'https://jitpack.io' } 16 | } 17 | } 18 | ``` 19 | 20 | Step 2: Add the dependency 21 | ``` 22 | dependencies { 23 | compile 'com.github.Ilhasoft:data-binding-validator:LATEST-VERSION' 24 | } 25 | ``` 26 | Latest Version: [![Latest version](https://jitpack.io/v/Ilhasoft/data-binding-validator.svg?style=flat-square)](https://jitpack.io/#Ilhasoft/data-binding-validator) 27 | 28 | 29 | ## Features: 30 | 31 | * Minimum/Maximum length validation for text fields; 32 | * Validate inputs based on field type (email, credit card, URL, CPF and so on); 33 | * Pre-defined error messages translated into English, Portuguese and Spanish; 34 | * Custom error messages by field; 35 | * Supports [`TextInputLayout`](https://developer.android.com/reference/android/support/design/widget/TextInputLayout.html) and EditText; 36 | 37 | ## Sample 38 | 39 | ... 40 | 41 | ## Usage 42 | 43 | ### Enabling Data Binding ### 44 | 45 | You need to enable Data Binding to use this library, add the following code into your main module's `build.gradle`: 46 | 47 | ``` 48 | android { 49 | .... 50 | dataBinding { 51 | enabled = true 52 | } 53 | } 54 | ``` 55 | 56 | ### Setting up validations directly on layout ### 57 | 58 | It's possible to insert directly on layout creation, the validation on input fields. The error messages in different languages already are configured inside the library, not requiring the adding by developers. These are the existing validation types: 59 | 60 | #### Validate Characters Length #### 61 | 62 | Adding `validateMinLength` or `validateMaxLength` to your `EditText`, it's possible to configure a minimum or maximum characters length: 63 | 64 | ``` 65 | 72 | ``` 73 | 74 | #### Validate Empty Characters #### 75 | 76 | Adding `validateEmpty`, you can validate if the `EditText` is empty: 77 | 78 | ``` 79 | 85 | ``` 86 | 87 | #### Validate Date Patterns #### 88 | 89 | Adding `validateDate`, you can set a pattern accepted by the `EditText` such as `dd/MM/yyyy`, `yyyy` and so on: 90 | 91 | ``` 92 | 98 | ``` 99 | 100 | #### Validate Regex #### 101 | 102 | Adding `validateRegex`, you can set a regular expression to be validated, for example: 103 | 104 | ``` 105 | 112 | ``` 113 | 114 | #### Validate Input Types #### 115 | 116 | You can even validate input by date, for example Email, URL, Username, CreditCard, CPF, CEP and so on: 117 | 118 | ``` 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | ``` 129 | 130 | ### Applying Validation ### 131 | 132 | It will be necessary to instantiate `Validator` passing as argument your `ViewDataBinding` instance got from your layout binding. After that you can call `validate()` that will return if your data is valid or not. Example: 133 | 134 | ``` 135 | @Override 136 | protected void onCreate(Bundle savedInstanceState) { 137 | super.onCreate(savedInstanceState); 138 | 139 | MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity); 140 | final Validator validator = new Validator(binding); 141 | 142 | binding.validate.setOnClickListener(new View.OnClickListener() { 143 | @Override 144 | public void onClick(View v) { 145 | if (validator.validate()) { 146 | saveToDatabase(); 147 | } 148 | } 149 | }); 150 | } 151 | ``` 152 | 153 | Or you can use `toValidate()` if prefer using listener to validation response: 154 | 155 | ``` 156 | public class YourActivity extends AppCompatActivity implements Validator.ValidationListener { 157 | 158 | ... 159 | 160 | @Override 161 | protected void onCreate(Bundle savedInstanceState) { 162 | super.onCreate(savedInstanceState); 163 | 164 | MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity); 165 | final Validator validator = new Validator(binding); 166 | validator.setValidationListener(this); 167 | 168 | binding.validate.setOnClickListener(new View.OnClickListener() { 169 | @Override 170 | public void onClick(View v) { 171 | validator.toValidate() 172 | } 173 | }); 174 | } 175 | 176 | @Override 177 | public void onValidationSuccess() { 178 | saveToDatabase(); 179 | } 180 | 181 | @Override 182 | public void onValidationError() { 183 | Toast.makeText(YourActivity.this, "Dados inválidos!", Toast.LENGTH_SHORT).show(); 184 | } 185 | } 186 | ``` 187 | 188 | ### Custom Error Messages ### 189 | 190 | You can add custom error messages by using the same validation rule name and adding `Message` at the end, such as `validateTypeMessage`, `validateDateMessage`, `validateRegexMessage` and so on. For example: 191 | 192 | ``` 193 | 200 | ``` 201 | 202 | ### Validating ### 203 | 204 | If you want to validate all the fields, you can simply call `validator.validate()`, to validate specific views you can call `validator.validate(view)` or `validator.validate(viewsList)`; 205 | 206 | ### Validation modes ### 207 | 208 | The validation can be applied in two way, field by field or the whole form at once. By default, it's configured field by field, however, you can call `validator.enableFormValidationMode();` to enable the validation of the whole form. 209 | 210 | If you want to come back to the default way, call `validator.enableFieldValidationMode();` 211 | 212 | ### Auto dismiss ### 213 | 214 | By default, the library prompts error messages and doens't dismiss the error automatically, however, you can add on your layout validation the same rule name by adding `AutoDismiss` at the end, which receives a `boolean`. In this case it could dismiss the error automatically. For example: 215 | 216 | ``` 217 | 225 | ``` 226 | 227 | ## License ## 228 | 229 | Copyright 2017-present Ilhasoft 230 | 231 | Licensed under the Apache License, Version 2.0 (the "License"); 232 | you may not use this file except in compliance with the License. 233 | You may obtain a copy of the License at 234 | 235 | http://www.apache.org/licenses/LICENSE-2.0 236 | 237 | Unless required by applicable law or agreed to in writing, software 238 | distributed under the License is distributed on an "AS IS" BASIS, 239 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 240 | See the License for the specific language governing permissions and 241 | limitations under the License. 242 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | maven { url 'https://maven.google.com' } 4 | jcenter() 5 | google() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.2.1' 9 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0' 10 | } 11 | } 12 | 13 | allprojects { 14 | repositories { 15 | maven { url 'https://maven.google.com' } 16 | jcenter() 17 | } 18 | } 19 | 20 | task clean(type: Delete) { 21 | delete rootProject.buildDir 22 | } 23 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | android.enableJetifier=true 20 | android.useAndroidX=true -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ilhasoft/data-binding-validator/c678970f612ae35245060910c863812a0469a4b1/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Oct 19 07:43:43 MSK 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /library/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'com.github.dcendents.android-maven' 3 | 4 | group='org.bitbucket.ilhasoft' 5 | 6 | android { 7 | compileSdkVersion 28 8 | buildToolsVersion '28.0.3' 9 | 10 | // Gradle automatically adds 'android.test.runner' as a dependency. 11 | useLibrary 'android.test.runner' 12 | 13 | dataBinding { 14 | enabled true 15 | } 16 | 17 | defaultConfig { 18 | minSdkVersion 15 19 | targetSdkVersion 28 20 | versionCode 3 21 | versionName "1.0.0" 22 | consumerProguardFiles 'proguard-rules.pro' 23 | 24 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 25 | } 26 | } 27 | 28 | dependencies { 29 | implementation fileTree(dir: 'libs', include: ['*.jar']) 30 | api 'androidx.appcompat:appcompat:1.0.0' 31 | api 'com.google.android.material:material:1.0.0' 32 | // JUnit 4 framework 33 | testImplementation 'junit:junit:4.12' 34 | // Android annotations 35 | androidTestImplementation 'androidx.annotation:annotation:1.0.0' 36 | // AndroidJUnitRunner and JUnit Rules 37 | androidTestImplementation 'androidx.test:runner:1.1.0-beta02' 38 | androidTestImplementation 'androidx.test:rules:1.1.0-beta02' 39 | } 40 | 41 | // build a jar with source files 42 | task sourcesJar(type: Jar) { 43 | from android.sourceSets.main.java.srcDirs 44 | classifier = 'sources' 45 | } 46 | 47 | task javadoc(type: Javadoc) { 48 | failOnError false 49 | source = android.sourceSets.main.java.sourceFiles 50 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 51 | classpath += configurations.compile 52 | } 53 | 54 | // build a jar with javadoc 55 | task javadocJar(type: Jar, dependsOn: javadoc) { 56 | classifier = 'javadoc' 57 | from javadoc.destinationDir 58 | } 59 | 60 | artifacts { 61 | archives sourcesJar 62 | archives javadocJar 63 | } 64 | 65 | // uncomment to build a jar file in addition to the default aar file 66 | //android.libraryVariants.all { variant -> 67 | // def name = variant.buildType.name 68 | // def task = project.tasks.create "jar${name.capitalize()}", Jar 69 | // task.dependsOn variant.javaCompile 70 | // task.from variant.javaCompile.destinationDir 71 | // artifacts.add('archives', task); -------------------------------------------------------------------------------- /library/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/john-mac/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /library/src/androidTest/java/br/com/ilhasoft/support/validation/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package br.com.ilhasoft.support.validation; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /library/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/Validator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation; 18 | 19 | import androidx.databinding.ViewDataBinding; 20 | import android.view.View; 21 | import android.view.ViewGroup; 22 | 23 | import java.util.Collections; 24 | import java.util.HashSet; 25 | import java.util.List; 26 | import java.util.Set; 27 | 28 | import br.com.ilhasoft.support.validation.rule.Rule; 29 | import br.com.ilhasoft.support.validation.util.ViewTagHelper; 30 | 31 | /** 32 | * Created by john-mac on 5/14/16. 33 | */ 34 | public class Validator { 35 | 36 | private static final int FIELD_VALIDATION_MODE = 0; 37 | private static final int FORM_VALIDATION_MODE = 1; 38 | 39 | private ViewDataBinding target; 40 | private ValidationListener validationListener; 41 | 42 | private int mode = FIELD_VALIDATION_MODE; 43 | private final Set disabledViews; 44 | 45 | public Validator(ViewDataBinding target) { 46 | this.target = target; 47 | this.disabledViews = new HashSet<>(); 48 | } 49 | 50 | public void setValidationListener(ValidationListener validationListener) { 51 | this.validationListener = validationListener; 52 | } 53 | 54 | public void toValidate() { 55 | if (validationListener == null) throw new IllegalArgumentException("Validation listener should not be null."); 56 | 57 | if (validate()) { 58 | validationListener.onValidationSuccess(); 59 | } else { 60 | validationListener.onValidationError(); 61 | } 62 | } 63 | 64 | public boolean validate() { 65 | List viewWithValidations = getViewsWithValidation(); 66 | return isAllViewsValid(viewWithValidations); 67 | } 68 | 69 | public boolean validate(View view) { 70 | List viewWithValidations = getViewsWithValidation(view); 71 | return isAllViewsValid(viewWithValidations); 72 | } 73 | 74 | public boolean validate(List views) { 75 | List viewWithValidations = getViewsWithValidation(views); 76 | return isAllViewsValid(viewWithValidations); 77 | } 78 | 79 | private boolean isAllViewsValid(List viewWithValidations) { 80 | boolean allViewsValid = true; 81 | for (View viewWithValidation : viewWithValidations) { 82 | boolean viewValid = true; 83 | List rules = (List) viewWithValidation.getTag(R.id.validator_rule); 84 | for (Rule rule : rules) { 85 | viewValid = viewValid && isRuleValid(rule); 86 | allViewsValid = allViewsValid && viewValid; 87 | } 88 | 89 | if(mode == FIELD_VALIDATION_MODE && !viewValid) { 90 | break; 91 | } 92 | } 93 | return allViewsValid; 94 | } 95 | 96 | private boolean isRuleValid(Rule rule) { 97 | return disabledViews.contains(rule.getView()) || rule.validate(); 98 | } 99 | 100 | public void disableValidation(View view) { 101 | disabledViews.add(view); 102 | } 103 | 104 | public void enableValidation(View view) { 105 | disabledViews.remove(view); 106 | } 107 | 108 | public void enableFormValidationMode() { 109 | this.mode = FORM_VALIDATION_MODE; 110 | } 111 | 112 | public void enableFieldValidationMode() { 113 | this.mode = FIELD_VALIDATION_MODE; 114 | } 115 | 116 | private List getViewsWithValidation() { 117 | if(target.getRoot() instanceof ViewGroup) { 118 | return ViewTagHelper.getViewsByTag((ViewGroup) target.getRoot(), R.id.validator_rule); 119 | } 120 | return Collections.singletonList(target.getRoot()); 121 | } 122 | 123 | private List getViewsWithValidation(List views) { 124 | return ViewTagHelper.filterViewsWithTag(R.id.validator_rule, views); 125 | } 126 | 127 | private List getViewsWithValidation(View view) { 128 | return ViewTagHelper.filterViewWithTag(R.id.validator_rule, view); 129 | } 130 | 131 | public interface ValidationListener { 132 | 133 | void onValidationSuccess(); 134 | 135 | void onValidationError(); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/binding/DateBindings.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.binding; 18 | 19 | import androidx.databinding.BindingAdapter; 20 | import android.widget.TextView; 21 | 22 | import br.com.ilhasoft.support.validation.R; 23 | import br.com.ilhasoft.support.validation.rule.DateRule; 24 | import br.com.ilhasoft.support.validation.util.EditTextHandler; 25 | import br.com.ilhasoft.support.validation.util.ErrorMessageHelper; 26 | import br.com.ilhasoft.support.validation.util.ViewTagHelper; 27 | 28 | /** 29 | * Created by john-mac on 6/16/16. 30 | */ 31 | public class DateBindings { 32 | 33 | @BindingAdapter(value = {"validateDate", "validateDateMessage", "validateDateAutoDismiss"}, requireAll = false) 34 | public static void bindingDate(TextView view, String pattern, String errorMessage, boolean autoDismiss) { 35 | if (autoDismiss) { 36 | EditTextHandler.disableErrorOnChanged(view); 37 | } 38 | 39 | String handledErrorMessage = ErrorMessageHelper.getStringOrDefault(view, 40 | errorMessage, R.string.error_message_date_validation); 41 | ViewTagHelper.appendValue(R.id.validator_rule, view, new DateRule(view, pattern, handledErrorMessage)); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/binding/LengthBindings.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.binding; 18 | 19 | import androidx.databinding.BindingAdapter; 20 | import android.widget.TextView; 21 | 22 | import br.com.ilhasoft.support.validation.R; 23 | import br.com.ilhasoft.support.validation.rule.EmptyRule; 24 | import br.com.ilhasoft.support.validation.rule.MaxLengthRule; 25 | import br.com.ilhasoft.support.validation.rule.MinLengthRule; 26 | import br.com.ilhasoft.support.validation.util.EditTextHandler; 27 | import br.com.ilhasoft.support.validation.util.ErrorMessageHelper; 28 | import br.com.ilhasoft.support.validation.util.ViewTagHelper; 29 | 30 | /** 31 | * Created by john-mac on 5/14/16. 32 | */ 33 | public class LengthBindings { 34 | 35 | @BindingAdapter(value = {"validateMinLength", "validateMinLengthMessage", "validateMinLengthAutoDismiss"}, requireAll = false) 36 | public static void bindingMinLength(TextView view, int minLength, String errorMessage, boolean autoDismiss) { 37 | if (autoDismiss) { 38 | EditTextHandler.disableErrorOnChanged(view); 39 | } 40 | 41 | String handledErrorMessage = ErrorMessageHelper.getStringOrDefault(view, 42 | errorMessage, R.string.error_message_min_length, minLength); 43 | ViewTagHelper.appendValue(R.id.validator_rule, view, new MinLengthRule(view, minLength, handledErrorMessage)); 44 | } 45 | 46 | @BindingAdapter(value = {"validateMaxLength", "validateMaxLengthMessage", "validateMaxLengthAutoDismiss"}, requireAll = false) 47 | public static void bindingMaxLength(TextView view, int maxLength, String errorMessage, boolean autoDismiss) { 48 | if (autoDismiss) { 49 | EditTextHandler.disableErrorOnChanged(view); 50 | } 51 | 52 | String handledErrorMessage = ErrorMessageHelper.getStringOrDefault(view, 53 | errorMessage, R.string.error_message_max_length, maxLength); 54 | ViewTagHelper.appendValue(R.id.validator_rule, view, new MaxLengthRule(view, maxLength, handledErrorMessage)); 55 | } 56 | 57 | @BindingAdapter(value = {"validateEmpty", "validateEmptyMessage", "validateEmptyAutoDismiss"}, requireAll = false) 58 | public static void bindingEmpty(TextView view, boolean empty, String errorMessage, boolean autoDismiss) { 59 | if (autoDismiss) { 60 | EditTextHandler.disableErrorOnChanged(view); 61 | } 62 | 63 | String handledErrorMessage = ErrorMessageHelper.getStringOrDefault(view, 64 | errorMessage, R.string.error_message_empty_validation); 65 | ViewTagHelper.appendValue(R.id.validator_rule, view, new EmptyRule(view, empty, handledErrorMessage)); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/binding/PasswordBindings.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.binding; 18 | 19 | import androidx.databinding.BindingAdapter; 20 | import android.widget.TextView; 21 | 22 | import br.com.ilhasoft.support.validation.R; 23 | import br.com.ilhasoft.support.validation.rule.ConfirmPasswordRule; 24 | import br.com.ilhasoft.support.validation.util.EditTextHandler; 25 | import br.com.ilhasoft.support.validation.util.ErrorMessageHelper; 26 | import br.com.ilhasoft.support.validation.util.ViewTagHelper; 27 | 28 | /** 29 | * Created by felipe on 22/12/16. 30 | */ 31 | public class PasswordBindings { 32 | 33 | @BindingAdapter(value = {"validatePassword", "validatePasswordMessage", "validatePasswordAutoDismiss"}, requireAll = false) 34 | public static void bindingPassword(TextView view, TextView comparableView, String errorMessage, boolean autoDismiss) { 35 | if (autoDismiss) { 36 | EditTextHandler.disableErrorOnChanged(view); 37 | } 38 | 39 | String handledErrorMessage = ErrorMessageHelper.getStringOrDefault(view, 40 | errorMessage, R.string.error_message_not_equal_password); 41 | ViewTagHelper.appendValue(R.id.validator_rule, view, 42 | new ConfirmPasswordRule(view, comparableView, handledErrorMessage)); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/binding/RegexBindings.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.binding; 18 | 19 | import androidx.databinding.BindingAdapter; 20 | import android.widget.TextView; 21 | 22 | import br.com.ilhasoft.support.validation.R; 23 | import br.com.ilhasoft.support.validation.rule.RegexRule; 24 | import br.com.ilhasoft.support.validation.util.EditTextHandler; 25 | import br.com.ilhasoft.support.validation.util.ErrorMessageHelper; 26 | import br.com.ilhasoft.support.validation.util.ViewTagHelper; 27 | 28 | /** 29 | * Created by john-mac on 3/24/17. 30 | */ 31 | public class RegexBindings { 32 | 33 | @BindingAdapter(value = {"validateRegex", "validateRegexMessage", "validateRegexAutoDismiss"}, requireAll = false) 34 | public static void bindingRegex(TextView view, String pattern, String errorMessage, boolean autoDismiss) { 35 | if (autoDismiss) { 36 | EditTextHandler.disableErrorOnChanged(view); 37 | } 38 | 39 | String handledErrorMessage = ErrorMessageHelper.getStringOrDefault(view, 40 | errorMessage, R.string.error_message_regex_validation); 41 | ViewTagHelper.appendValue(R.id.validator_rule, view, new RegexRule(view, pattern, handledErrorMessage)); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/binding/TypeBindings.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.binding; 18 | 19 | import androidx.databinding.BindingAdapter; 20 | import androidx.annotation.NonNull; 21 | import android.widget.TextView; 22 | 23 | import br.com.ilhasoft.support.validation.R; 24 | import br.com.ilhasoft.support.validation.rule.TypeRule; 25 | import br.com.ilhasoft.support.validation.util.EditTextHandler; 26 | import br.com.ilhasoft.support.validation.util.ErrorMessageHelper; 27 | import br.com.ilhasoft.support.validation.util.ViewTagHelper; 28 | 29 | /** 30 | * Created by john-mac on 5/14/16. 31 | */ 32 | public class TypeBindings { 33 | 34 | @BindingAdapter(value = {"validateType", "validateTypeMessage", "validateTypeAutoDismiss"}, requireAll = false) 35 | public static void bindingTypeValidation(TextView view, String fieldTypeText, String errorMessage, boolean autoDismiss) { 36 | if (autoDismiss) { 37 | EditTextHandler.disableErrorOnChanged(view); 38 | } 39 | TypeRule.FieldType fieldType = getFieldTypeByText(fieldTypeText); 40 | try { 41 | String handledErrorMessage = ErrorMessageHelper.getStringOrDefault(view, 42 | errorMessage, fieldType.errorMessageId); 43 | ViewTagHelper.appendValue(R.id.validator_rule, view, fieldType.instantiate(view, handledErrorMessage)); 44 | } catch (Exception ignored) {} 45 | } 46 | 47 | @NonNull 48 | private static TypeRule.FieldType getFieldTypeByText(String fieldTypeText) { 49 | TypeRule.FieldType fieldType = TypeRule.FieldType.None; 50 | for (TypeRule.FieldType type : TypeRule.FieldType.values()) { 51 | if (type.toString().equalsIgnoreCase(fieldTypeText)) { 52 | fieldType = type; 53 | break; 54 | } 55 | } 56 | return fieldType; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/rule/ConfirmPasswordRule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.rule; 18 | 19 | import android.widget.TextView; 20 | 21 | import br.com.ilhasoft.support.validation.R; 22 | import br.com.ilhasoft.support.validation.util.EditTextHandler; 23 | 24 | /** 25 | * Created by john-mac on 5/14/16. 26 | */ 27 | public class ConfirmPasswordRule extends Rule { 28 | 29 | public ConfirmPasswordRule(TextView view, TextView value, String errorMessage) { 30 | super(view, value, errorMessage); 31 | } 32 | 33 | @Override 34 | public boolean isValid(TextView view) { 35 | if (value == null) return false; 36 | 37 | final String value1 = view.getText().toString(); 38 | final String value2 = value.getText().toString(); 39 | return value1.trim().equals(value2.trim()); 40 | } 41 | 42 | @Override 43 | public void onValidationSucceeded(TextView view) { 44 | EditTextHandler.removeError(view); 45 | } 46 | 47 | @Override 48 | public void onValidationFailed(TextView view) { 49 | EditTextHandler.setError(view, errorMessage); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/rule/CpfTypeRule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.rule; 18 | 19 | import android.widget.TextView; 20 | 21 | import br.com.ilhasoft.support.validation.util.EditTextHandler; 22 | 23 | /** 24 | * Created by john-mac on 5/14/16. 25 | */ 26 | public class CpfTypeRule extends TypeRule { 27 | 28 | public CpfTypeRule(TextView view, String errorMessage) { 29 | super(view, FieldType.Cpf, errorMessage); 30 | } 31 | 32 | @Override 33 | protected boolean isValid(TextView view) { 34 | final String rawCpf = view.getText().toString().trim().replaceAll("[^\\d]", ""); 35 | return rawCpf.length() == 11 && !onBlackList(rawCpf) 36 | && (cpfDv(rawCpf, 1) == Character.getNumericValue(rawCpf.charAt(9)) 37 | && cpfDv(rawCpf, 2) == Character.getNumericValue(rawCpf.charAt(10))); 38 | } 39 | 40 | /** 41 | * 42 | * @param rawCpf raw CPF with length equal to 11. 43 | * @param step 1 or 2. 44 | * @return verification sum. 45 | */ 46 | private int cpfDv(final String rawCpf, final int step) { 47 | final int dv = 11 - cpfSum(rawCpf, step) % 11; 48 | return (dv == 10 || dv == 11) ? 0 : dv; 49 | } 50 | 51 | private int cpfSum(final String rawCPF, final int step) { 52 | int sum = 0; 53 | final int count = 8 + step; 54 | final int baseMultiplier = 9 + step; 55 | for (int i = 0; i < count; ++i) { 56 | sum += ((baseMultiplier - i) * Character.getNumericValue(rawCPF.charAt(i))); 57 | } 58 | return sum; 59 | } 60 | 61 | // Reference: https://github.com/concretesolutions/canarinho/blob/master/canarinho/src/main/java/br/com/concretesolutions/canarinho/validator/ValidadorCPF.java 62 | private boolean onBlackList(String rawCpf) { 63 | boolean equal = true; 64 | for (int i = 1; i < 11 && equal; i++) { 65 | if (rawCpf.charAt(i) != rawCpf.charAt(0)) { 66 | equal = false; 67 | } 68 | } 69 | return equal || rawCpf.equals("12345678909"); 70 | } 71 | 72 | @Override 73 | protected void onValidationSucceeded(TextView view) { 74 | super.onValidationSucceeded(view); 75 | EditTextHandler.removeError(view); 76 | } 77 | 78 | @Override 79 | protected void onValidationFailed(TextView view) { 80 | super.onValidationFailed(view); 81 | EditTextHandler.setError(view, errorMessage); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/rule/CreditCardTypeRule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.rule; 18 | 19 | import android.widget.TextView; 20 | 21 | import org.apache.commons.validator.routines.CreditCardValidator; 22 | 23 | import br.com.ilhasoft.support.validation.util.EditTextHandler; 24 | 25 | /** 26 | * Created by john-mac on 6/16/16. 27 | */ 28 | public class CreditCardTypeRule extends TypeRule { 29 | 30 | private final CreditCardValidator creditCardValidator; 31 | 32 | public CreditCardTypeRule(TextView view, String errorMessage) { 33 | super(view, FieldType.CreditCard, errorMessage); 34 | creditCardValidator = new CreditCardValidator(); 35 | } 36 | 37 | @Override 38 | protected boolean isValid(TextView view) { 39 | return creditCardValidator.isValid(view.getText().toString().replaceAll("\\s", "")); 40 | } 41 | 42 | @Override 43 | protected void onValidationSucceeded(TextView view) { 44 | super.onValidationSucceeded(view); 45 | EditTextHandler.removeError(view); 46 | } 47 | 48 | @Override 49 | protected void onValidationFailed(TextView view) { 50 | super.onValidationFailed(view); 51 | EditTextHandler.setError(view, errorMessage); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/rule/DateRule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.rule; 18 | 19 | import android.widget.TextView; 20 | 21 | import org.apache.commons.validator.routines.DateValidator; 22 | 23 | import br.com.ilhasoft.support.validation.util.EditTextHandler; 24 | 25 | /** 26 | * Created by john-mac on 6/16/16. 27 | */ 28 | public class DateRule extends Rule { 29 | 30 | private final DateValidator dateValidator; 31 | 32 | public DateRule(TextView view, String value, String errorMessage) { 33 | super(view, value, errorMessage); 34 | dateValidator = new DateValidator(); 35 | } 36 | 37 | @Override 38 | public boolean isValid(TextView view) { 39 | return dateValidator.isValid(view.getText().toString(), value); 40 | } 41 | 42 | @Override 43 | public void onValidationSucceeded(TextView view) { 44 | EditTextHandler.removeError(view); 45 | } 46 | 47 | @Override 48 | public void onValidationFailed(TextView view) { 49 | EditTextHandler.setError(view, errorMessage); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/rule/EmailTypeRule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.rule; 18 | 19 | import android.util.Patterns; 20 | import android.widget.TextView; 21 | 22 | import java.util.regex.Pattern; 23 | 24 | import br.com.ilhasoft.support.validation.R; 25 | import br.com.ilhasoft.support.validation.util.EditTextHandler; 26 | 27 | /** 28 | * Created by john-mac on 5/14/16. 29 | */ 30 | public class EmailTypeRule extends TypeRule { 31 | 32 | public EmailTypeRule(TextView view, String errorMessage) { 33 | super(view, FieldType.Email, errorMessage); 34 | } 35 | 36 | @Override 37 | protected boolean isValid(TextView view) { 38 | Pattern emailPattern = Patterns.EMAIL_ADDRESS; 39 | return emailPattern.matcher(view.getText()).matches(); 40 | } 41 | 42 | @Override 43 | protected void onValidationSucceeded(TextView view) { 44 | super.onValidationSucceeded(view); 45 | EditTextHandler.removeError(view); 46 | } 47 | 48 | @Override 49 | protected void onValidationFailed(TextView view) { 50 | super.onValidationFailed(view); 51 | EditTextHandler.setError(view, errorMessage); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/rule/EmptyRule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.rule; 18 | 19 | import android.text.TextUtils; 20 | import android.widget.TextView; 21 | 22 | import br.com.ilhasoft.support.validation.R; 23 | import br.com.ilhasoft.support.validation.util.EditTextHandler; 24 | 25 | /** 26 | * Created by john-mac on 5/14/16. 27 | */ 28 | public class EmptyRule extends Rule { 29 | 30 | public EmptyRule(TextView view, Boolean value, String errorMessage) { 31 | super(view, value, errorMessage); 32 | } 33 | 34 | @Override 35 | public boolean isValid(TextView view) { 36 | return !value || !TextUtils.isEmpty(view.getText()); 37 | } 38 | 39 | @Override 40 | public void onValidationSucceeded(TextView view) { 41 | EditTextHandler.removeError(view); 42 | } 43 | 44 | @Override 45 | public void onValidationFailed(TextView view) { 46 | EditTextHandler.setError(view, errorMessage); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/rule/MaxLengthRule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.rule; 18 | 19 | import android.widget.TextView; 20 | 21 | import br.com.ilhasoft.support.validation.R; 22 | import br.com.ilhasoft.support.validation.util.EditTextHandler; 23 | 24 | /** 25 | * Created by john-mac on 5/14/16. 26 | */ 27 | public class MaxLengthRule extends Rule { 28 | 29 | public MaxLengthRule(TextView view, Integer value, String errorMessage) { 30 | super(view, value, errorMessage); 31 | } 32 | 33 | @Override 34 | public boolean isValid(TextView view) { 35 | return view.length() <= value; 36 | } 37 | 38 | @Override 39 | public void onValidationSucceeded(TextView view) { 40 | EditTextHandler.removeError(view); 41 | } 42 | 43 | @Override 44 | public void onValidationFailed(TextView view) { 45 | EditTextHandler.setError(view, errorMessage); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/rule/MinLengthRule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.rule; 18 | 19 | import android.widget.TextView; 20 | 21 | import br.com.ilhasoft.support.validation.R; 22 | import br.com.ilhasoft.support.validation.util.EditTextHandler; 23 | 24 | /** 25 | * Created by john-mac on 5/14/16. 26 | */ 27 | public class MinLengthRule extends Rule { 28 | 29 | public MinLengthRule(TextView view, Integer value, String errorMessage) { 30 | super(view, value, errorMessage); 31 | } 32 | 33 | @Override 34 | public boolean isValid(TextView view) { 35 | return view.length() >= value; 36 | } 37 | 38 | @Override 39 | public void onValidationSucceeded(TextView view) { 40 | EditTextHandler.removeError(view); 41 | } 42 | 43 | @Override 44 | public void onValidationFailed(TextView view) { 45 | EditTextHandler.setError(view, errorMessage); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/rule/RegexRule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.rule; 18 | 19 | import android.widget.TextView; 20 | 21 | import org.apache.commons.validator.routines.DateValidator; 22 | 23 | import br.com.ilhasoft.support.validation.util.EditTextHandler; 24 | 25 | /** 26 | * Created by john-mac on 6/16/16. 27 | */ 28 | public class RegexRule extends Rule { 29 | 30 | public RegexRule(TextView view, String value, String errorMessage) { 31 | super(view, value, errorMessage); 32 | } 33 | 34 | @Override 35 | public boolean isValid(TextView view) { 36 | return view.getText().toString().matches(value); 37 | } 38 | 39 | @Override 40 | public void onValidationSucceeded(TextView view) { 41 | EditTextHandler.removeError(view); 42 | } 43 | 44 | @Override 45 | public void onValidationFailed(TextView view) { 46 | EditTextHandler.setError(view, errorMessage); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/rule/Rule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.rule; 18 | 19 | import android.view.View; 20 | 21 | /** 22 | * Created by john-mac on 5/14/16. 23 | */ 24 | public abstract class Rule { 25 | 26 | protected ValueType value; 27 | protected ViewType view; 28 | protected String errorMessage; 29 | 30 | public Rule(ViewType view, ValueType value, String errorMessage) { 31 | this.view = view; 32 | this.value = value; 33 | this.errorMessage = errorMessage; 34 | } 35 | 36 | public final boolean validate() { 37 | final boolean valid = isValid(view); 38 | if (valid) { 39 | onValidationSucceeded(view); 40 | } else { 41 | onValidationFailed(view); 42 | } 43 | return valid; 44 | } 45 | 46 | protected abstract boolean isValid(ViewType view); 47 | 48 | protected void onValidationSucceeded(ViewType view) {} 49 | 50 | protected void onValidationFailed(ViewType view) {} 51 | 52 | public ViewType getView() { 53 | return view; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/rule/TypeRule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.rule; 18 | 19 | import androidx.annotation.StringRes; 20 | import android.widget.TextView; 21 | 22 | import java.lang.reflect.InvocationTargetException; 23 | 24 | import br.com.ilhasoft.support.validation.R; 25 | 26 | /** 27 | * Created by john-mac on 5/14/16. 28 | */ 29 | public abstract class TypeRule extends Rule { 30 | 31 | public enum FieldType { 32 | Cpf(CpfTypeRule.class, R.string.error_message_cpf_validation), 33 | Username(UsernameRule.class, R.string.error_message_username_validation), 34 | Email(EmailTypeRule.class, R.string.error_message_email_validation), 35 | Url(UrlTypeRule.class, R.string.error_message_url_validation), 36 | CreditCard(CreditCardTypeRule.class, R.string.error_message_credit_card_validation), 37 | None; 38 | 39 | Class mClass; 40 | public @StringRes int errorMessageId; 41 | 42 | FieldType(Class mClass, @StringRes int errorMessageId) { 43 | this.mClass = mClass; 44 | this.errorMessageId = errorMessageId; 45 | } 46 | 47 | FieldType() {} 48 | 49 | public TypeRule instantiate(TextView view, String errorMessage) throws NoSuchMethodException, IllegalAccessException 50 | , InvocationTargetException, InstantiationException { 51 | if(this != None) { 52 | return mClass.getConstructor(TextView.class, String.class).newInstance(view, errorMessage); 53 | } 54 | throw new IllegalStateException("It's not possible to bind a none value type"); 55 | } 56 | } 57 | 58 | public TypeRule(TextView view, FieldType value, String errorMessage) { 59 | super(view, value, errorMessage); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/rule/UrlTypeRule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.rule; 18 | 19 | import android.webkit.URLUtil; 20 | import android.widget.TextView; 21 | 22 | import br.com.ilhasoft.support.validation.R; 23 | import br.com.ilhasoft.support.validation.util.EditTextHandler; 24 | 25 | /** 26 | * Created by john-mac on 5/14/16. 27 | */ 28 | public class UrlTypeRule extends TypeRule { 29 | 30 | public UrlTypeRule(TextView textView, String errorMessage) { 31 | super(textView, FieldType.Url, errorMessage); 32 | } 33 | 34 | @Override 35 | protected boolean isValid(TextView view) { 36 | return URLUtil.isValidUrl(view.getText().toString()); 37 | } 38 | 39 | @Override 40 | protected void onValidationSucceeded(TextView view) { 41 | super.onValidationSucceeded(view); 42 | EditTextHandler.removeError(view); 43 | } 44 | 45 | @Override 46 | protected void onValidationFailed(TextView view) { 47 | super.onValidationFailed(view); 48 | EditTextHandler.setError(view, errorMessage); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/rule/UsernameRule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.rule; 18 | 19 | import android.widget.TextView; 20 | 21 | import br.com.ilhasoft.support.validation.R; 22 | import br.com.ilhasoft.support.validation.util.EditTextHandler; 23 | 24 | /** 25 | * Created by john-mac on 3/24/17. 26 | */ 27 | public class UsernameRule extends TypeRule { 28 | 29 | public UsernameRule(TextView view, String errorMessage) { 30 | super(view, FieldType.Username, errorMessage); 31 | } 32 | 33 | @Override 34 | protected boolean isValid(TextView view) { 35 | String username = view.getText().toString(); 36 | return username.matches("[a-zA-Z0-9-._]+"); 37 | } 38 | 39 | @Override 40 | protected void onValidationSucceeded(TextView view) { 41 | super.onValidationSucceeded(view); 42 | EditTextHandler.removeError(view); 43 | } 44 | 45 | @Override 46 | protected void onValidationFailed(TextView view) { 47 | super.onValidationFailed(view); 48 | EditTextHandler.setError(view, errorMessage); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/util/EditTextHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.util; 18 | 19 | import androidx.databinding.adapters.ListenerUtil; 20 | import androidx.annotation.Nullable; 21 | import com.google.android.material.textfield.TextInputLayout; 22 | import android.text.Editable; 23 | import android.text.TextUtils; 24 | import android.text.TextWatcher; 25 | import android.view.View; 26 | import android.view.ViewParent; 27 | import android.widget.TextView; 28 | 29 | import br.com.ilhasoft.support.validation.R; 30 | 31 | /** 32 | * Created by john-mac on 5/14/16. 33 | */ 34 | public class EditTextHandler { 35 | 36 | public static void removeError(TextView textView) { 37 | EditTextHandler.setError(textView, null); 38 | } 39 | 40 | public static void setError(TextView textView, String errorMessage) { 41 | TextInputLayout textInputLayout = getTextInputLayout(textView); 42 | if (textInputLayout != null) { 43 | textInputLayout.setErrorEnabled(!TextUtils.isEmpty(errorMessage)); 44 | textInputLayout.setError(errorMessage); 45 | } else { 46 | textView.setError(errorMessage); 47 | } 48 | } 49 | 50 | @Nullable 51 | private static TextInputLayout getTextInputLayout(TextView textView) { 52 | TextInputLayout textInputLayout = null; 53 | 54 | ViewParent parent = textView.getParent(); 55 | while (parent instanceof View) { 56 | if (parent instanceof TextInputLayout) { 57 | textInputLayout = (TextInputLayout) parent; 58 | break; 59 | } 60 | parent = parent.getParent(); 61 | } 62 | return textInputLayout; 63 | } 64 | 65 | public static void disableErrorOnChanged(final TextView textView) { 66 | if (ListenerUtil.getListener(textView, R.id.text_watcher_clear_error) != null) { 67 | return; 68 | } 69 | 70 | final TextWatcher textWatcher = new TextWatcher() { 71 | @Override 72 | public void beforeTextChanged(CharSequence s, int start, int count, int after) { } 73 | @Override 74 | public void onTextChanged(CharSequence s, int start, int before, int count) { 75 | EditTextHandler.setError(textView, null); 76 | } 77 | @Override 78 | public void afterTextChanged(Editable s) { } 79 | }; 80 | textView.addTextChangedListener(textWatcher); 81 | ListenerUtil.trackListener(textView, textView, R.id.text_watcher_clear_error); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/util/ErrorMessageHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.util; 18 | 19 | import androidx.annotation.StringRes; 20 | import android.view.View; 21 | 22 | /** 23 | * Created by john-mac on 3/24/17. 24 | */ 25 | public class ErrorMessageHelper { 26 | 27 | public static String getStringOrDefault(View view, String errorMessage, 28 | @StringRes int defaultMessage) { 29 | return errorMessage != null ? errorMessage : view.getContext().getString(defaultMessage); 30 | } 31 | 32 | public static String getStringOrDefault(View view, String errorMessage, 33 | @StringRes int defaultMessage, int value) { 34 | return errorMessage != null ? errorMessage : view.getContext().getString(defaultMessage, value); 35 | } 36 | 37 | public static String getStringOrDefault(View view, CharSequence errorMessage, 38 | @StringRes int defaultMessage) { 39 | return errorMessage != null ? errorMessage.toString() : view.getContext().getString(defaultMessage); 40 | } 41 | 42 | public static String getStringOrDefault(View view, CharSequence errorMessage, 43 | @StringRes int defaultMessage, int value) { 44 | return errorMessage != null ? errorMessage.toString() : view.getContext().getString(defaultMessage, value); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /library/src/main/java/br/com/ilhasoft/support/validation/util/ViewTagHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-present Ilhasoft. 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 | 17 | package br.com.ilhasoft.support.validation.util; 18 | 19 | import android.view.View; 20 | import android.view.ViewGroup; 21 | 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | /** 26 | * Created by john-mac on 5/21/16. 27 | */ 28 | public class ViewTagHelper { 29 | 30 | public static void appendValue(int tagId, View view, Type value) { 31 | Object object = view.getTag(tagId); 32 | if(object != null && object instanceof List) { 33 | ((List)object).add(value); 34 | } else { 35 | List typeList = new ArrayList<>(); 36 | typeList.add(value); 37 | view.setTag(tagId, typeList); 38 | } 39 | } 40 | 41 | public static List getViewsByTag(ViewGroup root, int tagId) { 42 | List views = new ArrayList<>(); 43 | final int childCount = root.getChildCount(); 44 | for (int i = 0; i < childCount; i++) { 45 | final View child = root.getChildAt(i); 46 | if (child instanceof ViewGroup) { 47 | views.addAll(getViewsByTag((ViewGroup) child, tagId)); 48 | } 49 | addViewWhenContainsTag(tagId, views, child); 50 | } 51 | return views; 52 | } 53 | 54 | public static List filterViewWithTag(int tagId, View view) { 55 | List viewsWithTags = new ArrayList<>(); 56 | addViewWhenContainsTag(tagId, viewsWithTags, view); 57 | return viewsWithTags; 58 | } 59 | 60 | public static List filterViewsWithTag(int tagId, List views) { 61 | List viewsWithTags = new ArrayList<>(); 62 | for (View view : views) { 63 | addViewWhenContainsTag(tagId, viewsWithTags, view); 64 | } 65 | return viewsWithTags; 66 | } 67 | 68 | private static void addViewWhenContainsTag(int tagId, List views, View view) { 69 | final Object tagValue = view.getTag(tagId); 70 | if (tagValue != null) { 71 | views.add(view); 72 | } 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /library/src/main/java/org/apache/commons/validator/routines/AbstractCalendarValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.validator.routines; 18 | 19 | import java.text.DateFormatSymbols; 20 | import java.text.Format; 21 | import java.text.DateFormat; 22 | import java.text.SimpleDateFormat; 23 | import java.util.Calendar; 24 | import java.util.Locale; 25 | import java.util.TimeZone; 26 | 27 | /** 28 | *

Abstract class for Date/Time/Calendar validation.

29 | * 30 | *

This is a base class for building Date / Time 31 | * Validators using format parsing.

32 | * 33 | * @version $Revision: 1739356 $ 34 | * @since Validator 1.3.0 35 | */ 36 | public abstract class AbstractCalendarValidator extends AbstractFormatValidator { 37 | 38 | private static final long serialVersionUID = -1410008585975827379L; 39 | 40 | private final int dateStyle; 41 | 42 | private final int timeStyle; 43 | 44 | /** 45 | * Construct an instance with the specified strict, 46 | * time and date style parameters. 47 | * 48 | * @param strict true if strict 49 | * Format parsing should be used. 50 | * @param dateStyle the date style to use for Locale validation. 51 | * @param timeStyle the time style to use for Locale validation. 52 | */ 53 | public AbstractCalendarValidator(boolean strict, int dateStyle, int timeStyle) { 54 | super(strict); 55 | this.dateStyle = dateStyle; 56 | this.timeStyle = timeStyle; 57 | } 58 | 59 | /** 60 | *

Validate using the specified Locale. 61 | * 62 | * @param value The value validation is being performed on. 63 | * @param pattern The pattern used to format the value. 64 | * @param locale The locale to use for the Format, defaults to the default 65 | * @return true if the value is valid. 66 | */ 67 | @Override 68 | public boolean isValid(String value, String pattern, Locale locale) { 69 | Object parsedValue = parse(value, pattern, locale, (TimeZone)null); 70 | return (parsedValue == null ? false : true); 71 | } 72 | 73 | /** 74 | *

Format an object into a String using 75 | * the default Locale.

76 | * 77 | * @param value The value validation is being performed on. 78 | * @param timeZone The Time Zone used to format the date, 79 | * system default if null (unless value is a Calendar. 80 | * @return The value formatted as a String. 81 | */ 82 | public String format(Object value, TimeZone timeZone) { 83 | return format(value, (String)null, (Locale)null, timeZone); 84 | } 85 | 86 | /** 87 | *

Format an object into a String using 88 | * the specified pattern.

89 | * 90 | * @param value The value validation is being performed on. 91 | * @param pattern The pattern used to format the value. 92 | * @param timeZone The Time Zone used to format the date, 93 | * system default if null (unless value is a Calendar. 94 | * @return The value formatted as a String. 95 | */ 96 | public String format(Object value, String pattern, TimeZone timeZone) { 97 | return format(value, pattern, (Locale)null, timeZone); 98 | } 99 | 100 | /** 101 | *

Format an object into a String using 102 | * the specified Locale.

103 | * 104 | * @param value The value validation is being performed on. 105 | * @param locale The locale to use for the Format. 106 | * @param timeZone The Time Zone used to format the date, 107 | * system default if null (unless value is a Calendar. 108 | * @return The value formatted as a String. 109 | */ 110 | public String format(Object value, Locale locale, TimeZone timeZone) { 111 | return format(value, (String)null, locale, timeZone); 112 | } 113 | 114 | /** 115 | *

Format an object using the specified pattern and/or 116 | * Locale. 117 | * 118 | * @param value The value validation is being performed on. 119 | * @param pattern The pattern used to format the value. 120 | * @param locale The locale to use for the Format. 121 | * @return The value formatted as a String. 122 | */ 123 | @Override 124 | public String format(Object value, String pattern, Locale locale) { 125 | return format(value, pattern, locale, (TimeZone)null); 126 | } 127 | 128 | /** 129 | *

Format an object using the specified pattern and/or 130 | * Locale. 131 | * 132 | * @param value The value validation is being performed on. 133 | * @param pattern The pattern used to format the value. 134 | * @param locale The locale to use for the Format. 135 | * @param timeZone The Time Zone used to format the date, 136 | * system default if null (unless value is a Calendar. 137 | * @return The value formatted as a String. 138 | */ 139 | public String format(Object value, String pattern, Locale locale, TimeZone timeZone) { 140 | DateFormat formatter = (DateFormat)getFormat(pattern, locale); 141 | if (timeZone != null) { 142 | formatter.setTimeZone(timeZone); 143 | } else if (value instanceof Calendar) { 144 | formatter.setTimeZone(((Calendar)value).getTimeZone()); 145 | } 146 | return format(value, formatter); 147 | } 148 | 149 | /** 150 | *

Format a value with the specified DateFormat.

151 | * 152 | * @param value The value to be formatted. 153 | * @param formatter The Format to use. 154 | * @return The formatted value. 155 | */ 156 | @Override 157 | protected String format(Object value, Format formatter) { 158 | if (value == null) { 159 | return null; 160 | } else if (value instanceof Calendar) { 161 | value = ((Calendar)value).getTime(); 162 | } 163 | return formatter.format(value); 164 | } 165 | 166 | /** 167 | *

Checks if the value is valid against a specified pattern.

168 | * 169 | * @param value The value validation is being performed on. 170 | * @param pattern The pattern used to validate the value against, or the 171 | * default for the Locale if null. 172 | * @param locale The locale to use for the date format, system default if null. 173 | * @param timeZone The Time Zone used to parse the date, system default if null. 174 | * @return The parsed value if valid or null if invalid. 175 | */ 176 | protected Object parse(String value, String pattern, Locale locale, TimeZone timeZone) { 177 | 178 | value = (value == null ? null : value.trim()); 179 | if (value == null || value.length() == 0) { 180 | return null; 181 | } 182 | DateFormat formatter = (DateFormat)getFormat(pattern, locale); 183 | if (timeZone != null) { 184 | formatter.setTimeZone(timeZone); 185 | } 186 | return parse(value, formatter); 187 | 188 | } 189 | 190 | /** 191 | *

Process the parsed value, performing any further validation 192 | * and type conversion required.

193 | * 194 | * @param value The parsed object created. 195 | * @param formatter The Format used to parse the value with. 196 | * @return The parsed value converted to the appropriate type 197 | * if valid or null if invalid. 198 | */ 199 | @Override 200 | protected abstract Object processParsedValue(Object value, Format formatter); 201 | 202 | /** 203 | *

Returns a DateFormat for the specified pattern 204 | * and/or Locale.

205 | * 206 | * @param pattern The pattern used to validate the value against or 207 | * null to use the default for the Locale. 208 | * @param locale The locale to use for the currency format, system default if null. 209 | * @return The DateFormat to created. 210 | */ 211 | @Override 212 | protected Format getFormat(String pattern, Locale locale) { 213 | DateFormat formatter = null; 214 | boolean usePattern = (pattern != null && pattern.length() > 0); 215 | if (!usePattern) { 216 | formatter = (DateFormat)getFormat(locale); 217 | } else if (locale == null) { 218 | formatter = new SimpleDateFormat(pattern); 219 | } else { 220 | DateFormatSymbols symbols = new DateFormatSymbols(locale); 221 | formatter = new SimpleDateFormat(pattern, symbols); 222 | } 223 | formatter.setLenient(false); 224 | return formatter; 225 | } 226 | 227 | /** 228 | *

Returns a DateFormat for the specified Locale.

229 | * 230 | * @param locale The locale a DateFormat is required for, 231 | * system default if null. 232 | * @return The DateFormat to created. 233 | */ 234 | protected Format getFormat(Locale locale) { 235 | 236 | DateFormat formatter = null; 237 | if (dateStyle >= 0 && timeStyle >= 0) { 238 | if (locale == null) { 239 | formatter = DateFormat.getDateTimeInstance(dateStyle, timeStyle); 240 | } else { 241 | formatter = DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale); 242 | } 243 | } else if (timeStyle >= 0) { 244 | if (locale == null) { 245 | formatter = DateFormat.getTimeInstance(timeStyle); 246 | } else { 247 | formatter = DateFormat.getTimeInstance(timeStyle, locale); 248 | } 249 | } else { 250 | int useDateStyle = dateStyle >= 0 ? dateStyle : DateFormat.SHORT; 251 | if (locale == null) { 252 | formatter = DateFormat.getDateInstance(useDateStyle); 253 | } else { 254 | formatter = DateFormat.getDateInstance(useDateStyle, locale); 255 | } 256 | } 257 | formatter.setLenient(false); 258 | return formatter; 259 | 260 | } 261 | 262 | /** 263 | *

Compares a calendar value to another, indicating whether it is 264 | * equal, less then or more than at a specified level.

265 | * 266 | * @param value The Calendar value. 267 | * @param compare The Calendar to check the value against. 268 | * @param field The field level to compare to - e.g. specifying 269 | * Calendar.MONTH will compare the year and month 270 | * portions of the calendar. 271 | * @return Zero if the first value is equal to the second, -1 272 | * if it is less than the second or +1 if it is greater than the second. 273 | */ 274 | protected int compare(Calendar value, Calendar compare, int field) { 275 | 276 | int result = 0; 277 | 278 | // Compare Year 279 | result = calculateCompareResult(value, compare, Calendar.YEAR); 280 | if (result != 0 || field == Calendar.YEAR) { 281 | return result; 282 | } 283 | 284 | // Compare Week of Year 285 | if (field == Calendar.WEEK_OF_YEAR) { 286 | return calculateCompareResult(value, compare, Calendar.WEEK_OF_YEAR); 287 | } 288 | 289 | // Compare Day of the Year 290 | if (field == Calendar.DAY_OF_YEAR) { 291 | return calculateCompareResult(value, compare, Calendar.DAY_OF_YEAR); 292 | } 293 | 294 | // Compare Month 295 | result = calculateCompareResult(value, compare, Calendar.MONTH); 296 | if (result != 0 || field == Calendar.MONTH) { 297 | return result; 298 | } 299 | 300 | // Compare Week of Month 301 | if (field == Calendar.WEEK_OF_MONTH) { 302 | return calculateCompareResult(value, compare, Calendar.WEEK_OF_MONTH); 303 | } 304 | 305 | // Compare Date 306 | result = calculateCompareResult(value, compare, Calendar.DATE); 307 | if (result != 0 || (field == Calendar.DATE || 308 | field == Calendar.DAY_OF_WEEK || 309 | field == Calendar.DAY_OF_WEEK_IN_MONTH)) { 310 | return result; 311 | } 312 | 313 | // Compare Time fields 314 | return compareTime(value, compare, field); 315 | 316 | } 317 | 318 | /** 319 | *

Compares a calendar time value to another, indicating whether it is 320 | * equal, less then or more than at a specified level.

321 | * 322 | * @param value The Calendar value. 323 | * @param compare The Calendar to check the value against. 324 | * @param field The field level to compare to - e.g. specifying 325 | * Calendar.MINUTE will compare the hours and minutes 326 | * portions of the calendar. 327 | * @return Zero if the first value is equal to the second, -1 328 | * if it is less than the second or +1 if it is greater than the second. 329 | */ 330 | protected int compareTime(Calendar value, Calendar compare, int field) { 331 | 332 | int result = 0; 333 | 334 | // Compare Hour 335 | result = calculateCompareResult(value, compare, Calendar.HOUR_OF_DAY); 336 | if (result != 0 || (field == Calendar.HOUR || field == Calendar.HOUR_OF_DAY)) { 337 | return result; 338 | } 339 | 340 | // Compare Minute 341 | result = calculateCompareResult(value, compare, Calendar.MINUTE); 342 | if (result != 0 || field == Calendar.MINUTE) { 343 | return result; 344 | } 345 | 346 | // Compare Second 347 | result = calculateCompareResult(value, compare, Calendar.SECOND); 348 | if (result != 0 || field == Calendar.SECOND) { 349 | return result; 350 | } 351 | 352 | // Compare Milliseconds 353 | if (field == Calendar.MILLISECOND) { 354 | return calculateCompareResult(value, compare, Calendar.MILLISECOND); 355 | } 356 | 357 | throw new IllegalArgumentException("Invalid field: " + field); 358 | 359 | } 360 | 361 | /** 362 | *

Compares a calendar's quarter value to another, indicating whether it is 363 | * equal, less then or more than the specified quarter.

364 | * 365 | * @param value The Calendar value. 366 | * @param compare The Calendar to check the value against. 367 | * @param monthOfFirstQuarter The month that the first quarter starts. 368 | * @return Zero if the first quarter is equal to the second, -1 369 | * if it is less than the second or +1 if it is greater than the second. 370 | */ 371 | protected int compareQuarters(Calendar value, Calendar compare, int monthOfFirstQuarter) { 372 | int valueQuarter = calculateQuarter(value, monthOfFirstQuarter); 373 | int compareQuarter = calculateQuarter(compare, monthOfFirstQuarter); 374 | if (valueQuarter < compareQuarter) { 375 | return -1; 376 | } else if (valueQuarter > compareQuarter) { 377 | return 1; 378 | } else { 379 | return 0; 380 | } 381 | } 382 | 383 | /** 384 | *

Calculate the quarter for the specified Calendar.

385 | * 386 | * @param calendar The Calendar value. 387 | * @param monthOfFirstQuarter The month that the first quarter starts. 388 | * @return The calculated quarter. 389 | */ 390 | private int calculateQuarter(Calendar calendar, int monthOfFirstQuarter) { 391 | // Add Year 392 | int year = calendar.get(Calendar.YEAR); 393 | 394 | int month = (calendar.get(Calendar.MONTH) + 1); 395 | int relativeMonth = (month >= monthOfFirstQuarter) 396 | ? (month - monthOfFirstQuarter) 397 | : (month + (12 - monthOfFirstQuarter)); // CHECKSTYLE IGNORE MagicNumber 398 | int quarter = ((relativeMonth / 3) + 1); // CHECKSTYLE IGNORE MagicNumber 399 | // adjust the year if the quarter doesn't start in January 400 | if (month < monthOfFirstQuarter) { 401 | --year; 402 | } 403 | return (year * 10) + quarter; // CHECKSTYLE IGNORE MagicNumber 404 | } 405 | 406 | /** 407 | *

Compares the field from two calendars indicating whether the field for the 408 | * first calendar is equal to, less than or greater than the field from the 409 | * second calendar. 410 | * 411 | * @param value The Calendar value. 412 | * @param compare The Calendar to check the value against. 413 | * @param field The field to compare for the calendars. 414 | * @return Zero if the first calendar's field is equal to the seconds, -1 415 | * if it is less than the seconds or +1 if it is greater than the seconds. 416 | */ 417 | private int calculateCompareResult(Calendar value, Calendar compare, int field) { 418 | int difference = value.get(field) - compare.get(field); 419 | if (difference < 0) { 420 | return -1; 421 | } else if (difference > 0) { 422 | return 1; 423 | } else { 424 | return 0; 425 | } 426 | } 427 | } 428 | -------------------------------------------------------------------------------- /library/src/main/java/org/apache/commons/validator/routines/AbstractFormatValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.validator.routines; 18 | 19 | import java.text.Format; 20 | import java.text.ParsePosition; 21 | import java.util.Locale; 22 | import java.io.Serializable; 23 | 24 | /** 25 | *

Abstract class for Format based Validation.

26 | * 27 | *

This is a base class for building Date and Number 28 | * Validators using format parsing.

29 | * 30 | * @version $Revision: 1649191 $ 31 | * @since Validator 1.3.0 32 | */ 33 | public abstract class AbstractFormatValidator implements Serializable { 34 | 35 | private static final long serialVersionUID = -4690687565200568258L; 36 | 37 | private final boolean strict; 38 | 39 | /** 40 | * Construct an instance with the specified strict setting. 41 | * 42 | * @param strict true if strict 43 | * Format parsing should be used. 44 | */ 45 | public AbstractFormatValidator(boolean strict) { 46 | this.strict = strict; 47 | } 48 | 49 | /** 50 | *

Indicates whether validated values should adhere 51 | * strictly to the Format used.

52 | * 53 | *

Typically implementations of Format 54 | * ignore invalid characters at the end of the value 55 | * and just stop parsing. For example parsing a date 56 | * value of 01/01/20x0 using a pattern 57 | * of dd/MM/yyyy will result in a year 58 | * of 20 if strict is set 59 | * to false, whereas setting strict 60 | * to true will cause this value to fail 61 | * validation.

62 | * 63 | * @return true if strict Format 64 | * parsing should be used. 65 | */ 66 | public boolean isStrict() { 67 | return strict; 68 | } 69 | 70 | /** 71 | *

Validate using the default Locale. 72 | * 73 | * @param value The value validation is being performed on. 74 | * @return true if the value is valid. 75 | */ 76 | public boolean isValid(String value) { 77 | return isValid(value, (String)null, (Locale)null); 78 | } 79 | 80 | /** 81 | *

Validate using the specified pattern. 82 | * 83 | * @param value The value validation is being performed on. 84 | * @param pattern The pattern used to validate the value against. 85 | * @return true if the value is valid. 86 | */ 87 | public boolean isValid(String value, String pattern) { 88 | return isValid(value, pattern, (Locale)null); 89 | } 90 | 91 | /** 92 | *

Validate using the specified Locale. 93 | * 94 | * @param value The value validation is being performed on. 95 | * @param locale The locale to use for the Format, defaults to the default 96 | * @return true if the value is valid. 97 | */ 98 | public boolean isValid(String value, Locale locale) { 99 | return isValid(value, (String)null, locale); 100 | } 101 | 102 | /** 103 | *

Validate using the specified pattern and/or Locale. 104 | * 105 | * @param value The value validation is being performed on. 106 | * @param pattern The pattern used to format the value. 107 | * @param locale The locale to use for the Format, defaults to the default 108 | * @return true if the value is valid. 109 | */ 110 | public abstract boolean isValid(String value, String pattern, Locale locale); 111 | 112 | /** 113 | *

Format an object into a String using 114 | * the default Locale.

115 | * 116 | * @param value The value validation is being performed on. 117 | * @return The value formatted as a String. 118 | */ 119 | public String format(Object value) { 120 | return format(value, (String)null, (Locale)null); 121 | } 122 | 123 | /** 124 | *

Format an object into a String using 125 | * the specified pattern.

126 | * 127 | * @param value The value validation is being performed on. 128 | * @param pattern The pattern used to format the value. 129 | * @return The value formatted as a String. 130 | */ 131 | public String format(Object value, String pattern) { 132 | return format(value, pattern, (Locale)null); 133 | } 134 | 135 | /** 136 | *

Format an object into a String using 137 | * the specified Locale.

138 | * 139 | * @param value The value validation is being performed on. 140 | * @param locale The locale to use for the Format. 141 | * @return The value formatted as a String. 142 | */ 143 | public String format(Object value, Locale locale) { 144 | return format(value, (String)null, locale); 145 | } 146 | 147 | /** 148 | *

Format an object using the specified pattern and/or 149 | * Locale. 150 | * 151 | * @param value The value validation is being performed on. 152 | * @param pattern The pattern used to format the value. 153 | * @param locale The locale to use for the Format. 154 | * @return The value formatted as a String. 155 | */ 156 | public String format(Object value, String pattern, Locale locale) { 157 | Format formatter = getFormat(pattern, locale); 158 | return format(value, formatter); 159 | } 160 | 161 | /** 162 | *

Format a value with the specified Format.

163 | * 164 | * @param value The value to be formatted. 165 | * @param formatter The Format to use. 166 | * @return The formatted value. 167 | */ 168 | protected String format(Object value, Format formatter) { 169 | return formatter.format(value); 170 | } 171 | 172 | /** 173 | *

Parse the value with the specified Format.

174 | * 175 | * @param value The value to be parsed. 176 | * @param formatter The Format to parse the value with. 177 | * @return The parsed value if valid or null if invalid. 178 | */ 179 | protected Object parse(String value, Format formatter) { 180 | 181 | ParsePosition pos = new ParsePosition(0); 182 | Object parsedValue = formatter.parseObject(value, pos); 183 | if (pos.getErrorIndex() > -1) { 184 | return null; 185 | } 186 | 187 | if (isStrict() && pos.getIndex() < value.length()) { 188 | return null; 189 | } 190 | 191 | if (parsedValue != null) { 192 | parsedValue = processParsedValue(parsedValue, formatter); 193 | } 194 | 195 | return parsedValue; 196 | 197 | } 198 | 199 | /** 200 | *

Process the parsed value, performing any further validation 201 | * and type conversion required.

202 | * 203 | * @param value The parsed object created. 204 | * @param formatter The Format used to parse the value with. 205 | * @return The parsed value converted to the appropriate type 206 | * if valid or null if invalid. 207 | */ 208 | protected abstract Object processParsedValue(Object value, Format formatter); 209 | 210 | /** 211 | *

Returns a Format for the specified pattern 212 | * and/or Locale.

213 | * 214 | * @param pattern The pattern used to validate the value against or 215 | * null to use the default for the Locale. 216 | * @param locale The locale to use for the currency format, system default if null. 217 | * @return The NumberFormat to created. 218 | */ 219 | protected abstract Format getFormat(String pattern, Locale locale); 220 | 221 | } 222 | -------------------------------------------------------------------------------- /library/src/main/java/org/apache/commons/validator/routines/CodeValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.validator.routines; 18 | 19 | import java.io.Serializable; 20 | 21 | import org.apache.commons.validator.routines.checkdigit.CheckDigit; 22 | 23 | /** 24 | * Generic Code Validation providing format, minimum/maximum 25 | * length and {@link CheckDigit} validations. 26 | *

27 | * Performs the following validations on a code: 28 | *

    29 | *
  • if the code is null, return null/false as appropriate
  • 30 | *
  • trim the input. If the resulting code is empty, return null/false as appropriate
  • 31 | *
  • Check the format of the code using a regular expression. (if specified)
  • 32 | *
  • Check the minimum and maximum length (if specified) of the parsed code 33 | * (i.e. parsed by the regular expression).
  • 34 | *
  • Performs {@link CheckDigit} validation on the parsed code (if specified).
  • 35 | *
  • The {@link #validate(String)} method returns the trimmed, parsed input (or null if validation failed)
  • 36 | *
37 | *

38 | * Note 39 | * The {@link #isValid(String)} method will return true if the input passes validation. 40 | * Since this includes trimming as well as potentially dropping parts of the input, 41 | * it is possible for a String to pass validation 42 | * but fail the checkdigit test if passed directly to it (the check digit routines generally don't trim input 43 | * nor do they generally check the format/length). 44 | * To be sure that you are passing valid input to a method use {@link #validate(String)} as follows: 45 | *

 46 |  * Object valid = validator.validate(input); 
 47 |  * if (valid != null) {
 48 |  *    some_method(valid.toString());
 49 |  * }
 50 |  * 
51 | *

52 | * Configure the validator with the appropriate regular expression, minimum/maximum length 53 | * and {@link CheckDigit} validator and then call one of the two validation 54 | * methods provided:

55 | *
    56 | *
  • boolean isValid(code)
  • 57 | *
  • String validate(code)
  • 58 | *
59 | *

60 | * Codes often include format characters - such as hyphens - to make them 61 | * more easily human readable. These can be removed prior to length and check digit 62 | * validation by specifying them as a non-capturing group in the regular 63 | * expression (i.e. use the (?: ) notation). 64 | *
65 | * Or just avoid using parentheses except for the parts you want to capture 66 | * 67 | * @version $Revision: 1739011 $ 68 | * @since Validator 1.4 69 | */ 70 | public final class CodeValidator implements Serializable { 71 | 72 | private static final long serialVersionUID = 446960910870938233L; 73 | 74 | private final RegexValidator regexValidator; 75 | private final int minLength; 76 | private final int maxLength; 77 | private final CheckDigit checkdigit; 78 | 79 | /** 80 | * Construct a code validator with a specified regular 81 | * expression and {@link CheckDigit}. 82 | * The RegexValidator validator is created to be case-sensitive 83 | * 84 | * @param regex The format regular expression 85 | * @param checkdigit The check digit validation routine 86 | */ 87 | public CodeValidator(String regex, CheckDigit checkdigit) { 88 | this(regex, -1, -1, checkdigit); 89 | } 90 | 91 | /** 92 | * Construct a code validator with a specified regular 93 | * expression, length and {@link CheckDigit}. 94 | * The RegexValidator validator is created to be case-sensitive 95 | * 96 | * @param regex The format regular expression. 97 | * @param length The length of the code 98 | * (sets the mimimum/maximum to the same) 99 | * @param checkdigit The check digit validation routine 100 | */ 101 | public CodeValidator(String regex, int length, CheckDigit checkdigit) { 102 | this(regex, length, length, checkdigit); 103 | } 104 | 105 | /** 106 | * Construct a code validator with a specified regular 107 | * expression, minimum/maximum length and {@link CheckDigit} validation. 108 | * The RegexValidator validator is created to be case-sensitive 109 | * 110 | * @param regex The regular expression 111 | * @param minLength The minimum length of the code 112 | * @param maxLength The maximum length of the code 113 | * @param checkdigit The check digit validation routine 114 | */ 115 | public CodeValidator(String regex, int minLength, int maxLength, 116 | CheckDigit checkdigit) { 117 | if (regex != null && regex.length() > 0) { 118 | this.regexValidator = new RegexValidator(regex); 119 | } else { 120 | this.regexValidator = null; 121 | } 122 | this.minLength = minLength; 123 | this.maxLength = maxLength; 124 | this.checkdigit = checkdigit; 125 | } 126 | 127 | /** 128 | * Construct a code validator with a specified regular expression, 129 | * validator and {@link CheckDigit} validation. 130 | * 131 | * @param regexValidator The format regular expression validator 132 | * @param checkdigit The check digit validation routine. 133 | */ 134 | public CodeValidator(RegexValidator regexValidator, CheckDigit checkdigit) { 135 | this(regexValidator, -1, -1, checkdigit); 136 | } 137 | 138 | /** 139 | * Construct a code validator with a specified regular expression, 140 | * validator, length and {@link CheckDigit} validation. 141 | * 142 | * @param regexValidator The format regular expression validator 143 | * @param length The length of the code 144 | * (sets the mimimum/maximum to the same value) 145 | * @param checkdigit The check digit validation routine 146 | */ 147 | public CodeValidator(RegexValidator regexValidator, int length, CheckDigit checkdigit) { 148 | this(regexValidator, length, length, checkdigit); 149 | } 150 | 151 | /** 152 | * Construct a code validator with a specified regular expression 153 | * validator, minimum/maximum length and {@link CheckDigit} validation. 154 | * 155 | * @param regexValidator The format regular expression validator 156 | * @param minLength The minimum length of the code 157 | * @param maxLength The maximum length of the code 158 | * @param checkdigit The check digit validation routine 159 | */ 160 | public CodeValidator(RegexValidator regexValidator, int minLength, int maxLength, 161 | CheckDigit checkdigit) { 162 | this.regexValidator = regexValidator; 163 | this.minLength = minLength; 164 | this.maxLength = maxLength; 165 | this.checkdigit = checkdigit; 166 | } 167 | 168 | /** 169 | * Return the check digit validation routine. 170 | *

171 | * N.B. Optional, if not set no Check Digit 172 | * validation will be performed on the code. 173 | * 174 | * @return The check digit validation routine 175 | */ 176 | public CheckDigit getCheckDigit() { 177 | return checkdigit; 178 | } 179 | 180 | /** 181 | * Return the minimum length of the code. 182 | *

183 | * N.B. Optional, if less than zero the 184 | * minimum length will not be checked. 185 | * 186 | * @return The minimum length of the code or 187 | * -1 if the code has no minimum length 188 | */ 189 | public int getMinLength() { 190 | return minLength; 191 | } 192 | 193 | /** 194 | * Return the maximum length of the code. 195 | *

196 | * N.B. Optional, if less than zero the 197 | * maximum length will not be checked. 198 | * 199 | * @return The maximum length of the code or 200 | * -1 if the code has no maximum length 201 | */ 202 | public int getMaxLength() { 203 | return maxLength; 204 | } 205 | 206 | /** 207 | * Return the regular expression validator. 208 | *

209 | * N.B. Optional, if not set no regular 210 | * expression validation will be performed on the code. 211 | * 212 | * @return The regular expression validator 213 | */ 214 | public RegexValidator getRegexValidator() { 215 | return regexValidator; 216 | } 217 | 218 | /** 219 | * Validate the code returning either true 220 | * or false. 221 | * 222 | * @param input The code to validate 223 | * @return true if valid, otherwise 224 | * false 225 | */ 226 | public boolean isValid(String input) { 227 | return (validate(input) != null); 228 | } 229 | 230 | /** 231 | * Validate the code returning either the valid code or 232 | * null if invalid. 233 | * 234 | * @param input The code to validate 235 | * @return The code if valid, otherwise null 236 | * if invalid 237 | */ 238 | public Object validate(String input) { 239 | 240 | if (input == null) { 241 | return null; 242 | } 243 | 244 | String code = input.trim(); 245 | if (code.length() == 0) { 246 | return null; 247 | } 248 | 249 | // validate/reformat using regular expression 250 | if (regexValidator != null) { 251 | code = regexValidator.validate(code); 252 | if (code == null) { 253 | return null; 254 | } 255 | } 256 | 257 | // check the length (must be done after validate as that can change the code) 258 | if ((minLength >= 0 && code.length() < minLength) || 259 | (maxLength >= 0 && code.length() > maxLength)) { 260 | return null; 261 | } 262 | 263 | // validate the check digit 264 | if (checkdigit != null && !checkdigit.isValid(code)) { 265 | return null; 266 | } 267 | 268 | return code; 269 | 270 | } 271 | 272 | } 273 | -------------------------------------------------------------------------------- /library/src/main/java/org/apache/commons/validator/routines/CreditCardValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.validator.routines; 18 | 19 | import org.apache.commons.validator.routines.checkdigit.CheckDigit; 20 | import org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit; 21 | import java.io.Serializable; 22 | import java.util.Collections; 23 | import java.util.List; 24 | import java.util.ArrayList; 25 | 26 | /** 27 | * Perform credit card validations. 28 | * 29 | *

30 | * By default, all supported card types are allowed. You can specify which 31 | * cards should pass validation by configuring the validation options. For 32 | * example, 33 | *

34 | * 35 | *
 36 |  * CreditCardValidator ccv = new CreditCardValidator(CreditCardValidator.AMEX + CreditCardValidator.VISA);
 37 |  * 
38 | * 39 | *

40 | * configures the validator to only pass American Express and Visa cards. 41 | * If a card type is not directly supported by this class, you can implement 42 | * the CreditCardType interface and pass an instance into the 43 | * addAllowedCardType method. 44 | *

45 | * 46 | *

47 | * For a similar implementation in Perl, reference Sean M. Burke's 48 | * script. 49 | * More information can be found in Michael Gilleland's essay 50 | * Anatomy of Credit Card Numbers. 51 | *

52 | * 53 | * @version $Revision: 1739207 $ 54 | * @since Validator 1.4 55 | */ 56 | public class CreditCardValidator implements Serializable { 57 | 58 | private static final long serialVersionUID = 5955978921148959496L; 59 | 60 | /** 61 | * Option specifying that no cards are allowed. This is useful if 62 | * you want only custom card types to validate so you turn off the 63 | * default cards with this option. 64 | * 65 | *
 66 |      * 
 67 |      * CreditCardValidator v = new CreditCardValidator(CreditCardValidator.NONE);
 68 |      * v.addAllowedCardType(customType);
 69 |      * v.isValid(aCardNumber);
 70 |      * 
 71 |      * 
72 | */ 73 | public static final long NONE = 0; 74 | 75 | /** 76 | * Option specifying that American Express cards are allowed. 77 | */ 78 | public static final long AMEX = 1 << 0; 79 | 80 | /** 81 | * Option specifying that Visa cards are allowed. 82 | */ 83 | public static final long VISA = 1 << 1; 84 | 85 | /** 86 | * Option specifying that Mastercard cards are allowed. 87 | */ 88 | public static final long MASTERCARD = 1 << 2; 89 | 90 | /** 91 | * Option specifying that Discover cards are allowed. 92 | */ 93 | public static final long DISCOVER = 1 << 3; // CHECKSTYLE IGNORE MagicNumber 94 | 95 | /** 96 | * Option specifying that Diners cards are allowed. 97 | */ 98 | public static final long DINERS = 1 << 4; // CHECKSTYLE IGNORE MagicNumber 99 | 100 | /** 101 | * Option specifying that VPay (Visa) cards are allowed. 102 | * @since 1.5.0 103 | */ 104 | public static final long VPAY = 1 << 5; // CHECKSTYLE IGNORE MagicNumber 105 | 106 | /** 107 | * Option specifying that Mastercard cards (pre Oct 2016 only) are allowed. 108 | * @deprecated for use until Oct 2016 only 109 | */ 110 | @Deprecated 111 | public static final long MASTERCARD_PRE_OCT2016 = 1 << 6; // CHECKSTYLE IGNORE MagicNumber 112 | 113 | 114 | /** 115 | * The CreditCardTypes that are allowed to pass validation. 116 | */ 117 | private final List cardTypes = new ArrayList(); 118 | 119 | /** 120 | * Luhn checkdigit validator for the card numbers. 121 | */ 122 | private static final CheckDigit LUHN_VALIDATOR = LuhnCheckDigit.LUHN_CHECK_DIGIT; 123 | 124 | /** American Express (Amex) Card Validator */ 125 | public static final CodeValidator AMEX_VALIDATOR = new CodeValidator("^(3[47]\\d{13})$", LUHN_VALIDATOR); 126 | 127 | /** Diners Card Validator */ 128 | public static final CodeValidator DINERS_VALIDATOR = new CodeValidator("^(30[0-5]\\d{11}|3095\\d{10}|36\\d{12}|3[8-9]\\d{12})$", LUHN_VALIDATOR); 129 | 130 | /** Discover Card regular expressions */ 131 | private static final RegexValidator DISCOVER_REGEX = new RegexValidator(new String[] {"^(6011\\d{12})$", "^(64[4-9]\\d{13})$", "^(65\\d{14})$"}); 132 | 133 | /** Discover Card Validator */ 134 | public static final CodeValidator DISCOVER_VALIDATOR = new CodeValidator(DISCOVER_REGEX, LUHN_VALIDATOR); 135 | 136 | /** Mastercard regular expressions */ 137 | private static final RegexValidator MASTERCARD_REGEX = new RegexValidator( 138 | new String[] { 139 | "^(5[1-5]\\d{14})$", // 51 - 55 (pre Oct 2016) 140 | // valid from October 2016 141 | "^(2221\\d{12})$", // 222100 - 222199 142 | "^(222[2-9]\\d{12})$",// 222200 - 222999 143 | "^(22[3-9]\\d{13})$", // 223000 - 229999 144 | "^(2[3-6]\\d{14})$", // 230000 - 269999 145 | "^(27[01]\\d{13})$", // 270000 - 271999 146 | "^(2720\\d{12})$", // 272000 - 272099 147 | }); 148 | 149 | /** Mastercard Card Validator */ 150 | public static final CodeValidator MASTERCARD_VALIDATOR = new CodeValidator(MASTERCARD_REGEX, LUHN_VALIDATOR); 151 | 152 | /** 153 | * Mastercard Card Validator (pre Oct 2016) 154 | * @deprecated for use until Oct 2016 only 155 | */ 156 | @Deprecated 157 | public static final CodeValidator MASTERCARD_VALIDATOR_PRE_OCT2016 = new CodeValidator("^(5[1-5]\\d{14})$", LUHN_VALIDATOR); 158 | 159 | /** Visa Card Validator */ 160 | public static final CodeValidator VISA_VALIDATOR = new CodeValidator("^(4)(\\d{12}|\\d{15})$", LUHN_VALIDATOR); 161 | 162 | /** VPay (Visa) Card Validator 163 | * @since 1.5.0 164 | */ 165 | public static final CodeValidator VPAY_VALIDATOR = new CodeValidator("^(4)(\\d{12,18})$", LUHN_VALIDATOR); 166 | 167 | /** 168 | * Create a new CreditCardValidator with default options. 169 | * The default options are: 170 | * AMEX, VISA, MASTERCARD and DISCOVER 171 | */ 172 | public CreditCardValidator() { 173 | this(AMEX + VISA + MASTERCARD + DISCOVER); 174 | } 175 | 176 | /** 177 | * Create a new CreditCardValidator with the specified options. 178 | * @param options Pass in 179 | * CreditCardValidator.VISA + CreditCardValidator.AMEX to specify that 180 | * those are the only valid card types. 181 | */ 182 | public CreditCardValidator(long options) { 183 | super(); 184 | 185 | if (isOn(options, VISA)) { 186 | this.cardTypes.add(VISA_VALIDATOR); 187 | } 188 | 189 | if (isOn(options, VPAY)) { 190 | this.cardTypes.add(VPAY_VALIDATOR); 191 | } 192 | 193 | if (isOn(options, AMEX)) { 194 | this.cardTypes.add(AMEX_VALIDATOR); 195 | } 196 | 197 | if (isOn(options, MASTERCARD)) { 198 | this.cardTypes.add(MASTERCARD_VALIDATOR); 199 | } 200 | 201 | if (isOn(options, MASTERCARD_PRE_OCT2016)) { 202 | this.cardTypes.add(MASTERCARD_VALIDATOR_PRE_OCT2016); 203 | } 204 | 205 | if (isOn(options, DISCOVER)) { 206 | this.cardTypes.add(DISCOVER_VALIDATOR); 207 | } 208 | 209 | if (isOn(options, DINERS)) { 210 | this.cardTypes.add(DINERS_VALIDATOR); 211 | } 212 | } 213 | 214 | /** 215 | * Create a new CreditCardValidator with the specified {@link CodeValidator}s. 216 | * @param creditCardValidators Set of valid code validators 217 | */ 218 | public CreditCardValidator(CodeValidator[] creditCardValidators) { 219 | if (creditCardValidators == null) { 220 | throw new IllegalArgumentException("Card validators are missing"); 221 | } 222 | Collections.addAll(cardTypes, creditCardValidators); 223 | } 224 | 225 | /** 226 | * Checks if the field is a valid credit card number. 227 | * @param card The card number to validate. 228 | * @return Whether the card number is valid. 229 | */ 230 | public boolean isValid(String card) { 231 | if (card == null || card.length() == 0) { 232 | return false; 233 | } 234 | for (CodeValidator cardType : cardTypes) { 235 | if (cardType.isValid(card)) { 236 | return true; 237 | } 238 | } 239 | return false; 240 | } 241 | 242 | /** 243 | * Checks if the field is a valid credit card number. 244 | * @param card The card number to validate. 245 | * @return The card number if valid or null 246 | * if invalid. 247 | */ 248 | public Object validate(String card) { 249 | if (card == null || card.length() == 0) { 250 | return null; 251 | } 252 | Object result = null; 253 | for (CodeValidator cardType : cardTypes) { 254 | result = cardType.validate(card); 255 | if (result != null) { 256 | return result; 257 | } 258 | } 259 | return null; 260 | 261 | } 262 | /** 263 | * Tests whether the given flag is on. If the flag is not a power of 2 264 | * (ie. 3) this tests whether the combination of flags is on. 265 | * 266 | * @param options The options specified. 267 | * @param flag Flag value to check. 268 | * 269 | * @return whether the specified flag value is on. 270 | */ 271 | private boolean isOn(long options, long flag) { 272 | return (options & flag) > 0; 273 | } 274 | 275 | } 276 | -------------------------------------------------------------------------------- /library/src/main/java/org/apache/commons/validator/routines/DateValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.validator.routines; 18 | 19 | import java.text.DateFormat; 20 | import java.text.Format; 21 | import java.util.Calendar; 22 | import java.util.Date; 23 | import java.util.Locale; 24 | import java.util.TimeZone; 25 | 26 | /** 27 | *

Date Validation and Conversion routines (java.util.Date).

28 | * 29 | *

This validator provides a number of methods for validating/converting 30 | * a String date value to a java.util.Date using 31 | * java.text.DateFormat to parse either:

32 | *
    33 | *
  • using the default format for the default Locale
  • 34 | *
  • using a specified pattern with the default Locale
  • 35 | *
  • using the default format for a specified Locale
  • 36 | *
  • using a specified pattern with a specified Locale
  • 37 | *
38 | * 39 | *

For each of the above mechanisms, conversion method (i.e the 40 | * validate methods) implementations are provided which 41 | * either use the default TimeZone or allow the 42 | * TimeZone to be specified.

43 | * 44 | *

Use one of the isValid() methods to just validate or 45 | * one of the validate() methods to validate and receive a 46 | * converted Date value.

47 | * 48 | *

Implementations of the validate() method are provided 49 | * to create Date objects for different time zones 50 | * if the system default is not appropriate.

51 | * 52 | *

Once a value has been successfully converted the following 53 | * methods can be used to perform various date comparison checks:

54 | *
    55 | *
  • compareDates() compares the day, month and 56 | * year of two dates, returning 0, -1 or +1 indicating 57 | * whether the first date is equal, before or after the second.
  • 58 | *
  • compareWeeks() compares the week and 59 | * year of two dates, returning 0, -1 or +1 indicating 60 | * whether the first week is equal, before or after the second.
  • 61 | *
  • compareMonths() compares the month and 62 | * year of two dates, returning 0, -1 or +1 indicating 63 | * whether the first month is equal, before or after the second.
  • 64 | *
  • compareQuarters() compares the quarter and 65 | * year of two dates, returning 0, -1 or +1 indicating 66 | * whether the first quarter is equal, before or after the second.
  • 67 | *
  • compareYears() compares the 68 | * year of two dates, returning 0, -1 or +1 indicating 69 | * whether the first year is equal, before or after the second.
  • 70 | *
71 | * 72 | *

So that the same mechanism used for parsing an input value 73 | * for validation can be used to format output, corresponding 74 | * format() methods are also provided. That is you can 75 | * format either:

76 | *
    77 | *
  • using a specified pattern
  • 78 | *
  • using the format for a specified Locale
  • 79 | *
  • using the format for the default Locale
  • 80 | *
81 | * 82 | * @version $Revision: 1739356 $ 83 | * @since Validator 1.3.0 84 | */ 85 | public class DateValidator extends AbstractCalendarValidator { 86 | 87 | private static final long serialVersionUID = -3966328400469953190L; 88 | 89 | private static final DateValidator VALIDATOR = new DateValidator(); 90 | 91 | /** 92 | * Return a singleton instance of this validator. 93 | * @return A singleton instance of the DateValidator. 94 | */ 95 | public static DateValidator getInstance() { 96 | return VALIDATOR; 97 | } 98 | 99 | /** 100 | * Construct a strict instance with short 101 | * date style. 102 | */ 103 | public DateValidator() { 104 | this(true, DateFormat.SHORT); 105 | } 106 | 107 | /** 108 | * Construct an instance with the specified strict 109 | * and date style parameters. 110 | * 111 | * @param strict true if strict 112 | * Format parsing should be used. 113 | * @param dateStyle the date style to use for Locale validation. 114 | */ 115 | public DateValidator(boolean strict, int dateStyle) { 116 | super(strict, dateStyle, -1); 117 | } 118 | 119 | /** 120 | *

Validate/convert a Date using the default 121 | * Locale and TimeZone. 122 | * 123 | * @param value The value validation is being performed on. 124 | * @return The parsed Date if valid or null 125 | * if invalid. 126 | */ 127 | public Date validate(String value) { 128 | return (Date)parse(value, (String)null, (Locale)null, (TimeZone)null); 129 | } 130 | 131 | /** 132 | *

Validate/convert a Date using the specified 133 | * TimeZone and default Locale. 134 | * 135 | * @param value The value validation is being performed on. 136 | * @param timeZone The Time Zone used to parse the date, system default if null. 137 | * @return The parsed Date if valid or null if invalid. 138 | */ 139 | public Date validate(String value, TimeZone timeZone) { 140 | return (Date)parse(value, (String)null, (Locale)null, timeZone); 141 | } 142 | 143 | /** 144 | *

Validate/convert a Date using the specified 145 | * pattern and default TimeZone. 146 | * 147 | * @param value The value validation is being performed on. 148 | * @param pattern The pattern used to validate the value against, or the 149 | * default for the Locale if null. 150 | * @return The parsed Date if valid or null if invalid. 151 | */ 152 | public Date validate(String value, String pattern) { 153 | return (Date)parse(value, pattern, (Locale)null, (TimeZone)null); 154 | } 155 | 156 | /** 157 | *

Validate/convert a Date using the specified 158 | * pattern and TimeZone. 159 | * 160 | * @param value The value validation is being performed on. 161 | * @param pattern The pattern used to validate the value against, or the 162 | * default for the Locale if null. 163 | * @param timeZone The Time Zone used to parse the date, system default if null. 164 | * @return The parsed Date if valid or null if invalid. 165 | */ 166 | public Date validate(String value, String pattern, TimeZone timeZone) { 167 | return (Date)parse(value, pattern, (Locale)null, timeZone); 168 | } 169 | 170 | /** 171 | *

Validate/convert a Date using the specified 172 | * Locale and default TimeZone. 173 | * 174 | * @param value The value validation is being performed on. 175 | * @param locale The locale to use for the date format, system default if null. 176 | * @return The parsed Date if valid or null if invalid. 177 | */ 178 | public Date validate(String value, Locale locale) { 179 | return (Date)parse(value, (String)null, locale, (TimeZone)null); 180 | } 181 | 182 | /** 183 | *

Validate/convert a Date using the specified 184 | * Locale and TimeZone. 185 | * 186 | * @param value The value validation is being performed on. 187 | * @param locale The locale to use for the date format, system default if null. 188 | * @param timeZone The Time Zone used to parse the date, system default if null. 189 | * @return The parsed Date if valid or null if invalid. 190 | */ 191 | public Date validate(String value, Locale locale, TimeZone timeZone) { 192 | return (Date)parse(value, (String)null, locale, timeZone); 193 | } 194 | 195 | /** 196 | *

Validate/convert a Date using the specified pattern 197 | * and Locale and the default TimeZone. 198 | * 199 | * @param value The value validation is being performed on. 200 | * @param pattern The pattern used to validate the value against, or the 201 | * default for the Locale if null. 202 | * @param locale The locale to use for the date format, system default if null. 203 | * @return The parsed Date if valid or null if invalid. 204 | */ 205 | public Date validate(String value, String pattern, Locale locale) { 206 | return (Date)parse(value, pattern, locale, (TimeZone)null); 207 | } 208 | 209 | /** 210 | *

Validate/convert a Date using the specified 211 | * pattern, and Locale and TimeZone. 212 | * 213 | * @param value The value validation is being performed on. 214 | * @param pattern The pattern used to validate the value against, or the 215 | * default for the Locale if null. 216 | * @param locale The locale to use for the date format, system default if null. 217 | * @param timeZone The Time Zone used to parse the date, system default if null. 218 | * @return The parsed Date if valid or null if invalid. 219 | */ 220 | public Date validate(String value, String pattern, Locale locale, TimeZone timeZone) { 221 | return (Date)parse(value, pattern, locale, timeZone); 222 | } 223 | 224 | /** 225 | *

Compare Dates (day, month and year - not time).

226 | * 227 | * @param value The Calendar value to check. 228 | * @param compare The Calendar to compare the value to. 229 | * @param timeZone The Time Zone used to compare the dates, system default if null. 230 | * @return Zero if the dates are equal, -1 if first 231 | * date is less than the seconds and +1 if the first 232 | * date is greater than. 233 | */ 234 | public int compareDates(Date value, Date compare, TimeZone timeZone) { 235 | Calendar calendarValue = getCalendar(value, timeZone); 236 | Calendar calendarCompare = getCalendar(compare, timeZone); 237 | return compare(calendarValue, calendarCompare, Calendar.DATE); 238 | } 239 | 240 | /** 241 | *

Compare Weeks (week and year).

242 | * 243 | * @param value The Date value to check. 244 | * @param compare The Date to compare the value to. 245 | * @param timeZone The Time Zone used to compare the dates, system default if null. 246 | * @return Zero if the weeks are equal, -1 if first 247 | * parameter's week is less than the seconds and +1 if the first 248 | * parameter's week is greater than. 249 | */ 250 | public int compareWeeks(Date value, Date compare, TimeZone timeZone) { 251 | Calendar calendarValue = getCalendar(value, timeZone); 252 | Calendar calendarCompare = getCalendar(compare, timeZone); 253 | return compare(calendarValue, calendarCompare, Calendar.WEEK_OF_YEAR); 254 | } 255 | 256 | /** 257 | *

Compare Months (month and year).

258 | * 259 | * @param value The Date value to check. 260 | * @param compare The Date to compare the value to. 261 | * @param timeZone The Time Zone used to compare the dates, system default if null. 262 | * @return Zero if the months are equal, -1 if first 263 | * parameter's month is less than the seconds and +1 if the first 264 | * parameter's month is greater than. 265 | */ 266 | public int compareMonths(Date value, Date compare, TimeZone timeZone) { 267 | Calendar calendarValue = getCalendar(value, timeZone); 268 | Calendar calendarCompare = getCalendar(compare, timeZone); 269 | return compare(calendarValue, calendarCompare, Calendar.MONTH); 270 | } 271 | 272 | /** 273 | *

Compare Quarters (quarter and year).

274 | * 275 | * @param value The Date value to check. 276 | * @param compare The Date to compare the value to. 277 | * @param timeZone The Time Zone used to compare the dates, system default if null. 278 | * @return Zero if the months are equal, -1 if first 279 | * parameter's quarter is less than the seconds and +1 if the first 280 | * parameter's quarter is greater than. 281 | */ 282 | public int compareQuarters(Date value, Date compare, TimeZone timeZone) { 283 | return compareQuarters(value, compare, timeZone, 1); 284 | } 285 | 286 | /** 287 | *

Compare Quarters (quarter and year).

288 | * 289 | * @param value The Date value to check. 290 | * @param compare The Date to compare the value to. 291 | * @param timeZone The Time Zone used to compare the dates, system default if null. 292 | * @param monthOfFirstQuarter The month that the first quarter starts. 293 | * @return Zero if the quarters are equal, -1 if first 294 | * parameter's quarter is less than the seconds and +1 if the first 295 | * parameter's quarter is greater than. 296 | */ 297 | public int compareQuarters(Date value, Date compare, TimeZone timeZone, int monthOfFirstQuarter) { 298 | Calendar calendarValue = getCalendar(value, timeZone); 299 | Calendar calendarCompare = getCalendar(compare, timeZone); 300 | return super.compareQuarters(calendarValue, calendarCompare, monthOfFirstQuarter); 301 | } 302 | 303 | /** 304 | *

Compare Years.

305 | * 306 | * @param value The Date value to check. 307 | * @param compare The Date to compare the value to. 308 | * @param timeZone The Time Zone used to compare the dates, system default if null. 309 | * @return Zero if the years are equal, -1 if first 310 | * parameter's year is less than the seconds and +1 if the first 311 | * parameter's year is greater than. 312 | */ 313 | public int compareYears(Date value, Date compare, TimeZone timeZone) { 314 | Calendar calendarValue = getCalendar(value, timeZone); 315 | Calendar calendarCompare = getCalendar(compare, timeZone); 316 | return compare(calendarValue, calendarCompare, Calendar.YEAR); 317 | } 318 | 319 | /** 320 | *

Returns the parsed Date unchanged.

321 | * 322 | * @param value The parsed Date object created. 323 | * @param formatter The Format used to parse the value with. 324 | * @return The parsed value converted to a Calendar. 325 | */ 326 | @Override 327 | protected Object processParsedValue(Object value, Format formatter) { 328 | return value; 329 | } 330 | 331 | /** 332 | *

Convert a Date to a Calendar.

333 | * 334 | * @param value The date value to be converted. 335 | * @return The converted Calendar. 336 | */ 337 | private Calendar getCalendar(Date value, TimeZone timeZone) { 338 | 339 | Calendar calendar = null; 340 | if (timeZone != null) { 341 | calendar = Calendar.getInstance(timeZone); 342 | } else { 343 | calendar = Calendar.getInstance(); 344 | } 345 | calendar.setTime(value); 346 | return calendar; 347 | 348 | } 349 | 350 | } 351 | -------------------------------------------------------------------------------- /library/src/main/java/org/apache/commons/validator/routines/RegexValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.validator.routines; 18 | 19 | import java.io.Serializable; 20 | import java.util.regex.Pattern; 21 | import java.util.regex.Matcher; 22 | 23 | /** 24 | * Regular Expression validation (using JDK 1.4+ regex support). 25 | *

26 | * Construct the validator either for a single regular expression or a set (array) of 27 | * regular expressions. By default validation is case sensitive but constructors 28 | * are provided to allow case in-sensitive validation. For example to create 29 | * a validator which does case in-sensitive validation for a set of regular 30 | * expressions: 31 | *

32 | *
 33 |  * 
 34 |  * String[] regexs = new String[] {...};
 35 |  * RegexValidator validator = new RegexValidator(regexs, false);
 36 |  * 
 37 |  * 
38 | * 39 | *
    40 | *
  • Validate true or false:
  • 41 | *
  • 42 | *
      43 | *
    • boolean valid = validator.isValid(value);
    • 44 | *
    45 | *
  • 46 | *
  • Validate returning an aggregated String of the matched groups:
  • 47 | *
  • 48 | *
      49 | *
    • String result = validator.validate(value);
    • 50 | *
    51 | *
  • 52 | *
  • Validate returning the matched groups:
  • 53 | *
  • 54 | *
      55 | *
    • String[] result = validator.match(value);
    • 56 | *
    57 | *
  • 58 | *
59 | * 60 | * Note that patterns are matched against the entire input. 61 | * 62 | *

63 | * Cached instances pre-compile and re-use {@link Pattern}(s) - which according 64 | * to the {@link Pattern} API are safe to use in a multi-threaded environment. 65 | *

66 | * 67 | * @version $Revision: 1739356 $ 68 | * @since Validator 1.4 69 | */ 70 | public class RegexValidator implements Serializable { 71 | 72 | private static final long serialVersionUID = -8832409930574867162L; 73 | 74 | private final Pattern[] patterns; 75 | 76 | /** 77 | * Construct a case sensitive validator for a single 78 | * regular expression. 79 | * 80 | * @param regex The regular expression this validator will 81 | * validate against 82 | */ 83 | public RegexValidator(String regex) { 84 | this(regex, true); 85 | } 86 | 87 | /** 88 | * Construct a validator for a single regular expression 89 | * with the specified case sensitivity. 90 | * 91 | * @param regex The regular expression this validator will 92 | * validate against 93 | * @param caseSensitive when true matching is case 94 | * sensitive, otherwise matching is case in-sensitive 95 | */ 96 | public RegexValidator(String regex, boolean caseSensitive) { 97 | this(new String[] {regex}, caseSensitive); 98 | } 99 | 100 | /** 101 | * Construct a case sensitive validator that matches any one 102 | * of the set of regular expressions. 103 | * 104 | * @param regexs The set of regular expressions this validator will 105 | * validate against 106 | */ 107 | public RegexValidator(String[] regexs) { 108 | this(regexs, true); 109 | } 110 | 111 | /** 112 | * Construct a validator that matches any one of the set of regular 113 | * expressions with the specified case sensitivity. 114 | * 115 | * @param regexs The set of regular expressions this validator will 116 | * validate against 117 | * @param caseSensitive when true matching is case 118 | * sensitive, otherwise matching is case in-sensitive 119 | */ 120 | public RegexValidator(String[] regexs, boolean caseSensitive) { 121 | if (regexs == null || regexs.length == 0) { 122 | throw new IllegalArgumentException("Regular expressions are missing"); 123 | } 124 | patterns = new Pattern[regexs.length]; 125 | int flags = (caseSensitive ? 0: Pattern.CASE_INSENSITIVE); 126 | for (int i = 0; i < regexs.length; i++) { 127 | if (regexs[i] == null || regexs[i].length() == 0) { 128 | throw new IllegalArgumentException("Regular expression[" + i + "] is missing"); 129 | } 130 | patterns[i] = Pattern.compile(regexs[i], flags); 131 | } 132 | } 133 | 134 | /** 135 | * Validate a value against the set of regular expressions. 136 | * 137 | * @param value The value to validate. 138 | * @return true if the value is valid 139 | * otherwise false. 140 | */ 141 | public boolean isValid(String value) { 142 | if (value == null) { 143 | return false; 144 | } 145 | for (int i = 0; i < patterns.length; i++) { 146 | if (patterns[i].matcher(value).matches()) { 147 | return true; 148 | } 149 | } 150 | return false; 151 | } 152 | 153 | /** 154 | * Validate a value against the set of regular expressions 155 | * returning the array of matched groups. 156 | * 157 | * @param value The value to validate. 158 | * @return String array of the groups matched if 159 | * valid or null if invalid 160 | */ 161 | public String[] match(String value) { 162 | if (value == null) { 163 | return null; 164 | } 165 | for (int i = 0; i < patterns.length; i++) { 166 | Matcher matcher = patterns[i].matcher(value); 167 | if (matcher.matches()) { 168 | int count = matcher.groupCount(); 169 | String[] groups = new String[count]; 170 | for (int j = 0; j < count; j++) { 171 | groups[j] = matcher.group(j+1); 172 | } 173 | return groups; 174 | } 175 | } 176 | return null; 177 | } 178 | 179 | 180 | /** 181 | * Validate a value against the set of regular expressions 182 | * returning a String value of the aggregated groups. 183 | * 184 | * @param value The value to validate. 185 | * @return Aggregated String value comprised of the 186 | * groups matched if valid or null if invalid 187 | */ 188 | public String validate(String value) { 189 | if (value == null) { 190 | return null; 191 | } 192 | for (int i = 0; i < patterns.length; i++) { 193 | Matcher matcher = patterns[i].matcher(value); 194 | if (matcher.matches()) { 195 | int count = matcher.groupCount(); 196 | if (count == 1) { 197 | return matcher.group(1); 198 | } 199 | StringBuilder buffer = new StringBuilder(); 200 | for (int j = 0; j < count; j++) { 201 | String component = matcher.group(j+1); 202 | if (component != null) { 203 | buffer.append(component); 204 | } 205 | } 206 | return buffer.toString(); 207 | } 208 | } 209 | return null; 210 | } 211 | 212 | /** 213 | * Provide a String representation of this validator. 214 | * @return A String representation of this validator 215 | */ 216 | @Override 217 | public String toString() { 218 | StringBuilder buffer = new StringBuilder(); 219 | buffer.append("RegexValidator{"); 220 | for (int i = 0; i < patterns.length; i++) { 221 | if (i > 0) { 222 | buffer.append(","); 223 | } 224 | buffer.append(patterns[i].pattern()); 225 | } 226 | buffer.append("}"); 227 | return buffer.toString(); 228 | } 229 | 230 | } 231 | -------------------------------------------------------------------------------- /library/src/main/java/org/apache/commons/validator/routines/checkdigit/CheckDigit.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.validator.routines.checkdigit; 18 | 19 | /** 20 | * Check Digit calculation and validation. 21 | *

22 | * The logic for validating check digits has previously been 23 | * embedded within the logic for specific code validation, which 24 | * includes other validations such as verifying the format 25 | * or length of a code. {@link CheckDigit} provides for separating out 26 | * the check digit calculation logic enabling it to be more easily 27 | * tested and reused. 28 | *

29 | *

30 | * Although Commons Validator is primarily concerned with validation, 31 | * {@link CheckDigit} also defines behaviour for calculating/generating check 32 | * digits, since it makes sense that users will want to (re-)use the 33 | * same logic for both. The {@link org.apache.commons.validator.routines.ISBNValidator} 34 | * makes specific use of this feature by providing the facility to validate ISBN-10 codes 35 | * and then convert them to the new ISBN-13 standard. 36 | *

37 | *

38 | * CheckDigit is used by the new generic @link CodeValidator} implementation. 39 | *

40 | * 41 | *

Implementations

42 | * See the 43 | * Package Summary for a full 44 | * list of implementations provided within Commons Validator. 45 | * 46 | * @see org.apache.commons.validator.routines.CodeValidator 47 | * @version $Revision: 1649287 $ 48 | * @since Validator 1.4 49 | */ 50 | public interface CheckDigit { 51 | 52 | /** 53 | * Calculates the Check Digit for a code. 54 | * 55 | * @param code The code to calculate the Check Digit for. 56 | * The string must not include the check digit 57 | * @return The calculated Check Digit 58 | * @throws CheckDigitException if an error occurs. 59 | */ 60 | String calculate(String code) throws CheckDigitException; 61 | 62 | /** 63 | * Validates the check digit for the code. 64 | * 65 | * @param code The code to validate, the string must include the check digit. 66 | * @return true if the check digit is valid, otherwise 67 | * false. 68 | */ 69 | boolean isValid(String code); 70 | 71 | } 72 | -------------------------------------------------------------------------------- /library/src/main/java/org/apache/commons/validator/routines/checkdigit/CheckDigitException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.validator.routines.checkdigit; 18 | 19 | /** 20 | * Check Digit calculation/validation error. 21 | * 22 | * @version $Revision: 1649191 $ 23 | * @since Validator 1.4 24 | */ 25 | public class CheckDigitException extends Exception { 26 | 27 | private static final long serialVersionUID = -3519894732624685477L; 28 | 29 | /** 30 | * Construct an Exception with no message. 31 | */ 32 | public CheckDigitException() { 33 | } 34 | 35 | /** 36 | * Construct an Exception with a message. 37 | * 38 | * @param msg The error message. 39 | */ 40 | public CheckDigitException(String msg) { 41 | super(msg); 42 | } 43 | 44 | /** 45 | * Construct an Exception with a message and 46 | * the underlying cause. 47 | * 48 | * @param msg The error message. 49 | * @param cause The underlying cause of the error 50 | */ 51 | public CheckDigitException(String msg, Throwable cause) { 52 | super(msg, cause); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /library/src/main/java/org/apache/commons/validator/routines/checkdigit/LuhnCheckDigit.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.validator.routines.checkdigit; 18 | 19 | /** 20 | * Modulus 10 Luhn Check Digit calculation/validation. 21 | * 22 | * Luhn check digits are used, for example, by: 23 | * 28 | * Check digit calculation is based on modulus 10 with digits in 29 | * an odd position (from right to left) being weighted 1 and even 30 | * position digits being weighted 2 (weighted values greater than 9 have 9 subtracted). 31 | * 32 | *

33 | * See Wikipedia 34 | * for more details. 35 | *

36 | * 37 | * @version $Revision: 1739356 $ 38 | * @since Validator 1.4 39 | */ 40 | public final class LuhnCheckDigit extends ModulusCheckDigit { 41 | 42 | private static final long serialVersionUID = -2976900113942875999L; 43 | 44 | /** Singleton Luhn Check Digit instance */ 45 | public static final CheckDigit LUHN_CHECK_DIGIT = new LuhnCheckDigit(); 46 | 47 | /** weighting given to digits depending on their right position */ 48 | private static final int[] POSITION_WEIGHT = new int[] {2, 1}; 49 | 50 | /** 51 | * Construct a modulus 10 Luhn Check Digit routine. 52 | */ 53 | public LuhnCheckDigit() { 54 | super(10); // CHECKSTYLE IGNORE MagicNumber 55 | } 56 | 57 | /** 58 | *

Calculates the weighted value of a charcter in the 59 | * code at a specified position.

60 | * 61 | *

For Luhn (from right to left) odd digits are weighted 62 | * with a factor of one and even digits with a factor 63 | * of two. Weighted values > 9, have 9 subtracted

64 | * 65 | * @param charValue The numeric value of the character. 66 | * @param leftPos The position of the character in the code, counting from left to right 67 | * @param rightPos The positionof the character in the code, counting from right to left 68 | * @return The weighted value of the character. 69 | */ 70 | @Override 71 | protected int weightedValue(int charValue, int leftPos, int rightPos) { 72 | int weight = POSITION_WEIGHT[rightPos % 2]; // CHECKSTYLE IGNORE MagicNumber 73 | int weightedValue = charValue * weight; 74 | return weightedValue > 9 ? (weightedValue - 9) : weightedValue; // CHECKSTYLE IGNORE MagicNumber 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /library/src/main/java/org/apache/commons/validator/routines/checkdigit/ModulusCheckDigit.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache.commons.validator.routines.checkdigit; 18 | 19 | import java.io.Serializable; 20 | 21 | /** 22 | * Abstract Modulus Check digit calculation/validation. 23 | *

24 | * Provides a base class for building modulus Check 25 | * Digit routines. 26 | *

27 | * This implementation only handles single-digit numeric codes, such as 28 | * EAN-13. For alphanumeric codes such as EAN-128 you 29 | * will need to implement/override the toInt() and 30 | * toChar() methods. 31 | *

32 | * 33 | * @version $Revision: 1739357 $ 34 | * @since Validator 1.4 35 | */ 36 | public abstract class ModulusCheckDigit implements CheckDigit, Serializable { 37 | 38 | private static final long serialVersionUID = 2948962251251528941L; 39 | 40 | // N.B. The modulus can be > 10 provided that the implementing class overrides toCheckDigit and toInt 41 | // (for example as in ISBN10CheckDigit) 42 | private final int modulus; 43 | 44 | /** 45 | * Construct a {@link CheckDigit} routine for a specified modulus. 46 | * 47 | * @param modulus The modulus value to use for the check digit calculation 48 | */ 49 | public ModulusCheckDigit(int modulus) { 50 | this.modulus = modulus; 51 | } 52 | 53 | /** 54 | * Return the modulus value this check digit routine is based on. 55 | * 56 | * @return The modulus value this check digit routine is based on 57 | */ 58 | public int getModulus() { 59 | return modulus; 60 | } 61 | 62 | /** 63 | * Validate a modulus check digit for a code. 64 | * 65 | * @param code The code to validate 66 | * @return true if the check digit is valid, otherwise 67 | * false 68 | */ 69 | @Override 70 | public boolean isValid(String code) { 71 | if (code == null || code.length() == 0) { 72 | return false; 73 | } 74 | try { 75 | int modulusResult = calculateModulus(code, true); 76 | return (modulusResult == 0); 77 | } catch (CheckDigitException ex) { 78 | return false; 79 | } 80 | } 81 | 82 | /** 83 | * Calculate a modulus Check Digit for a code which does not yet have one. 84 | * 85 | * @param code The code for which to calculate the Check Digit; 86 | * the check digit should not be included 87 | * @return The calculated Check Digit 88 | * @throws CheckDigitException if an error occurs calculating the check digit 89 | */ 90 | @Override 91 | public String calculate(String code) throws CheckDigitException { 92 | if (code == null || code.length() == 0) { 93 | throw new CheckDigitException("Code is missing"); 94 | } 95 | int modulusResult = calculateModulus(code, false); 96 | int charValue = (modulus - modulusResult) % modulus; 97 | return toCheckDigit(charValue); 98 | } 99 | 100 | /** 101 | * Calculate the modulus for a code. 102 | * 103 | * @param code The code to calculate the modulus for. 104 | * @param includesCheckDigit Whether the code includes the Check Digit or not. 105 | * @return The modulus value 106 | * @throws CheckDigitException if an error occurs calculating the modulus 107 | * for the specified code 108 | */ 109 | protected int calculateModulus(String code, boolean includesCheckDigit) throws CheckDigitException { 110 | int total = 0; 111 | for (int i = 0; i < code.length(); i++) { 112 | int lth = code.length() + (includesCheckDigit ? 0 : 1); 113 | int leftPos = i + 1; 114 | int rightPos = lth - i; 115 | int charValue = toInt(code.charAt(i), leftPos, rightPos); 116 | total += weightedValue(charValue, leftPos, rightPos); 117 | } 118 | if (total == 0) { 119 | throw new CheckDigitException("Invalid code, sum is zero"); 120 | } 121 | return total % modulus; 122 | } 123 | 124 | /** 125 | * Calculates the weighted value of a character in the 126 | * code at a specified position. 127 | *

128 | * Some modulus routines weight the value of a character 129 | * depending on its position in the code (e.g. ISBN-10), while 130 | * others use different weighting factors for odd/even positions 131 | * (e.g. EAN or Luhn). Implement the appropriate mechanism 132 | * required by overriding this method. 133 | * 134 | * @param charValue The numeric value of the character 135 | * @param leftPos The position of the character in the code, counting from left to right 136 | * @param rightPos The positionof the character in the code, counting from right to left 137 | * @return The weighted value of the character 138 | * @throws CheckDigitException if an error occurs calculating 139 | * the weighted value 140 | */ 141 | protected abstract int weightedValue(int charValue, int leftPos, int rightPos) 142 | throws CheckDigitException; 143 | 144 | 145 | /** 146 | * Convert a character at a specified position to an integer value. 147 | *

148 | * Note: this implementation only handlers numeric values 149 | * For non-numeric characters, override this method to provide 150 | * character-->integer conversion. 151 | * 152 | * @param character The character to convert 153 | * @param leftPos The position of the character in the code, counting from left to right (for identifiying the position in the string) 154 | * @param rightPos The position of the character in the code, counting from right to left (not used here) 155 | * @return The integer value of the character 156 | * @throws CheckDigitException if character is non-numeric 157 | */ 158 | protected int toInt(char character, int leftPos, int rightPos) 159 | throws CheckDigitException { 160 | if (Character.isDigit(character)) { 161 | return Character.getNumericValue(character); 162 | } 163 | throw new CheckDigitException("Invalid Character[" + 164 | leftPos + "] = '" + character + "'"); 165 | } 166 | 167 | /** 168 | * Convert an integer value to a check digit. 169 | *

170 | * Note: this implementation only handles single-digit numeric values 171 | * For non-numeric characters, override this method to provide 172 | * integer-->character conversion. 173 | * 174 | * @param charValue The integer value of the character 175 | * @return The converted character 176 | * @throws CheckDigitException if integer character value 177 | * doesn't represent a numeric character 178 | */ 179 | protected String toCheckDigit(int charValue) 180 | throws CheckDigitException { 181 | if (charValue >= 0 && charValue <= 9) { // CHECKSTYLE IGNORE MagicNumber 182 | return Integer.toString(charValue); 183 | } 184 | throw new CheckDigitException("Invalid Check Digit Value =" + 185 | + charValue); 186 | } 187 | 188 | /** 189 | * Add together the individual digits in a number. 190 | * 191 | * @param number The number whose digits are to be added 192 | * @return The sum of the digits 193 | */ 194 | public static int sumDigits(int number) { 195 | int total = 0; 196 | int todo = number; 197 | while (todo > 0) { 198 | total += todo % 10; // CHECKSTYLE IGNORE MagicNumber 199 | todo = todo / 10; // CHECKSTYLE IGNORE MagicNumber 200 | } 201 | return total; 202 | } 203 | 204 | } 205 | -------------------------------------------------------------------------------- /library/src/main/res/values-es/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Campo no válido. El número mínimo de caracteres %1$d 4 | Campo no válido. El número máximo de caracteres %1$d 5 | Formato de datos no válido 6 | Formato no válido 7 | 8 | Formato de correo electrónico no válido 9 | Formato de CPF no válido 10 | Formato de url no válido 11 | Formato de tarjeta de crédito no válido 12 | Este campo no puede estar vacío 13 | Las contraseñas no son similares 14 | Formato de nombre de usuario no válido 15 | 16 | -------------------------------------------------------------------------------- /library/src/main/res/values-pt/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Campo inválido. O número mínimo de caracteres é %1$d 4 | Campo inválido. O número máximo de caracteres é %1$d 5 | Formato de data inválido 6 | Formato inválido 7 | 8 | Formato do e-mail inválido 9 | Formato do CPF inválido 10 | Formato da url inválida 11 | Formato do cartão de crédito inválido 12 | Esse campo não pode ser vazio 13 | As senhas não são iguais 14 | Formato de nome de usuário inválido 15 | 16 | -------------------------------------------------------------------------------- /library/src/main/res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /library/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Invalid field. The minimum number of characters %1$d 4 | Invalid field. The maximum number of characters %1$d 5 | Invalid data format 6 | Invalid format 7 | 8 | Invalid email format 9 | Invalid username format 10 | Invalid CPF format 11 | Invalid url format 12 | Invalid credit card format 13 | This field can\'t be empty 14 | Passwords are not the same 15 | 16 | -------------------------------------------------------------------------------- /library/src/test/java/br/com/ilhasoft/support/validation/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package br.com.ilhasoft.support.validation; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * To work on unit tests, switch the Test Artifact in the Build Variants view. 9 | */ 10 | public class ExampleUnitTest { 11 | 12 | @Test 13 | public void addition_isCorrect() throws Exception { 14 | assertEquals(4, 2 + 2); 15 | } 16 | } -------------------------------------------------------------------------------- /sample/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /sample/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | buildToolsVersion "28.0.3" 6 | 7 | // Gradle automatically adds 'android.test.runner' as a dependency. 8 | useLibrary 'android.test.runner' 9 | 10 | dataBinding { 11 | enabled true 12 | } 13 | 14 | defaultConfig { 15 | applicationId "br.com.ilhasoft.support.validation.sample" 16 | minSdkVersion 15 17 | targetSdkVersion 28 18 | versionCode 1 19 | versionName "1.0" 20 | 21 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 22 | } 23 | buildTypes { 24 | release { 25 | minifyEnabled false 26 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 27 | } 28 | } 29 | } 30 | 31 | allprojects { 32 | repositories { 33 | maven { url "https://jitpack.io" } 34 | } 35 | } 36 | 37 | dependencies { 38 | implementation fileTree(dir: 'libs', include: ['*.jar']) 39 | implementation project(':library') 40 | // JUnit 4 framework 41 | testImplementation 'junit:junit:4.12' 42 | // Android annotations 43 | androidTestImplementation 'androidx.annotation:annotation:1.0.0' 44 | // AndroidJUnitRunner and JUnit Rules 45 | androidTestImplementation 'androidx.test:runner:1.1.0-beta02' 46 | androidTestImplementation 'androidx.test:rules:1.1.0-beta02' 47 | // compile 'org.bitbucket.ilhasoft:support-validation:e3ed964' 48 | } 49 | -------------------------------------------------------------------------------- /sample/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /home/daniel/libs/android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /sample/src/androidTest/java/br/com/ilhasoft/support/validation/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package br.com.ilhasoft.support.validation; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /sample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /sample/src/main/java/br/com/ilhasoft/support/validation/sample/MainActivity.java: -------------------------------------------------------------------------------- 1 | package br.com.ilhasoft.support.validation.sample; 2 | 3 | import androidx.databinding.DataBindingUtil; 4 | import android.os.Bundle; 5 | import androidx.appcompat.app.AppCompatActivity; 6 | import android.util.Log; 7 | import android.view.View; 8 | import android.widget.Toast; 9 | 10 | import java.util.Arrays; 11 | 12 | import br.com.ilhasoft.support.validation.Validator; 13 | import br.com.ilhasoft.support.validation.sample.databinding.ActivityMainBinding; 14 | 15 | public class MainActivity extends AppCompatActivity implements Validator.ValidationListener { 16 | 17 | private static final String TAG = "MainActivity"; 18 | 19 | private ActivityMainBinding binding; 20 | private Validator validator; 21 | 22 | @Override 23 | public void onValidationSuccess() { 24 | saveToDatabase(); 25 | } 26 | 27 | @Override 28 | public void onValidationError() { 29 | Toast.makeText(MainActivity.this, "Dados inválidos!", Toast.LENGTH_SHORT).show(); 30 | } 31 | 32 | @Override 33 | protected void onCreate(Bundle savedInstanceState) { 34 | super.onCreate(savedInstanceState); 35 | 36 | binding = DataBindingUtil.setContentView(this, R.layout.activity_main); 37 | binding.validateName.setOnClickListener(onValidateNameClickListener); 38 | binding.validateMultiple.setOnClickListener(onValidateMultipleClickListener); 39 | binding.validate.setOnClickListener(onValidateAllClickListener); 40 | binding.toValidate.setOnClickListener(onValidateAllWithListenerClickListener); 41 | 42 | validator = new Validator(binding); 43 | validator.setValidationListener(this); 44 | validator.enableFormValidationMode(); 45 | } 46 | 47 | private View.OnClickListener onValidateNameClickListener = new View.OnClickListener() { 48 | @Override 49 | public void onClick(View v) { 50 | validator.validate(binding.name); 51 | } 52 | }; 53 | 54 | private View.OnClickListener onValidateMultipleClickListener = new View.OnClickListener() { 55 | @Override 56 | public void onClick(View v) { 57 | validator.validate(Arrays.asList(binding.username, binding.email)); 58 | } 59 | }; 60 | 61 | private View.OnClickListener onValidateAllClickListener = new View.OnClickListener() { 62 | @Override 63 | public void onClick(View v) { 64 | if (validator.validate()) { 65 | saveToDatabase(); 66 | } else { 67 | Toast.makeText(MainActivity.this, "Dados inválidos!", Toast.LENGTH_SHORT).show(); 68 | } 69 | } 70 | }; 71 | 72 | private View.OnClickListener onValidateAllWithListenerClickListener = new View.OnClickListener() { 73 | @Override 74 | public void onClick(View v) { 75 | validator.toValidate(); 76 | } 77 | }; 78 | 79 | private void saveToDatabase() { 80 | Log.i(TAG, "Salvar os dados no banco de dados"); 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 9 | 10 | 16 | 17 | 20 | 21 | 31 | 32 | 33 | 34 |