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

ru.progrm_jarvis.javacommons.delegate.CachingGeneratingDelegateFactory Maven / Gradle / Ivy

package ru.progrm_jarvis.javacommons.delegate;

import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import ru.progrm_jarvis.javacommons.cache.Cache;

import java.util.function.Supplier;

/**
 * Base for implementing {@link DelegateFactory delegate factory}
 * using internal {@link DelegateWrapperFactory} cached for each unique type.
 */
@RequiredArgsConstructor
public abstract class CachingGeneratingDelegateFactory implements DelegateFactory {

    /**
     * Cache of {@link DelegateWrapperFactory delegate-wrapper factories} by wrapped types
     */
    protected final @NonNull Cache, DelegateWrapperFactory> factories;

    /**
     * Creates a {@link DelegateWrapperFactory delegate-wrapper factory} fot the given type.
     *
     * @param targetType type of the wrapper to be created by the factory
     * @param  created wrapper's type
     * @return delegate-wrapper factory for the given type
     */
    protected abstract  @NotNull DelegateWrapperFactory createFactory(@NotNull Class targetType);

    @Override
    public  @NotNull T createWrapper(final @NonNull Class targetType, final @NonNull Supplier supplier) {
        return CachingGeneratingDelegateFactory.uncheckedDelegateWrapperFactoryCast(
                factories.get(targetType, actualTargetType -> {
                    // validation happens only on creation of the wrapper
                    DelegateFactory.verifyTargetType(actualTargetType);

                    return createFactory(actualTargetType);
                })
        ).create(supplier);
    }

    /**
     * Delegate-wrapper factory responsible for creating delegate wrappers based on the specified supplier.
     *
     * @param  type of the wrapper which this factory produces
     */
    @FunctionalInterface
    protected interface DelegateWrapperFactory {

        /**
         * Creates a new delegate-wrapper based on the given supplier.
         *
         * @param supplier supplier used to create the object
         * as specified by {@link DelegateFactory#createWrapper(Class, Supplier)}
         * @return delegate wrapper created for the given supplier
         */
        @NotNull T create(@NotNull Supplier supplier);
    }

    /**
     * Casts the given delegate wrapper factory into the specific one.
     *
     * @param type raw-typed delegate wrapper factory
     * @param  exact wanted type of delegate wrapper factory
     * @return the provided delegate wrapper factory with its type case to the specific one
     *
     * @apiNote this is effectively no-op
     */
    // note: no nullability annotations are present on parameter and return type as cast of `null` is also safe
    @Contract("_ -> param1")
    @SuppressWarnings("unchecked")
    private static  DelegateWrapperFactory uncheckedDelegateWrapperFactoryCast(
            final DelegateWrapperFactory type
    ) {
        return (DelegateWrapperFactory) type;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy