diff --git a/.gitignore b/.gitignore index c139cbf..b7ab4b7 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ !.mvn target *.log +*.iml diff --git a/common/pom.xml b/common/pom.xml index 515be8d..a27b3e3 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -22,6 +22,11 @@ jakarta.validation-api + + jakarta.annotation + jakarta.annotation-api + + diff --git a/common/src/main/java/org/fuin/objects4j/common/ConstraintViolationException.java b/common/src/main/java/org/fuin/objects4j/common/ConstraintViolationException.java index a1223ce..bf62bc3 100644 --- a/common/src/main/java/org/fuin/objects4j/common/ConstraintViolationException.java +++ b/common/src/main/java/org/fuin/objects4j/common/ConstraintViolationException.java @@ -18,7 +18,9 @@ package org.fuin.objects4j.common; import jakarta.validation.ConstraintViolation; +import jakarta.validation.constraints.NotEmpty; +import java.io.Serial; import java.util.Collections; import java.util.Set; @@ -27,8 +29,10 @@ */ public final class ConstraintViolationException extends RuntimeException { + @Serial private static final long serialVersionUID = 1L; + @SuppressWarnings("squid:S1948") // Cannot fix as external interface, but Hibernate is serializable private final Set> constraintViolations; /** @@ -37,7 +41,7 @@ public final class ConstraintViolationException extends RuntimeException { * @param message * Message. */ - public ConstraintViolationException(final String message) { + public ConstraintViolationException(@NotEmpty final String message) { super(message); this.constraintViolations = null; } @@ -50,7 +54,7 @@ public ConstraintViolationException(final String message) { * @param constraintViolations * Constraint violations. */ - public ConstraintViolationException(final String message, final Set> constraintViolations) { + public ConstraintViolationException(@NotEmpty final String message, @Nullable final Set> constraintViolations) { super(message); this.constraintViolations = constraintViolations; } @@ -58,8 +62,9 @@ public ConstraintViolationException(final String message, final Setnull if only a message is available. + * @return Immutable set of constraint violations or {@literal null} if only a message is available. */ + @SuppressWarnings("squid:S1168") // Won't fix. Needs to be backward compatible. public final Set> getConstraintViolations() { if (constraintViolations == null) { return null; diff --git a/common/src/main/java/org/fuin/objects4j/common/Contract.java b/common/src/main/java/org/fuin/objects4j/common/Contract.java index 7f05058..ded2087 100644 --- a/common/src/main/java/org/fuin/objects4j/common/Contract.java +++ b/common/src/main/java/org/fuin/objects4j/common/Contract.java @@ -1,22 +1,23 @@ /** - * Copyright (C) 2015 Michael Schnell. All rights reserved. + * Copyright (C) 2015 Michael Schnell. All rights reserved. * http://www.fuin.org/ - * + *

* This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) any * later version. - * + *

* This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. - * + *

