Search in sources :

Example 1 with RegistryType

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);
}
Also used : DataContainer(org.spongepowered.api.data.persistence.DataContainer) Array(java.lang.reflect.Array) BiFunction(java.util.function.BiFunction) HashMap(java.util.HashMap) DataView(org.spongepowered.api.data.persistence.DataView) Function(java.util.function.Function) Value(org.spongepowered.api.data.value.Value) SpongeDataManager(org.spongepowered.common.data.SpongeDataManager) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) DataStore(org.spongepowered.api.data.persistence.DataStore) ImmutableList(com.google.common.collect.ImmutableList) DataQuery(org.spongepowered.api.data.persistence.DataQuery) Map(java.util.Map) BiConsumer(java.util.function.BiConsumer) ResourceKey(org.spongepowered.api.ResourceKey) Nullable(org.checkerframework.checker.nullness.qual.Nullable) DataContentUpdater(org.spongepowered.api.data.persistence.DataContentUpdater) Types(org.spongepowered.configurate.util.Types) IdentityHashMap(java.util.IdentityHashMap) DataSerializable(org.spongepowered.api.data.persistence.DataSerializable) ImmutableMap(com.google.common.collect.ImmutableMap) Collection(java.util.Collection) Sponge(org.spongepowered.api.Sponge) Set(java.util.Set) DataHolder(org.spongepowered.api.data.DataHolder) RegistryType(org.spongepowered.api.registry.RegistryType) Tuple(org.spongepowered.api.util.Tuple) UUID(java.util.UUID) TypeToken(io.leangen.geantyref.TypeToken) DataUtil(org.spongepowered.common.data.DataUtil) Key(org.spongepowered.api.data.Key) List(java.util.List) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) Optional(java.util.Optional) GenericTypeReflector(io.leangen.geantyref.GenericTypeReflector) Collections(java.util.Collections) Optional(java.util.Optional) RegistryType(org.spongepowered.api.registry.RegistryType) DataSerializable(org.spongepowered.api.data.persistence.DataSerializable) ParameterizedType(java.lang.reflect.ParameterizedType) DataView(org.spongepowered.api.data.persistence.DataView) RegistryType(org.spongepowered.api.registry.RegistryType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) DataQuery(org.spongepowered.api.data.persistence.DataQuery) UUID(java.util.UUID) HashMap(java.util.HashMap) Map(java.util.Map) IdentityHashMap(java.util.IdentityHashMap) ImmutableMap(com.google.common.collect.ImmutableMap) HashSet(java.util.HashSet)

Aggregations

ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 GenericTypeReflector (io.leangen.geantyref.GenericTypeReflector)1 TypeToken (io.leangen.geantyref.TypeToken)1 Array (java.lang.reflect.Array)1 ParameterizedType (java.lang.reflect.ParameterizedType)1 Type (java.lang.reflect.Type)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 IdentityHashMap (java.util.IdentityHashMap)1 List (java.util.List)1 Map (java.util.Map)1 Optional (java.util.Optional)1 Set (java.util.Set)1 UUID (java.util.UUID)1 BiConsumer (java.util.function.BiConsumer)1 BiFunction (java.util.function.BiFunction)1