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

io.tracee.contextlogger.outputgenerator.RecursiveOutputElementTreeBuilderImpl Maven / Gradle / Ivy

package io.tracee.contextlogger.outputgenerator;

import java.util.Collection;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.tracee.contextlogger.impl.ContextLoggerConfiguration;
import io.tracee.contextlogger.outputgenerator.functions.ArrayToOutputElementTransformerFunction;
import io.tracee.contextlogger.outputgenerator.functions.AtomicToOutputElementTransformerFunction;
import io.tracee.contextlogger.outputgenerator.functions.BeanToOutputElementTransformerFunction;
import io.tracee.contextlogger.outputgenerator.functions.CollectionToOutputElementTransformerFunction;
import io.tracee.contextlogger.outputgenerator.functions.MapToOutputElementTransformerFunction;
import io.tracee.contextlogger.outputgenerator.functions.TraceeContextProviderToOutputElementTransformerFunction;
import io.tracee.contextlogger.outputgenerator.functions.TraceeContextProviderWrapperFunction;
import io.tracee.contextlogger.outputgenerator.outputelements.NullValueOutputElement;
import io.tracee.contextlogger.outputgenerator.outputelements.OutputElement;
import io.tracee.contextlogger.outputgenerator.predicates.IsBeanTypePredicate;
import io.tracee.contextlogger.outputgenerator.predicates.IsCollectionTypePredicate;
import io.tracee.contextlogger.outputgenerator.predicates.IsMapTypePredicate;
import io.tracee.contextlogger.outputgenerator.predicates.IsTraceeContextProviderPredicate;
import io.tracee.contextlogger.profile.ProfileSettings;

/**
 * Creates output element tree for the passed instance recursively. Acts as scheduler for ToOutputTransformerFunctions invocations.
 */
public class RecursiveOutputElementTreeBuilderImpl implements RecursiveOutputElementTreeBuilder {

    private static final Logger logger = LoggerFactory.getLogger(RecursiveOutputElementTreeBuilderImpl.class);

    private final InstanceToOutputElementPool instanceToOutputElementPool;
    private final ContextLoggerConfiguration contextLoggerConfiguration;
    private final ProfileSettings profileSettings;

    /**
     * Main constructor.
     *
     * @param profileSettings the profile settings to use.
     */
    public RecursiveOutputElementTreeBuilderImpl(final ProfileSettings profileSettings) {
        this(profileSettings, new InstanceToOutputElementPool(), ContextLoggerConfiguration.getOrCreateContextLoggerConfiguration());

    }

    /**
     * Constructor used by tests.
     *
     * @param profileSettings the profile settings to use.
     * @param instanceToOutputElementPool the instance output element
     * @param contextLoggerConfiguration The context logger configuration to use
     */
    protected RecursiveOutputElementTreeBuilderImpl(final ProfileSettings profileSettings, final InstanceToOutputElementPool instanceToOutputElementPool,
            final ContextLoggerConfiguration contextLoggerConfiguration) {
        this.profileSettings = profileSettings;
        this.instanceToOutputElementPool = instanceToOutputElementPool;
        this.contextLoggerConfiguration = contextLoggerConfiguration;
    }

    @Override
    public OutputElement convertInstanceRecursively(final RecursiveOutputElementTreeBuilderState state, final Object passedInstanceToDeserialize) {

        OutputElement outputElement = null;

        if (passedInstanceToDeserialize == null) {

            // handle null value
            outputElement = NullValueOutputElement.INSTANCE;

        }
        else if (state.maxDepthReached()) {
            // fallback deserialize instance as atomic value
            outputElement = AtomicToOutputElementTransformerFunction.getInstance().apply(this, state.next(),
                    TraceeContextProviderWrapperFunction.getInstance().apply(contextLoggerConfiguration, passedInstanceToDeserialize));

        }
        else {

            // wraps passed instance in tracee context provider if possible or otherwise returns the passed instance
            Object instanceToDeserialize = TraceeContextProviderWrapperFunction.getInstance()
                    .apply(contextLoggerConfiguration, passedInstanceToDeserialize);

            // abort execution if class is disabled
            Boolean isClassActive = profileSettings.getPropertyValue(instanceToDeserialize.getClass().getCanonicalName());
            if (isClassActive != null && !isClassActive) {
                return null;
            }

            if (IsCollectionTypePredicate.getInstance().apply(instanceToDeserialize)) {
                // handle arrays and collections

                if (instanceToDeserialize.getClass().isArray()) {
                    outputElement = ArrayToOutputElementTransformerFunction.getInstance().apply(this, state.next(), (Object[])instanceToDeserialize);
                }
                else {
                    outputElement = CollectionToOutputElementTransformerFunction.getInstance().apply(this, state.next(), (Collection)instanceToDeserialize);
                }

            }
            else if (IsMapTypePredicate.getInstance().apply(instanceToDeserialize)) {

                outputElement = MapToOutputElementTransformerFunction.getInstance().apply(this, state.next(), (Map)instanceToDeserialize);

            }
            else if (IsTraceeContextProviderPredicate.getInstance().apply(instanceToDeserialize)) {

                outputElement = TraceeContextProviderToOutputElementTransformerFunction.getInstance().apply(this, state.next(), instanceToDeserialize);

            }
            else if (IsBeanTypePredicate.getInstance().apply(instanceToDeserialize)) {

                outputElement = BeanToOutputElementTransformerFunction.getInstance().apply(this, state.next(), instanceToDeserialize);

            }
            else {
                // fallback deserialize instance as atomic value
                outputElement = AtomicToOutputElementTransformerFunction.getInstance().apply(this, state.next(), instanceToDeserialize);
            }

        }
        return outputElement;
    }

    @Override
    public void registerOutputElement(final OutputElement outputElement) {

        if (outputElement != null && outputElement.getEncapsulatedInstance() != null) {
            this.instanceToOutputElementPool.add(outputElement);
        }
    }

    @Override
    public boolean checkIfInstanceIsAlreadyRegistered(final OutputElement outputElement) {

        return outputElement != null && this.instanceToOutputElementPool.isInstanceMarkedAsProcessed(outputElement);

    }

    @Override
    public OutputElement getRegisteredOutputElementAndMarkItAsMultipleRegistered(final OutputElement outputElement) {
        OutputElement alreadyRegisteredOutputElement = this.instanceToOutputElementPool.getOutputElement(outputElement);
        if (alreadyRegisteredOutputElement != null) {
            alreadyRegisteredOutputElement.setIsMarkedAsMultipleReferenced();
        }
        return alreadyRegisteredOutputElement;
    }

    @Override
    public ProfileSettings getProfileSettings() {
        return this.profileSettings;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy