Skip to content

Commit 0e49cbb

Browse files
committed
#49 #54 Revise javadoc, add more tests, rename method
1 parent 631aa60 commit 0e49cbb

File tree

6 files changed

+159
-58
lines changed

6 files changed

+159
-58
lines changed

src/main/java/ch/jalu/typeresolver/EnumUtil.java

+9-9
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,29 @@ private EnumUtil() {
1515
}
1616

1717
/**
18-
* Returns the enum entry with the given name if the provided class is an enum and has an entry that matches
19-
* exactly the given name. Null is returned otherwise.
18+
* Returns an optional of the enum entry with the given name if the provided class is an enum and has an entry that
19+
* matches exactly the given name. Otherwise, an empty optional is returned.
2020
*
2121
* @param clazz the class to check for enum entries, or null
2222
* @param name the name to match, or null
2323
* @param <T> the class type
24-
* @return the enum entry if the name was non-null, the class was an enum and had such an enum entry; null otherwise
24+
* @return optional of the enum entry if the class is an enum and has an entry of the given name; empty otherwise
2525
*/
26-
@Nullable
2726
@SuppressWarnings({"unchecked", "rawtypes"})
28-
public static <T> T valueOfOrNull(@Nullable Class<T> clazz, @Nullable String name) {
27+
public static <T> Optional<T> tryValueOf(@Nullable Class<T> clazz, @Nullable String name) {
2928
if (clazz == null || !clazz.isEnum() || name == null) {
30-
return null;
29+
return Optional.empty();
3130
}
3231
try {
33-
return (T) Enum.valueOf((Class) clazz, name);
32+
return Optional.of((T) Enum.valueOf((Class) clazz, name));
3433
} catch (IllegalArgumentException ignored) {
35-
return null;
34+
return Optional.empty();
3635
}
3736
}
3837

3938
/**
40-
* Specifies whether the given class is an enum or a synthetic class of an enum entry.
39+
* Indicates whether the given class is an enum or a synthetic class of an enum entry. Synthetic classes are
40+
* created when an enum entry extends the enum type anonymously.
4141
* <p>
4242
* Examples:<pre>{@code
4343
* Class<?> class1 = NumericShaper.Range.class;

src/main/java/ch/jalu/typeresolver/classutil/ClassType.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ public enum ClassType {
99
ENUM,
1010

1111
/**
12-
* The class is the synthetic class of an enum entry that anonymously extends the base type. This class returns
13-
* false for {@link Class#isEnum()} but is assignable to {@link Enum}.
12+
* The class is the synthetic class of an enum entry that anonymously extends the enum type. Although this class
13+
* returns {@code false} for the {@link Class#isEnum()} method, it is assignable to the {@link Enum} type.
1414
* <br>Example: {@code NumericShaper.Range.ETHIOPIC.getClass()}
1515
*/
1616
ENUM_ENTRY,
@@ -35,7 +35,7 @@ public enum ClassType {
3535
PRIMITIVE,
3636

3737
/**
38-
* The class is an array, such as {@code String[]}.
38+
* The class is an array, such as {@code String[].class} or {@code int[].class}.
3939
*
4040
* @see ch.jalu.typeresolver.array.ArrayClassProperties
4141
*/
@@ -54,8 +54,11 @@ public enum ClassType {
5454

5555
/**
5656
* The class is a "regular" Java class, which typically means it was declared with the {@code class} or
57-
* {@code record} keyword. An enum type is also considered a "regular class".
57+
* {@code record} keyword. A class is considered a "regular class" by exclusion: it is a "regular class" if none of
58+
* the other types of this enum apply to it.
5859
* <br>Example: {@link String}
60+
* <p>
61+
* Note that nested classes and anonymous classes may also be considered "regular classes".
5962
*/
6063
REGULAR_CLASS
6164

src/main/java/ch/jalu/typeresolver/classutil/ClassTypeCallback.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66
/**
77
* Extendable class with a method dedicated for each {@link ClassType}, with appropriately cast method parameters.
8-
* This class's methods are meant to be (partially) overridden.
8+
* This class's methods are meant to be overridden. The methods can be overridden partially if only certain class types
9+
* are of interest.
910
*
1011
* @param <R> the result type of the callback
1112
* @see ClassUtil#processClassByType
@@ -63,7 +64,8 @@ public R forPrimitiveType(Class<?> primitiveClass) {
6364
/**
6465
* Called when the class to process is an array class, such as {@code int[].class} or {@code String[][].class}.
6566
* <p>
66-
* Note that the class cannot be blindly cast to {@code Class<? extends Object[]>} due to arrays of primitive types.
67+
* Note that the class cannot be cast to {@code Class<? extends Object[]>} without checking beforehand, due to
68+
* arrays of primitive types such as {@code int[].class}.
6769
*
6870
* @param arrayClass the array class
6971
* @return result or null
@@ -96,7 +98,7 @@ public R forProxyClass(Class<?> proxyClass) {
9698
}
9799

98100
/**
99-
* Called when the class to process is a "regular class" (cf. {@link ClassUtil#isActualJavaClass}).
101+
* Called when the class to process is a "regular class", as explained in {@link ClassUtil#isRegularJavaClass}.
100102
*
101103
* @param regularClass the Java class
102104
* @return result or null

src/main/java/ch/jalu/typeresolver/classutil/ClassUtil.java

+8-6
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ public static Optional<Class<?>> tryLoadClass(String name) {
4747
/**
4848
* Loads a class or throws an {@link IllegalArgumentException}. This method wraps {@link Class#forName(String)}
4949
* to throw a runtime exception for convenience.
50+
* <p>
51+
* Note that errors thrown by {@link Class#forName(String)} (e.g. {@link LinkageError}) are not caught as they
52+
* typically indicate more severe issues.
5053
*
5154
* @param name the class name to load
5255
* @return the loaded class, never null
@@ -61,8 +64,7 @@ public static Class<?> loadClassOrThrow(String name) {
6164

6265
/**
6366
* Returns the {@link Class#getName() class name} of the object null-safely, returning "null" if the object is null.
64-
* See also {@link #getSemanticName(Object)} for another null-safe, more user-appropriate name of an object
65-
* or class.
67+
* Use {@link #getSemanticName(Object)} to generate a null-safe, more user-appropriate name of the object's type.
6668
*
6769
* @param object the object whose type should be returned as string
6870
* @return the object's class name, or "null" if the object was null
@@ -147,8 +149,8 @@ public static String getSemanticName(@Nullable Class<?> clazz) {
147149
* @param clazz the class to inspect, or null
148150
* @return true if the class is a "regular Java class"
149151
*/
150-
public static boolean isActualJavaClass(@Nullable Class<?> clazz) {
151-
return clazz != null && getType(clazz) == ClassType.REGULAR_CLASS;
152+
public static boolean isRegularJavaClass(@Nullable Class<?> clazz) {
153+
return getType(clazz) == ClassType.REGULAR_CLASS;
152154
}
153155

154156
/**
@@ -179,8 +181,8 @@ public static ClassType getType(Class<?> clazz) {
179181
}
180182

181183
/**
182-
* Returns the result obtained by the given's {@link ClassTypeCallback} method that is applicable for the given
183-
* class's type.
184+
* Calls the method on the given {@link ClassTypeCallback} that corresponds to the given class's type and
185+
* returns the result.
184186
*
185187
* @param clazz the class to inspect and process
186188
* @param typeCallback the type callback to generate a result with

src/test/java/ch/jalu/typeresolver/EnumUtilTest.java

+15-12
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import static org.hamcrest.Matchers.contains;
1616
import static org.hamcrest.Matchers.empty;
1717
import static org.hamcrest.Matchers.equalTo;
18-
import static org.hamcrest.Matchers.nullValue;
1918
import static org.junit.jupiter.api.Assertions.assertFalse;
2019
import static org.junit.jupiter.api.Assertions.assertTrue;
2120

@@ -65,16 +64,20 @@ void shouldHaveValidJavadocExampleOnAsEnumType() {
6564
@Test
6665
void shouldTryToResolveNameToEntry() {
6766
// given / when / then
68-
assertThat(EnumUtil.valueOfOrNull(TestEnum.class, "FIRST"), equalTo(TestEnum.FIRST));
69-
assertThat(EnumUtil.valueOfOrNull(TestEnum.class, "SECOND"), equalTo(TestEnum.SECOND));
70-
assertThat(EnumUtil.valueOfOrNull(TestEnum.class, "THIRD"), equalTo(TestEnum.THIRD));
71-
assertThat(EnumUtil.valueOfOrNull(TimeUnit.class, "MINUTES"), equalTo(TimeUnit.MINUTES));
72-
73-
assertThat(EnumUtil.valueOfOrNull(TestEnum.class, null), nullValue());
74-
assertThat(EnumUtil.valueOfOrNull(TestEnum.class, "WRONG"), nullValue());
75-
assertThat(EnumUtil.valueOfOrNull(null, "ENTRY"), nullValue());
76-
assertThat(EnumUtil.valueOfOrNull(HashMap.class, "WRONG"), nullValue());
77-
assertThat(EnumUtil.valueOfOrNull(TimeUnit.class, "WRONG"), nullValue());
67+
assertThat(EnumUtil.tryValueOf(TestEnum.class, "FIRST"), equalTo(Optional.of(TestEnum.FIRST)));
68+
assertThat(EnumUtil.tryValueOf(TestEnum.class, "SECOND"), equalTo(Optional.of(TestEnum.SECOND)));
69+
assertThat(EnumUtil.tryValueOf(TestEnum.class, "THIRD"), equalTo(Optional.of(TestEnum.THIRD)));
70+
assertThat(EnumUtil.tryValueOf(TimeUnit.class, "MINUTES"), equalTo(Optional.of(TimeUnit.MINUTES)));
71+
assertThat(EnumUtil.tryValueOf(TestEnum.NestedEnum.class, "SECOND"), equalTo(Optional.of(TestEnum.NestedEnum.SECOND)));
72+
73+
assertThat(EnumUtil.tryValueOf(null, null), equalTo(Optional.empty()));
74+
assertThat(EnumUtil.tryValueOf(TestEnum.class, null), equalTo(Optional.empty()));
75+
assertThat(EnumUtil.tryValueOf(null, "ENTRY"), equalTo(Optional.empty()));
76+
77+
assertThat(EnumUtil.tryValueOf(TestEnum.class, "WRONG"), equalTo(Optional.empty()));
78+
assertThat(EnumUtil.tryValueOf(TestEnum.NestedEnum.class, "WRONG"), equalTo(Optional.empty()));
79+
assertThat(EnumUtil.tryValueOf(HashMap.class, "WRONG"), equalTo(Optional.empty()));
80+
assertThat(EnumUtil.tryValueOf(TimeUnit.class, "WRONG"), equalTo(Optional.empty()));
7881
}
7982

8083
@Test
@@ -146,7 +149,7 @@ private enum TestEnum {
146149
FIRST,
147150

148151
SECOND() {
149-
class InsideSecondClass {
152+
class InsideSecondClass { // Referenced via TestEnum.SECOND.getClass().getDeclaredClasses()[0];
150153

151154
}
152155
},

0 commit comments

Comments
 (0)