
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