Search in sources :

Example 1 with DataSerializable

use of org.spongepowered.api.data.persistence.DataSerializable in project SpongeCommon by SpongePowered.

the class MemoryDataView method setCollection.

@SuppressWarnings({ "unchecked", "rawtypes" })
private void setCollection(final String key, final Collection<?> value) {
    final ImmutableList.Builder<Object> builder = ImmutableList.builder();
    @Nullable DataManager manager;
    try {
        manager = Sponge.dataManager();
    } catch (final Exception e) {
        manager = null;
    }
    for (final Object object : value) {
        if (object instanceof DataSerializable) {
            builder.add(((DataSerializable) object).toContainer());
        } else if (object instanceof DataView) {
            if (this.safety == org.spongepowered.api.data.persistence.DataView.SafetyMode.ALL_DATA_CLONED || this.safety == org.spongepowered.api.data.persistence.DataView.SafetyMode.CLONED_ON_SET) {
                final MemoryDataView view = new MemoryDataContainer(this.safety);
                final DataView internalView = (DataView) object;
                for (final Map.Entry<DataQuery, Object> entry : internalView.values(false).entrySet()) {
                    view.set(entry.getKey(), entry.getValue());
                }
                builder.add(view);
            } else {
                builder.add(object);
            }
        } else if (object instanceof ResourceKey) {
            builder.add(object.toString());
        } else if (object instanceof Map) {
            builder.add(this.ensureSerialization((Map) object));
        } else if (object instanceof Collection) {
            builder.add(this.ensureSerialization((Collection) object));
        } else {
            if (manager != null) {
                final Optional<? extends DataTranslator<?>> translatorOptional = manager.translator(object.getClass());
                if (translatorOptional.isPresent()) {
                    final DataTranslator translator = translatorOptional.get();
                    final DataContainer container = translator.translate(object);
                    checkArgument(!container.equals(this), "Cannot insert self-referencing Objects!");
                    builder.add(container);
                } else {
                    builder.add(object);
                }
            } else {
                builder.add(object);
            }
        }
    }
    this.map.put(key, builder.build());
}
Also used : DataTranslator(org.spongepowered.api.data.persistence.DataTranslator) ImmutableList(com.google.common.collect.ImmutableList) DataManager(org.spongepowered.api.data.DataManager) DataSerializable(org.spongepowered.api.data.persistence.DataSerializable) ResourceKey(org.spongepowered.api.ResourceKey) DataView(org.spongepowered.api.data.persistence.DataView) DataContainer(org.spongepowered.api.data.persistence.DataContainer) Collection(java.util.Collection) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Example 2 with DataSerializable

use of org.spongepowered.api.data.persistence.DataSerializable in project SpongeCommon by SpongePowered.

the class MemoryDataView method set.

