ZipArchiveWrapper.java

/*
 * Copyright © 2024-2025 The CTAN Team and individual authors
 *
 * This file is distributed under the 3-clause BSD license.
 * See file LICENSE for details.
 */
package org.ctan.site.services.upload.util.archive;

import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import lombok.NonNull;

/**
 * The class <code>Archive</code> contains the wrapper for a ZIP archive.
 *
 * @author <a href="mailto:gene@ctan.org">Gerd Neugebauer</a>
 */
public class ZipArchiveWrapper implements Archive {

    /**
     * The class <code>ZipEntryWrapper</code> contains the wrapper for an entry.
     */
    public static class ZipEntryWrapper implements Entry {

        /**
         * The field <code>entry</code> contains the wrapped entry.
         */
        private ZipEntry entry;

        /**
         * This is the constructor for <code>ZipEntry</code>.
         *
         * @param entry the entry
         */
        @SuppressFBWarnings(value = "EI_EXPOSE_REP2")
        public ZipEntryWrapper(ZipEntry entry) {

            this.entry = entry;
        }

        /**
         * {@inheritDoc}
         *
         * @see org.ctan.site.services.upload.util.archive.Archive.Entry#getName()
         */
        @Override
        public String getName() {

            return entry.getName();
        }

        /**
         * {@inheritDoc}
         *
         * @see org.ctan.site.services.upload.util.archive.Archive.Entry#isDirectory()
         */
        @Override
        public boolean isDirectory() {

            return entry.isDirectory();
        }
    }

    /**
     * The field <code>stream</code> contains the wrapped stream.
     */
    private ZipInputStream stream;

    /**
     * The field <code>name</code> contains the file name.
     */
    private String name;

    /**
     * This is the constructor for <code>ZipArchiveWrapper</code>.
     *
     * @param name the file name
     * @param in the wrapped input stream
     */
    @SuppressFBWarnings(value = {"CT_CONSTRUCTOR_THROW", "EI_EXPOSE_REP2"})
    public ZipArchiveWrapper(@NonNull String name, @NonNull InputStream in) {

        this.name = name;
        this.stream = new ZipInputStream(in);
    }

    /**
     * {@inheritDoc}
     *
     * @see org.ctan.site.services.upload.util.archive.Archive#close()
     */
    @Override
    public void close() throws IOException {

        stream.close();
    }

    /**
     * {@inheritDoc}
     *
     * @see org.ctan.site.services.upload.util.archive.Archive#closeEntry()
     */
    @Override
    public void closeEntry() throws IOException {

        stream.closeEntry();
    }

    /**
     * {@inheritDoc}
     *
     * @see org.ctan.site.services.upload.util.archive.Archive#getName()
     */
    @Override
    public String getName() {

        return name;
    }

    /**
     * {@inheritDoc}
     *
     * @see org.ctan.site.services.upload.util.archive.Archive#getNextEntry()
     */
    @Override
    public Entry getNextEntry() throws IOException {

        ZipEntry nextEntry = stream.getNextEntry();
        return nextEntry != null ? new ZipEntryWrapper(nextEntry) : null;
    }

    /**
     * {@inheritDoc}
     *
     * @see org.ctan.site.services.upload.util.archive.Archive#getStream()
     */
    @Override
    public InputStream getStream() {

        return stream;
    }
}