• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

trydofor / professional-wings / #138

05 Feb 2025 07:54AM UTC coverage: 63.648% (+0.02%) from 63.633%
#138

push

trydofor
♻️ refactor/remove jackson empty-xxx #313

75 of 86 new or added lines in 9 files covered. (87.21%)

12930 of 20315 relevant lines covered (63.65%)

0.64 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.62
/wings/slardar/src/main/java/pro/fessional/wings/slardar/jackson/JacksonIncludeValue.java
1
package pro.fessional.wings.slardar.jackson;
2

3
import com.fasterxml.jackson.annotation.JsonInclude;
4
import com.fasterxml.jackson.annotation.JsonInclude.Include;
5
import com.fasterxml.jackson.annotation.JsonInclude.Value;
6
import com.fasterxml.jackson.databind.ObjectMapper;
7
import lombok.extern.slf4j.Slf4j;
8
import org.jetbrains.annotations.NotNull;
9
import org.jetbrains.annotations.Nullable;
10

11
import java.time.LocalDate;
12
import java.time.LocalDateTime;
13
import java.time.OffsetDateTime;
14
import java.time.ZoneId;
15
import java.time.ZonedDateTime;
16
import java.util.Date;
17

18
/**
19
 *
20
 * @author trydofor
21
 * @see JsonInclude
22
 * @since 2021-10-28
23
 */
24
@Slf4j
1✔
25
public class JacksonIncludeValue {
26

27
    protected JacksonIncludeValue(@Nullable LocalDate emptyDate, int offset) {
1✔
28
        EmptyDate = emptyDate == null ? null : new EmptyDateRange(emptyDate, offset);
1✔
29
    }
1✔
30

31
    private static volatile EmptyDateRange EmptyDate;
32

33
    @SuppressWarnings({ "EqualsWhichDoesntCheckParameterClass", "EqualsDoesntCheckParameterClass" })
34
    public static class EmptyDates {
1✔
35
        @Override
36
        public boolean equals(Object obj) {
37
            if (obj == null) return true;
1✔
38

39
            final EmptyDateRange empty = EmptyDate;
1✔
40
            if (empty == null) return false;
1✔
41

42
            return switch (obj) {
1✔
NEW
43
                case Date dt -> empty.isEmpty(dt);
×
44
                case LocalDate dt -> empty.isEmpty(dt);
1✔
45
                case LocalDateTime dt -> empty.isEmpty(dt);
1✔
46
                case ZonedDateTime dt -> empty.isEmpty(dt);
1✔
47
                case OffsetDateTime dt -> empty.isEmpty(dt);
1✔
NEW
48
                default -> false;
×
49
            };
50
        }
51
    }
52

53
    public static final Value NonEmptyValue = Value.construct(Include.NON_EMPTY, null, null, null);
1✔
54
    public static final Value NonEmptyDates = Value.construct(Include.CUSTOM, null, EmptyDates.class, null);
1✔
55

56
    /*
57
     * com.fasterxml.jackson.databind.ser.std.StdArraySerializers
58
     * BasicSerializerFactory#buildArraySerializer
59
     */
60
    public static void configNonEmptyDates(@NotNull ObjectMapper mapper) {
61
        config(mapper, NonEmptyDates,
1✔
62
            java.sql.Date.class,
63
            Date.class,
64
            LocalDate.class,
65
            LocalDateTime.class,
66
            ZonedDateTime.class,
67
            OffsetDateTime.class
68
            );
69
    }
1✔
70

71
    public static void configNonEmptyValue(@NotNull ObjectMapper mapper, Class<?>... claz) {
72
        config(mapper, NonEmptyValue, claz);
1✔
73
    }
1✔
74

75
    public static void config(@NotNull ObjectMapper mapper, @NotNull Value value, Class<?>... claz) {
76
        for (Class<?> clz : claz) {
1✔
77
            mapper.configOverride(clz).setInclude(value);
1✔
78
        }
79
    }
1✔
80

81
    private static class EmptyDateRange {
82
        private final @NotNull LocalDate emptyDate;
83
        private final LocalDateTime emptyDateMin;
84
        private final LocalDateTime emptyDateMax;
85
        private final long timestampMin;
86
        private final long timestampMax;
87

88
        public EmptyDateRange(@NotNull LocalDate empty, int offsetHours) {
1✔
89
            emptyDate = empty;
1✔
90

91
            long offsetMs = offsetHours * 3600_000L;
1✔
92
            final LocalDateTime dt = empty.atStartOfDay();
1✔
93
            final long ms = dt.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
1✔
94
            timestampMin = ms - offsetMs;
1✔
95
            timestampMax = ms + offsetMs;
1✔
96
            if (offsetHours == 0) {
1✔
NEW
97
                emptyDateMin = null;
×
NEW
98
                emptyDateMax = null;
×
99
            }
100
            else {
101
                emptyDateMin = dt.minusHours(offsetHours);
1✔
102
                emptyDateMax = dt.plusHours(offsetHours);
1✔
103

104
            }
105
        }
1✔
106

107
        public boolean isEmpty(Date dt) {
NEW
108
            if (dt == null) return true;
×
109

NEW
110
            final long time = dt.getTime();
×
NEW
111
            return timestampMin <= time && time <= timestampMax;
×
112
        }
113

114
        public boolean isEmpty(LocalDate dt) {
115
            if (dt == null) return true;
1✔
116

117
            return emptyDate.equals(dt);
1✔
118
        }
119

120
        public boolean isEmpty(LocalDateTime dt) {
121
            if (dt == null) return true;
1✔
122
            return _isEmpty(dt);
1✔
123
        }
124

125
        public boolean isEmpty(ZonedDateTime dt) {
126
            if (dt == null) return true;
1✔
127
            return _isEmpty(dt.toLocalDateTime());
1✔
128
        }
129

130
        public boolean isEmpty(OffsetDateTime dt) {
131
            if (dt == null) return true;
1✔
132
            return _isEmpty(dt.toLocalDateTime());
1✔
133
        }
134

135
        // Considering timezone, the difference is considered equal within `offset` hours.
136
        private boolean _isEmpty(@NotNull LocalDateTime dt) {
137
            if (emptyDate.equals(dt.toLocalDate())) return true;
1✔
138

139
            if (emptyDateMin == null || emptyDateMax == null) {
1✔
NEW
140
                return false;
×
141
            }
142
            else {
143
                //noinspection RedundantCompareToJavaTime
144
                return emptyDateMin.compareTo(dt) <= 0 && dt.compareTo(emptyDateMax) <= 0;
1✔
145
            }
146
        }
147
    }
148
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc