diff options
author | Dico200 <dico.karssiens@gmail.com> | 2018-07-25 01:53:23 +0100 |
---|---|---|
committer | Dico200 <dico.karssiens@gmail.com> | 2018-07-25 01:53:23 +0100 |
commit | 44587e49ff1840219d9bc44844d4a3a6cd8ac5de (patch) | |
tree | 276ae9625795e9d79fc7db8592dbcb3a1af60928 /dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/MapBasedParameterTypeSelector.java | |
parent | 5e168847c2624b767deb9da310ecfdf169e0f43c (diff) |
Add dicore3-command
Diffstat (limited to 'dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/MapBasedParameterTypeSelector.java')
-rw-r--r-- | dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/MapBasedParameterTypeSelector.java | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/MapBasedParameterTypeSelector.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/MapBasedParameterTypeSelector.java new file mode 100644 index 0000000..4e475fe --- /dev/null +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/MapBasedParameterTypeSelector.java @@ -0,0 +1,109 @@ +package io.dico.dicore.command.parameter.type; + +import java.lang.annotation.Annotation; +import java.util.HashMap; +import java.util.Map; + +/** + * Map based implementation of {@link IParameterTypeSelector} + */ +public class MapBasedParameterTypeSelector implements IParameterTypeSelector { + static final MapBasedParameterTypeSelector defaultSelector = new MapBasedParameterTypeSelector(false); + private final Map<ParameterKey, ParameterType<?, ?>> parameterTypeMap; + private final boolean useDefault; + + public MapBasedParameterTypeSelector(boolean useDefault) { + this.parameterTypeMap = new HashMap<>(); + this.useDefault = useDefault; + } + + @Override + public <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectExact(ParameterKey key) { + ParameterType<?, ?> out = parameterTypeMap.get(key); + if (useDefault && out == null) { + out = defaultSelector.selectExact(key); + } + return cast(out); + } + + @Override + public <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectAny(ParameterKey key) { + ParameterType<TReturn, TParamInfo> exact = selectExact(key); + if (exact != null) { + return exact; + } + + if (key.getAnnotationClass() != null) { + exact = selectExact(new ParameterKey(key.getReturnType())); + if (exact != null) { + return exact; + } + } + + Class<?> returnType = key.getReturnType(); + Class<? extends Annotation> annotationClass = key.getAnnotationClass(); + + ParameterType<?, ?> out = selectByReturnType(parameterTypeMap, returnType, annotationClass, false); + if (out == null && useDefault) { + out = selectByReturnType(defaultSelector.parameterTypeMap, returnType, annotationClass, false); + } + if (out == null) { + out = selectByReturnType(parameterTypeMap, returnType, annotationClass, true); + } + if (out == null && useDefault) { + out = selectByReturnType(defaultSelector.parameterTypeMap, returnType, annotationClass, true); + } + return cast(out); + } + + private static ParameterType<?, ?> selectByReturnType(Map<ParameterKey, ParameterType<?, ?>> map, Class<?> returnType, + Class<? extends Annotation> annotationClass, boolean allowSubclass) { + ParameterType<?, ?> out = null; + if (allowSubclass) { + for (ParameterType<?, ?> type : map.values()) { + if (returnType.isAssignableFrom(type.getReturnType())) { + if (annotationClass == type.getAnnotationClass()) { + out = type; + break; + } + if (out == null) { + out = type; + } + } + } + } else { + for (ParameterType<?, ?> type : map.values()) { + if (returnType == type.getReturnType()) { + if (annotationClass == type.getAnnotationClass()) { + out = type; + break; + } + if (out == null) { + out = type; + } + } + } + } + return out; + } + + private static <T> T cast(Object o) { + //noinspection unchecked + return (T) o; + } + + @Override + public void addType(boolean infolessAlias, ParameterType<?, ?> type) { + parameterTypeMap.put(type.getTypeKey(), type); + + if (infolessAlias) { + parameterTypeMap.putIfAbsent(type.getInfolessTypeKey(), type); + } + } + + static { + // registers default parameter types + ParameterTypes.clinit(); + } + +} |