Skip to content

Commit 57d4998

Browse files
committed
add custom types
remove obsolete validators remove snapshots fix actions fix version fix missing steps add basic validators add PR snapshots
1 parent 4df098f commit 57d4998

11 files changed

Lines changed: 702 additions & 0 deletions

File tree

.idea/encodings.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pom.xml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,56 @@
33
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
44
<modelVersion>4.0.0</modelVersion>
55

6+
<parent>
7+
<groupId>org.springframework.boot</groupId>
8+
<artifactId>spring-boot-starter-parent</artifactId>
9+
<version>3.3.2</version>
10+
<relativePath/> <!-- lookup parent from repository -->
11+
</parent>
12+
613
<groupId>it.aboutbits</groupId>
714
<artifactId>spring-boot-toolbox</artifactId>
815
<version>BUILD-SNAPSHOT</version>
916
<description>Utility library for Spring Boot projects.</description>
17+
<packaging>jar</packaging>
1018

1119
<properties>
1220
<java.version>21</java.version>
1321
</properties>
1422

1523
<dependencies>
24+
<dependency>
25+
<groupId>org.springframework.boot</groupId>
26+
<artifactId>spring-boot-starter-validation</artifactId>
27+
</dependency>
28+
29+
<!-- Utilities -->
30+
<dependency>
31+
<groupId>org.projectlombok</groupId>
32+
<artifactId>lombok</artifactId>
33+
<optional>true</optional>
34+
</dependency>
35+
36+
<!-- Validation -->
37+
<!-- https://mvnrepository.com/artifact/commons-validator/commons-validator -->
38+
<dependency>
39+
<groupId>commons-validator</groupId>
40+
<artifactId>commons-validator</artifactId>
41+
<version>1.9.0</version>
42+
</dependency>
43+
44+
<!-- https://mvnrepository.com/artifact/org.jetbrains/annotations -->
45+
<dependency>
46+
<groupId>org.jetbrains</groupId>
47+
<artifactId>annotations</artifactId>
48+
<version>24.1.0</version>
49+
</dependency>
1650

51+
<!-- Testing -->
52+
<dependency>
53+
<groupId>org.springframework.boot</groupId>
54+
<artifactId>spring-boot-starter-test</artifactId>
55+
</dependency>
1756
</dependencies>
1857