* You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see http://www.gnu.org/licenses/. */ package org.fuin.objects4j.common; +import jakarta.annotation.Nullable; import jakarta.validation.ConstraintViolation; import jakarta.validation.Validation; import jakarta.validation.Validator; @@ -40,7 +41,7 @@ public final class Contract { /** * Sets the validator to use for contract validation. This method is NOT thread safe. It should only be called once per application * during the initialization phase. - * + * * @param newValidator * Set the validator to a new value. */ @@ -51,7 +52,7 @@ public static void setValidator(final Validator newValidator) { /** * Returns the validator that is used for contract validation. This method is NOT thread safe - This may lead to concurrent * initialization of the validator if it's not set yet. - * + * * @return Current instance - If the validator is not set yet, a new default validator will be created. */ public static Validator getValidator() { @@ -70,12 +71,12 @@ private Contract() { /** * Checks if the value is not null. - * + * * @param name * Name of the value for a possible error message. * @param value * Value to check. - * + * * @throws ConstraintViolationException * The value was null. */ @@ -86,33 +87,33 @@ public static void requireArgNotNull(@NotNull final String name, final Object va } /** - * Checks if the value is not null or empty. A single space is considered a valid value. - * + * Checks if the value is not {@literal null} or empty. A single space is considered a valid value. + * * @param name * Name of the value for a possible error message. * @param value * Value to check. - * + * * @throws ConstraintViolationException * The value was null or empty. */ public static void requireArgNotEmpty(@NotNull final String name, final String value) throws ConstraintViolationException { requireArgNotNull(name, value); - if (value.length() < 1) { + if (value.isEmpty()) { throw new ConstraintViolationException("The argument '" + name + "' cannot be empty"); } } /** * Checks if the length of value is not higher than a give maximum. - * + * * @param name * Name of the value for a possible error message. * @param value * Value to check. * @param max * Max length (inclusive). - * + * * @throws ConstraintViolationException * The length was more than max. */ @@ -125,14 +126,14 @@ public static void requireArgMaxLength(@NotNull final String name, @NotNull fina /** * Checks if the length of value is not less than a give minimum. - * + * * @param name * Name of the value for a possible error message. * @param value * Value to check. * @param min * Minimal length. - * + * * @throws ConstraintViolationException * The length was less than min. */ @@ -145,14 +146,14 @@ public static void requireArgMinLength(@NotNull final String name, @NotNull fina /** * Checks if the value is not higher than a give maximum. - * + * * @param name * Name of the value for a possible error message. * @param value * Value to check. * @param max * Max value (inclusive). - * + * * @throws ConstraintViolationException * The value was more than max. */ @@ -165,14 +166,14 @@ public static void requireArgMax(@NotNull final String name, @NotNull final long /** * Checks if the value is not less than a give minimum. - * + * * @param name * Name of the value for a possible error message. * @param value * Value to check. * @param min * Minimal value (inclusive). - * + * * @throws ConstraintViolationException * The value was less than min. */ @@ -185,14 +186,14 @@ public static void requireArgMin(@NotNull final String name, @NotNull final long /** * Checks if the given value is valid. - * + * * @param validator * Validator to use. * @param value * Value to check. * @param groups * Group or list of groups targeted for validation (defaults to {@link Default}) - * + * * @throws ConstraintViolationException * The value is invalid. */ @@ -203,11 +204,15 @@ public static void requireValid(@NotNull final Validator validator, @NotNull fin if (!constraintViolations.isEmpty()) { final StringBuilder sb = new StringBuilder(); for (final ConstraintViolation constraintViolation : constraintViolations) { - if (sb.length() > 0) { + if (!sb.isEmpty()) { sb.append(", "); } - sb.append("[" + constraintViolation.getPropertyPath() + "] " + constraintViolation.getMessage() + " {" - + constraintViolation.getInvalidValue() + "}"); + sb.append("[") + .append(constraintViolation.getPropertyPath()) + .append("] ") + .append(constraintViolation.getMessage()) + .append(" {").append(constraintViolation.getInvalidValue()) + .append("}"); } throw new ConstraintViolationException(sb.toString(), constraintViolations); } @@ -216,12 +221,12 @@ public static void requireValid(@NotNull final Validator validator, @NotNull fin /** * Checks if the given value is valid using a default validator. - * + * * @param value * Value to check. * @param groups * Group or list of groups targeted for validation (defaults to {@link Default}) - * + * * @throws ConstraintViolationException * The value is invalid. */ @@ -231,38 +236,38 @@ public static void requireValid(@NotNull final Object value, @Nullable final Cla /** * Validates the given object. - * + * * @param validator * Validator to use. * @param value * Value to validate. * @param groups * Group or list of groups targeted for validation (defaults to {@link Default}) - * + * * @return List of constraint violations. - * + * * @param * Type of the validated object. */ @NotNull public static Set> validate(@NotNull final Validator validator, @Nullable final TYPE value, - @Nullable final Class... groups) { + @Nullable final Class... groups) { if (value == null) { - return new HashSet>(); + return new HashSet<>(); } return validator.validate(value, groups); } /** * Validates the given object using a default validator. - * + * * @param value * Value to validate. * @param groups * Group or list of groups targeted for validation (defaults to {@link Default}) - * + * * @return List of constraint violations. - * + * * @param * Type of the validated object. */ @@ -273,16 +278,16 @@ public static Set> validate(@Nullable final TYP /** * Converts a set of constraint violation into a string list. - * + * * @param constraintViolations * Violations to convert to a string. - * + * * @return List of string representations for all violations. - * + * * @param Type of list content. */ public static List asString(@Nullable final Set> constraintViolations) { - if (constraintViolations == null || constraintViolations.size() == 0) { + if (constraintViolations == null || constraintViolations.isEmpty()) { return Collections.emptyList(); } final List list = new ArrayList<>(); @@ -294,14 +299,14 @@ public static List asString(@Nullable final Set Type of the root bean. */ public static String asString(@Nullable final Set> constraintViolations, @Nullable final String separator) { @@ -314,9 +319,9 @@ public static String asString(@Nullable final Set> co } else { sepStr = separator; } - final StringBuffer sb = new StringBuffer(); + final StringBuilder sb = new StringBuilder(); for (final ConstraintViolation constraintViolation : constraintViolations) { - if (sb.length() > 0) { + if (!sb.isEmpty()) { sb.append(sepStr); } sb.append(asString(constraintViolation)); @@ -326,12 +331,12 @@ public static String asString(@Nullable final Set> co /** * Returns a constraint violation as string. - * + * * @param violation * Violation to convert to a string. - * + * * @return Text like "SIMPLE_CLASS_NAME.PROPERTY_PATH MESSAGE" or "SIMPLE_CLASS_NAME.PROPERTY_PATH MESSAGE (INVALID_VALUE)". - * + * * @param Type of the validated root object. */ public static String asString(@Nullable final ConstraintViolation violation) { diff --git a/common/src/main/java/org/fuin/objects4j/common/NeverEmpty.java b/common/src/main/java/org/fuin/objects4j/common/NeverEmpty.java index 7976827..e016093 100644 --- a/common/src/main/java/org/fuin/objects4j/common/NeverEmpty.java +++ b/common/src/main/java/org/fuin/objects4j/common/NeverEmpty.java @@ -25,7 +25,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Used to express that a method's return value is never null or empty. + * Used to express that a method's return value is never {@literal null} or empty. * * @deprecated Use jakarta.validation.constraints.NotNull from bean validation instead. * It wasn't allowed to use it for a return value, but it is now. diff --git a/common/src/main/java/org/fuin/objects4j/common/NeverNull.java b/common/src/main/java/org/fuin/objects4j/common/NeverNull.java index d3ed3df..cf0c9e5 100644 --- a/common/src/main/java/org/fuin/objects4j/common/NeverNull.java +++ b/common/src/main/java/org/fuin/objects4j/common/NeverNull.java @@ -25,7 +25,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Used to express that a method's return value is never null. + * Used to express that a method's return value is never {@literal null}. * * @deprecated Use jakarta.validation.constraints.NotNull from bean validation instead. * It wasn't allowed to use it for a return value, but it is now. diff --git a/common/src/main/java/org/fuin/objects4j/common/Nullable.java b/common/src/main/java/org/fuin/objects4j/common/Nullable.java index 96f2584..4addef8 100644 --- a/common/src/main/java/org/fuin/objects4j/common/Nullable.java +++ b/common/src/main/java/org/fuin/objects4j/common/Nullable.java @@ -25,7 +25,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Used to express that a value may be null. + * Used to express that a value may be {@literal null}. * * @deprecated Use jakarta.annotation.Nullable from Jakarta annotations instead. */ diff --git a/common/src/main/java/org/fuin/objects4j/common/UniquelyNumberedException.java b/common/src/main/java/org/fuin/objects4j/common/UniquelyNumberedException.java index a483273..dda96b9 100644 --- a/common/src/main/java/org/fuin/objects4j/common/UniquelyNumberedException.java +++ b/common/src/main/java/org/fuin/objects4j/common/UniquelyNumberedException.java @@ -19,11 +19,14 @@ import jakarta.validation.constraints.NotNull; +import java.io.Serial; + /** * Exception that provides a number for the exception that is unique in the context. */ public abstract class UniquelyNumberedException extends Exception implements UniquelyNumbered { + @Serial private static final long serialVersionUID = 1L; private final long number; diff --git a/common/src/test/java/org/fuin/objects4j/common/UniquelyNumberedExceptionTest.java b/common/src/test/java/org/fuin/objects4j/common/UniquelyNumberedExceptionTest.java index e160419..c421167 100644 --- a/common/src/test/java/org/fuin/objects4j/common/UniquelyNumberedExceptionTest.java +++ b/common/src/test/java/org/fuin/objects4j/common/UniquelyNumberedExceptionTest.java @@ -19,6 +19,8 @@ import org.junit.jupiter.api.Test; +import java.io.Serial; + import static org.assertj.core.api.Assertions.assertThat; public final class UniquelyNumberedExceptionTest { @@ -71,6 +73,7 @@ void testCreateNumberMessageCause() { public static final class MyException extends UniquelyNumberedException { + @Serial private static final long serialVersionUID = 1L; public MyException(long number, String message, Throwable cause) { diff --git a/core/pom.xml b/core/pom.xml index 4b17132..b4548d6 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -42,6 +42,11 @@ jakarta.annotation-api + + com.google.code.findbugs + jsr305 + + diff --git a/core/src/main/java/org/fuin/objects4j/core/AbstractIntegerValueObject.java b/core/src/main/java/org/fuin/objects4j/core/AbstractIntegerValueObject.java index 03cee7d..d3dd015 100644 --- a/core/src/main/java/org/fuin/objects4j/core/AbstractIntegerValueObject.java +++ b/core/src/main/java/org/fuin/objects4j/core/AbstractIntegerValueObject.java @@ -17,6 +17,7 @@ */ package org.fuin.objects4j.core; +import java.io.Serial; import java.io.Serializable; /** @@ -26,6 +27,7 @@ public abstract class AbstractIntegerValueObject implements ValueObjectWithBaseType, Comparable, Serializable { + @Serial private static final long serialVersionUID = 1000L; @Override diff --git a/core/src/main/java/org/fuin/objects4j/core/AbstractLongValueObject.java b/core/src/main/java/org/fuin/objects4j/core/AbstractLongValueObject.java index b3b6adb..ec09357 100644 --- a/core/src/main/java/org/fuin/objects4j/core/AbstractLongValueObject.java +++ b/core/src/main/java/org/fuin/objects4j/core/AbstractLongValueObject.java @@ -17,6 +17,7 @@ */ package org.fuin.objects4j.core; +import java.io.Serial; import java.io.Serializable; /** @@ -25,6 +26,7 @@ */ public abstract class AbstractLongValueObject implements ValueObjectWithBaseType, Comparable, Serializable { + @Serial private static final long serialVersionUID = 1000L; @Override diff --git a/core/src/main/java/org/fuin/objects4j/core/AbstractStringValueObject.java b/core/src/main/java/org/fuin/objects4j/core/AbstractStringValueObject.java index 752da4a..21b5cd3 100644 --- a/core/src/main/java/org/fuin/objects4j/core/AbstractStringValueObject.java +++ b/core/src/main/java/org/fuin/objects4j/core/AbstractStringValueObject.java @@ -17,6 +17,7 @@ */ package org.fuin.objects4j.core; +import java.io.Serial; import java.io.Serializable; /** @@ -26,6 +27,7 @@ public abstract class AbstractStringValueObject implements ValueObjectWithBaseType, Comparable, Serializable, AsStringCapable { + @Serial private static final long serialVersionUID = 1000L; @Override diff --git a/core/src/main/java/org/fuin/objects4j/core/AbstractUuidValueObject.java b/core/src/main/java/org/fuin/objects4j/core/AbstractUuidValueObject.java index 5ab0c8a..0071530 100644 --- a/core/src/main/java/org/fuin/objects4j/core/AbstractUuidValueObject.java +++ b/core/src/main/java/org/fuin/objects4j/core/AbstractUuidValueObject.java @@ -19,6 +19,7 @@ import org.fuin.objects4j.common.HasPublicStaticIsValidMethod; +import java.io.Serial; import java.io.Serializable; import java.util.UUID; import java.util.regex.Pattern; @@ -30,6 +31,7 @@ @HasPublicStaticIsValidMethod public abstract class AbstractUuidValueObject implements ValueObjectWithBaseType, Comparable, Serializable { + @Serial private static final long serialVersionUID = 1000L; @Override @@ -66,7 +68,7 @@ public final Class getBaseType() { * Verifies that a given string is a valid UUID. * * @param value - * Value to check. A null value returns {@literal true}. + * Value to check. A {@literal null} value returns {@literal true}. * * @return TRUE if it's a valid key, else FALSE. */ diff --git a/core/src/main/java/org/fuin/objects4j/core/CurrencyAmount.java b/core/src/main/java/org/fuin/objects4j/core/CurrencyAmount.java index 9c54a45..861c2f1 100644 --- a/core/src/main/java/org/fuin/objects4j/core/CurrencyAmount.java +++ b/core/src/main/java/org/fuin/objects4j/core/CurrencyAmount.java @@ -23,10 +23,11 @@ import org.fuin.objects4j.common.Contract; import org.fuin.objects4j.common.HasPublicStaticIsValidMethod; import org.fuin.objects4j.common.HasPublicStaticValueOfMethod; -import org.fuin.objects4j.common.Immutable; +import javax.annotation.concurrent.Immutable; import org.fuin.objects4j.ui.Label; import org.fuin.objects4j.ui.ShortLabel; +import java.io.Serial; import java.io.Serializable; import java.math.BigDecimal; import java.math.BigInteger; @@ -43,6 +44,7 @@ @HasPublicStaticValueOfMethod(method = "valueOf", param = String.class) public final class CurrencyAmount implements ValueObjectWithBaseType, Comparable, Serializable, AsStringCapable { + @Serial private static final long serialVersionUID = 1000L; private static final String DECIMAL = "((\\+|-)?([0-9]+(\\.?[0-9]+)))"; @@ -200,7 +202,7 @@ public String toString() { } /** - * Converts a big decimal into a canonical string representation. A null argument will return null. + * Converts a big decimal into a canonical string representation. A {@literal null} argument will return {@literal null}. * * @param amount * Amount to convert. @@ -227,8 +229,8 @@ public static String amountToStr(final BigDecimal amount) { } /** - * Converts an amount from its canonical string representation back into a big decimal. A null argument will return - * null. + * Converts an amount from its canonical string representation back into a big decimal. A {@literal null} argument will return + * {@literal null}. * * @param amount * Amount string to convert. diff --git a/core/src/main/java/org/fuin/objects4j/core/DayOfTheWeek.java b/core/src/main/java/org/fuin/objects4j/core/DayOfTheWeek.java index 8359e80..008d4e8 100644 --- a/core/src/main/java/org/fuin/objects4j/core/DayOfTheWeek.java +++ b/core/src/main/java/org/fuin/objects4j/core/DayOfTheWeek.java @@ -23,13 +23,14 @@ import org.fuin.objects4j.common.Contract; import org.fuin.objects4j.common.HasPublicStaticIsValidMethod; import org.fuin.objects4j.common.HasPublicStaticValueOfMethod; -import org.fuin.objects4j.common.Immutable; -import org.fuin.objects4j.common.Nullable; +import javax.annotation.concurrent.Immutable; +import jakarta.annotation.Nullable; import org.fuin.objects4j.ui.Label; import org.fuin.objects4j.ui.Prompt; import org.fuin.objects4j.ui.ShortLabel; import org.fuin.objects4j.ui.Tooltip; +import java.io.Serial; import java.io.Serializable; import java.time.DayOfWeek; import java.util.ArrayList; @@ -49,6 +50,7 @@ @HasPublicStaticValueOfMethod(method = "valueOf", param = DayOfWeek.class) public final class DayOfTheWeek implements ValueObjectWithBaseType, Comparable, Serializable, AsStringCapable { + @Serial private static final long serialVersionUID = 1000L; /** Monday. */ diff --git a/core/src/main/java/org/fuin/objects4j/core/DayOpeningHours.java b/core/src/main/java/org/fuin/objects4j/core/DayOpeningHours.java index 712ddc4..64860e2 100644 --- a/core/src/main/java/org/fuin/objects4j/core/DayOpeningHours.java +++ b/core/src/main/java/org/fuin/objects4j/core/DayOpeningHours.java @@ -23,11 +23,12 @@ import org.fuin.objects4j.common.Contract; import org.fuin.objects4j.common.HasPublicStaticIsValidMethod; import org.fuin.objects4j.common.HasPublicStaticValueOfMethod; -import org.fuin.objects4j.common.Immutable; -import org.fuin.objects4j.common.Nullable; +import javax.annotation.concurrent.Immutable; +import jakarta.annotation.Nullable; import org.fuin.objects4j.core.HourRanges.ChangeType; import org.fuin.objects4j.ui.Prompt; +import java.io.Serial; import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -48,6 +49,7 @@ @HasPublicStaticValueOfMethod public final class DayOpeningHours implements ValueObjectWithBaseType, Comparable, Serializable, AsStringCapable { + @Serial private static final long serialVersionUID = 1000L; @NotNull diff --git a/core/src/main/java/org/fuin/objects4j/core/EmailAddress.java b/core/src/main/java/org/fuin/objects4j/core/EmailAddress.java index 2ad5a95..4341173 100644 --- a/core/src/main/java/org/fuin/objects4j/core/EmailAddress.java +++ b/core/src/main/java/org/fuin/objects4j/core/EmailAddress.java @@ -25,11 +25,13 @@ import org.fuin.objects4j.common.Contract; import org.fuin.objects4j.common.HasPublicStaticIsValidMethod; import org.fuin.objects4j.common.HasPublicStaticValueOfMethod; -import org.fuin.objects4j.common.Immutable; +import javax.annotation.concurrent.Immutable; import org.fuin.objects4j.ui.Label; import org.fuin.objects4j.ui.ShortLabel; import org.fuin.objects4j.ui.Tooltip; +import java.io.Serial; + /** * A valid email address with all characters lower case. */ @@ -41,6 +43,7 @@ @HasPublicStaticValueOfMethod public final class EmailAddress extends AbstractStringValueObject { + @Serial private static final long serialVersionUID = 811127657088134517L; @NotNull diff --git a/core/src/main/java/org/fuin/objects4j/core/Hour.java b/core/src/main/java/org/fuin/objects4j/core/Hour.java index efe09a3..93a2f3b 100644 --- a/core/src/main/java/org/fuin/objects4j/core/Hour.java +++ b/core/src/main/java/org/fuin/objects4j/core/Hour.java @@ -23,13 +23,14 @@ import org.fuin.objects4j.common.Contract; import org.fuin.objects4j.common.HasPublicStaticIsValidMethod; import org.fuin.objects4j.common.HasPublicStaticValueOfMethod; -import org.fuin.objects4j.common.Immutable; -import org.fuin.objects4j.common.Nullable; +import javax.annotation.concurrent.Immutable; +import jakarta.annotation.Nullable; import org.fuin.objects4j.ui.Label; import org.fuin.objects4j.ui.Prompt; import org.fuin.objects4j.ui.ShortLabel; import org.fuin.objects4j.ui.Tooltip; +import java.io.Serial; import java.util.regex.Pattern; /** @@ -55,6 +56,7 @@ @HasPublicStaticValueOfMethod public final class Hour extends AbstractStringValueObject { + @Serial private static final long serialVersionUID = 1000L; private static final Pattern PATTERN = Pattern.compile("^([01]\\d|2[0-3]):?([0-5]\\d)|24:00$"); diff --git a/core/src/main/java/org/fuin/objects4j/core/HourRange.java b/core/src/main/java/org/fuin/objects4j/core/HourRange.java index 595ed55..4dac02a 100644 --- a/core/src/main/java/org/fuin/objects4j/core/HourRange.java +++ b/core/src/main/java/org/fuin/objects4j/core/HourRange.java @@ -23,13 +23,14 @@ import org.fuin.objects4j.common.Contract; import org.fuin.objects4j.common.HasPublicStaticIsValidMethod; import org.fuin.objects4j.common.HasPublicStaticValueOfMethod; -import org.fuin.objects4j.common.Immutable; -import org.fuin.objects4j.common.Nullable; +import javax.annotation.concurrent.Immutable; +import jakarta.annotation.Nullable; import org.fuin.objects4j.ui.Label; import org.fuin.objects4j.ui.Prompt; import org.fuin.objects4j.ui.ShortLabel; import org.fuin.objects4j.ui.Tooltip; +import java.io.Serial; import java.util.ArrayList; import java.util.BitSet; import java.util.List; @@ -55,6 +56,7 @@ @HasPublicStaticValueOfMethod public final class HourRange extends AbstractStringValueObject { + @Serial private static final long serialVersionUID = 1000L; @NotNull diff --git a/core/src/main/java/org/fuin/objects4j/core/HourRanges.java b/core/src/main/java/org/fuin/objects4j/core/HourRanges.java index 772222f..6871ea8 100644 --- a/core/src/main/java/org/fuin/objects4j/core/HourRanges.java +++ b/core/src/main/java/org/fuin/objects4j/core/HourRanges.java @@ -23,10 +23,11 @@ import org.fuin.objects4j.common.Contract; import org.fuin.objects4j.common.HasPublicStaticIsValidMethod; import org.fuin.objects4j.common.HasPublicStaticValueOfMethod; -import org.fuin.objects4j.common.Immutable; -import org.fuin.objects4j.common.Nullable; +import javax.annotation.concurrent.Immutable; +import jakarta.annotation.Nullable; import org.fuin.objects4j.ui.Prompt; +import java.io.Serial; import java.util.ArrayList; import java.util.BitSet; import java.util.Collections; @@ -45,6 +46,7 @@ @HasPublicStaticValueOfMethod(method = "valueOf", param = BitSet.class) public final class HourRanges extends AbstractStringValueObject implements Iterable { + @Serial private static final long serialVersionUID = 1000L; @NotEmpty diff --git a/core/src/main/java/org/fuin/objects4j/core/KeyValue.java b/core/src/main/java/org/fuin/objects4j/core/KeyValue.java index 5dceba2..a84d74c 100644 --- a/core/src/main/java/org/fuin/objects4j/core/KeyValue.java +++ b/core/src/main/java/org/fuin/objects4j/core/KeyValue.java @@ -19,7 +19,7 @@ import jakarta.validation.constraints.NotNull; import org.fuin.objects4j.common.Contract; -import org.fuin.objects4j.common.Immutable; +import javax.annotation.concurrent.Immutable; import java.util.Collection; import java.util.HashMap; @@ -96,7 +96,7 @@ public final String getValueString() { * @param message * Message to replace. * @param keyValue - * Array of key values or null. + * Array of key values or {@literal null}. * * @return Replaced message. */ @@ -136,9 +136,9 @@ private static String nullSafeAsString(final Object obj) { * Replaces all variables inside a string with values from a map. * * @param str - * Text with variables (Format: ${key} ) - May be null or empty. + * Text with variables (Format: ${key} ) - May be {@literal null} or empty. * @param vars - * Map with key/values (both of type String - Cannot be null. + * Map with key/values (both of type String - Cannot be {@literal null}. * * @return String with replaced variables. Unknown variables will remain unchanged. */ diff --git a/core/src/main/java/org/fuin/objects4j/core/LocaleStrValidator.java b/core/src/main/java/org/fuin/objects4j/core/LocaleStrValidator.java index cba948b..785d2fc 100644 --- a/core/src/main/java/org/fuin/objects4j/core/LocaleStrValidator.java +++ b/core/src/main/java/org/fuin/objects4j/core/LocaleStrValidator.java @@ -32,6 +32,7 @@ public final class LocaleStrValidator implements ConstraintValidator { + @Serial private static final long serialVersionUID = 1000L; @NotEmpty @@ -135,11 +137,15 @@ public Iterator iterator() { * @return Shortened version. */ public MultiDayOfTheWeek compress() { - if (multipleDayOfTheWeek.size() == 1) { return this; } + return new MultiDayOfTheWeek(optimize()); + + } + @SuppressWarnings("java:S3776") // Complexity OK here + private String optimize() { DayOfTheWeek start = null; final StringBuilder sb = new StringBuilder(); for (int i = 0; i < multipleDayOfTheWeek.size(); i++) { @@ -163,8 +169,7 @@ public MultiDayOfTheWeek compress() { } } } - return new MultiDayOfTheWeek(sb.toString()); - + return sb.toString(); } private String separator(DayOfTheWeek start, final DayOfTheWeek current) { @@ -177,7 +182,7 @@ private String separator(DayOfTheWeek start, final DayOfTheWeek current) { private static String asStr(final List days) { final StringBuilder sb = new StringBuilder(); for (final DayOfTheWeek dow : days) { - if (sb.length() > 0) { + if (!sb.isEmpty()) { sb.append("/"); } sb.append(dow); @@ -193,6 +198,7 @@ private static String asStr(final List days) { * * @return {@literal true} if the string is a valid string, else {@literal false}. */ + @SuppressWarnings("java:S3776") // Complexity not nice, but OK here public static boolean isValid(@Nullable final String multiDayOfTheWeeks) { if (multiDayOfTheWeeks == null) { return true; diff --git a/core/src/main/java/org/fuin/objects4j/core/Password.java b/core/src/main/java/org/fuin/objects4j/core/Password.java index ad09777..b7e3149 100644 --- a/core/src/main/java/org/fuin/objects4j/core/Password.java +++ b/core/src/main/java/org/fuin/objects4j/core/Password.java @@ -19,12 +19,14 @@ import jakarta.validation.constraints.NotNull; import org.fuin.objects4j.common.Contract; -import org.fuin.objects4j.common.Immutable; -import org.fuin.objects4j.common.Nullable; +import javax.annotation.concurrent.Immutable; +import jakarta.annotation.Nullable; import org.fuin.objects4j.ui.Label; import org.fuin.objects4j.ui.ShortLabel; import org.fuin.objects4j.ui.Tooltip; +import java.io.Serial; + /** * A password with a length between 8 and 20 characters. */ @@ -34,6 +36,7 @@ @Tooltip("Secret password") public final class Password extends AbstractStringValueObject { + @Serial private static final long serialVersionUID = -7745110729063955842L; @NotNull diff --git a/core/src/main/java/org/fuin/objects4j/core/PasswordSha512.java b/core/src/main/java/org/fuin/objects4j/core/PasswordSha512.java index ea27726..5b78801 100644 --- a/core/src/main/java/org/fuin/objects4j/core/PasswordSha512.java +++ b/core/src/main/java/org/fuin/objects4j/core/PasswordSha512.java @@ -22,8 +22,8 @@ import org.fuin.objects4j.common.Contract; import org.fuin.objects4j.common.HasPublicStaticIsValidMethod; import org.fuin.objects4j.common.HasPublicStaticValueOfMethod; -import org.fuin.objects4j.common.Immutable; -import org.fuin.objects4j.common.Nullable; +import javax.annotation.concurrent.Immutable; +import jakarta.annotation.Nullable; import java.io.Serial; import java.security.MessageDigest; diff --git a/core/src/main/java/org/fuin/objects4j/core/PasswordSha512StrValidator.java b/core/src/main/java/org/fuin/objects4j/core/PasswordSha512StrValidator.java index ed0de04..4e11afd 100644 --- a/core/src/main/java/org/fuin/objects4j/core/PasswordSha512StrValidator.java +++ b/core/src/main/java/org/fuin/objects4j/core/PasswordSha512StrValidator.java @@ -27,6 +27,7 @@ public final class PasswordSha512StrValidator implements ConstraintValidator 20)) { - return false; - } - return true; + return value.length() >= 8 && value.length() <= 20; } /** diff --git a/core/src/main/java/org/fuin/objects4j/core/SecurityToken.java b/core/src/main/java/org/fuin/objects4j/core/SecurityToken.java index 52dddce..515925c 100644 --- a/core/src/main/java/org/fuin/objects4j/core/SecurityToken.java +++ b/core/src/main/java/org/fuin/objects4j/core/SecurityToken.java @@ -21,7 +21,7 @@ import jakarta.validation.constraints.NotNull; import org.fuin.objects4j.common.HasPublicStaticIsValidMethod; import org.fuin.objects4j.common.HasPublicStaticValueOfMethod; -import org.fuin.objects4j.common.Immutable; +import javax.annotation.concurrent.Immutable; import java.io.Serial; import java.security.MessageDigest; @@ -41,8 +41,6 @@ public final class SecurityToken extends AbstractStringValueObject { @Serial private static final long serialVersionUID = 8737032520847641569L; - private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - private static final Pattern PATTERN = Pattern.compile("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"); private static final SecureRandom SECURE_RANDOM; @@ -57,7 +55,7 @@ public final class SecurityToken extends AbstractStringValueObject { } @NotNull - private String token; + private final String token; /** * Constructor that creates a new random token. diff --git a/core/src/main/java/org/fuin/objects4j/core/TrimmedNotEmpty.java b/core/src/main/java/org/fuin/objects4j/core/TrimmedNotEmpty.java index 29f8945..7b15fca 100644 --- a/core/src/main/java/org/fuin/objects4j/core/TrimmedNotEmpty.java +++ b/core/src/main/java/org/fuin/objects4j/core/TrimmedNotEmpty.java @@ -28,7 +28,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * The string is not null and the trimmed size is at least one. + * The string is not {@literal null} and the trimmed size is at least one. */ // CHECKSTYLE:OFF @Documented diff --git a/core/src/main/java/org/fuin/objects4j/core/TrimmedNotEmptyValidator.java b/core/src/main/java/org/fuin/objects4j/core/TrimmedNotEmptyValidator.java index 9a071c7..028a68c 100644 --- a/core/src/main/java/org/fuin/objects4j/core/TrimmedNotEmptyValidator.java +++ b/core/src/main/java/org/fuin/objects4j/core/TrimmedNotEmptyValidator.java @@ -24,7 +24,7 @@ import org.fuin.objects4j.common.Contract; /** - * Check that a given string is not null and the trimmed length is greater than zero. + * Check that a given string is not {@literal null} and the trimmed length is greater than zero. */ public class TrimmedNotEmptyValidator implements ConstraintValidator { diff --git a/core/src/main/java/org/fuin/objects4j/core/UUIDStrValidator.java b/core/src/main/java/org/fuin/objects4j/core/UUIDStrValidator.java index a55e109..43eb96e 100644 --- a/core/src/main/java/org/fuin/objects4j/core/UUIDStrValidator.java +++ b/core/src/main/java/org/fuin/objects4j/core/UUIDStrValidator.java @@ -31,6 +31,7 @@ public final class UUIDStrValidator implements ConstraintValidator getValueObjectClass(); /** - * Verifies that the given value can be converted into a value object using the factory. A null parameter will return + * Verifies that the given value can be converted into a value object using the factory. A {@literal null} parameter will return * {@literal true}. * * @param value @@ -55,7 +55,7 @@ public interface ValueObjectConverternull parameter will return null. + * Converts the base type into an value object. A {@literal null} parameter will return {@literal null}. * * @param value * Representation of the value object as base type. @@ -65,7 +65,7 @@ public interface ValueObjectConverternull parameter will return null. + * Converts the value object into an base type. A {@literal null} parameter will return {@literal null}. * * @param value * Value object. diff --git a/core/src/main/java/org/fuin/objects4j/core/ValueOfCapable.java b/core/src/main/java/org/fuin/objects4j/core/ValueOfCapable.java index a5269e0..8e63488 100644 --- a/core/src/main/java/org/fuin/objects4j/core/ValueOfCapable.java +++ b/core/src/main/java/org/fuin/objects4j/core/ValueOfCapable.java @@ -31,7 +31,7 @@ public interface ValueOfCapable { * Parses a string and returns the converted type. * * @param value - * Value to convert. A null value returns null. + * Value to convert. A {@literal null} value returns {@literal null}. * * @return Converted value. */ diff --git a/core/src/main/java/org/fuin/objects4j/core/WeeklyOpeningHours.java b/core/src/main/java/org/fuin/objects4j/core/WeeklyOpeningHours.java index 9ec3d93..3e12a2a 100644 --- a/core/src/main/java/org/fuin/objects4j/core/WeeklyOpeningHours.java +++ b/core/src/main/java/org/fuin/objects4j/core/WeeklyOpeningHours.java @@ -23,11 +23,12 @@ import org.fuin.objects4j.common.Contract; import org.fuin.objects4j.common.HasPublicStaticIsValidMethod; import org.fuin.objects4j.common.HasPublicStaticValueOfMethod; -import org.fuin.objects4j.common.Immutable; -import org.fuin.objects4j.common.Nullable; +import javax.annotation.concurrent.Immutable; +import jakarta.annotation.Nullable; import org.fuin.objects4j.core.DayOpeningHours.Change; import org.fuin.objects4j.ui.Prompt; +import java.io.Serial; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -47,27 +48,28 @@ @HasPublicStaticValueOfMethod public final class WeeklyOpeningHours extends AbstractStringValueObject implements Iterable { + @Serial private static final long serialVersionUID = 1000L; @NotEmpty - private final List weeklyOpeningHours; + private final List openingHours; private final String value; /** * Constructor with string. * - * @param weeklyOpeningHours + * @param openingHours * Opening hours like 'Mon-Fri 09:00-12:00+13:00-17:00,Sat/Sun 09:-12:00'. */ - public WeeklyOpeningHours(@NotNull @WeeklyOpeningHoursStr final String weeklyOpeningHours) { + public WeeklyOpeningHours(@NotNull @WeeklyOpeningHoursStr final String openingHours) { super(); - Contract.requireArgNotEmpty("weeklyOpeningHours", weeklyOpeningHours); - requireArgValid("weeklyOpeningHours", weeklyOpeningHours); + Contract.requireArgNotEmpty("weeklyOpeningHours", openingHours); + requireArgValid("weeklyOpeningHours", openingHours); - this.weeklyOpeningHours = new ArrayList<>(); + this.openingHours = new ArrayList<>(); - final StringTokenizer tok = new StringTokenizer(weeklyOpeningHours, ","); + final StringTokenizer tok = new StringTokenizer(openingHours, ","); while (tok.hasMoreTokens()) { final String part = tok.nextToken(); final int p = part.indexOf(' '); @@ -85,8 +87,8 @@ public WeeklyOpeningHours(@NotNull @WeeklyOpeningHoursStr final String weeklyOpe } } - Collections.sort(this.weeklyOpeningHours); - this.value = weeklyOpeningHours.toUpperCase(); + Collections.sort(this.openingHours); + this.value = openingHours.toUpperCase(); } @@ -102,27 +104,27 @@ public WeeklyOpeningHours(@NotEmpty final DayOpeningHours... dayOpeningHours) { if (dayOpeningHours.length == 0) { throw new ConstraintViolationException("The argument 'dayOpeningHours' cannot be an empty array"); } - this.weeklyOpeningHours = new ArrayList<>(); + this.openingHours = new ArrayList<>(); for (final DayOpeningHours doh : dayOpeningHours) { if (doh != null) { - if (this.weeklyOpeningHours.contains(doh)) { + if (this.openingHours.contains(doh)) { throw new ConstraintViolationException("The argument 'dayOpeningHours' cannot contain duplicates: " + doh); } addOrUpdate(doh); } } - Collections.sort(this.weeklyOpeningHours); - this.value = asString(this.weeklyOpeningHours); + Collections.sort(this.openingHours); + this.value = asString(this.openingHours); } private void addOrUpdate(final DayOpeningHours doh) { - final int idx = this.weeklyOpeningHours.indexOf(doh); + final int idx = this.openingHours.indexOf(doh); if (idx < 0) { - this.weeklyOpeningHours.add(doh); + this.openingHours.add(doh); } else { - this.weeklyOpeningHours.set(idx, this.weeklyOpeningHours.get(idx).add(doh)); + this.openingHours.set(idx, this.openingHours.get(idx).add(doh)); } } @@ -142,7 +144,7 @@ public WeeklyOpeningHours normalize() { final List days = new ArrayList<>(); - for (final DayOpeningHours doh : weeklyOpeningHours) { + for (final DayOpeningHours doh : openingHours) { final List normalized = doh.normalize(); for (final DayOpeningHours normalizedDay : normalized) { final int idx = days.indexOf(normalizedDay); @@ -164,7 +166,7 @@ public WeeklyOpeningHours normalize() { @Override public Iterator iterator() { - return Collections.unmodifiableList(weeklyOpeningHours).iterator(); + return Collections.unmodifiableList(openingHours).iterator(); } /** @@ -235,11 +237,11 @@ public List asAddedChanges() { } private DayOpeningHours findDay(final DayOpeningHours toFind) { - final int idx = weeklyOpeningHours.indexOf(toFind); + final int idx = openingHours.indexOf(toFind); if (idx < 0) { return null; } - return weeklyOpeningHours.get(idx); + return openingHours.get(idx); } /** @@ -260,11 +262,11 @@ public final boolean openAt(@NotNull final DayOpeningHours dayOpeningHours) { "The argument 'dayOpeningHours' is expected to have only hours of a single day, but was: " + dayOpeningHours); } - final int idx = weeklyOpeningHours.indexOf(dayOpeningHours); + final int idx = openingHours.indexOf(dayOpeningHours); if (idx < 0) { return false; } - final DayOpeningHours found = weeklyOpeningHours.get(idx); + final DayOpeningHours found = openingHours.get(idx); final List normalized = found.normalize(); final DayOpeningHours day = normalized.get(0); @@ -296,26 +298,22 @@ public boolean isSimilarTo(final WeeklyOpeningHours other) { public final WeeklyOpeningHours compress() { final Map> map = new HashMap<>(); - for (final DayOpeningHours doh : weeklyOpeningHours) { + for (final DayOpeningHours doh : openingHours) { final HourRanges ranges = doh.getHourRanges().compress(); - List dayList = map.get(ranges); - if (dayList == null) { - dayList = new ArrayList<>(); - map.put(ranges, dayList); - } + List dayList = map.computeIfAbsent(ranges, k -> new ArrayList<>()); dayList.add(doh.getDayOfTheWeek()); } final StringBuilder sb = new StringBuilder(); - final Iterator it = map.keySet().iterator(); - while (it.hasNext()) { - final HourRanges ranges = it.next(); - final List days = map.get(ranges); + for (final Map.Entry> entry : map.entrySet()) { + final List days = entry.getValue(); Collections.sort(days); - if (sb.length() > 0) { + if (!sb.isEmpty()) { sb.append(","); } - sb.append(new MultiDayOfTheWeek(days.toArray(new DayOfTheWeek[days.size()])).compress().asBaseType() + " " + ranges); + sb.append(new MultiDayOfTheWeek(days.toArray(new DayOfTheWeek[0])).compress().asBaseType()) + .append(" ") + .append(entry.getKey()); } return new WeeklyOpeningHours(sb.toString()); @@ -330,7 +328,7 @@ public final String toString() { private static String asString(final List weeklyOpeningHours) { final StringBuilder sb = new StringBuilder(); for (final DayOpeningHours dow : weeklyOpeningHours) { - if (sb.length() > 0) { + if (!sb.isEmpty()) { sb.append(","); } sb.append(dow.toString()); @@ -346,6 +344,7 @@ private static String asString(final List weeklyOpeningHours) { * * @return {@literal true} if the string is a valid string, else {@literal false}. */ + @SuppressWarnings("java:S3776") // Complexity not nice, but OK here public static boolean isValid(@Nullable final String weeklyOpeningHours) { if (weeklyOpeningHours == null) { return true; diff --git a/core/src/test/java/org/fuin/objects4j/core/AbstractIntegerValueObjectTest.java b/core/src/test/java/org/fuin/objects4j/core/AbstractIntegerValueObjectTest.java index 95d2858..4b89d53 100644 --- a/core/src/test/java/org/fuin/objects4j/core/AbstractIntegerValueObjectTest.java +++ b/core/src/test/java/org/fuin/objects4j/core/AbstractIntegerValueObjectTest.java @@ -21,6 +21,8 @@ import nl.jqno.equalsverifier.Warning; import org.junit.jupiter.api.Test; +import java.io.Serial; + //CHECKSTYLE:OFF public class AbstractIntegerValueObjectTest { @@ -34,6 +36,7 @@ void testEqualsHashCode() { /** Implementation for tests. */ public static final class TestIntegerVO extends AbstractIntegerValueObject { + @Serial private static final long serialVersionUID = 1L; private final Integer value; diff --git a/core/src/test/java/org/fuin/objects4j/core/AbstractLongValueObjectTest.java b/core/src/test/java/org/fuin/objects4j/core/AbstractLongValueObjectTest.java index 4be1ea2..7b07cae 100644 --- a/core/src/test/java/org/fuin/objects4j/core/AbstractLongValueObjectTest.java +++ b/core/src/test/java/org/fuin/objects4j/core/AbstractLongValueObjectTest.java @@ -21,6 +21,8 @@ import nl.jqno.equalsverifier.Warning; import org.junit.jupiter.api.Test; +import java.io.Serial; + //CHECKSTYLE:OFF public class AbstractLongValueObjectTest { @@ -35,6 +37,7 @@ void testEqualsHashCode() { /** Implementation for tests. */ public static final class TestLongVO extends AbstractLongValueObject { + @Serial private static final long serialVersionUID = 1L; private final Long value; diff --git a/core/src/test/java/org/fuin/objects4j/core/AbstractStringValueObjectTest.java b/core/src/test/java/org/fuin/objects4j/core/AbstractStringValueObjectTest.java index 19695ee..bd8d9c5 100644 --- a/core/src/test/java/org/fuin/objects4j/core/AbstractStringValueObjectTest.java +++ b/core/src/test/java/org/fuin/objects4j/core/AbstractStringValueObjectTest.java @@ -21,6 +21,8 @@ import nl.jqno.equalsverifier.Warning; import org.junit.jupiter.api.Test; +import java.io.Serial; + //CHECKSTYLE:OFF public class AbstractStringValueObjectTest { @@ -35,6 +37,7 @@ void testEqualsHashCode() { /** Implementation for tests. */ public static final class TestStringVO extends AbstractStringValueObject { + @Serial private static final long serialVersionUID = 1L; private final String value; diff --git a/core/src/test/java/org/fuin/objects4j/core/AbstractUuidValueObjectTest.java b/core/src/test/java/org/fuin/objects4j/core/AbstractUuidValueObjectTest.java index aa90476..6d23029 100644 --- a/core/src/test/java/org/fuin/objects4j/core/AbstractUuidValueObjectTest.java +++ b/core/src/test/java/org/fuin/objects4j/core/AbstractUuidValueObjectTest.java @@ -21,6 +21,7 @@ import nl.jqno.equalsverifier.Warning; import org.junit.jupiter.api.Test; +import java.io.Serial; import java.util.UUID; //CHECKSTYLE:OFF @@ -37,6 +38,7 @@ void testEqualsHashCode() { /** Implementation for tests. */ public static final class TestStringVO extends AbstractUuidValueObject { + @Serial private static final long serialVersionUID = 1L; private final UUID value; diff --git a/core/src/test/java/org/fuin/objects4j/core/AnyStr.java b/core/src/test/java/org/fuin/objects4j/core/AnyStr.java index 3a59783..26f14b4 100644 --- a/core/src/test/java/org/fuin/objects4j/core/AnyStr.java +++ b/core/src/test/java/org/fuin/objects4j/core/AnyStr.java @@ -3,15 +3,18 @@ import com.tngtech.archunit.junit.ArchIgnore; import org.fuin.objects4j.common.Contract; +import java.io.Serial; + /** * Test implementation for a {@link AbstractStringValueObject}. */ @ArchIgnore public final class AnyStr extends AbstractStringValueObject { + @Serial private static final long serialVersionUID = 1L; - private String str; + private final String str; /** * Constructor with manadatory data. diff --git a/core/src/test/java/org/fuin/objects4j/core/DayOfTheWeekTest.java b/core/src/test/java/org/fuin/objects4j/core/DayOfTheWeekTest.java index 875ef95..f5982e4 100644 --- a/core/src/test/java/org/fuin/objects4j/core/DayOfTheWeekTest.java +++ b/core/src/test/java/org/fuin/objects4j/core/DayOfTheWeekTest.java @@ -1,17 +1,17 @@ /** * Copyright (C) 2013 Future Invent Informationsmanagement GmbH. All rights * reserved. - * + *

