Skip to content

Commit 6d93916

Browse files
authored
Merge pull request #3 from societe-generale/master
New rule added : no java util date (#5)
2 parents 78291b7 + fb6183b commit 6d93916

7 files changed

Lines changed: 199 additions & 43 deletions

File tree

pom.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@
2323
<name>Vincent Fuchs</name>
2424
<email>vincent.fuchs@gmail.com</email>
2525
</developer>
26+
27+
<developer>
28+
<id>FanJups</id>
29+
<name>Fanon Jupkwo</name>
30+
<email>jupsfan@gmail.com</email>
31+
</developer>
32+
2633
</developers>
2734

2835
<licenses>
@@ -256,6 +263,8 @@
256263
<artifactId>coveralls-maven-plugin</artifactId>
257264
<version>4.3.0</version>
258265
</plugin>
266+
267+
259268
</plugins>
260269
</build>
261270

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.societegenerale.commons.plugin.rules;
2+
3+
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
4+
5+
import com.societegenerale.commons.plugin.utils.ArchUtils;
6+
import com.tngtech.archunit.core.domain.JavaClass;
7+
import com.tngtech.archunit.core.domain.JavaField;
8+
import com.tngtech.archunit.lang.ArchCondition;
9+
import com.tngtech.archunit.lang.ConditionEvents;
10+
import com.tngtech.archunit.lang.SimpleConditionEvent;
11+
12+
/**
13+
* java.util.Date is deprecated but a lot of people still use it out of years of
14+
* habit. This rule will catch such instances and remind developers they should
15+
* use alternatives (java.time, java.util.GregorianCalendar ,
16+
* java.text.DateFormat (and its subclasses) to parse and format dates) because
17+
* they support internationalization better
18+
*
19+
*
20+
*
21+
* @see <a href=
22+
* "https://www.math.uni-hamburg.de/doc/java/tutorial/post1.0/converting/deprecated.html">java.util.Date
23+
* is deprecated</a> : <i>developers can use other libraries : java.time,
24+
* java.util.GregorianCalendar ; java.text.DateFormat ; ... </i>
25+
*
26+
* @see <a href=
27+
* "https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html">Java
28+
* 8 Time Oracle</a>
29+
*/
30+
31+
public class NoJavaUtilDateRuleTest implements ArchRuleTest {
32+
33+
private static final String JAVA_UTIL_DATE_PACKAGE_PREFIX = "java.util.Date";
34+
35+
protected static final String NO_JAVA_UTIL_DATE_VIOLATION_MESSAGE = "Use Java8 java.time or java.util.GregorianCalendar or java.text.DateFormat to parse and format dates instead of java.util.Date library because they support internationalization better";
36+
37+
@Override
38+
public void execute(String path) {
39+
classes().should(notUseJavaUtilDate()).check(ArchUtils.importAllClassesInPackage(path, SRC_CLASSES_FOLDER));
40+
}
41+
42+
protected static ArchCondition<JavaClass> notUseJavaUtilDate() {
43+
44+
return new ArchCondition<JavaClass>("not use Java Util Date ") {
45+
@Override
46+
public void check(JavaClass item, ConditionEvents events) {
47+
48+
item.getAllFields().stream().filter(field -> isJavaUtilDateField(field)).forEach(field -> {
49+
events.add(SimpleConditionEvent.violated(field,
50+
NO_JAVA_UTIL_DATE_VIOLATION_MESSAGE + " - class: " + field.getOwner().getName()));
51+
});
52+
53+
}
54+
55+
private boolean isJavaUtilDateField(JavaField field) {
56+
return field.getRawType().getName().startsWith(JAVA_UTIL_DATE_PACKAGE_PREFIX);
57+
}
58+
59+
};
60+
}
61+
62+
}
Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,55 @@
11
package com.societegenerale.commons.plugin.rules;
22

3-
import com.societegenerale.commons.plugin.utils.ArchUtils;
4-
import com.tngtech.archunit.core.domain.JavaClass;
5-
import com.tngtech.archunit.core.domain.JavaClasses;
6-
import org.junit.Assert;
7-
import org.junit.Test;
3+
import static org.assertj.core.api.Assertions.assertThat;
84

95
import java.lang.reflect.Constructor;
106
import java.lang.reflect.InvocationTargetException;
117

12-
import static org.assertj.core.api.Assertions.assertThat;
8+
import org.junit.Assert;
9+
import org.junit.Test;
1310

14-
public class ArchUtilsTest {
11+
import com.societegenerale.commons.plugin.utils.ArchUtils;
12+
import com.tngtech.archunit.core.domain.JavaClass;
13+
import com.tngtech.archunit.core.domain.JavaClasses;
1514

15+
public class ArchUtilsTest {
1616

17-
@Test
18-
public void constructorInvocationTest() {
19-
try {
20-
final Constructor<ArchUtils> c = ArchUtils.class.getDeclaredConstructor();
21-
c.setAccessible(true);
22-
final ArchUtils newInstance = c.newInstance();
23-
Assert.assertNull(newInstance);
24-
} catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException
25-
| InvocationTargetException e) {
26-
assertThat(e).hasCauseExactlyInstanceOf(UnsupportedOperationException.class);
27-
}
28-
}
29-
30-
@Test
31-
public void testNumberOfRulesAvailable() {
32-
JavaClasses classes = ArchUtils.importAllClassesInPackage("./target/classes/com/societegenerale/commons/plugin/", "rules");
33-
int noOfClasses = 0;
34-
for (JavaClass javaClass : classes) {
35-
if(! javaClass.getName().contains("$") && !javaClass.isInterface()) {
36-
noOfClasses++;
37-
}
38-
}
39-
assertThat(noOfClasses).isEqualTo(9);
40-
}
41-
42-
@Test
43-
public void totalClassesInPathWhenPackageFolderDoesNotExists() {
44-
JavaClasses classes = ArchUtils.importAllClassesInPackage("./target/classes", "classFolder");
45-
int noOfClasses = 0;
46-
for (JavaClass javaClass : classes) {
47-
if(!javaClass.getName().contains("$")) {
48-
noOfClasses++;
49-
}
50-
}
51-
assertThat(noOfClasses).isEqualTo(16);
52-
}
17+
@Test
18+
public void constructorInvocationTest() {
19+
try {
20+
final Constructor<ArchUtils> c = ArchUtils.class.getDeclaredConstructor();
21+
c.setAccessible(true);
22+
final ArchUtils newInstance = c.newInstance();
23+
Assert.assertNull(newInstance);
24+
} catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException
25+
| IllegalArgumentException | InvocationTargetException e) {
26+
assertThat(e).hasCauseExactlyInstanceOf(UnsupportedOperationException.class);
27+
}
28+
}
29+
30+
@Test
31+
public void testNumberOfRulesAvailable() {
32+
JavaClasses classes = ArchUtils
33+
.importAllClassesInPackage("./target/classes/com/societegenerale/commons/plugin/", "rules");
34+
int noOfClasses = 0;
35+
for (JavaClass javaClass : classes) {
36+
if (!javaClass.getName().contains("$") && !javaClass.isInterface()) {
37+
noOfClasses++;
38+
}
39+
}
40+
assertThat(noOfClasses).isEqualTo(10);
41+
}
42+
43+
@Test
44+
public void totalClassesInPathWhenPackageFolderDoesNotExists() {
45+
JavaClasses classes = ArchUtils.importAllClassesInPackage("./target/classes", "classFolder");
46+
int noOfClasses = 0;
47+
for (JavaClass javaClass : classes) {
48+
if (!javaClass.getName().contains("$")) {
49+
noOfClasses++;
50+
}
51+
}
52+
assertThat(noOfClasses).isEqualTo(17);
53+
}
5354

5455
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.societegenerale.commons.plugin.rules;
2+
3+
import static com.societegenerale.commons.plugin.rules.NoJavaUtilDateRuleTest.NO_JAVA_UTIL_DATE_VIOLATION_MESSAGE;
4+
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
5+
import static org.assertj.core.api.Assertions.assertThatCode;
6+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
7+
8+
import org.junit.Test;
9+
10+
import com.societegenerale.commons.plugin.rules.classesForTests.ObjectWithAdateField;
11+
import com.societegenerale.commons.plugin.rules.classesForTests.ObjectWithJava8TimeLib;
12+
import com.societegenerale.commons.plugin.rules.classesForTests.ObjectWithJavaTextDateFormat;
13+
import com.societegenerale.commons.plugin.rules.classesForTests.ObjectWithJavaUtilGregorianCalendar;
14+
import com.tngtech.archunit.core.domain.JavaClasses;
15+
import com.tngtech.archunit.core.importer.ClassFileImporter;
16+
17+
public class NoJavaUtilDateRuleTestTest {
18+
19+
@Test
20+
public void shouldThrowViolations() {
21+
22+
assertExceptionIsThrownFor(ObjectWithAdateField.class);
23+
24+
}
25+
26+
@Test
27+
public void shouldNotThrowAnyViolation() {
28+
29+
assertNoExceptionIsThrownFor(ObjectWithJava8TimeLib.class);
30+
31+
assertNoExceptionIsThrownFor(ObjectWithJavaTextDateFormat.class);
32+
33+
assertNoExceptionIsThrownFor(ObjectWithJavaUtilGregorianCalendar.class);
34+
35+
}
36+
37+
private void assertExceptionIsThrownFor(Class clazz) {
38+
39+
JavaClasses classToTest = new ClassFileImporter().importClasses(clazz);
40+
41+
assertThatThrownBy(() -> {
42+
classes().should(NoJavaUtilDateRuleTest.notUseJavaUtilDate()).check(classToTest);
43+
}).hasMessageContaining(ObjectWithAdateField.class.getName())
44+
.hasMessageContaining(NO_JAVA_UTIL_DATE_VIOLATION_MESSAGE);
45+
46+
}
47+
48+
private void assertNoExceptionIsThrownFor(Class clazz) {
49+
50+
JavaClasses classToTest = new ClassFileImporter().importClasses(clazz);
51+
52+
assertThatCode(() -> classes().should(NoJavaUtilDateRuleTest.notUseJavaUtilDate()).check(classToTest))
53+
.doesNotThrowAnyException();
54+
55+
}
56+
57+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.societegenerale.commons.plugin.rules.classesForTests;
2+
3+
import java.util.Date;
4+
5+
public class ObjectWithAdateField {
6+
7+
private Date date = new Date(0, 0, 0);
8+
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.societegenerale.commons.plugin.rules.classesForTests;
2+
3+
import java.text.DateFormat;
4+
5+
public class ObjectWithJavaTextDateFormat {
6+
7+
private DateFormat dateFormat;
8+
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.societegenerale.commons.plugin.rules.classesForTests;
2+
3+
import java.util.GregorianCalendar;
4+
5+
public class ObjectWithJavaUtilGregorianCalendar {
6+
7+
private GregorianCalendar cal;
8+
9+
}

0 commit comments

Comments
 (0)