001    package org.bukkit.util.io;
002    
003    import java.io.IOException;
004    import java.io.InputStream;
005    import java.io.ObjectInputStream;
006    
007    import org.bukkit.configuration.serialization.ConfigurationSerializable;
008    import org.bukkit.configuration.serialization.ConfigurationSerialization;
009    
010    /**
011     * This class is designed to be used in conjunction with the {@link
012     * ConfigurationSerializable} API. It translates objects back to their
013     * original implementation after being serialized by {@link
014     * BukkitObjectInputStream}.
015     * <p>
016     * Behavior of implementations extending this class is not guaranteed across
017     * future versions.
018     */
019    public class BukkitObjectInputStream extends ObjectInputStream {
020    
021        /**
022         * Constructor provided to mirror super functionality.
023         *
024         * @throws IOException
025         * @throws SecurityException
026         * @see ObjectInputStream#ObjectInputStream()
027         */
028        protected BukkitObjectInputStream() throws IOException, SecurityException {
029            super();
030            super.enableResolveObject(true);
031        }
032    
033        /**
034         * Object input stream decoration constructor.
035         *
036         * @param in
037         * @throws IOException
038         * @see ObjectInputStream#ObjectInputStream(InputStream)
039         */
040        public BukkitObjectInputStream(InputStream in) throws IOException {
041            super(in);
042            super.enableResolveObject(true);
043        }
044    
045        @Override
046        protected Object resolveObject(Object obj) throws IOException {
047            if (obj instanceof Wrapper) {
048                try {
049                    (obj = ConfigurationSerialization.deserializeObject(((Wrapper<?>) obj).map)).getClass(); // NPE
050                } catch (Throwable ex) {
051                    throw newIOException("Failed to deserialize object", ex);
052                }
053            }
054    
055            return super.resolveObject(obj);
056        }
057    
058        private static IOException newIOException(String string, Throwable cause) {
059            IOException exception = new IOException(string);
060            exception.initCause(cause);
061            return exception;
062        }
063    }