mirror of
https://github.com/PaperMC/Paper.git
synced 2025-08-14 03:35:51 -07:00
Add ConfigurationSerializable-Serializable compatibility. Adds BUKKIT-4662
This commit adds a comaptibility layer for use between ConfigurationSerializable and Java Serializable, such that when using the Bukkit object streams, any ConfigurationSerializable acts as if it implements Serializable for purposes of that wrapped stream. Included are a set of unit tests for the stream with a check for backward compatibility across versions. By: Wesley Wolfe <weswolf@aol.com>
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
package org.bukkit.util.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||
|
||||
/**
|
||||
* This class is designed to be used in conjunction with the {@link
|
||||
* ConfigurationSerializable} API. It translates objects back to their
|
||||
* original implementation after being serialized by {@link
|
||||
* BukkitObjectInputStream}.
|
||||
* <p>
|
||||
* Behavior of implementations extending this class is not guaranteed across
|
||||
* future versions.
|
||||
*/
|
||||
public class BukkitObjectInputStream extends ObjectInputStream {
|
||||
|
||||
/**
|
||||
* Constructor provided to mirror super functionality.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws SecurityException
|
||||
* @see {@link ObjectInputStream#ObjectInputStream()}
|
||||
*/
|
||||
protected BukkitObjectInputStream() throws IOException, SecurityException {
|
||||
super();
|
||||
super.enableResolveObject(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Object input stream decoration constructor.
|
||||
*
|
||||
* @param in
|
||||
* @throws IOException
|
||||
* @see {@link ObjectInputStream#ObjectInputStream(InputStream)}
|
||||
*/
|
||||
public BukkitObjectInputStream(InputStream in) throws IOException {
|
||||
super(in);
|
||||
super.enableResolveObject(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object resolveObject(Object obj) throws IOException {
|
||||
if (obj instanceof Wrapper) {
|
||||
try {
|
||||
(obj = ConfigurationSerialization.deserializeObject(((Wrapper<?>) obj).map)).getClass(); // NPE
|
||||
} catch (Throwable ex) {
|
||||
throw newIOException("Failed to deserialize object", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return super.resolveObject(obj);
|
||||
}
|
||||
|
||||
private static IOException newIOException(String string, Throwable cause) {
|
||||
IOException exception = new IOException(string);
|
||||
exception.initCause(cause);
|
||||
return exception;
|
||||
}
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
package org.bukkit.util.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
|
||||
/**
|
||||
* This class is designed to be used in conjunction with the {@link
|
||||
* ConfigurationSerializable} API. It translates objects to an internal
|
||||
* implementation for later deserialization using {@link
|
||||
* BukkitObjectInputStream}.
|
||||
* <p>
|
||||
* Behavior of implementations extending this class is not guaranteed across
|
||||
* future versions.
|
||||
*/
|
||||
public class BukkitObjectOutputStream extends ObjectOutputStream {
|
||||
|
||||
/**
|
||||
* Constructor provided to mirror super functionality.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws SecurityException
|
||||
* @see {@link ObjectOutputStream#ObjectOutputStream()}
|
||||
*/
|
||||
protected BukkitObjectOutputStream() throws IOException, SecurityException {
|
||||
super();
|
||||
super.enableReplaceObject(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Object output stream decoration constructor.
|
||||
*
|
||||
* @param out
|
||||
* @throws IOException
|
||||
* @see {@link ObjectOutputStream#ObjectOutputStream(OutputStream)}
|
||||
*/
|
||||
public BukkitObjectOutputStream(OutputStream out) throws IOException {
|
||||
super(out);
|
||||
super.enableReplaceObject(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object replaceObject(Object obj) throws IOException {
|
||||
if (!(obj instanceof Serializable) && (obj instanceof ConfigurationSerializable)) {
|
||||
obj = Wrapper.newWrapper((ConfigurationSerializable) obj);
|
||||
}
|
||||
|
||||
return super.replaceObject(obj);
|
||||
}
|
||||
}
|
23
paper-api/src/main/java/org/bukkit/util/io/Wrapper.java
Normal file
23
paper-api/src/main/java/org/bukkit/util/io/Wrapper.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package org.bukkit.util.io;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
class Wrapper<T extends Map<String, ?> & Serializable> implements Serializable {
|
||||
private static final long serialVersionUID = -986209235411767547L;
|
||||
|
||||
final T map;
|
||||
|
||||
static Wrapper<ImmutableMap<String, ?>> newWrapper(ConfigurationSerializable obj) {
|
||||
return new Wrapper<ImmutableMap<String, ?>>(ImmutableMap.<String, Object>builder().put(ConfigurationSerialization.SERIALIZED_TYPE_KEY, ConfigurationSerialization.getAlias(obj.getClass())).putAll(obj.serialize()).build());
|
||||
}
|
||||
|
||||
private Wrapper(T map) {
|
||||
this.map = map;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user