1958
<build>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package it.aboutbits.springboot.toolbox.type;
2+
3+
import it.aboutbits.springboot.toolbox.validation.util.EmailAddressValidator;
4+
import org.jetbrains.annotations.NotNull;
5+
6+
/**
7+
* A record representing an email address, validated and stored in lowercase.
8+
* <p>
9+
* The EmailAddress record ensures that the provided email address string
10+
* is in a valid format and automatically converts it to lowercase for
11+
* consistent internal representation. It implements the Comparable
12+
* interface to allow comparison between different email addresses.
13+
* </p>
14+
*
15+
* @param value the email address string
16+
* @throws IllegalArgumentException if the provided email address is not in a valid format
17+
*/
18+
public record EmailAddress(String value) implements Comparable<EmailAddress> {
19+
public EmailAddress(String value) {
20+
if (value == null || EmailAddressValidator.isNotValid(value)) {
21+
throw new IllegalArgumentException("Value is not a valid email address: " + value);
22+
}
23+
24+
this.value = value.toLowerCase();
25+
}
26+
27+
@Override
28+
public String toString() {
29+
return value;
30+
}
31+
32+
@Override
33+
public int compareTo(@NotNull EmailAddress o) {
34+
return value().compareTo(o.value());
35+
}
36+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package it.aboutbits.springboot.toolbox.type;
2+
3+
import it.aboutbits.springboot.toolbox.validation.util.IbanValidator;
4+
import org.jetbrains.annotations.NotNull;
5+
6+
import java.util.Optional;
7+
8+
/**
9+
* The {@code Iban} class represents an International Bank Account Number (IBAN) and provides functionality for validation
10+
* and comparison of IBANs. It ensures the valid format of the IBAN according to predefined rules.
11+
*
12+
* @param value the IBAN value, which must be a valid and non-null string
13+
*/
14+
public record Iban(String value) implements Comparable<Iban> {
15+
public Iban(String value) {
16+
if (value == null || IbanValidator.isNotValid(value.toUpperCase())) {
17+
throw new IllegalArgumentException("Value is not a valid IBAN: " + value);
18+
}
19+
20+
this.value = value.toUpperCase();
21+
}
22+
23+
@Override
24+
public String toString() {
25+
return value;
26+
}
27+
28+
/**
29+
* Retrieves the ABI (Bank Branch Code) if the IBAN belongs to an Italian bank.
30+
*
31+
* @return An {@code Optional} containing the ABI value if the IBAN is Italian, or an empty {@code Optional} otherwise.
32+
*/
33+
public Optional<String> getAbiIfItalian() {
34+
var iban = value();
35+
36+
if (!iban.startsWith("IT")) {
37+
return Optional.empty();
38+
}
39+
return Optional.of(iban.substring(5, 10));
40+
}
41+
42+
@Override
43+
public int compareTo(@NotNull Iban o) {
44+
return value().compareTo(o.value());
45+
}
46+
}
Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
package it.aboutbits.springboot.toolbox.type;
2+
3+
import lombok.NonNull;
4+
import org.jetbrains.annotations.NotNull;
5+
6+
import java.math.BigDecimal;
7+
import java.math.BigInteger;
8+
import java.math.MathContext;
9+
import java.math.RoundingMode;
10+
import java.util.Objects;
11+
12+
/**
13+
* A record that represents a scaled BigDecimal with a fixed MathContext.
14+
* This class provides various constructors for creating instances with different numerical types.
15+
* It also provides a set of arithmetic operations that return new instances with the appropriate scale and rounding.
16+
*/
17+
public record ScaledBigDecimal(
18+
@NonNull BigDecimal value
19+
) implements Comparable<ScaledBigDecimal> {
20+
private static final MathContext MATH_CONTEXT = new MathContext(15, RoundingMode.HALF_UP);
21+
22+
public static final ScaledBigDecimal ZERO = new ScaledBigDecimal(0);
23+
public static final ScaledBigDecimal ONE = new ScaledBigDecimal(1);
24+
public static final ScaledBigDecimal TWO = new ScaledBigDecimal(2);
25+
public static final ScaledBigDecimal TEN = new ScaledBigDecimal(10);
26+
27+
public ScaledBigDecimal(@NonNull BigDecimal value) {
28+
this.value = value.setScale(MATH_CONTEXT.getPrecision(), MATH_CONTEXT.getRoundingMode());
29+
}
30+
31+
public ScaledBigDecimal(int value) {
32+
this(new BigDecimal(value, MATH_CONTEXT));
33+
}
34+
35+
public ScaledBigDecimal(@NonNull Integer value) {
36+
this(new BigDecimal(value, MATH_CONTEXT));
37+
}
38+
39+
public ScaledBigDecimal(@NonNull BigInteger value) {
40+
this(new BigDecimal(value, MATH_CONTEXT));
41+
}
42+
43+
public ScaledBigDecimal(long value) {
44+
this(new BigDecimal(value, MATH_CONTEXT));
45+
}
46+
47+
public ScaledBigDecimal(@NonNull Long value) {
48+
this(new BigDecimal(value, MATH_CONTEXT));
49+
}
50+
51+
public ScaledBigDecimal(float value) {
52+
this(new BigDecimal(String.valueOf(value), MATH_CONTEXT));
53+
}
54+
55+
public ScaledBigDecimal(@NonNull Float value) {
56+
this(new BigDecimal(String.valueOf(value), MATH_CONTEXT));
57+
}
58+
59+
public ScaledBigDecimal(double value) {
60+
this(new BigDecimal(String.valueOf(value), MATH_CONTEXT));
61+
}
62+
63+
public ScaledBigDecimal(@NonNull Double value) {
64+
this(new BigDecimal(String.valueOf(value), MATH_CONTEXT));
65+
}
66+
67+
public ScaledBigDecimal(@NonNull String value) {
68+
this(new BigDecimal(value, MATH_CONTEXT));
69+
}
70+
71+
public static ScaledBigDecimal valueOf(int value) {
72+
return new ScaledBigDecimal(value);
73+
}
74+
75+
public static ScaledBigDecimal valueOf(@NonNull Integer value) {
76+
return new ScaledBigDecimal(value);
77+
}
78+
79+
public static ScaledBigDecimal valueOf(@NonNull BigInteger value) {
80+
return new ScaledBigDecimal(value);
81+
}
82+
83+
public static ScaledBigDecimal valueOf(long value) {
84+
return new ScaledBigDecimal(value);
85+
}
86+
87+
public static ScaledBigDecimal valueOf(@NonNull Long value) {
88+
return new ScaledBigDecimal(value);
89+
}
90+
91+
public static ScaledBigDecimal valueOf(float value) {
92+
return new ScaledBigDecimal(value);
93+
}
94+
95+
public static ScaledBigDecimal valueOf(@NonNull Float value) {
96+
return new ScaledBigDecimal(value);
97+
}
98+
99+
public static ScaledBigDecimal valueOf(double value) {
100+
return new ScaledBigDecimal(value);
101+
}
102+
103+
public static ScaledBigDecimal valueOf(@NonNull Double value) {
104+
return new ScaledBigDecimal(value);
105+
}
106+
107+
public static ScaledBigDecimal valueOf(@NonNull String value) {
108+
return new ScaledBigDecimal(value);
109+
}
110+
111+
@NotNull
112+
public ScaledBigDecimal add(@NonNull ScaledBigDecimal other) {
113+
return new ScaledBigDecimal(this.value().add(other.value()));
114+
}
115+
116+
@NotNull
117+
public ScaledBigDecimal subtract(@NonNull ScaledBigDecimal other) {
118+
return new ScaledBigDecimal(this.value().subtract(other.value()));
119+
}
120+
121+
@NotNull
122+
public ScaledBigDecimal multiply(@NonNull ScaledBigDecimal other) {
123+
return new ScaledBigDecimal(this.value().multiply(other.value()));
124+
}
125+
126+
@NotNull
127+
public ScaledBigDecimal divide(@NonNull ScaledBigDecimal other) {
128+
return new ScaledBigDecimal(this.value().divide(other.value(), MATH_CONTEXT));
129+
}
130+
131+
@NotNull
132+
public ScaledBigDecimal add(@NonNull BigDecimal other) {
133+
return new ScaledBigDecimal(this.value().add(other));
134+
}
135+
136+
@NotNull
137+
public ScaledBigDecimal subtract(@NonNull BigDecimal other) {
138+
return new ScaledBigDecimal(this.value().subtract(other));
139+
}
140+
141+
@NotNull
142+
public ScaledBigDecimal multiply(@NonNull BigDecimal other) {
143+
return new ScaledBigDecimal(this.value().multiply(other));
144+
}
145+
146+
@NotNull
147+
public ScaledBigDecimal divide(@NonNull BigDecimal other) {
148+
return new ScaledBigDecimal(this.value().divide(other, MATH_CONTEXT));
149+
}
150+
151+
@NotNull
152+
public ScaledBigDecimal remainder(@NonNull ScaledBigDecimal divisor) {
153+
return new ScaledBigDecimal(this.value().remainder(divisor.value(), MATH_CONTEXT));
154+
}
155+
156+
@NotNull
157+
public ScaledBigDecimal remainder(@NonNull BigDecimal divisor) {
158+
return new ScaledBigDecimal(this.value().remainder(divisor, MATH_CONTEXT));
159+
}
160+
161+
@NotNull
162+
public ScaledBigDecimal sqrt() {
163+
return new ScaledBigDecimal(this.value().sqrt(MATH_CONTEXT));
164+
}
165+
166+
@NotNull
167+
public ScaledBigDecimal pow(int n) {
168+
return new ScaledBigDecimal(this.value().pow(n, MATH_CONTEXT));
169+
}
170+
171+
@NotNull
172+
public ScaledBigDecimal abs() {
173+
return new ScaledBigDecimal(this.value().abs(MATH_CONTEXT));
174+
}
175+
176+
@NotNull
177+
public ScaledBigDecimal negate() {
178+
return new ScaledBigDecimal(this.value().negate(MATH_CONTEXT));
179+
}
180+
181+
@NotNull
182+
public ScaledBigDecimal min(@NonNull ScaledBigDecimal val) {
183+
return new ScaledBigDecimal(this.value().min(val.value()));
184+
}
185+
186+
@NotNull
187+
public ScaledBigDecimal min(@NonNull BigDecimal val) {
188+
return new ScaledBigDecimal(this.value().min(val));
189+
}
190+
191+
@NotNull
192+
public ScaledBigDecimal max(@NonNull ScaledBigDecimal val) {
193+
return new ScaledBigDecimal(this.value().max(val.value()));
194+
}
195+
196+
@NotNull
197+
public ScaledBigDecimal max(@NonNull BigDecimal val) {
198+
return new ScaledBigDecimal(this.value().max(val));
199+
}
200+
201+
@NotNull
202+
public BigDecimal toBigDecimal(int scale) {
203+
return this.value().setScale(scale, RoundingMode.HALF_UP);
204+
}
205+
206+
@NotNull
207+
public ScaledBigDecimal roundToScale(int scale) {
208+
return new ScaledBigDecimal(this.value().setScale(scale, RoundingMode.HALF_UP));
209+
}
210+
211+
@Override
212+
public boolean equals(Object o) {
213+
if (this == o) {
214+
return true;
215+
}
216+
217+
if (o instanceof ScaledBigDecimal other) {
218+
return this.value().compareTo(other.value()) == 0;
219+
}
220+
221+
return false;
222+
}
223+
224+
@Override
225+
public int hashCode() {
226+
return Objects.hash(MATH_CONTEXT, value());
227+
}
228+
229+
@Override
230+
public int compareTo(@NotNull ScaledBigDecimal o) {
231+
return this.value().compareTo(o.value());
232+
}
233+
}

0 commit comments

Comments
 (0)