use of org.spongepowered.api.registry.RegistryType in project SpongeCommon by SpongePowered.
the class SpongeDataStoreBuilder method getDeserializer.
@SuppressWarnings({ "rawtypes", "unchecked" })
public <T> BiFunction<DataView, DataQuery, Optional<T>> getDeserializer(final Type elementType) {
final Class<?> rawType = GenericTypeReflector.erase(elementType);
if (DataView.class.isAssignableFrom(rawType)) {
return (view, dataQuery) -> (Optional<T>) view.getView(dataQuery);
}
if (DataSerializable.class.isAssignableFrom(rawType)) {
return (view, dataQuery) -> (Optional<T>) view.getSerializable(dataQuery, (Class<? extends DataSerializable>) rawType);
}
final Optional<RegistryType<Object>> registryTypeForValue = SpongeDataManager.INSTANCE.findRegistryTypeFor(rawType);
if (registryTypeForValue.isPresent()) {
return (view, dataQuery) -> (Optional<T>) registryTypeForValue.flatMap(regType -> view.getRegistryValue(dataQuery, regType));
}
if (ResourceKey.class.isAssignableFrom(rawType)) {
return (view, dataQuery) -> (Optional<T>) view.getString(dataQuery).map(ResourceKey::resolve);
}
if (Sponge.game().dataManager().translator(rawType).isPresent()) {
return (view, dataQuery) -> (Optional<T>) view.getObject(dataQuery, rawType);
}
if (Set.class.isAssignableFrom(rawType)) {
final Type listType = ((ParameterizedType) elementType).getActualTypeArguments()[0];
return (view, dataQuery) -> (Optional<T>) SpongeDataStoreBuilder.deserializeList((Class<?>) listType, view, dataQuery).map(list -> new HashSet(list));
}
if (List.class.isAssignableFrom(rawType)) {
final Type listType = ((ParameterizedType) elementType).getActualTypeArguments()[0];
return (view, dataQuery) -> (Optional<T>) SpongeDataStoreBuilder.deserializeList((Class<?>) listType, view, dataQuery);
}
if (Collection.class.isAssignableFrom(rawType)) {
throw new UnsupportedOperationException("Collection deserialization is not supported. Provide the deserializer for it.");
}
if (Types.isArray(elementType)) {
final Class arrayType = GenericTypeReflector.erase(GenericTypeReflector.getArrayComponentType(elementType));
return (view, dataQuery) -> (Optional<T>) SpongeDataStoreBuilder.deserializeList((Class<?>) arrayType, view, dataQuery).map(list -> this.listToArray(arrayType, list));
}
if (Map.class.isAssignableFrom(rawType)) {
final Type[] parameterTypes = ((ParameterizedType) elementType).getActualTypeArguments();
final Type keyType = parameterTypes[0];
final Type valueType = parameterTypes[1];
if (!(keyType instanceof Class)) {
throw new UnsupportedOperationException("Unsupported map-key type " + keyType);
}
final Function<DataQuery, Optional<?>> keyDeserializer;
final Optional<RegistryType<Object>> registryTypeForKey = SpongeDataManager.INSTANCE.findRegistryTypeFor((Class) keyType);
if (registryTypeForKey.isPresent()) {
keyDeserializer = key -> registryTypeForKey.flatMap(regType -> Sponge.game().findRegistry(regType)).flatMap(r -> r.findValue(ResourceKey.resolve(key.toString())));
} else if (((Class<?>) keyType).isEnum()) {
keyDeserializer = key -> Optional.ofNullable(Enum.valueOf(((Class<? extends Enum>) keyType), key.toString()));
} else if (keyType == String.class) {
keyDeserializer = key -> Optional.of(key.toString());
} else if (keyType == UUID.class) {
keyDeserializer = key -> Optional.of(UUID.fromString(key.toString()));
} else if (keyType == ResourceKey.class) {
keyDeserializer = key -> Optional.of(ResourceKey.resolve(key.toString()));
} else {
throw new UnsupportedOperationException("Unsupported map-key type " + keyType);
}
final BiFunction<DataView, DataQuery, Optional<Object>> valueDeserializer = this.getDeserializer(valueType);
return (view, dataQuery) -> (Optional<T>) view.getView(dataQuery).map(mapView -> {
final Map<Object, Object> resultMap = new HashMap<>();
for (final DataQuery key : mapView.keys(false)) {
final Object mapKey = keyDeserializer.apply(key).orElseThrow(() -> new UnsupportedOperationException("Key not found " + key + " as " + keyType));
final Optional<?> mapValue = valueDeserializer.apply(mapView, key);
resultMap.put(mapKey, mapValue.get());
}
return resultMap;
});
}
return (view, dataQuery) -> (Optional<T>) view.get(dataQuery);
}
Aggregations