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