More unit tests for jdk17

This commit is contained in:
2023-09-18 18:32:52 -05:00
parent 587f8bbaf6
commit 3cd7639da1
3 changed files with 212 additions and 122 deletions

View File

@@ -13,7 +13,7 @@ import java.lang.annotation.Target;
* @author Isaac Parenteau
*
*/
@Target({ElementType.FIELD, ElementType.TYPE})
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MapValue {

View File

@@ -4,17 +4,7 @@ import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
@@ -24,8 +14,6 @@ import java.util.stream.IntStream;
import net.locusworks.common.annotations.MapValue;
import net.locusworks.common.interfaces.ThrowingConsumer;
import java.util.Set;
/***
* Utils class with generic methods
* @author Isaac Parenteau
@@ -110,49 +98,33 @@ public class Utils {
*/
@SuppressWarnings("unchecked")
public static <K, V> Map<K, V> buildMap(Class<?> mapClass, Class<K> mapKey, Class<V> mapValue, Object... data) {
Objects.requireNonNull(mapKey, "Null key value");
Objects.requireNonNull(mapValue, "Null map value");
Map<K, V> results;
try {
results = (Map<K, V>) mapClass.getDeclaredConstructor().newInstance();
} catch (Exception ex) {
throw new IllegalArgumentException("Unable to create instance of " + mapClass.getSimpleName());
throw new IllegalArgumentException("Unable to create instance of " + mapClass.getSimpleName() + " e: " + ex.getMessage());
}
if (data.length % 2 != 0) {
throw new IllegalArgumentException("Odd number of arguments provided");
}
Object key = null;
int step = -1;
for(int i = 0; i < data.length; i+=2) {
Object key = data[i];
Object value = data[i + 1];
for (Object value : data) {
switch(++step % 2) {
case 0:
if (mapKey == null) {
throw new IllegalArgumentException("Null key value");
}
if (value instanceof Class) {
try {
value = ((Class<?>)value).getDeclaredConstructor().newInstance();
} catch (Exception ex) {
throw new IllegalArgumentException("Unable to create new instance of " + value);
}
}
if (!mapKey.isInstance(value)) {
throw new IllegalArgumentException("Key is not the correct instance. Expecting " + mapKey.getName() + " Received " + value.getClass().getName());
}
key = value;
continue;
case 1:
if (!mapValue.isInstance(value)) {
throw new IllegalArgumentException("Value is not the correct instance. Expecting " + mapValue.getName() + " Received " + value.getClass().getName());
}
results.put((K) key, (V) value);
break;
default:
throw new IllegalAccessError("Calculation for step was not a multiple of two. This shouldn't have happened");
if (!mapKey.isInstance(key)) {
throw new IllegalArgumentException("Key is not the correct instance. Expecting " + mapKey.getName() + " Received " + key.getClass().getName());
}
if (!mapValue.isInstance(value)) {
throw new IllegalArgumentException("Value is not the correct instance. Expecting " + mapValue.getName() + " Received " + value.getClass().getName());
}
results.put((K) key, (V) value);
}
return results;
}
@@ -161,28 +133,24 @@ public class Utils {
* Builds a set of objects
* @param setClass Class type of the set to create
* @param setValue Class type of the objects being placed in the set
* @param <V> Class type of the return object (should be the same as setValue)
* @param <E> Class type of the return object (should be the same as setValue)
* @param data Data to place inside the set
* @return Set filled with the data
* @deprecated since JDk11 can use Set.of
*/
@SuppressWarnings("unchecked")
public static <V> Set<V> buildSet(Class<?> setClass, Class<V> setValue, Object... data) {
Set<V> results;
public static <E> Set<E> buildSet(Class<?> setClass, Class<E> setValue, E... data) {
return buildSet(data);
}
try {
results = (Set<V>) setClass.getDeclaredConstructor().newInstance();
} catch (Exception ex) {
throw new IllegalArgumentException("Unable to create instance of " + setClass.getSimpleName());
}
for (Object value : data) {
if (!setValue.isInstance(value)) {
throw new IllegalArgumentException("Value is not the correct instance. Expecting " + setValue.getName() + " Received " + value.getClass().getName());
}
results.add((V) value);
}
return results;
/**
* Builds a set of objects
* @param data the data to set
* @return the set
* @param <E> the type
*/
@SafeVarargs public static <E> Set<E> buildSet(E... data) {
return Set.of(data);
}
/**
@@ -197,23 +165,12 @@ public class Utils {
}
/**
* Clone list.
* Clone list and makes it unmodifiable.
*
* @param <E> the type parameter
* @param list the list
*
* @return the list
* @throws IllegalAccessException throw when an object in the list cannot be accessed through reflection
* @throws InstantiationException thrown when an object in the list cannot be instantiated through reflection
* @return unmodifiable list
*/
@SuppressWarnings("unchecked")
public static <E> List<E> cloneList(List<E> list)
throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
List<E> clone = new ArrayList<>();
for (E item : list) {
clone.add((E) cloneObject(item));
}
return clone;
public static <E> List<E> cloneList(List<E> list) {
return Collections.unmodifiableList(list);
}
/**
@@ -223,7 +180,8 @@ public class Utils {
* @throws IllegalAccessException thrown when the filed cannot be access
* @throws InstantiationException Thrown when the object cannot be instantiated
*/
public static Object cloneObject(Object obj)
@SuppressWarnings("unchecked")
public static <O> O cloneObject(O obj)
throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Object clone = obj.getClass().getDeclaredConstructor().newInstance();
for (Field field : obj.getClass().getDeclaredFields()) {
@@ -232,9 +190,10 @@ public class Utils {
if (field.get(obj) == null || Modifier.isFinal(field.getModifiers())){
continue;
}
if (field.getType().isPrimitive() || field.getType().equals(String.class)
|| field.getType().getSuperclass().equals(Number.class)
|| field.getType().equals(Boolean.class)){
Class<?> type = field.getType();
if (type.isPrimitive() || getWrapperTypes().contains(type)) {
field.set(clone, field.get(obj));
} else {
Object childObj = field.get(obj);
@@ -246,7 +205,7 @@ public class Utils {
}
} catch (NullPointerException ignored) { }
}
return clone;
return (O) clone;
}
/***
@@ -260,18 +219,17 @@ public class Utils {
Class<?> clazz = obj.getClass();
Map<String, Object> map = new LinkedHashMap<>();
boolean hasAnnotations = clazz.isAnnotationPresent(MapValue.class);
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
boolean hasAnnotations = field.isAnnotationPresent(MapValue.class);
String key = field.getName();
Object value = field.get(obj);
if (value == null) continue;
if (hasAnnotations) {
if (!field.isAnnotationPresent(MapValue.class)) {
continue;
}
MapValue annotation = field.getDeclaredAnnotation(MapValue.class);
if (annotation.ignore()) {
continue;
@@ -303,6 +261,12 @@ public class Utils {
return convert;
}
/**
* Converts an object toa string map;
* @param obj the object to convert
* @return the map
* @throws Exception thrown if something happens
*/
public static Map<String, String> convertToStringMap(Object obj) throws Exception {
return convertToStringMap(convertToMap(obj));
}
@@ -459,6 +423,27 @@ public class Utils {
return tmpList;
}
/**
* Use reflection to get the field values
* @param clazz the class to find the field
* @param fieldName the field name
* @return field
*/
private static Field getField(Class<?> clazz, String fieldName) {
Field field = null;
while(clazz != null) {
try {
field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
break;
} catch(Exception ex) {
clazz = clazz.getSuperclass();
}
}
return field;
}
/**
* A replacement for String.format. Allows for to many parameters or too few
* Replaces {} in the string in order.
@@ -503,27 +488,6 @@ public class Utils {
return obj == null ? "Unknown" : (verbose ? obj.getClass().getName() : obj.getClass().getSimpleName());
}
/**
* Use reflection to get the field values
* @param clazz the class to find the field
* @param fieldName the field name
* @return field
*/
private static Field getField(Class<?> clazz, String fieldName) {
Field field = null;
while(clazz != null) {
try {
field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
break;
} catch(Exception ex) {
clazz = clazz.getSuperclass();
}
}
return field;
}
/**
* Get a value from a map
*
@@ -1076,16 +1040,16 @@ public class Utils {
}
private static Set<Class<?>> getWrapperTypes() {
Set<Class<?>> ret = new HashSet<>();
ret.add(Boolean.class);
ret.add(Character.class);
ret.add(Byte.class);
ret.add(Short.class);
ret.add(Integer.class);
ret.add(Long.class);
ret.add(Float.class);
ret.add(Double.class);
ret.add(String.class);
return ret;
return Set.of(
Boolean.class,
Character.class,
Byte.class,
Short.class,
Integer.class,
Long.class,
Float.class,
Double.class,
String.class
);
}
}