com.codebox.bean.ValueBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of javabean-tester Show documentation
Show all versions of javabean-tester Show documentation
Javabean Tester Simplifies POJO Testing and greatly simplifies Lombok Bean Testing!
The newest version!
/*
* JavaBean Tester (https://github.com/hazendaz/javabean-tester)
*
* Copyright 2012-2024 Hazendaz.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of The Apache Software License,
* Version 2.0 which accompanies this distribution, and is available at
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
* Contributors:
* CodeBox (Rob Dawson).
* Hazendaz (Jeremy Landis).
*/
package com.codebox.bean;
import com.codebox.enums.LoadData;
import com.codebox.enums.LoadType;
import com.codebox.instance.ClassInstance;
import com.codebox.instance.ConstructorInstance;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Value Builder Builds values from given type.
*/
@Data
public class ValueBuilder {
/** The Constant Logger. */
private static final Logger logger = LoggerFactory.getLogger(ValueBuilder.class);
/** The load data. */
private LoadData loadData;
/**
* Builds the value.
*
* @param
* the generic type
* @param clazz
* the clazz
* @param loadType
* the load type
*
* @return the object
*/
public Object buildValue(final Class clazz, final LoadType loadType) {
// Next check for a no-arg constructor
final Constructor>[] ctrs = clazz.getConstructors();
for (final Constructor> ctr : ctrs) {
if (ctr.getParameterTypes().length == 0 && clazz != String.class) {
if (this.loadData == LoadData.ON && !containsSelf(clazz)) {
// Load Underlying Data to deeply test when it doesn't contain self
final JavaBeanTesterWorker beanTesterWorker = new JavaBeanTesterWorker<>(clazz);
beanTesterWorker.setLoadData(this.loadData);
beanTesterWorker.getterSetterTests(new ClassInstance().newInstance(clazz));
return null;
}
// The class has a no-arg constructor, so just call it
return ConstructorInstance.newInstance(ctr);
}
}
// Specific rules for common classes
Object returnObject = null;
switch (loadType) {
case ALTERNATE_DATA:
returnObject = ValueBuilder.setAlternateValues(clazz);
break;
case NULL_DATA:
returnObject = ValueBuilder.setNullValues(clazz);
break;
case STANDARD_DATA:
default:
returnObject = ValueBuilder.setStandardValues(clazz);
break;
}
if (returnObject != null || loadType == LoadType.NULL_DATA) {
return returnObject;
}
if (clazz.isAssignableFrom(BigDecimal.class)) {
return BigDecimal.ONE;
}
if (clazz.isAssignableFrom(UUID.class)) {
return UUID.fromString("00000000-0000-0000-0000-000123456789");
}
if (clazz.isAssignableFrom(Instant.class)) {
return Instant.ofEpochSecond(1L);
}
if (clazz.isAssignableFrom(List.class)) {
return new ArrayList<>();
}
if (clazz.isAssignableFrom(Map.class)) {
return new HashMap<>();
}
if (clazz.isAssignableFrom(ConcurrentMap.class)) {
return new ConcurrentHashMap<>();
}
if (clazz.isAssignableFrom(Set.class)) {
return new TreeSet<>();
}
if (clazz.isAssignableFrom(Date.class)) {
return new Date();
}
if (clazz.isAssignableFrom(LocalDate.class)) {
return LocalDate.now();
}
if (clazz.isAssignableFrom(LocalDateTime.class)) {
return LocalDateTime.of(2000, 10, 1, 0, 0);
}
if (clazz.isAssignableFrom(LocalTime.class)) {
return LocalTime.of(0, 0);
}
if (clazz.isAssignableFrom(OffsetDateTime.class)) {
return OffsetDateTime.of(2000, 10, 1, 0, 0, 0, 0, ZoneOffset.MIN);
}
if (clazz.isAssignableFrom(ZonedDateTime.class)) {
return ZonedDateTime.of(LocalDateTime.of(2020, 11, 16, 10, 26, 00, 01), ZoneId.of("UTC"));
}
if (clazz == Logger.class) {
return LoggerFactory.getLogger(clazz);
}
if (clazz.isEnum()) {
return clazz.getEnumConstants()[0];
}
// XXX Add additional rules here
// XXX Don't fail this...until alternative solution is determined
ValueBuilder.logger.warn(
"Unable to build value for class '{}', please raise ticket with JavaBeanTester for desired support.",
clazz.getName());
return null;
}
/**
* Set using alternate test values.
*
* @param
* the type parameter associated with the class under test.
* @param clazz
* the class under test.
*
* @return Object the Object to use for test.
*/
private static Object setAlternateValues(final Class clazz) {
return ValueBuilder.setValues(clazz, "ALT_VALUE", 1, Boolean.FALSE, Integer.valueOf(2), Long.valueOf(2),
Double.valueOf(2.0), Float.valueOf(2.0F), Character.valueOf('N'), Byte.valueOf((byte) 2));
}
/**
* Set using null test values.
*
* @param
* the type parameter associated with the class under test.
* @param clazz
* the class under test.
*
* @return Object the Object to use for test.
*/
private static Object setNullValues(final Class clazz) {
return ValueBuilder.setValues(clazz, null, 0, null, null, null, null, null, null, null);
}
/**
* Set using standard test values.
*
* @param
* the type parameter associated with the class under test.
* @param clazz
* the class under test.
*
* @return Object the Object to use for test.
*/
private static Object setStandardValues(final Class clazz) {
return ValueBuilder.setValues(clazz, "TEST_VALUE", 1, Boolean.TRUE, Integer.valueOf(1), Long.valueOf(1),
Double.valueOf(1.0), Float.valueOf(1.0F), Character.valueOf('Y'), Byte.valueOf((byte) 1));
}
/**
* Set Values for object.
*
* @param
* the type parameter associated with the class under test.
* @param clazz
* the class instance under test.
* @param string
* value of string object.
* @param arrayLength
* amount of array objects to create.
* @param booleanValue
* value of boolean object.
* @param integerValue
* value of integer object.
* @param longValue
* value of long object.
* @param doubleValue
* value of double object.
* @param floatValue
* value of float object.
* @param characterValue
* value of character object.
* @param byteValue
* value of character object.
*
* @return Object value determined by input class. If not found, returns null.
*/
private static Object setValues(final Class clazz, final String string, final int arrayLength,
final Boolean booleanValue, final Integer integerValue, final Long longValue, final Double doubleValue,
final Float floatValue, final Character characterValue, final Byte byteValue) {
if (clazz == String.class) {
return string;
}
if (clazz.isArray()) {
return Array.newInstance(clazz.getComponentType(), arrayLength);
}
if (clazz == boolean.class || clazz == Boolean.class) {
return ValueBuilder.initializeBoolean(clazz, booleanValue);
}
if (clazz == int.class || clazz == Integer.class) {
return ValueBuilder.initializeInteger(clazz, integerValue);
}
if (clazz == long.class || clazz == Long.class) {
return ValueBuilder.initializeLong(clazz, longValue);
}
if (clazz == double.class || clazz == Double.class) {
return ValueBuilder.initializeDouble(clazz, doubleValue);
}
if (clazz == float.class || clazz == Float.class) {
return ValueBuilder.initializeFloat(clazz, floatValue);
}
if (clazz == char.class || clazz == Character.class) {
return ValueBuilder.initializeCharacter(clazz, characterValue);
}
if (clazz == byte.class || clazz == Byte.class) {
return ValueBuilder.initializeByte(clazz, byteValue);
}
return null;
}
/**
* Initialize boolean.
*
* @param
* the generic type
* @param clazz
* the clazz
* @param booleanValue
* the boolean value
*
* @return the object
*/
private static Object initializeBoolean(final Class clazz, final Boolean booleanValue) {
if (clazz == boolean.class && booleanValue == null) {
return Boolean.FALSE;
}
return booleanValue;
}
/**
* Initialize integer.
*
* @param
* the generic type
* @param clazz
* the clazz
* @param integerValue
* the integer value
*
* @return the object
*/
private static Object initializeInteger(final Class clazz, final Integer integerValue) {
if (clazz == int.class && integerValue == null) {
return Integer.valueOf(-1);
}
return integerValue;
}
/**
* Initialize long.
*
* @param
* the generic type
* @param clazz
* the clazz
* @param longValue
* the long value
*
* @return the object
*/
private static Object initializeLong(final Class clazz, final Long longValue) {
if (clazz == long.class && longValue == null) {
return Long.valueOf(-1);
}
return longValue;
}
/**
* Initialize double.
*
* @param
* the generic type
* @param clazz
* the clazz
* @param doubleValue
* the double value
*
* @return the object
*/
private static Object initializeDouble(final Class clazz, final Double doubleValue) {
if (clazz == double.class && doubleValue == null) {
return Double.valueOf(-1.0);
}
return doubleValue;
}
/**
* Initialize float.
*
* @param
* the generic type
* @param clazz
* the clazz
* @param floatValue
* the float value
*
* @return the object
*/
private static Object initializeFloat(final Class clazz, final Float floatValue) {
if (clazz == float.class && floatValue == null) {
return Float.valueOf(-1.0F);
}
return floatValue;
}
/**
* Initialize character.
*
* @param
* the generic type
* @param clazz
* the clazz
* @param characterValue
* the character value
*
* @return the object
*/
private static Object initializeCharacter(final Class clazz, final Character characterValue) {
if (clazz == char.class && characterValue == null) {
return Character.valueOf('\u0000');
}
return characterValue;
}
/**
* Initialize byte.
*
* @param
* the generic type
* @param clazz
* the clazz
* @param byteValue
* the byte value
*
* @return the object
*/
private static Object initializeByte(final Class clazz, final Byte byteValue) {
if (clazz == byte.class && byteValue == null) {
return Byte.valueOf((byte) -1);
}
return byteValue;
}
/**
* Contains self.
*
* @param
* the generic type
* @param clazz
* the clazz
* @return true, if successful
*/
private boolean containsSelf(final Class clazz) {
final List fields = Arrays.asList(clazz.getDeclaredFields());
for (Field field : fields) {
if (field.getType().equals(clazz)) {
return true;
}
}
return false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy