com.hltech.pact.gen.domain.pact.PojoValidator   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 81
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 56
dl 0
loc 81
rs 10
c 0
b 0
f 0
wmc 15

9 Methods

Rating   Name   Duplication   Size   Complexity  
A validateComplianceWithJackson(Class) 0 15 2
A PojoValidator() 0 1 1
A validateAll(Collection) 0 2 1
A validateComplianceWithPodam(Class) 0 21 4
A isNotClassGetter(Method) 0 2 1
A isGetter(Method) 0 7 3
A isBuilder(Method) 0 5 1
A isSetter(Method) 0 5 1
A validate(Class) 0 3 1
1
package com.hltech.pact.gen.domain.pact;
2
3
import lombok.extern.slf4j.Slf4j;
4
5
import java.lang.reflect.Constructor;
6
import java.lang.reflect.Method;
7
import java.lang.reflect.Modifier;
8
import java.util.Arrays;
9
import java.util.Collection;
10
import java.util.List;
11
import java.util.stream.Collectors;
12
13
@Slf4j
14
final class PojoValidator {
15
16
    private PojoValidator() {}
17
18
    static void validateAll(Collection<Class<?>> classes) {
19
        classes.forEach(PojoValidator::validate);
20
    }
21
22
    private static void validate(Class<?> clazz) {
23
        validateComplianceWithPodam(clazz);
24
        validateComplianceWithJackson(clazz);
25
    }
26
27
    private static void validateComplianceWithPodam(Class<?> clazz) {
28
        List<Constructor<?>> constructors = Arrays.asList(clazz.getConstructors());
29
        List<Method> methods = Arrays.asList(clazz.getMethods());
30
        int fieldsCount = Arrays.stream(clazz.getDeclaredFields())
31
            .filter(field -> !field.isSynthetic())
32
            .collect(Collectors.toList())
33
            .size();
34
35
        boolean hasNoArgsConstructor = constructors.stream()
36
            .anyMatch(constructor -> constructor.getParameterCount() == 0);
37
        boolean hasAllArgsConstructor = constructors.stream()
38
            .anyMatch(constructor -> constructor.getParameterCount() == fieldsCount);
39
        boolean hasSetterForEveryField = methods.stream()
40
            .filter(PojoValidator::isSetter)
41
            .collect(Collectors.toList()).size() >= fieldsCount;
42
        boolean hasBuilder = methods.stream()
43
            .anyMatch(PojoValidator::isBuilder);
44
45
        if (!(hasNoArgsConstructor && hasSetterForEveryField) && !hasAllArgsConstructor && !hasBuilder) {
46
            log.error("Validation failed for pojo {}", clazz.getSimpleName());
47
            throw new PojoNonCompliantWithPodamException(clazz.getSimpleName());
48
        }
49
    }
50
51
    private static void validateComplianceWithJackson(Class<?> clazz) {
52
        List<Method> methods = Arrays.asList(clazz.getMethods());
53
        int fieldsCount = Arrays.stream(clazz.getDeclaredFields())
54
            .filter(field -> !field.isSynthetic())
55
            .collect(Collectors.toList())
56
            .size();
57
58
        boolean hasGetterForEveryField = methods.stream()
59
            .filter(PojoValidator::isNotClassGetter)
60
            .filter(PojoValidator::isGetter)
61
            .collect(Collectors.toList()).size() >= fieldsCount;
62
63
        if (!hasGetterForEveryField) {
64
            log.error("Validation failed for pojo {}", clazz.getSimpleName());
65
            throw new MissingGettersException(clazz.getSimpleName());
66
        }
67
    }
68
69
    private static boolean isSetter(Method method) {
70
        return Modifier.isPublic(method.getModifiers())
71
            && method.getReturnType().equals(void.class)
72
            && method.getParameterTypes().length == 1
73
            && method.getName().matches("^set[A-Z].*");
74
    }
75
76
    private static boolean isGetter(Method method) {
77
        if (Modifier.isPublic(method.getModifiers()) && method.getParameterTypes().length == 0) {
78
            return (method.getName().matches("^get[A-Z].*") && !method.getReturnType().equals(void.class))
79
                || (method.getName().matches("^is[A-Z].*") && method.getReturnType().equals(boolean.class));
80
        }
81
82
        return false;
83
    }
84
85
    private static boolean isNotClassGetter(Method method) {
86
        return !method.getName().contains("getClass");
87
    }
88
89
    private static boolean isBuilder(Method method) {
90
        return Modifier.isPublic(method.getModifiers())
91
            && method.getName().equals("builder")
92
            && method.getParameterTypes().length == 0
93
            && !method.getReturnType().equals(void.class);
94
    }
95
}
96