001/*
002 * JDrupes Builder
003 * Copyright (C) 2025 Michael N. Lipp
004 * 
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
017 */
018
019package org.jdrupes.builder.java;
020
021import java.io.IOException;
022import java.io.InputStream;
023import java.io.OutputStream;
024import java.time.Instant;
025import java.util.Objects;
026import java.util.Optional;
027import java.util.jar.JarEntry;
028import java.util.jar.JarFile;
029import org.jdrupes.builder.api.IOResource;
030import org.jdrupes.builder.core.ResourceObject;
031
032/// Represents an entry in a jar file.
033///
034public class JarFileEntry extends ResourceObject implements IOResource {
035
036    private final JarFile jarFile;
037    private final JarEntry entry;
038
039    /// Initializes a new jar file entry.
040    ///
041    /// @param jarFile the jar file
042    /// @param entry the entry
043    ///
044    public JarFileEntry(JarFile jarFile, JarEntry entry) {
045        super();
046        this.jarFile = jarFile;
047        this.entry = entry;
048    }
049
050    @Override
051    public Optional<Instant> asOf() {
052        return Optional.of(entry.getLastModifiedTime().toInstant());
053    }
054
055    @Override
056    public InputStream inputStream() throws IOException {
057        return jarFile.getInputStream(entry);
058    }
059
060    @Override
061    public OutputStream outputStream() throws IOException {
062        throw new UnsupportedOperationException();
063    }
064
065    @Override
066    public int hashCode() {
067        final int prime = 31;
068        int result = super.hashCode();
069        result
070            = prime * result + Objects.hash(entry.getName(), jarFile.getName());
071        return result;
072    }
073
074    @Override
075    public boolean equals(Object obj) {
076        if (this == obj) {
077            return true;
078        }
079        if (!super.equals(obj)) {
080            return false;
081        }
082        return (obj instanceof JarFileEntry other)
083            && Objects.equals(entry.getName(), other.entry.getName())
084            && Objects.equals(jarFile.getName(), other.jarFile.getName());
085    }
086
087    @Override
088    public String toString() {
089        return jarFile.getName() + "!" + entry.getName() + " ("
090            + asOfLocalized() + ")";
091    }
092
093}