* This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) any * later version. - * + *

* This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. - * + *

* You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ @@ -136,8 +136,8 @@ void testFollows() { DayOfTheWeek last = null; for (final DayOfTheWeek dow : DayOfTheWeek.getAll()) { - if (last != null) { - assertThat(dow.follows(last)); + if (last != null && dow != DayOfTheWeek.PH) { + assertThat(dow.follows(last)).describedAs("Expected that " + dow + " follows on " + last + ", but did not").isTrue(); } assertThat(DayOfTheWeek.PH.follows(dow)).isFalse(); assertThat(dow.follows(dow)).isFalse(); @@ -157,7 +157,7 @@ void testAfter() { for (final DayOfTheWeek dow : DayOfTheWeek.getAll()) { if (current != null) { for (final DayOfTheWeek dow2 : DayOfTheWeek.getPart(dow, DayOfTheWeek.SUN)) { - assertThat(dow2.after(current)); + assertThat(dow2.after(current)).describedAs("Expected that " + dow2 + " is after " + current + ", but was not").isTrue(); } } current = dow; diff --git a/jaxb/src/main/java/org/fuin/objects4j/jaxb/CurrencyConverter.java b/jaxb/src/main/java/org/fuin/objects4j/jaxb/CurrencyConverter.java index ec65eb7..222e7fe 100644 --- a/jaxb/src/main/java/org/fuin/objects4j/jaxb/CurrencyConverter.java +++ b/jaxb/src/main/java/org/fuin/objects4j/jaxb/CurrencyConverter.java @@ -30,7 +30,7 @@ public final class CurrencyConverter extends XmlAdapter { /** - * Verifies that the given value can be converted into a value object using the factory. A null parameter will return + * Verifies that the given value can be converted into a value object using the factory. A {@literal null} parameter will return * {@literal true}. * * @param value Value to check. @@ -41,7 +41,7 @@ public final boolean isValid(final String value) { } /** - * Converts the base type into an value object. A null parameter will return null. + * Converts the base type into an value object. A {@literal null} parameter will return {@literal null}. * * @param value Representation of the value object as base type. * @return Value object. @@ -54,7 +54,7 @@ public final Currency toVO(final String value) { } /** - * Converts the value object into an base type. A null parameter will return null. + * Converts the value object into an base type. A {@literal null} parameter will return {@literal null}. * * @param value Value object. * @return Base type. diff --git a/jsonb/src/test/java/org/fuin/objects4j/jsonb/AnyStr.java b/jsonb/src/test/java/org/fuin/objects4j/jsonb/AnyStr.java index 86bac49..50ecc15 100644 --- a/jsonb/src/test/java/org/fuin/objects4j/jsonb/AnyStr.java +++ b/jsonb/src/test/java/org/fuin/objects4j/jsonb/AnyStr.java @@ -4,12 +4,15 @@ import org.fuin.objects4j.common.Contract; import org.fuin.objects4j.core.AbstractStringValueObject; +import java.io.Serial; + /** * Test implementation for a {@link AbstractStringValueObject}. */ @ArchIgnore public final class AnyStr extends AbstractStringValueObject { + @Serial private static final long serialVersionUID = 1L; private String str; diff --git a/junit/src/main/java/org/fuin/objects4j/junit/HasPublicStaticIsValidMethodCondition.java b/junit/src/main/java/org/fuin/objects4j/junit/HasPublicStaticIsValidMethodCondition.java index f4beae4..876e55a 100644 --- a/junit/src/main/java/org/fuin/objects4j/junit/HasPublicStaticIsValidMethodCondition.java +++ b/junit/src/main/java/org/fuin/objects4j/junit/HasPublicStaticIsValidMethodCondition.java @@ -14,6 +14,10 @@ import static com.tngtech.archunit.lang.ConditionEvent.createMessage; +/** + * Verifies if a class has a public static "isValid" method that matches the conditions defined + * with the annotation {@link HasPublicStaticIsValidMethods} attached to that class. + */ public final class HasPublicStaticIsValidMethodCondition extends ArchCondition { private final HasPublicStaticIsValidMethodValidator validator; diff --git a/junit/src/main/java/org/fuin/objects4j/junit/HasPublicStaticValueOfMethodCondition.java b/junit/src/main/java/org/fuin/objects4j/junit/HasPublicStaticValueOfMethodCondition.java index 7936bac..2d00029 100644 --- a/junit/src/main/java/org/fuin/objects4j/junit/HasPublicStaticValueOfMethodCondition.java +++ b/junit/src/main/java/org/fuin/objects4j/junit/HasPublicStaticValueOfMethodCondition.java @@ -7,20 +7,20 @@ import com.tngtech.archunit.lang.ConditionEvents; import com.tngtech.archunit.lang.SimpleConditionEvent; import org.fuin.objects4j.common.HasPublicStaticValueOfMethod; -import org.fuin.objects4j.common.HasPublicStaticValueOfMethodValidator; import org.fuin.objects4j.common.HasPublicStaticValueOfMethods; import java.util.Optional; import static com.tngtech.archunit.lang.ConditionEvent.createMessage; +/** + * Verifies if a class has a public static "valueOf" method that matches the conditions defined + * with the annotation {@link HasPublicStaticValueOfMethods} attached to that class. + */ public final class HasPublicStaticValueOfMethodCondition extends ArchCondition { - private final HasPublicStaticValueOfMethodValidator validator; - public HasPublicStaticValueOfMethodCondition() { super("have a public static 'value of' method with the signature defined by the annotation"); - validator = new HasPublicStaticValueOfMethodValidator(); } @Override diff --git a/pom.xml b/pom.xml index 9b61e51..ad6149f 100644 --- a/pom.xml +++ b/pom.xml @@ -271,6 +271,12 @@ 2.0.1 + + com.google.code.findbugs + jsr305 + 3.0.2 + + diff --git a/ui/pom.xml b/ui/pom.xml index 157b71d..e78fc0b 100644 --- a/ui/pom.xml +++ b/ui/pom.xml @@ -32,6 +32,11 @@ jakarta.validation-api + + com.google.code.findbugs + jsr305 + + diff --git a/ui/src/main/java/org/fuin/objects4j/ui/AnnotationAnalyzer.java b/ui/src/main/java/org/fuin/objects4j/ui/AnnotationAnalyzer.java index eb6da96..d6ff303 100644 --- a/ui/src/main/java/org/fuin/objects4j/ui/AnnotationAnalyzer.java +++ b/ui/src/main/java/org/fuin/objects4j/ui/AnnotationAnalyzer.java @@ -63,7 +63,7 @@ public final class AnnotationAnalyzer { * @param annotationClasz * Type of annotation to find. * - * @return Label information - Never null. + * @return Label information - Never {@literal null}. */ public final ClassTextInfo createClassInfo(@NotNull final Class clasz, @NotNull final Locale locale, @NotNull final Class annotationClasz) { @@ -101,7 +101,7 @@ public final ClassTextInfo createClassInfo(@NotNull final Class clasz, @NotNu * @param annotationClasz * Type of annotation to find. * - * @return List of informations - Never null, but may be empty. + * @return List of informations - Never {@literal null}, but may be empty. */ public final List createFieldInfos(@NotNull final Class clasz, @NotNull final Locale locale, @NotNull final Class annotationClasz) { @@ -146,7 +146,7 @@ public final List createFieldInfos(@NotNull final Class clasz, * @param annotationClasz * Type of annotation to find. * - * @return Label information - May be null in case the annotation was not found. + * @return Label information - May be {@literal null} in case the annotation was not found. */ public final FieldTextInfo createFieldInfo(@NotNull final Field field, @NotNull final Locale locale, @NotNull final Class annotationClasz) { @@ -172,7 +172,7 @@ public final FieldTextInfo createFieldInfo(@NotNull final Field field, @NotNull /** * Returns the text for the annotation. If no entry is found in the resource bundle for Annotation#key() then - * Annotation#value() will be returned instead. If Annotation#value() is also empty then null is + * Annotation#value() will be returned instead. If Annotation#value() is also empty then {@literal null} is * returned. If Annotation#key() is empty defaultKey will be used as key in the properties file. * * @param bundle @@ -182,7 +182,7 @@ public final FieldTextInfo createFieldInfo(@NotNull final Field field, @NotNull * @param defaultKey * Default key if Annotation#key() is empty. * - * @return Text or null. + * @return Text or {@literal null}. */ private String getText(@NotNull final ResourceBundle bundle, @NotNull final Annotation annotation, @NotNull final String defaultKey) { @@ -217,7 +217,7 @@ private String getText(@NotNull final ResourceBundle bundle, @NotNull final Anno * Class to use if the Annotation#bundle() is empty. Example: a.b.c.MyClass is used as * a/b/c/MyClass.properties (default) or a/b/c/MyClass_en.properties (with {@link Locale#ENGLISH}). * - * @return Resource bundle - Never null. + * @return Resource bundle - Never {@literal null}. */ private ResourceBundle getResourceBundle(@NotNull final Annotation annotation, @NotNull final Locale locale, @NotNull final Class clasz) { @@ -232,12 +232,12 @@ private ResourceBundle getResourceBundle(@NotNull final Annotation annotation, @ } /** - * Returns null if the argument is an empty string. + * Returns {@literal null} if the argument is an empty string. * * @param value * Argument to check. * - * @return Argument or null. + * @return Argument or {@literal null}. */ private final String toNullableString(final String value) { if (value.equals("")) { @@ -262,9 +262,9 @@ private String getKey(final Annotation annotation) { * Calls a method with no arguments using reflection and maps all errors into a runtime exception. * * @param obj - * The object the underlying method is invoked from - Cannot be null. + * The object the underlying method is invoked from - Cannot be {@literal null}. * @param methodName - * Name of the Method - Cannot be null. + * Name of the Method - Cannot be {@literal null}. * * @return The result of dispatching the method represented by this object on obj with parameters args. * @@ -280,13 +280,13 @@ private static T invoke(final Object obj, final String methodName) { * Calls a method with reflection and maps all errors into a runtime exception. * * @param obj - * The object the underlying method is invoked from - Cannot be null. + * The object the underlying method is invoked from - Cannot be {@literal null}. * @param methodName - * Name of the Method - Cannot be null or empty. + * Name of the Method - Cannot be {@literal null} or empty. * @param argTypes - * The list of parameters - May be null. + * The list of parameters - May be {@literal null}. * @param args - * Arguments the arguments used for the method call - May be null if "argTypes" is also null. + * Arguments the arguments used for the method call - May be {@literal null} if "argTypes" is also {@literal null}. * * @return The result of dispatching the method represented by this object on obj with parameters args. */ @@ -352,11 +352,11 @@ private static void checkSameLength(final Class[] argTypes, final Object[] ar * Creates a textual representation of the method. * * @param returnType - * Return type of the method - Cannot be null. + * Return type of the method - Cannot be {@literal null}. * @param methodName - * Name of the method - Cannot be null. + * Name of the method - Cannot be {@literal null}. * @param argTypes - * The list of parameters - Can be null. + * The list of parameters - Can be {@literal null}. * * @return Textual signature of the method. */ diff --git a/ui/src/main/java/org/fuin/objects4j/ui/ClassTextInfo.java b/ui/src/main/java/org/fuin/objects4j/ui/ClassTextInfo.java index 654881a..ed83da2 100644 --- a/ui/src/main/java/org/fuin/objects4j/ui/ClassTextInfo.java +++ b/ui/src/main/java/org/fuin/objects4j/ui/ClassTextInfo.java @@ -19,7 +19,7 @@ import jakarta.validation.constraints.NotNull; import org.fuin.objects4j.common.Contract; -import org.fuin.objects4j.common.Immutable; +import javax.annotation.concurrent.Immutable; /** * Stores some text associated with a class. @@ -35,7 +35,7 @@ public final class ClassTextInfo extends TextInfo { * @param clasz * Class the text belongs to. * @param text - * Text or null. + * Text or {@literal null}. */ public ClassTextInfo(@NotNull final Class clasz, final String text) { super(text); @@ -46,7 +46,7 @@ public ClassTextInfo(@NotNull final Class clasz, final String text) { /** * Returns the class the text belongs to. * - * @return Class - Never null. + * @return Class - Never {@literal null}. */ public final Class getClasz() { return clasz; diff --git a/ui/src/main/java/org/fuin/objects4j/ui/FieldTextInfo.java b/ui/src/main/java/org/fuin/objects4j/ui/FieldTextInfo.java index b4d12f8..8e350e5 100644 --- a/ui/src/main/java/org/fuin/objects4j/ui/FieldTextInfo.java +++ b/ui/src/main/java/org/fuin/objects4j/ui/FieldTextInfo.java @@ -46,16 +46,16 @@ public FieldTextInfo(@NotNull final Field field, final String text) { /** * Returns the field. * - * @return Field - Never null. + * @return Field - Never {@literal null}. */ public final Field getField() { return field; } /** - * Returns the text of the label or the name of the field if the text is null. + * Returns the text of the label or the name of the field if the text is {@literal null}. * - * @return Long text or field name - Never null. + * @return Long text or field name - Never {@literal null}. */ public final String getTextOrField() { final String text = getText(); diff --git a/ui/src/main/java/org/fuin/objects4j/ui/FontSize.java b/ui/src/main/java/org/fuin/objects4j/ui/FontSize.java index ebda004..0eabd41 100644 --- a/ui/src/main/java/org/fuin/objects4j/ui/FontSize.java +++ b/ui/src/main/java/org/fuin/objects4j/ui/FontSize.java @@ -19,8 +19,9 @@ import jakarta.validation.constraints.NotNull; import org.fuin.objects4j.common.Contract; -import org.fuin.objects4j.common.Immutable; +import javax.annotation.concurrent.Immutable; +import java.io.Serial; import java.io.Serializable; import java.text.DecimalFormat; @@ -30,6 +31,7 @@ @Immutable public final class FontSize implements Serializable { + @Serial private static final long serialVersionUID = -1572749922357083439L; private final float size; diff --git a/ui/src/main/java/org/fuin/objects4j/ui/TableColumnInfo.java b/ui/src/main/java/org/fuin/objects4j/ui/TableColumnInfo.java index 58ac0bc..a5d34c5 100644 --- a/ui/src/main/java/org/fuin/objects4j/ui/TableColumnInfo.java +++ b/ui/src/main/java/org/fuin/objects4j/ui/TableColumnInfo.java @@ -20,7 +20,7 @@ import jakarta.annotation.Nullable; import jakarta.validation.constraints.NotNull; import org.fuin.objects4j.common.Contract; -import org.fuin.objects4j.common.Immutable; +import javax.annotation.concurrent.Immutable; import java.lang.reflect.Field; import java.util.ArrayList; @@ -107,7 +107,7 @@ public TableColumnInfo(@NotNull final Field field, @Nullable final String text, /** * Returns the field. * - * @return Field - Never null. + * @return Field - Never {@literal null}. */ public final Field getField() { return field; @@ -161,7 +161,7 @@ public final int getPos() { /** * The name of the getter for the table column field. * - * @return Getter name - Never null. + * @return Getter name - Never {@literal null}. */ public final String getGetter() { return getter; @@ -235,7 +235,7 @@ public static List create(@NotNull final Class clasz, @NotNu * @param locale * Locale to use. * - * @return Information or null. + * @return Information or {@literal null}. */ public static TableColumnInfo create(@NotNull final Field field, @NotNull final Locale locale) { diff --git a/ui/src/main/java/org/fuin/objects4j/ui/TextFieldInfo.java b/ui/src/main/java/org/fuin/objects4j/ui/TextFieldInfo.java index b2b08c1..38a9912 100644 --- a/ui/src/main/java/org/fuin/objects4j/ui/TextFieldInfo.java +++ b/ui/src/main/java/org/fuin/objects4j/ui/TextFieldInfo.java @@ -19,7 +19,7 @@ import jakarta.validation.constraints.NotNull; import org.fuin.objects4j.common.Contract; -import org.fuin.objects4j.common.Immutable; +import javax.annotation.concurrent.Immutable; import java.lang.reflect.Field; import java.util.Locale; @@ -55,7 +55,7 @@ public TextFieldInfo(@NotNull final Field field, final int width) { /** * Returns the field. * - * @return Field - Never null + * @return Field - Never {@literal null} */ public final Field getField() { return field; @@ -101,7 +101,7 @@ public final boolean equals(final Object obj) { * @param locale * Locale to use. * - * @return Information or null. + * @return Information or {@literal null}. */ public static TextFieldInfo create(@NotNull final Field field, @NotNull final Locale locale) { diff --git a/ui/src/main/java/org/fuin/objects4j/ui/TextInfo.java b/ui/src/main/java/org/fuin/objects4j/ui/TextInfo.java index 5745bb5..df362d5 100644 --- a/ui/src/main/java/org/fuin/objects4j/ui/TextInfo.java +++ b/ui/src/main/java/org/fuin/objects4j/ui/TextInfo.java @@ -17,7 +17,7 @@ */ package org.fuin.objects4j.ui; -import org.fuin.objects4j.common.Immutable; +import javax.annotation.concurrent.Immutable; /** * Stores some text. @@ -31,7 +31,7 @@ public abstract class TextInfo { * Constructor with text. * * @param text - * Text or null. + * Text or {@literal null}. */ public TextInfo(final String text) { super(); @@ -41,7 +41,7 @@ public TextInfo(final String text) { /** * Returns the text. * - * @return Text or null. + * @return Text or {@literal null}. */ public final String getText() { return text;