Marinara/lib/src/main/java/net/tomatentum/marinara/wrapper/IdentifierProvider.java
tueem 4c5e28b679
All checks were successful
github-mirror / push-github (push) Successful in 3s
Build / Gradle-Build (push) Successful in 38s
Test / Gradle-Test (push) Successful in 51s
feat(logging): replace log4j dependency with slf4j and replace imports
2025-03-17 10:52:24 +01:00

73 lines
2.5 KiB
Java

package net.tomatentum.marinara.wrapper;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import io.leangen.geantyref.GenericTypeReflector;
import net.tomatentum.marinara.interaction.ident.InteractionIdentifier;
import net.tomatentum.marinara.util.LoggerUtil;
import net.tomatentum.marinara.util.ReflectionUtil;
public class IdentifierProvider {
public static IdentifierProvider of(Converter<?>... converter) {
return new IdentifierProvider(Arrays.asList(converter));
}
private Map<Class<?>, Converter<?>> converter;
private Logger logger = LoggerUtil.getLogger(getClass());
private IdentifierProvider(List<Converter<?>> converter) {
this.converter = new HashMap<>();
for (Converter<?> conv : converter) {
if (conv.getClass().getName().contains("$$Lambda"))
throw new IllegalArgumentException("Lambdas cannot be used for IdentifierConverter because of Type erasure.");
Type type = GenericTypeReflector.getExactSuperType(conv.getClass(), Converter.class);
Type parameterType = (Class<?>) ((ParameterizedType) type).getActualTypeArguments()[0];
if (!(parameterType instanceof Class))
throw new IllegalArgumentException("Only full Class types are supported by IdentiferConverters");
this.converter.put((Class<?>) parameterType, conv);
}
}
public InteractionIdentifier provide(Object context) {
Type type = ReflectionUtil.getMostSpecificClass(
converter.keySet().stream().filter(x -> x.isAssignableFrom(context.getClass())).toArray(Class<?>[]::new),
context.getClass());
if (type == null)
logger.debug("No Identifier converter found for context {}", context.getClass().toString());
@SuppressWarnings("unchecked")
Converter<Object> conv = (Converter<Object>) converter.get(type);
return conv.convert(context);
}
@FunctionalInterface
public interface Converter<T extends Object> {
InteractionIdentifier convert(T context);
}
public static class LambdaWrapper<T extends Object> implements Converter<T> {
private Converter<T> converter;
LambdaWrapper(Converter<T> converter) {
this.converter = converter;
}
@Override
public InteractionIdentifier convert(T context) {
return this.converter.convert(context);
}
}
}