All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.schlichtherle.truezip.socket.ClutchInputSocket Maven / Gradle / Ivy

/*
 * Copyright (C) 2005-2015 Schlichtherle IT Services.
 * All rights reserved. Use is subject to license terms.
 */
package de.schlichtherle.truezip.socket;

import de.schlichtherle.truezip.entry.Entry;
import de.schlichtherle.truezip.rof.ReadOnlyFile;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.SeekableByteChannel;
import javax.annotation.CheckForNull;
import javax.annotation.concurrent.NotThreadSafe;

/**
 * An input socket which obtains its delegate lazily and {@link #reset()}s it
 * upon any {@link Throwable}.
 *
 * @see    ClutchOutputSocket
 * @param   the type of the {@link #getLocalTarget() local target}.
 * @since  TrueZIP 7.5
 * @author Christian Schlichtherle
 */
@NotThreadSafe
public abstract class ClutchInputSocket
extends DelegatingInputSocket {
    @CheckForNull InputSocket delegate;

    @Override
    protected final InputSocket getDelegate() throws IOException {
        final InputSocket is = delegate;
        return null != is ? is : (delegate = getLazyDelegate());
    };

    /**
     * Returns the delegate socket for lazy initialization.
     * 
     * @return the delegate socket for lazy initialization.
     * @throws IOException on any I/O failure. 
     */
    protected abstract InputSocket getLazyDelegate()
    throws IOException;

    @Override
    public E getLocalTarget() throws IOException {
        try {
            return getBoundSocket().getLocalTarget();
        } catch (Throwable ex) {
            throw reset(ex);
        }
    }

    @Override
    public ReadOnlyFile newReadOnlyFile() throws IOException {
        try {
            return getBoundSocket().newReadOnlyFile();
        } catch (Throwable ex) {
            throw reset(ex);
        }
    }

    @Override
    public SeekableByteChannel newSeekableByteChannel()
    throws IOException {
        try {
            return getBoundSocket().newSeekableByteChannel();
        } catch (Throwable ex) {
            throw reset(ex);
        }
    }

    @Override
    public InputStream newInputStream() throws IOException {
        try {
            return getBoundSocket().newInputStream();
        } catch (Throwable ex) {
            throw reset(ex);
        }
    }

    private IOException reset(final Throwable ex) {
        reset();
        if (ex instanceof RuntimeException)
            throw (RuntimeException) ex;
        else if (ex instanceof Error)
            throw (Error) ex;
        return (IOException) ex;
    }

    protected final void reset() {
        this.delegate = null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy