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

org.javers.shadow.ShadowBuilder Maven / Gradle / Ivy

package org.javers.shadow;

import org.javers.core.metamodel.object.CdoSnapshot;
import org.javers.core.metamodel.type.EnumerableType;
import org.javers.core.metamodel.type.JaversProperty;

import java.util.HashSet;
import java.util.Set;

/**
 * @author bartosz.walacik
 */
class ShadowBuilder {
    private final CdoSnapshot cdoSnapshot;
    private Object shadow;
    private Set wirings = new HashSet<>();

    ShadowBuilder(CdoSnapshot cdoSnapshot, Object shadow) {
        this.cdoSnapshot = cdoSnapshot;
        this.shadow = shadow;
    }

    void withStub(Object shadowStub) {
        this.shadow = shadowStub;
    }

    Object getShadow() {
        return shadow;
    }

    /**
     * nullable
     */
    CdoSnapshot getCdoSnapshot() {
        return cdoSnapshot;
    }

    void addReferenceWiring(JaversProperty property, ShadowBuilder targetShadow) {
        this.wirings.add(new ReferenceWiring(property, targetShadow));
    }

    void addEnumerableWiring(JaversProperty property, Object targetWithShadows) {
        this.wirings.add(new EnumerableWiring(property, targetWithShadows));
    }

    void wire() {
        wirings.forEach(Wiring::wire);
    }

    private abstract class Wiring {
        final JaversProperty property;

        Wiring(JaversProperty property) {
            this.property = property;
        }

        abstract void wire();
    }

    private class ReferenceWiring extends Wiring {
        final ShadowBuilder target;

        ReferenceWiring(JaversProperty property, ShadowBuilder targetShadow) {
            super(property);
            this.target = targetShadow;
        }

        @Override
        void wire() {
            property.set(shadow, target.shadow);
        }
    }

    private class EnumerableWiring extends Wiring {
        final Object targetWithShadows;

        EnumerableWiring(JaversProperty property, Object targetWithShadows) {
            super(property);
            this.targetWithShadows = targetWithShadows;
        }

        @Override
        void wire() {
            EnumerableType propertyType = property.getType();

            Object targetContainer = propertyType.map(targetWithShadows, (valueOrShadow) -> {
                if (valueOrShadow instanceof ShadowBuilder) {
                    //injecting reference to shadow
                    return ((ShadowBuilder) valueOrShadow).shadow;
                }
                return valueOrShadow; //vale is passed as is
            });

            property.set(shadow, targetContainer);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy