All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.anhem.testpopulator.internal.object.ObjectBuilder Maven / Gradle / Ivy

Go to download

Populate java classes with fixed or random data using reflection. Facilitates the creation of objects in tests.

The newest version!
package com.github.anhem.testpopulator.internal.object;

import com.github.anhem.testpopulator.exception.ObjectException;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.github.anhem.testpopulator.PopulateFactory.BUILDER_METHOD;
import static com.github.anhem.testpopulator.internal.util.ObjectBuilderUtil.*;

public class ObjectBuilder {

    public static final String NULL = "null";
    public static final String PSF = "public static final";
    private static final String NEW_OBJECT_WITH_ARGUMENTS = "%s %s %s = new %s(%s);";
    private static final String NEW_OBJECT = "%s %s %s = new %s();";
    private static final String BUILDER = "%s %s %s = %s.%s()";
    private static final String NEW_TYPED_OBJECT = "%s %s<%s> %s = new %s<>();";
    private static final String SET_OF = "%s %s<%s> %s = Set.of(%s);";
    private static final String LIST_OF = "%s %s<%s> %s = List.of(%s);";
    private static final String MAP_OF = "%s %s<%s> %s = Map.of(%s);";
    private static final String NEW_ARRAY = "%s %s[] %s = new %s[]{%s};";
    private static final String NEW_VALUE = "%s %s %s = %s;";
    private static final String ARGUMENT_DELIMITER = ", ";
    private Class clazz;
    private final String name;
    private final BuildType buildType;
    private final List children = new ArrayList<>();
    private final int expectedChildren;
    private ObjectBuilder parent;
    private String value;

    public ObjectBuilder(Class clazz, String name, BuildType buildType, int expectedChildren) {
        this.clazz = clazz;
        this.name = name;
        this.buildType = buildType;
        this.expectedChildren = expectedChildren;
    }

    public ObjectBuilder(String name, BuildType buildType, int expectedChildren) {
        this.name = name;
        this.buildType = buildType;
        this.expectedChildren = expectedChildren;
    }

    public void addChild(ObjectBuilder child) {
        children.add(child);
    }

    public List getChildren() {
        return children;
    }

    public boolean hasAllChildren() {
        return expectedChildren == children.size();
    }

    public Class getClazz() {
        return clazz;
    }

    public String getName() {
        return name;
    }

    public BuildType getBuildType() {
        return buildType;
    }

    public ObjectBuilder getParent() {
        return parent;
    }

