    001/*
    002 *  Licensed to the Apache Software Foundation (ASF) under one or more
    003 *  contributor license agreements.  See the NOTICE file distributed with
    004 *  this work for additional information regarding copyright ownership.
    005 *  The ASF licenses this file to You under the Apache License, Version 2.0
    006 *  (the "License"); you may not use this file except in compliance with
    007 *  the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 *  Unless required by applicable law or agreed to in writing, software
    012 *  distributed under the License is distributed on an "AS IS" BASIS,
    013 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 *  See the License for the specific language governing permissions and
    015 *  limitations under the License.
    016 *
    017 */
    018package org.apache.commons.compress.archivers.arj;
    019
    020import java.io.File;
    021import java.util.Date;
    022
    023import org.apache.commons.compress.archivers.ArchiveEntry;
    024import org.apache.commons.compress.archivers.zip.ZipUtil;
    025
    026/**
    027 * An entry in an ARJ archive.
    028 *
    029 * @NotThreadSafe
    030 * @since 1.6
    031 */
    032public class ArjArchiveEntry implements ArchiveEntry {
    033    /**
    034     * The known values for HostOs.
    035     */
    036    public static class HostOs {
    037        public static final int DOS = 0;
    038        public static final int PRIMOS = 1;
    039        public static final int UNIX = 2;
    040        public static final int AMIGA = 3;
    041        public static final int MAC_OS = 4;
    042        public static final int OS_2 = 5;
    043        public static final int APPLE_GS = 6;
    044        public static final int ATARI_ST = 7;
    045        public static final int NEXT = 8;
    046        public static final int VAX_VMS = 9;
    047        public static final int WIN95 = 10;
    048        public static final int WIN32 = 11;
    049    }
    050
    051    private final LocalFileHeader localFileHeader;
    052
    053    public ArjArchiveEntry() {
    054        localFileHeader = new LocalFileHeader();
    055    }
    056
    057    ArjArchiveEntry(final LocalFileHeader localFileHeader) {
    058        this.localFileHeader = localFileHeader;
    059    }
    060
    061    @Override
    062    public boolean equals(final Object obj) {
    063        if (this == obj) {
    064            return true;
    065        }
    066        if (obj == null || getClass() != obj.getClass()) {
    067            return false;
    068        }
    069        final ArjArchiveEntry other = (ArjArchiveEntry) obj;
    070        return localFileHeader.equals(other.localFileHeader);
    071    }
    072
    073    /**
    074     * The operating system the archive has been created on.
    075     * @see HostOs
    076     * @return the host OS code
    077     */
    078    public int getHostOs() {
    079        return localFileHeader.hostOS;
    080    }
    081
    082    /**
    083     * The last modified date of the entry.
    084     *
    085     * <p>Note the interpretation of time is different depending on
    086     * the HostOS that has created the archive.  While an OS that is
    087     * {@link #isHostOsUnix considered to be Unix} stores time in a
    088     * time zone independent manner, other platforms only use the local
    089     * time.  I.e. if an archive has been created at midnight UTC on a
    090     * machine in time zone UTC this method will return midnight
    091     * regardless of time zone if the archive has been created on a
    092     * non-Unix system and a time taking the current time zone into
    093     * account if the archive has been created on Unix.</p>
    094     *
    095     * @return the last modified date
    096     */
    097    @Override
    098    public Date getLastModifiedDate() {
    099        final long ts = isHostOsUnix() ? localFileHeader.dateTimeModified * 1000L
    100            : ZipUtil.dosToJavaTime(0xFFFFFFFFL & localFileHeader.dateTimeModified);
    101        return new Date(ts);
    102    }
    103
    104    int getMethod() {
    105        return localFileHeader.method;
    106    }
    107
    108    /**
    109     * File mode of this entry.
    110     *
    111     * <p>The format depends on the host os that created the entry.</p>
    112     *
    113     * @return the file mode
    114     */
    115    public int getMode() {
    116        return localFileHeader.fileAccessMode;
    117    }
    118
    119    /**
    120     * Get this entry's name.
    121     *
    122     * <p>This method returns the raw name as it is stored inside of the archive.</p>
    123     *
    124     * @return This entry's name.
    125     */
    126    @Override
    127    public String getName() {
    128        if ((localFileHeader.arjFlags & LocalFileHeader.Flags.PATHSYM) != 0) {
    129            return localFileHeader.name.replace("/",
    130                    File.separator);
    131        }
    132        return localFileHeader.name;
    133    }
    134
    135    /**
    136     * Get this entry's file size.
    137     *
    138     * @return This entry's file size.
    139     */
    140    @Override
    141    public long getSize() {
    142        return localFileHeader.originalSize;
    143    }
    144
    145    /**
    146     * File mode of this entry as Unix stat value.
    147     *
    148     * <p>Will only be non-zero of the host os was UNIX.
    149     *
    150     * @return the Unix mode
    151     */
    152    public int getUnixMode() {
    153        return isHostOsUnix() ? getMode() : 0;
    154    }
    155
    156    @Override
    157    public int hashCode() {
    158        final String name = getName();
    159        return name == null ? 0 : name.hashCode();
    160    }
    161
    162    /** True if the entry refers to a directory.
    163     *
    164     * @return True if the entry refers to a directory
    165     */
    166    @Override
    167    public boolean isDirectory() {
    168        return localFileHeader.fileType == LocalFileHeader.FileTypes.DIRECTORY;
    169    }
    170
    171    /**
    172     * Is the operating system the archive has been created on one
    173     * that is considered a UNIX OS by arj?
    174     * @return whether the operating system the archive has been
    175     * created on is considered a UNIX OS by arj
    176     */
    177    public boolean isHostOsUnix() {
    178        return getHostOs() == HostOs.UNIX || getHostOs() == HostOs.NEXT;
    179    }
    180
    181}