RandomUtils.java
/*-
* #%L
* JSQLParser library
* %%
* Copyright (C) 2004 - 2020 JSQLParser
* %%
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
* #L%
*/
package net.sf.jsqlparser.util;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang3.RandomStringUtils;
/**
* An utility to get a random value for any type given - see {@link #getRandomValueForType(Class)}
*
* @author gitmotte
* @see #pushObjects(List)
*/
public class RandomUtils {
private static final Logger LOG = Logger.getLogger(RandomUtils.class.getName());
private static final Random RANDOM = new Random();
private static final ThreadLocal<Map<Class<?>, Object>> OBJECTS = new ThreadLocal<>();
/**
* register models (for use within method {@link #getRandomValueForType(Class)}
*/
public static void pushObjects(List<Object> obj) {
Map<Class<?>, Object> m = new HashMap<>();
OBJECTS.set(m);
obj.stream().forEach(o -> {
m.put(o.getClass(), o);
for (Class<?> iface : o.getClass().getInterfaces()) {
// register object with its implemented interfaces
// if we need an object for interface requested, an instance is available
m.put(iface, o);
}
Class<?> cls = o.getClass();
while ((cls = cls.getSuperclass()) != null) {
if (!Object.class.equals(cls)) {
// register object with its parent classes
// if we need an object for parent class requested, an instance is available
m.put(cls, o);
}
}
});
}
/**
* @param <T>
* @param type
* @return a random non-<code>null</code> value for given type or <code>null</code> if not
* supported.
*/
public static <T> T getRandomValueForType(Class<T> type) {
Object value = null;
if (Integer.class.equals(type) || int.class.equals(type)) {
value = RandomUtils.RANDOM.nextInt();
} else if (Long.class.equals(type) || long.class.equals(type)) {
value = RandomUtils.RANDOM.nextLong();
} else if (Boolean.class.equals(type) || boolean.class.equals(type)) {
value = RandomUtils.RANDOM.nextBoolean();
} else if (Float.class.equals(type) || float.class.equals(type)) {
value = RandomUtils.RANDOM.nextFloat();
} else if (Double.class.equals(type) || double.class.equals(type)) {
value = RandomUtils.RANDOM.nextDouble();
} else if (Byte.class.equals(type) || byte.class.equals(type)) {
byte[] b = new byte[1];
RandomUtils.RANDOM.nextBytes(b);
value = b[0];
} else if (Short.class.equals(type) || short.class.equals(type)) {
value = (short) RandomUtils.RANDOM.nextInt(15);
} else if (char.class.equals(type)) {
value = RandomStringUtils.random(1).toCharArray()[0];
} else if (Time.class.equals(type)) {
value = new Time(Math.abs(RandomUtils.RANDOM.nextLong()));
} else if (Timestamp.class.equals(type)) {
value = new Timestamp(Math.abs(RandomUtils.RANDOM.nextLong()));
} else if (Date.class.equals(type)) {
value = new Date(Math.abs(RandomUtils.RANDOM.nextLong()));
} else {
int size = RandomUtils.RANDOM.nextInt(10);
if (String.class.equals(type)) {
value = RandomStringUtils.random(size);
} else if (Collection.class.equals(type) || List.class.equals(type)) {
List<Object> c = new ArrayList<>();
value = c;
} else if (Set.class.equals(type)) {
Set<Object> c = new HashSet<>();
value = c;
} else if (type.isArray()) {
Object[] a = (Object[]) Array.newInstance(type.getComponentType(), size);
for (int i = 0; i < size; i++) {
a[i] = getRandomValueForType(type.getComponentType());
}
value = a;
} else if (Map.class.equals(type)) {
Map<Object, Object> c = new HashMap<>();
value = c;
} else if (LocalDateTime.class.equals(type)) {
value = LocalDateTime.now();
} else {
// try to get an object from test-objects
value = OBJECTS.get().get(type);
if (value == null) {
if (type.isEnum()) {
@SuppressWarnings("unchecked")
EnumSet<?> enums = EnumSet.allOf(type.asSubclass(Enum.class));
value = new ArrayList<>(enums)
.get(RandomUtils.RANDOM.nextInt(enums.size()));
} else {
try {
value = type.getConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException
| IllegalArgumentException
| InvocationTargetException | NoSuchMethodException
| SecurityException e) {
// cannot get default instance with empty constructor
LOG.log(Level.WARNING,
"cannot get default instance with reflection for type " + type);
}
}
}
}
}
// do not use type.cast (does not support primitive types and
// autoboxing/unboxing
@SuppressWarnings("unchecked")
T t = (T) value;
return t;
}
}