@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public DataView set(final DataQuery path, final Object value) {
    Objects.requireNonNull(path, "path");
    Objects.requireNonNull(value, "value");
    checkState(this.container != null);
    checkState(!path.parts().isEmpty(), "The path is empty");
    @Nullable DataManager manager;
    // TODO: this call to dataManager each set can be cleaned up
    try {
        manager = Sponge.dataManager();
    } catch (final Exception e) {
        manager = null;
    }
    final List<String> parts = path.parts();
    final String key = parts.get(0);
    if (parts.size() > 1) {
        final DataQuery subQuery = DataQuery.of(key);
        final Optional<DataView> subViewOptional = this.getUnsafeView(subQuery);
        final DataView subView;
        if (!subViewOptional.isPresent()) {
            this.createView(subQuery);
            subView = (DataView) this.map.get(key);
        } else {
            subView = subViewOptional.get();
        }
        subView.set(path.popFirst(), value);
        return this;
    }
    if (value instanceof DataView) {
        checkArgument(value != this, "Cannot set a DataView to itself.");
        // always have to copy a data view to avoid overwriting existing
        // views and to set the interior path correctly.
        this.copyDataView(path, (DataView) value);
    } else if (value instanceof DataSerializable) {
        final DataContainer valueContainer = ((DataSerializable) value).toContainer();
        checkArgument(!(valueContainer).equals(this), "Cannot insert self-referencing DataSerializable");
        // see above for why this is copied
        this.copyDataView(path, valueContainer);
    } else if (SpongeDataManager.INSTANCE.findRegistryTypeFor(value.getClass()).isPresent()) {
        final RegistryType<Object> registry = SpongeDataManager.INSTANCE.findRegistryTypeFor(value.getClass()).get();
        final ResourceKey valueKey = Sponge.game().registry(registry).valueKey(value);
        // view.set(DataQuery.of("scope"), scope);
        return this.set(path, valueKey);
    } else if (value instanceof ResourceKey) {
        return this.set(path, value.toString());
    } else if (manager != null && manager.translator(value.getClass()).isPresent()) {
        final DataTranslator serializer = manager.translator(value.getClass()).get();
        final DataContainer container = serializer.translate(value);
        checkArgument(!container.equals(this), "Cannot insert self-referencing Objects!");
        // see above for why this is copied
        this.copyDataView(path, container);
    } else if (value instanceof Collection) {
        this.setCollection(key, (Collection) value);
    } else if (value instanceof Map) {
        this.setMap(key, (Map) value);
    } else if (value.getClass().isArray()) {
        if (this.safety == org.spongepowered.api.data.persistence.DataView.SafetyMode.ALL_DATA_CLONED || this.safety == org.spongepowered.api.data.persistence.DataView.SafetyMode.CLONED_ON_SET) {
            if (value instanceof byte[]) {
                this.map.put(key, ArrayUtils.clone((byte[]) value));
            } else if (value instanceof short[]) {
                this.map.put(key, ArrayUtils.clone((short[]) value));
            } else if (value instanceof int[]) {
                this.map.put(key, ArrayUtils.clone((int[]) value));
            } else if (value instanceof long[]) {
                this.map.put(key, ArrayUtils.clone((long[]) value));
            } else if (value instanceof float[]) {
                this.map.put(key, ArrayUtils.clone((float[]) value));
            } else if (value instanceof double[]) {
                this.map.put(key, ArrayUtils.clone((double[]) value));
            } else if (value instanceof boolean[]) {
                this.map.put(key, ArrayUtils.clone((boolean[]) value));
            } else {
                this.map.put(key, ArrayUtils.clone((Object[]) value));
            }
        } else {
            this.map.put(key, value);
        }
    } else {
        this.map.put(key, value);
    }
    return this;
}
Also used : DataTranslator(org.spongepowered.api.data.persistence.DataTranslator) DataManager(org.spongepowered.api.data.DataManager) DataSerializable(org.spongepowered.api.data.persistence.DataSerializable) ResourceKey(org.spongepowered.api.ResourceKey) DataView(org.spongepowered.api.data.persistence.DataView) DataContainer(org.spongepowered.api.data.persistence.DataContainer) Collection(java.util.Collection) DataQuery(org.spongepowered.api.data.persistence.DataQuery) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Example 3 with DataSerializable

use of org.spongepowered.api.data.persistence.DataSerializable 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

ImmutableMap (com.google.common.collect.ImmutableMap)3 Collection (java.util.Collection)3 Map (java.util.Map)3 Nullable (org.checkerframework.checker.nullness.qual.Nullable)3 ResourceKey (org.spongepowered.api.ResourceKey)3 DataContainer (org.spongepowered.api.data.persistence.DataContainer)3 DataSerializable (org.spongepowered.api.data.persistence.DataSerializable)3 DataView (org.spongepowered.api.data.persistence.DataView)3 ImmutableList (com.google.common.collect.ImmutableList)2 DataManager (org.spongepowered.api.data.DataManager)2 DataQuery (org.spongepowered.api.data.persistence.DataQuery)2 DataTranslator (org.spongepowered.api.data.persistence.DataTranslator)2 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 Collections (java.util.Collections)1 HashMap (java.util.HashMap)1