package droidkit.content;
import android.support.annotation.NonNull;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author Daniel Serdyukov
*/
class KeyValueProxy implements InvocationHandler {
private final Map<String, TypedValue> mKeyValue = new ConcurrentHashMap<>();
private final KeyValueDelegate mDelegate;
protected KeyValueProxy(@NonNull KeyValueDelegate delegate) {
mDelegate = delegate;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
final String key = extractKey(method);
final Class<?> returnType = method.getReturnType();
if (IntValue.class.isAssignableFrom(returnType)) {
return getIntValue(key, IntValue.EMPTY);
} else if (StringValue.class.isAssignableFrom(returnType)) {
return getStringValue(key, StringValue.EMPTY);
} else if (BoolValue.class.isAssignableFrom(returnType)) {
return getBoolValue(key, BoolValue.EMPTY);
} else if (LongValue.class.isAssignableFrom(returnType)) {
return getLongValue(key, LongValue.EMPTY);
} else if (DoubleValue.class.isAssignableFrom(returnType)) {
return getDoubleValue(key, DoubleValue.EMPTY);
} else if (FloatValue.class.isAssignableFrom(returnType)) {
return getFloatValue(key, FloatValue.EMPTY);
} else if (StringSetValue.class.isAssignableFrom(returnType)) {
return getStringSetValue(key);
} else if (StringListValue.class.isAssignableFrom(returnType)) {
return getStringListValue(key);
} else if (ParcelableValue.class.isAssignableFrom(returnType)) {
return getParcelableValue(key);
}
return invokeForKey(key, returnType);
}
protected Object invokeForKey(String key, Class<?> returnType) {
throw new UnsupportedOperationException("No such value for key='" + key + "' with type '" + returnType + "'");
}
@NonNull
private String extractKey(@NonNull Method method) {
return method.getName();
}
@NonNull
private IntValue getIntValue(@NonNull String key, int defaultValue) {
IntValue value = (IntValue) mKeyValue.get(key);
if (value == null) {
value = new IntValue(mDelegate, key, defaultValue);
mKeyValue.put(key, value);
}
return value;
}
@NonNull
private StringValue getStringValue(@NonNull String key, String defaultValue) {
StringValue value = (StringValue) mKeyValue.get(key);
if (value == null) {
value = new StringValue(mDelegate, key, defaultValue);
mKeyValue.put(key, value);
}
return value;
}
@NonNull
private BoolValue getBoolValue(@NonNull String key, boolean defaultValue) {
BoolValue value = (BoolValue) mKeyValue.get(key);
if (value == null) {
value = new BoolValue(mDelegate, key, defaultValue);
mKeyValue.put(key, value);
}
return value;
}
@NonNull
private LongValue getLongValue(@NonNull String key, long defaultValue) {
LongValue value = (LongValue) mKeyValue.get(key);
if (value == null) {
value = new LongValue(mDelegate, key, defaultValue);
mKeyValue.put(key, value);
}
return value;
}
@NonNull
private DoubleValue getDoubleValue(@NonNull String key, double defaultValue) {
DoubleValue value = (DoubleValue) mKeyValue.get(key);
if (value == null) {
value = new DoubleValue(mDelegate, key, defaultValue);
mKeyValue.put(key, value);
}
return value;
}
@NonNull
private FloatValue getFloatValue(@NonNull String key, float defaultValue) {
FloatValue value = (FloatValue) mKeyValue.get(key);
if (value == null) {
value = new FloatValue(mDelegate, key, defaultValue);
mKeyValue.put(key, value);
}
return value;
}
@NonNull
private StringSetValue getStringSetValue(@NonNull String key) {
StringSetValue value = (StringSetValue) mKeyValue.get(key);
if (value == null) {
value = new StringSetValue(mDelegate, key);
mKeyValue.put(key, value);
}
return value;
}
@NonNull
private StringListValue getStringListValue(@NonNull String key) {
StringListValue value = (StringListValue) mKeyValue.get(key);
if (value == null) {
value = new StringListValue(mDelegate, key);
mKeyValue.put(key, value);
}
return value;
}
@NonNull
private ParcelableValue getParcelableValue(@NonNull String key) {
ParcelableValue value = (ParcelableValue) mKeyValue.get(key);
if (value == null) {
value = new ParcelableValue(mDelegate, key);
mKeyValue.put(key, value);
}
return value;
}
}