    public void setParent(ObjectBuilder parent) {
        this.parent = parent;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public ObjectResult build() {
        String packageName = getPackageName(clazz);
        String className = formatClassName(clazz);
        Set imports = new HashSet<>();
        Set staticImports = new HashSet<>();
        getImports(imports, staticImports);
        List objects = buildByBuildType();

        return new ObjectResult(packageName, className, imports, staticImports, objects);
    }

    private void getImports(Set imports, Set staticImports) {
        addImport(clazz, value, imports, staticImports);
        children.forEach(objectBuilder -> objectBuilder.getImports(imports, staticImports));
    }

    private List buildByBuildType() {
        switch (buildType) {
            case CONSTRUCTOR:
                return buildConstructor();
            case SETTER:
                return buildSetter();
            case BUILDER:
                return buildBuilder();
            case METHOD:
                return buildMethod();
            case SET:
                return buildSet();
            case SET_OF:
                return buildSetOf();
            case LIST:
                return buildList();
            case LIST_OF:
                return buildListOf();
            case MAP:
                return buildMap();
            case MAP_OF:
                return buildMapOf();
            case ARRAY:
                return buildArray();
            case VALUE:
                return buildValue();
            default:
                throw new ObjectException(String.format("Invalid buildType %s", buildType));
        }
    }

    private Stream buildChildren() {
        return children.stream()
                .filter(child -> !isBasicValue(child))
                .map(ObjectBuilder::buildByBuildType)
                .flatMap(Collection::stream);
    }

    private List buildConstructor() {
        return concatenate(buildChildren(),
                Stream.of(String.format(NEW_OBJECT_WITH_ARGUMENTS, PSF, clazz.getSimpleName(), name, clazz.getSimpleName(), buildArguments())))
                .collect(Collectors.toList());
    }

    private List buildSetter() {
        return concatenate(
                buildChildren(),
                Stream.of(String.format(NEW_OBJECT, PSF, clazz.getSimpleName(), name, clazz.getSimpleName())),
                startStaticBlock(),
                createMethods(),
                endStaticBlock()
        ).collect(Collectors.toList());
    }

    private List buildBuilder() {
        return concatenate(
                buildChildren(),
                Stream.of(String.format(BUILDER, PSF, clazz.getSimpleName(), name, clazz.getSimpleName(), BUILDER_METHOD)),
                createMethods(),
                endBuilder()
        ).collect(Collectors.toList());
    }

    private List buildMethod() {
        return buildChildren().collect(Collectors.toList());
    }

    private List buildSet() {
        return buildCollection();
    }

    private List buildSetOf() {
        return concatenate(
                buildChildren(),
                Stream.of(String.format(SET_OF, PSF, clazz.getSimpleName(), formatTypes(), name, getNullableArguments(buildArguments()))))
                .collect(Collectors.toList());
    }

    private List buildList() {
        return buildCollection();
    }

    private List buildListOf() {
        return concatenate(
                buildChildren(),
                Stream.of(String.format(LIST_OF, PSF, clazz.getSimpleName(), formatTypes(), name, getNullableArguments(buildArguments()))))
                .collect(Collectors.toList());
    }

    private List buildMap() {
        return buildCollection();
    }

    private List buildMapOf() {
        return concatenate(
                buildChildren(),
                Stream.of(String.format(MAP_OF, PSF, clazz.getSimpleName(), formatTypes(), name, getNullableArguments(buildArguments()))))
                .collect(Collectors.toList());
    }

    private List buildArray() {
        return concatenate(
                buildChildren(),
                Stream.of(String.format(NEW_ARRAY, PSF, clazz.getSimpleName(), name, clazz.getSimpleName(), buildArguments())))
                .collect(Collectors.toList());
    }

    private List buildCollection() {
        if (collectionHasNullValues(this)) {
            return concatenate(
                    buildChildren(),
                    Stream.of(String.format(NEW_TYPED_OBJECT, PSF, clazz.getSimpleName(), formatTypes(), name, clazz.getSimpleName())))
                    .collect(Collectors.toList());
        }
        return concatenate(
                buildChildren(),
                Stream.of(String.format(NEW_TYPED_OBJECT, PSF, clazz.getSimpleName(), formatTypes(), name, clazz.getSimpleName())),
                startStaticBlock(),
                createMethods(),
                endStaticBlock()
        ).collect(Collectors.toList());
    }

    private List buildValue() {
        if (isNullValue()) {
            return List.of();
        }
        return List.of(String.format(NEW_VALUE, PSF, clazz.getSimpleName(), name, value));
    }

    public boolean isNullValue() {
        return value != null && value.equals(NULL);
    }

    private Stream createMethods() {
        return children.stream()
                .map(child -> buildType == BuildType.BUILDER ?
                        String.format(".%s(%s)", child.getName(), child.buildArguments()) :
                        String.format("%s.%s(%s);", name, child.getName(), child.buildArguments()));
    }

    private static String getNullableArguments(String buildArguments) {
        return Arrays.asList(buildArguments.split(ARGUMENT_DELIMITER)).contains(NULL) ? "" : buildArguments;
    }

    private String buildArguments() {
        return children.stream()
                .map(child -> {
                    if (child.isNullValue()) {
                        return List.of(NULL);
                    }
                    if (isBasicValue(child)) {
                        return child.buildInlineArgument();
                    }
                    return List.of(child.getName());
                }).flatMap(Collection::stream)
                .collect(Collectors.joining(ARGUMENT_DELIMITER));
    }

    private List buildInlineArgument() {
        return List.of(this.value);
    }

    private String formatTypes() {
        return children.stream()
                .map(child -> {
                    if (child.getClazz() == null) {
                        return child.formatTypes();
                    }
                    if (child.getBuildType().isParameterizedType()) {
                        return String.format("%s<%s>", child.getClazz().getSimpleName(), child.formatTypes());
                    } else {
                        return child.getClazz().getSimpleName();
                    }
                }).collect(Collectors.joining(ARGUMENT_DELIMITER));

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy