1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.compress.archivers.arj;
18
19 import java.io.File;
20 import java.util.Date;
21
22 import org.apache.commons.compress.archivers.ArchiveEntry;
23 import org.apache.commons.compress.archivers.zip.ZipUtil;
24
25 /**
26 * An entry in an ARJ archive.
27 *
28 * @NotThreadSafe
29 * @since 1.6
30 */
31 public class ArjArchiveEntry implements ArchiveEntry {
32
33 /**
34 * The known values for HostOs.
35 */
36 public static class HostOs {
37
38 /**
39 * {@value}
40 */
41 public static final int DOS = 0;
42
43 /**
44 * {@value}
45 */
46 public static final int PRIMOS = 1;
47
48 /**
49 * {@value}
50 */
51 public static final int UNIX = 2;
52
53 /**
54 * {@value}
55 */
56 public static final int AMIGA = 3;
57
58 /**
59 * {@value}
60 */
61 public static final int MAC_OS = 4;
62
63 /**
64 * {@value}
65 */
66 public static final int OS_2 = 5;
67
68 /**
69 * {@value}
70 */
71 public static final int APPLE_GS = 6;
72
73 /**
74 * {@value}
75 */
76 public static final int ATARI_ST = 7;
77
78 /**
79 * {@value}
80 */
81 public static final int NEXT = 8;
82
83 /**
84 * {@value}
85 */
86 public static final int VAX_VMS = 9;
87
88 /**
89 * {@value}
90 */
91 public static final int WIN95 = 10;
92
93 /**
94 * {@value}
95 */
96 public static final int WIN32 = 11;
97 }
98
99 private final LocalFileHeader localFileHeader;
100
101 public ArjArchiveEntry() {
102 localFileHeader = new LocalFileHeader();
103 }
104
105 ArjArchiveEntry(final LocalFileHeader localFileHeader) {
106 this.localFileHeader = localFileHeader;
107 }
108
109 @Override
110 public boolean equals(final Object obj) {
111 if (this == obj) {
112 return true;
113 }
114 if (obj == null || getClass() != obj.getClass()) {
115 return false;
116 }
117 final ArjArchiveEntry other = (ArjArchiveEntry) obj;
118 return localFileHeader.equals(other.localFileHeader);
119 }
120
121 /**
122 * The operating system the archive has been created on.
123 *
124 * @see HostOs
125 * @return the host OS code
126 */
127 public int getHostOs() {
128 return localFileHeader.hostOS;
129 }
130
131 /**
132 * The last modified date of the entry.
133 *
134 * <p>
135 * Note the interpretation of time is different depending on the HostOS that has created the archive. While an OS that is {@link #isHostOsUnix considered to
136 * be Unix} stores time in a time zone independent manner, other platforms only use the local time. I.e. if an archive has been created at midnight UTC on a
137 * machine in time zone UTC this method will return midnight regardless of time zone if the archive has been created on a non-UNIX system and a time taking
138 * the current time zone into account if the archive has been created on Unix.
139 * </p>
140 *
141 * @return the last modified date
142 */
143 @Override
144 public Date getLastModifiedDate() {
145 final long ts = isHostOsUnix() ? localFileHeader.dateTimeModified * 1000L : ZipUtil.dosToJavaTime(0xFFFFFFFFL & localFileHeader.dateTimeModified);
146 return new Date(ts);
147 }
148
149 int getMethod() {
150 return localFileHeader.method;
151 }
152
153 /**
154 * File mode of this entry.
155 *
156 * <p>
157 * The format depends on the host os that created the entry.
158 * </p>
159 *
160 * @return the file mode
161 */
162 public int getMode() {
163 return localFileHeader.fileAccessMode;
164 }
165
166 /**
167 * Gets this entry's name.
168 *
169 * <p>
170 * This method returns the raw name as it is stored inside of the archive.
171 * </p>
172 *
173 * @return This entry's name.
174 */
175 @Override
176 public String getName() {
177 if ((localFileHeader.arjFlags & LocalFileHeader.Flags.PATHSYM) != 0) {
178 return localFileHeader.name.replace("/", File.separator);
179 }
180 return localFileHeader.name;
181 }
182
183 /**
184 * Gets this entry's file size.
185 *
186 * @return This entry's file size.
187 */
188 @Override
189 public long getSize() {
190 return localFileHeader.originalSize;
191 }
192
193 /**
194 * File mode of this entry as UNIX stat value.
195 *
196 * <p>
197 * Will only be non-zero of the host os was UNIX.
198 *
199 * @return the UNIX mode
200 */
201 public int getUnixMode() {
202 return isHostOsUnix() ? getMode() : 0;
203 }
204
205 @Override
206 public int hashCode() {
207 final String name = getName();
208 return name == null ? 0 : name.hashCode();
209 }
210
211 /**
212 * True if the entry refers to a directory.
213 *
214 * @return True if the entry refers to a directory
215 */
216 @Override
217 public boolean isDirectory() {
218 return localFileHeader.fileType == LocalFileHeader.FileTypes.DIRECTORY;
219 }
220
221 /**
222 * Is the operating system the archive has been created on one that is considered a UNIX OS by arj?
223 *
224 * @return whether the operating system the archive has been created on is considered a UNIX OS by arj
225 */
226 public boolean isHostOsUnix() {
227 return getHostOs() == HostOs.UNIX || getHostOs() == HostOs.NEXT;
228 }
229
230 }