From 1e7bcde4a4aa5dd60379004aaae2fac158879690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20B=C3=BCnger?= Date: Wed, 27 Nov 2024 20:25:49 +0100 Subject: [PATCH] General coding rule to detect usages of old time and date classes (#1384 / #1385) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With this commit new general rules are added which detect the usages of old time and date classes, e.g. java.util.Date. closes #1384 > Developer's Certificate of Origin 1.1 > > By making a contribution to this project, I certify that: > > (a) The contribution was created in whole or in part by me and I > have the right to submit it under the open source license > indicated in the file; or > > (b) The contribution is based upon previous work that, to the best > of my knowledge, is covered under an appropriate open source > license and I have the right under that license to submit that > work with modifications, whether created in whole or in part > by me, under the same open source license (unless I am > permitted to submit under a different license), as indicated > in the file; or > > (c) The contribution was provided directly to me by some other > person who certified (a), (b) or (c) and I have not modified > it. > > (d) I understand and agree that this project and the contribution > are public and that a record of the contribution (including all > personal information I submit with it, including my sign-off) is > maintained indefinitely and may be redistributed consistent with > this project or the open source license(s) involved. Signed-off-by: Matthias Bünger --- .../archunit/library/GeneralCodingRules.java | 14 ++++++ .../library/GeneralCodingRulesTest.java | 46 +++++++++++++++++++ .../timeapi/incorrect/UsesJavaSqlDate.java | 10 ++++ .../timeapi/incorrect/UsesJavaSqlTime.java | 10 ++++ .../incorrect/UsesJavaSqlTimestamp.java | 10 ++++ .../incorrect/UsesJavaUtilCalender.java | 10 ++++ .../timeapi/incorrect/UsesJavaUtilDate.java | 11 +++++ 7 files changed, 111 insertions(+) create mode 100644 archunit/src/test/java/com/tngtech/archunit/library/testclasses/timeapi/incorrect/UsesJavaSqlDate.java create mode 100644 archunit/src/test/java/com/tngtech/archunit/library/testclasses/timeapi/incorrect/UsesJavaSqlTime.java create mode 100644 archunit/src/test/java/com/tngtech/archunit/library/testclasses/timeapi/incorrect/UsesJavaSqlTimestamp.java create mode 100644 archunit/src/test/java/com/tngtech/archunit/library/testclasses/timeapi/incorrect/UsesJavaUtilCalender.java create mode 100644 archunit/src/test/java/com/tngtech/archunit/library/testclasses/timeapi/incorrect/UsesJavaUtilDate.java diff --git a/archunit/src/main/java/com/tngtech/archunit/library/GeneralCodingRules.java b/archunit/src/main/java/com/tngtech/archunit/library/GeneralCodingRules.java index 03af68e14e..52a4b02ada 100644 --- a/archunit/src/main/java/com/tngtech/archunit/library/GeneralCodingRules.java +++ b/archunit/src/main/java/com/tngtech/archunit/library/GeneralCodingRules.java @@ -509,4 +509,18 @@ public void check(JavaClass implementationClass, ConditionEvents events) { .should(accessTargetWhere(JavaAccess.Predicates.target(annotatedWith(Deprecated.class))).as("access @Deprecated members")) .orShould(dependOnClassesThat(annotatedWith(Deprecated.class)).as("depend on @Deprecated classes")) .because("there should be a better alternative"); + + /** + * A rule checking that no classes uses old date and time classes and point out to use the Java 8 time API. + */ + @PublicAPI(usage = ACCESS) + public static final ArchRule OLD_DATE_AND_TIME_CLASSES_SHOULD_NOT_BE_USED = + noClasses() + .should().dependOnClassesThat().haveFullyQualifiedName("java.sql.Date") + .orShould().dependOnClassesThat().haveFullyQualifiedName("java.sql.Time") + .orShould().dependOnClassesThat().haveFullyQualifiedName("java.sql.Timestamp") + .orShould().dependOnClassesThat().haveFullyQualifiedName("java.util.Calendar") + .orShould().dependOnClassesThat().haveFullyQualifiedName("java.util.Date") + .as("since Java 8 (and JavaEE 7 if JPA is needed) java.time-API should be used.") + .because("since Java 8 (and JavaEE 7 if JPA is needed) java.time-API should be used."); } diff --git a/archunit/src/test/java/com/tngtech/archunit/library/GeneralCodingRulesTest.java b/archunit/src/test/java/com/tngtech/archunit/library/GeneralCodingRulesTest.java index 22ef0e6bf0..55853951ac 100644 --- a/archunit/src/test/java/com/tngtech/archunit/library/GeneralCodingRulesTest.java +++ b/archunit/src/test/java/com/tngtech/archunit/library/GeneralCodingRulesTest.java @@ -10,11 +10,17 @@ import com.tngtech.archunit.library.testclasses.packages.incorrect.wrongsubdir.customsuffix.subdir.ImplementationClassWithWrongTestClassPackageCustomSuffixTestingScenario; import com.tngtech.archunit.library.testclasses.packages.incorrect.wrongsubdir.defaultsuffix.ImplementationClassWithWrongTestClassPackage; import com.tngtech.archunit.library.testclasses.packages.incorrect.wrongsubdir.defaultsuffix.subdir.ImplementationClassWithWrongTestClassPackageTest; +import com.tngtech.archunit.library.testclasses.timeapi.incorrect.UsesJavaSqlDate; +import com.tngtech.archunit.library.testclasses.timeapi.incorrect.UsesJavaSqlTime; +import com.tngtech.archunit.library.testclasses.timeapi.incorrect.UsesJavaSqlTimestamp; +import com.tngtech.archunit.library.testclasses.timeapi.incorrect.UsesJavaUtilCalender; +import com.tngtech.archunit.library.testclasses.timeapi.incorrect.UsesJavaUtilDate; import org.junit.Test; import static com.tngtech.archunit.core.domain.JavaConstructor.CONSTRUCTOR_NAME; import static com.tngtech.archunit.library.GeneralCodingRules.ASSERTIONS_SHOULD_HAVE_DETAIL_MESSAGE; import static com.tngtech.archunit.library.GeneralCodingRules.DEPRECATED_API_SHOULD_NOT_BE_USED; +import static com.tngtech.archunit.library.GeneralCodingRules.OLD_DATE_AND_TIME_CLASSES_SHOULD_NOT_BE_USED; import static com.tngtech.archunit.library.GeneralCodingRules.testClassesShouldResideInTheSamePackageAsImplementation; import static com.tngtech.archunit.testutil.Assertions.assertThatRule; @@ -180,4 +186,44 @@ void origin() { @SuppressWarnings("DeprecatedIsStillUsed") private @interface DeprecatedAnnotation { } + + @Test + public void OLD_DATE_AND_TIME_CLASSES_SHOULD_NOT_BE_USED_should_fail_when_class_uses_java_util_date() { + assertThatRule(OLD_DATE_AND_TIME_CLASSES_SHOULD_NOT_BE_USED) + .hasDescriptionContaining("since Java 8 (and JavaEE 7 if JPA is needed) java.time-API should be used.") + .checking(new ClassFileImporter().importClasses(UsesJavaUtilDate.class)) + .hasViolationContaining("calls method