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

io.polyglotted.common.model.Builder Maven / Gradle / Ivy

package io.polyglotted.common.model;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.Map;

import static io.polyglotted.common.util.NullUtil.nonNullFn;
import static io.polyglotted.common.util.ReflectionUtil.annotation;
import static io.polyglotted.common.util.ReflectionUtil.create;
import static io.polyglotted.common.util.ReflectionUtil.declaredField;
import static io.polyglotted.common.util.ReflectionUtil.declaredMethod;
import static io.polyglotted.common.util.ReflectionUtil.detectValueClass;
import static io.polyglotted.common.util.ReflectionUtil.safeInvoke;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

public interface Builder {
    T build();

    @Documented @Retention(RUNTIME)
    @Target(FIELD) @interface Name {
        String value();
    }

    static > T buildWith(Map mapResult, Class clazz) { return buildWith(mapResult, clazz, false); }

    @SuppressWarnings("unchecked") static > T buildWith(Map mapResult, Class clazz, boolean inclMeta) {
        T built = builder(mapResult, clazz).build();
        return (inclMeta && built instanceof HasMeta) ? (T) ((HasMeta) built).withMetas(mapResult) : built;
    }

    @SuppressWarnings("unchecked") static > C builder(Map mapResult, Class clazz) {
        C builder = (C) create(clazz);
        for (Field field : clazz.getDeclaredFields()) {
            Object value = mapResult.get(field.getName());
            if (value == null) { value = mapResult.get(nonNullFn(annotation(field, Builder.Name.class), Builder.Name::value, "_$")); }

            if (value != null) {
                Class valueClass = detectValueClass(value, () -> declaredField(clazz, field.getName()));
                try {
                    safeInvoke(declaredMethod(clazz, field.getName(), new Class[]{valueClass}), builder, value);
                } catch (Exception ex) { throw new RuntimeException("failed invoke " + field.getName(), ex); }
            }
        }
        return builder;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy