Skip to content

Commit 4187f95

Browse files
authored
Merge pull request #12 from sashirestela/10-add-constraint-for-file-extension
Update Readme
2 parents 95208f9 + 6d6387c commit 4187f95

File tree

2 files changed

+120
-15
lines changed

2 files changed

+120
-15
lines changed

README.md

Lines changed: 118 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@ Java lightweight validator.
77
![Maven Central](https://img.shields.io/maven-central/v/io.github.sashirestela/slimvalidator)
88
![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/sashirestela/slimvalidator/build_java_maven.yml)
99

10+
### Table of Contents
11+
- [Description](#-description)
12+
- [Installation](#-installation)
13+
- [Constraints](#-constraints)
14+
- [@Required](#@required)
15+
- [@Range](#@range)
16+
- [@Size](#@size)
17+
- [@Extension](#@extension)
18+
- [@ObjectType](#@objecttype)
19+
- [@Valid](#@valid)
20+
- [Create New Constraint](#-create-new-constraint)
21+
- [New Constraint Annotation](#new-constraint-annotation)
22+
- [New Validator Class](#new-validator-class)
23+
- [Contributing](#-contributing)
24+
- [License](#-license)
25+
26+
1027
## 💡 Description
1128
SlimValidator is a Java library for providing object validation through annotations. It is inspired by the Java Bean Validation specification but is not a implementation at all.
1229

@@ -40,6 +57,9 @@ class Person {
4057
@ObjectType(baseClass = String.class, firstGroup = true, maxSize = 3)
4158
Object reference;
4259

60+
@Extension({"jpg", "png", "bmp"})
61+
Path photograph;
62+
4363
// Constructors , getters, setters, etc.
4464

4565
}
@@ -79,12 +99,15 @@ person.setIncome(1850.5);
7999
person.setHobbies(new String[] {"dancing", "running"});
80100
person.setAddress(address);
81101
person.setReference(List.of(10, 20));
102+
person.setPhotograph(Paths.get("src/test/resources/sample.txt"));
82103

83104
/* Validate objects */
84105

85106
var validator = new Validator();
86107
var violations = validator.validate(person);
87-
violations.forEach(v -> System.out.println(v.getName() + " " + v.getMessage()));
108+
if (violations.size() > 0) {
109+
violations.forEach(v -> System.out.println(v.getName() + " " + v.getMessage()));
110+
}
88111
```
89112
As a result of the validation process, you will see the following messages in console, because the object does not meet several constraints:
90113
```txt
@@ -94,8 +117,31 @@ hobbies size must be at least 3 at most 5.
94117
address.apartment size must be at most 4.
95118
address.city must have a value.
96119
reference type must be or String or Collection<String> (max 3 items).
120+
photograph extension must be one of [jpg, png, bmp].
121+
```
122+
123+
## ⚙ Installation
124+
125+
You can install this library by adding the following dependency to your Maven project:
126+
127+
```xml
128+
<dependency>
129+
<groupId>io.github.sashirestela</groupId>
130+
<artifactId>slimvalidator</artifactId>
131+
<version>[latest version]</version>
132+
</dependency>
133+
```
134+
135+
Or alternatively using Gradle:
136+
137+
```groovy
138+
dependencies {
139+
implementation 'io.github.sashirestela:slimvalidator:[latest version]'
140+
}
97141
```
98142

143+
NOTE: Requires Java 11 or greater.
144+
99145
## 🚩 Constraints
100146

101147
### @Required
@@ -153,6 +199,20 @@ reference type must be or String or Collection<String> (max 3 items).
153199
private List<Project> projects;
154200
```
155201

202+
### @Extension
203+
- **Description**: Checks that the file extension is one of an expected list.
204+
- **Applies to**: Fields of type: java.nio.file.Path, java.io.File.
205+
- **Parameters**:
206+
- _value_: Array of expected extensions. Mandatory.
207+
- **Error messages**:
208+
- If file extension is not any of the _value_ array:
209+
- _extension must be one of {value}._
210+
- **Example**:
211+
```java
212+
@Extension({"doc", "xls", "txt"})
213+
private Path evidenceFile;
214+
```
215+
156216
### @ObjectType
157217
- **Description**: Checks that the type of an object is one of a list of candidate types.
158218
- **Applies to**: Fields of the Object type, including Collection of objects or Collection of Collection of objects. Collection can be any subinterface such as: List, Set, etc.
@@ -196,27 +256,70 @@ reference type must be or String or Collection<String> (max 3 items).
196256
private Address mainAddress;
197257
```
198258

199-
## 🛠️ Installation
259+
## 🪝 Create New Constraint
260+
For creating a new constraint you need to create both a new constraint annotation and a new validator class:
200261

201-
You can install this library by adding the following dependency to your Maven project:
262+
### New Constraint Annotation
263+
Create a new annotation `YourNewConstraint` with the following template:
264+
```java
265+
@Documented
266+
@Constraint(validatedBy = YourNewValidator.class)
267+
@Target({ ElementType.FIELD })
268+
@Retention(RetentionPolicy.RUNTIME)
269+
public @interface YourNewConstraint {
202270

203-
```xml
204-
<dependency>
205-
<groupId>io.github.sashirestela</groupId>
206-
<artifactId>slimvalidator</artifactId>
207-
<version>[latest version]</version>
208-
</dependency>
209-
```
271+
String message() default "<your custom message when validation fails>.";
210272

211-
Or alternatively using Gradle:
273+
// Add any other annotation methods needed by your new constraint.
212274

213-
```groovy
214-
dependencies {
215-
implementation 'io.github.sashirestela:slimvalidator:[latest version]'
216275
}
217276
```
277+
- Use the `@Constraint` annotation to link `YourNewConstraint` annotation to `YourNewValidator` class.
278+
- Define at least the `message()` method. This is the message to show when validation fails. Here you can use optionally:
279+
- Curly brackets to reference other annotation methods. For example: `some text with {max} value.`. The message includes the value of the annotation method `max()`.
280+
- Conditional segments based on the value of some annotation method. For example: `#if(max)some text with {max} value.#endif`. The message includes the value of the annotation method `max()` and it will be shown only if the `max()` is not empty. In this context, "empty" depends on the the annotation method type:
281+
- If boolean, empty means the value is false.
282+
- If String, empty means the text is empty.
283+
- If double, empty means the number is Double.MIN_VALUE or Double.MAX_VALUE.
284+
- If int, empty means the number is zero or Integer.MAX_VALUE.
285+
- If Class, empty means the class is equals to javax.lang.model.type.NullType.
286+
- If array, empty means the array has no elements.
287+
- Loop segments for constraint annotations defined as arrays. For example: `type must be#for(value) or {message}#endfor.`. That message will concatenate the `message()` of each constraint in the constraint array. The argument `value` is not meaningful.
288+
- Add any other annotation methods needed by your new constraint.
289+
290+
### New Validator Class
291+
Create a new class `YourNewValidator` with the following template:
292+
```java
293+
public class YourNewValidator implements ConstraintValidator<YourNewConstraint, ClassOfObjectsToValidate> {
294+
295+
private Type1 annotMethod1;
296+
private Type2 annotMethod2;
297+
...
298+
299+
@Override
300+
public void initialize(YourNewConstraint annotation) {
301+
annotMethod1 = annotation.annotMethod1();
302+
annotMethod2 = annotation.annotMethod2();
303+
...
304+
}
305+
306+
@Override
307+
public boolean isValid(Object value) {
308+
if (value == null) {
309+
return true;
310+
}
311+
312+
// Add your validation logic here
313+
314+
return validationResult;
315+
}
218316

219-
NOTE: Requires Java 11 or greater.
317+
}
318+
```
319+
- Implement the `ConstraintValidator<A, T>` interface, where A represents YourNewConstraint and T represents the class of the objects to validate, in this case, you can use `Object` if your validations applies to more than one class.
320+
- Create as field members as annotation methods you have in YourNewConstraint, excluding message().
321+
- Overrides the `initialize()` method to capture the annotation method values in your field members.
322+
- Overrides the `isValid()` method to do the validation logic. Your first validation step must return true if the object to validate is null, because we have the annotation `@Required` to validate that condition, we don't want to evaluate that nullity here.
220323

221324
## 💼 Contributing
222325
Please read our [Contributing](CONTRIBUTING.md) guide to learn and understand how to contribute to this project.

src/main/java/io/github/sashirestela/slimvalidator/constraints/Extension.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
import io.github.sashirestela.slimvalidator.Constraint;
44
import io.github.sashirestela.slimvalidator.validators.ExtensionValidator;
55

6+
import java.lang.annotation.Documented;
67
import java.lang.annotation.ElementType;
78
import java.lang.annotation.Retention;
89
import java.lang.annotation.RetentionPolicy;
910
import java.lang.annotation.Target;
1011

12+
@Documented
1113
@Constraint(validatedBy = ExtensionValidator.class)
1214
@Target({ ElementType.FIELD })
1315
@Retention(RetentionPolicy.RUNTIME)

0 commit comments

Comments
 (0)