Skip to content

Commit d252fe2

Browse files
committed
- Improvements on Validation Base
1 parent 87c4c27 commit d252fe2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+1344
-888
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.nubeiot.core.exceptions;
2+
3+
import lombok.NonNull;
4+
5+
public class ValidationError extends NubeException {
6+
7+
public ValidationError(@NonNull ErrorCode code, @NonNull String message) {
8+
super(code, message);
9+
}
10+
11+
public ValidationError(@NonNull String message) {
12+
super(ErrorCode.INVALID_ARGUMENT, message);
13+
}
14+
15+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.nubeiot.core.validator;
2+
3+
import com.nubeiot.core.utils.Strings;
4+
5+
import io.reactivex.Single;
6+
7+
public abstract class DataTypeValidation<T> extends Validation<T, T> {
8+
9+
public abstract Class classType();
10+
11+
@Override
12+
public Single<ValidationResult<T>> validity(T s) {
13+
if (classType().isInstance(s)) {
14+
return ValidationResult.valid(s);
15+
}
16+
return ValidationResult.invalid(getErrorMessage());
17+
}
18+
19+
@Override
20+
protected String getErrorMessage() {
21+
return Strings.format("{0}: \"{1}\" is not the type of {2}", getErrorType(), getInput(), classType().getName());
22+
}
23+
24+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package com.nubeiot.core.validator;
2+
3+
import com.nubeiot.core.utils.Strings;
4+
5+
import io.reactivex.Single;
6+
import io.vertx.core.json.JsonObject;
7+
import lombok.RequiredArgsConstructor;
8+
import lombok.Setter;
9+
10+
@RequiredArgsConstructor
11+
public class JsonConverter<T, R, I> extends Validation<T, R> {
12+
13+
private final Validation<I, R> validator;
14+
@Setter
15+
private String parentField;
16+
@Setter
17+
private String field;
18+
private Object defaultValue = null;
19+
20+
public static <E, F, G> Single<ValidationResult<F>> validate(Validation<G, F> validator, E s, String field) {
21+
return new JsonConverter<>(validator).validate(s, "", field);
22+
}
23+
24+
public static <E, F, G> Single<ValidationResult<F>> validate(Validation<G, F> validator, E s, String parentField,
25+
String field) {
26+
return new JsonConverter<>(validator).validate(s, parentField, field);
27+
}
28+
29+
public static <E, F, G> Single<ValidationResult<F>> validate(Validation<G, F> validator, E s, String parentField,
30+
String field, Object defaultValue) {
31+
return new JsonConverter<>(validator).registerDefaultValue(defaultValue).validate(s, parentField, field);
32+
}
33+
34+
/**
35+
* @param defaultValue if value is null on the Json, then the default value will be inserted
36+
* @return own class object
37+
*/
38+
public JsonConverter<T, R, I> registerDefaultValue(Object defaultValue) {
39+
this.defaultValue = defaultValue;
40+
return this;
41+
}
42+
43+
@Override
44+
public Single<ValidationResult<R>> validity(T s) {
45+
46+
if (s instanceof JsonObject) {
47+
T value = null;
48+
// field is generally blank for Loop and KeyLoop
49+
if (Strings.isBlank(field)) {
50+
return validator.registerInput(buildInputField()).validate((I) s);
51+
}
52+
String[] fields = field.split("\\.");
53+
JsonObject jsonObject = (JsonObject) s;
54+
55+
try {
56+
for (int i = 0; i < fields.length - 1; i++) {
57+
if (jsonObject.getJsonObject(fields[i]) == null && this.defaultValue != null) {
58+
jsonObject.put(fields[i], new JsonObject());
59+
}
60+
jsonObject = jsonObject.getJsonObject(fields[i]);
61+
}
62+
value = (T) jsonObject.getValue(fields[fields.length - 1]);
63+
} catch (NullPointerException ignored) {
64+
}
65+
66+
if (value == null) {
67+
if (this.defaultValue != null) {
68+
jsonObject.put(fields[fields.length - 1], defaultValue);
69+
value = (T) defaultValue;
70+
}
71+
}
72+
73+
return validator.registerInput(buildInputField()).validate((I) value);
74+
}
75+
76+
if (this.validator.isNullable() && s == null) {
77+
return ValidationResult.valid();
78+
}
79+
80+
// Case: JsonArray
81+
return validator.registerInput(buildInputField()).validate((I) s);
82+
}
83+
84+
@Override
85+
protected String getErrorMessage() {
86+
return null;
87+
}
88+
89+
@Override
90+
public Validation<T, R> registerInput(String input) {
91+
return this;
92+
}
93+
94+
public Single<ValidationResult<R>> validate(T s, String parentField, String field) {
95+
this.parentField = parentField;
96+
this.field = field;
97+
return this.validate(s);
98+
}
99+
100+
String buildInputField() {
101+
if (Strings.isNotBlank(parentField) && Strings.isNotBlank(this.field)) {
102+
return this.parentField + "." + this.field;
103+
} else {
104+
return this.parentField + this.field;
105+
}
106+
}
107+
108+
}
Lines changed: 40 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,64 @@
11
package com.nubeiot.core.validator;
22

3-
import com.nubeiot.core.utils.Strings;
3+
import com.nubeiot.core.exceptions.NubeException;
44

55
import io.reactivex.Single;
6-
import io.vertx.core.json.JsonObject;
6+
import lombok.Getter;
7+
import lombok.Setter;
78

89
public abstract class Validation<T, R> {
910

10-
protected String parentField = "";
11-
protected String field = "";
12-
protected Object defaultValue = null;
13-
protected String errorType = "ValidationError";
11+
@Getter
12+
protected String input = "";
1413

15-
public abstract Single<ValidationResult<R>> validate(T s);
16-
17-
protected abstract String getErrorMessage();
18-
19-
public Validation<T, R> registerField(String field) {
20-
this.field = field;
21-
return this;
22-
}
23-
24-
public Validation<T, R> registerParentField(String parentField) {
25-
this.parentField = parentField;
26-
return this;
27-
}
28-
29-
public Validation<T, R> registerDefaultValue(Object defaultValue) {
30-
this.defaultValue = defaultValue;
31-
return this;
32-
}
14+
@Getter
15+
@Setter
16+
private String errorType = "ValidationError";
17+
@Getter
18+
@Setter
19+
private NubeException.ErrorCode errorCode = NubeException.ErrorCode.INVALID_ARGUMENT;
20+
private boolean overrideInput = true;
3321

3422
/**
35-
* @param jsonObject : JSON object to be passed to extract value
36-
* @param field : JSON field on String format like "thing.features.points.UI1.value"
37-
* @return : Resulted value on ValidationResult form
38-
* <p>
39-
* Basically this will works as a mediator for parsing JSON value and sending it to actual business logic of
40-
* validation
23+
* @param s input value
24+
* @return validation result
4125
*/
42-
public final Single<ValidationResult<R>> validate(JsonObject jsonObject, String field) {
43-
this.field = field;
44-
if (Strings.isBlank(field)) {
45-
return validate((T) jsonObject);
26+
public final Single<ValidationResult<R>> validate(T s) {
27+
// May be default value also be failed on the validation
28+
if (isNullable() && s == null) {
29+
return ValidationResult.valid();
4630
}
4731

48-
T value;
49-
String[] fields = field.split("\\.");
50-
51-
JsonObject object = jsonObject;
52-
try {
53-
for (int i = 0; i < fields.length - 1; i++) {
54-
if (object.getJsonObject(fields[i]) == null && this.defaultValue != null) {
55-
object.put(fields[i], new JsonObject());
56-
}
57-
object = object.getJsonObject(fields[i]);
58-
}
59-
} catch (NullPointerException ignored) {
60-
}
61-
value = (T) object.getValue(fields[fields.length - 1]);
62-
63-
if (value == null) {
64-
if (this.defaultValue != null) {
65-
object.put(fields[fields.length - 1], defaultValue);
66-
}
67-
68-
if (this.passNullCase()) {
69-
return new ValidationResult<R>().asyncSuccess();
70-
}
32+
// Set input only if no DI occurred from parent on Method: registerInput(String input)
33+
if (overrideInput) {
34+
this.input = s != null ? s.toString() : "";
7135
}
7236

73-
return validate(value);
37+
return this.validity(s);
7438
}
7539

76-
protected boolean passNullCase() {
77-
return true;
78-
}
79-
80-
public final Single<ValidationResult<R>> validate(Object s, String parentField, String field) {
81-
this.field = field;
82-
this.parentField = parentField;
83-
84-
if (s instanceof JsonObject) {
85-
return validate((JsonObject) s, field);
86-
}
40+
/**
41+
* This method contains the actual business logic for the individual validation
42+
*
43+
* @param s input value
44+
* @return validation result
45+
*/
46+
public abstract Single<ValidationResult<R>> validity(T s);
8747

88-
if (this.passNullCase() && s == null) {
89-
return new ValidationResult<R>().asyncSuccess();
90-
}
48+
protected abstract String getErrorMessage();
9149

92-
return validate((T) s);
50+
/**
51+
* @param input input value for displaying error value if exist
52+
* @return own class object
53+
*/
54+
public Validation<T, R> registerInput(String input) {
55+
overrideInput = false;
56+
this.input = input;
57+
return this;
9358
}
9459

95-
protected final String getAbsoluteField() {
96-
if (Strings.isNotBlank(parentField) && Strings.isNotBlank(this.field)) {
97-
return parentField + "." + this.field;
98-
} else {
99-
return this.parentField + this.field;
100-
}
60+
protected boolean isNullable() {
61+
return true;
10162
}
10263

10364
}
Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,35 @@
11
package com.nubeiot.core.validator;
22

33
import com.nubeiot.core.exceptions.NubeException;
4-
import com.nubeiot.core.validator.enums.ValidationState;
4+
import com.nubeiot.core.exceptions.ValidationError;
55

66
import io.reactivex.Single;
77
import lombok.Getter;
8-
import lombok.NoArgsConstructor;
8+
import lombok.RequiredArgsConstructor;
99

1010
@Getter
11-
@NoArgsConstructor
11+
@RequiredArgsConstructor
1212
public class ValidationResult<T> {
1313

14-
private ValidationState validity;
15-
private String reason;
1614
private T data;
1715

18-
public ValidationResult<T> success(T data) {
19-
this.validity = ValidationState.VALID;
20-
this.reason = null;
21-
this.data = data;
22-
return this;
16+
public static <E> Single<ValidationResult<E>> valid() {
17+
ValidationResult<E> validationResult = new ValidationResult<>();
18+
return Single.just(validationResult);
2319
}
2420

25-
public ValidationResult<T> success() {
26-
return success(null);
21+
public static <E> Single<ValidationResult<E>> valid(E data) {
22+
ValidationResult<E> validationResult = new ValidationResult<>();
23+
validationResult.data = data;
24+
return Single.just(validationResult);
2725
}
2826

29-
public NubeException invalid(String reason) {
30-
return new NubeException(NubeException.ErrorCode.INVALID_ARGUMENT, reason);
27+
public static <E> Single<ValidationResult<E>> invalid(NubeException.ErrorCode errorCode, String message) {
28+
return Single.error(new ValidationError(errorCode, message));
3129
}
3230

33-
public Single<ValidationResult<T>> asyncSuccess(T data) {
34-
return Single.just(success(data));
35-
}
36-
37-
public Single<ValidationResult<T>> asyncSuccess() {
38-
return Single.just(success());
39-
}
40-
41-
public Single<ValidationResult<T>> asyncInvalid(String reason) {
42-
return Single.error(new NubeException(NubeException.ErrorCode.INVALID_ARGUMENT, reason));
43-
}
44-
45-
public Single<ValidationResult<T>> asyncInvalid(NubeException.ErrorCode errorCode, String reason) {
46-
return Single.error(new NubeException(errorCode, reason));
31+
public static <E> Single<ValidationResult<E>> invalid(String message) {
32+
return Single.error(new ValidationError(message));
4733
}
4834

4935
}

core/validator/src/main/java/com/nubeiot/core/validator/enums/ValidationState.java

Lines changed: 0 additions & 5 deletions
This file was deleted.

core/validator/src/main/java/com/nubeiot/core/validator/validations/Alternative.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.nubeiot.core.validator.validations;
22

33
import java.util.ArrayList;
4+
import java.util.HashSet;
45
import java.util.List;
56

67
import com.nubeiot.core.exceptions.NubeException;
@@ -16,12 +17,12 @@ public class Alternative<T> extends Validation<T, Object> {
1617
private final List<Validation<T, ?>> validations;
1718

1819
@Override
19-
public Single<ValidationResult<Object>> validate(T s) {
20+
public Single<ValidationResult<Object>> validity(T s) {
2021
final List<NubeException> exception = new ArrayList<>();
2122
return Single.create(source -> {
22-
for (Validation<T, ?> validation : validations) {
23+
for (Validation<T, ?> validation : new HashSet<>(validations)) {
2324

24-
validation.registerField(field).registerParentField(parentField).validate(s)
25+
validation.registerInput(this.input).validate(s)
2526
.subscribe(validationResult -> source.onSuccess((ValidationResult) validationResult),
2627
error -> exception.add((NubeException) error));
2728
}

0 commit comments

Comments
 (0)