]> WPIA git - gigi.git/blob - lib/jtar/org/kamranzafar/jtar/TarEntry.java
Merge branch 'libs/jetty/upstream' into libs/jetty/local
[gigi.git] / lib / jtar / org / kamranzafar / jtar / TarEntry.java
1 /**
2  * Copyright 2012 Kamran Zafar 
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License"); 
5  * you may not use this file except in compliance with the License. 
6  * You may obtain a copy of the License at 
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0 
9  * 
10  * Unless required by applicable law or agreed to in writing, software 
11  * distributed under the License is distributed on an "AS IS" BASIS, 
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13  * See the License for the specific language governing permissions and 
14  * limitations under the License. 
15  * 
16  */
17
18 package org.kamranzafar.jtar;
19
20 import java.io.File;
21 import java.util.Date;
22
23 /**
24  * @author Kamran Zafar
25  * 
26  */
27 public class TarEntry {
28         protected File file;
29         protected TarHeader header;
30
31         private TarEntry() {
32                 this.file = null;
33                 header = new TarHeader();
34         }
35
36         public TarEntry(File file, String entryName) {
37                 this();
38                 this.file = file;
39                 this.extractTarHeader(entryName);
40         }
41
42         public TarEntry(byte[] headerBuf) {
43                 this();
44                 this.parseTarHeader(headerBuf);
45         }
46
47         /**
48          * Constructor to create an entry from an existing TarHeader object.
49          * 
50          * This method is useful to add new entries programmatically (e.g. for
51          * adding files or directories that do not exist in the file system).
52          * 
53          * @param header
54          * 
55          */
56         public TarEntry(TarHeader header) {
57                 this.file = null;
58                 this.header = header;
59         }
60
61         @Override
62         public boolean equals(Object it) {
63                 if (!(it instanceof TarEntry)) {
64                         return false;
65                 }
66                 return header.name.toString().equals(
67                                 ((TarEntry) it).header.name.toString());
68         }
69
70         @Override
71         public int hashCode() {
72                 return header.name.hashCode();
73         }
74
75         public boolean isDescendent(TarEntry desc) {
76                 return desc.header.name.toString().startsWith(header.name.toString());
77         }
78
79         public TarHeader getHeader() {
80                 return header;
81         }
82
83         public String getName() {
84                 String name = header.name.toString();
85                 if (header.namePrefix != null
86                                 && !header.namePrefix.toString().equals("")) {
87                         name = header.namePrefix.toString() + "/" + name;
88                 }
89
90                 return name;
91         }
92
93         public void setName(String name) {
94                 header.name = new StringBuffer(name);
95         }
96
97         public int getUserId() {
98                 return header.userId;
99         }
100
101         public void setUserId(int userId) {
102                 header.userId = userId;
103         }
104
105         public int getGroupId() {
106                 return header.groupId;
107         }
108
109         public void setGroupId(int groupId) {
110                 header.groupId = groupId;
111         }
112
113         public String getUserName() {
114                 return header.userName.toString();
115         }
116
117         public void setUserName(String userName) {
118                 header.userName = new StringBuffer(userName);
119         }
120
121         public String getGroupName() {
122                 return header.groupName.toString();
123         }
124
125         public void setGroupName(String groupName) {
126                 header.groupName = new StringBuffer(groupName);
127         }
128
129         public void setIds(int userId, int groupId) {
130                 this.setUserId(userId);
131                 this.setGroupId(groupId);
132         }
133
134         public void setModTime(long time) {
135                 header.modTime = time / 1000;
136         }
137
138         public void setModTime(Date time) {
139                 header.modTime = time.getTime() / 1000;
140         }
141
142         public Date getModTime() {
143                 return new Date(header.modTime * 1000);
144         }
145
146         public File getFile() {
147                 return this.file;
148         }
149
150         public long getSize() {
151                 return header.size;
152         }
153
154         public void setSize(long size) {
155                 header.size = size;
156         }
157
158         /**
159          * Checks if the org.kamrazafar.jtar entry is a directory
160          * 
161          * @return
162          */
163         public boolean isDirectory() {
164                 if (this.file != null) {
165                         return this.file.isDirectory();
166                 }
167
168                 if (header != null) {
169                         if (header.linkFlag == TarHeader.LF_DIR) {
170                                 return true;
171                         }
172
173                         if (header.name.toString().endsWith("/")) {
174                                 return true;
175                         }
176                 }
177
178                 return false;
179         }
180
181         /**
182          * Extract header from File
183          * 
184          * @param entryName
185          */
186         public void extractTarHeader(String entryName) {
187                 header = TarHeader.createHeader(entryName, file.length(),
188                                 file.lastModified() / 1000, file.isDirectory());
189         }
190
191         /**
192          * Calculate checksum
193          * 
194          * @param buf
195          * @return
196          */
197         public long computeCheckSum(byte[] buf) {
198                 long sum = 0;
199
200                 for (int i = 0; i < buf.length; ++i) {
201                         sum += 255 & buf[i];
202                 }
203
204                 return sum;
205         }
206
207         /**
208          * Writes the header to the byte buffer
209          * 
210          * @param outbuf
211          */
212         public void writeEntryHeader(byte[] outbuf) {
213                 int offset = 0;
214
215                 offset = TarHeader.getNameBytes(header.name, outbuf, offset,
216                                 TarHeader.NAMELEN);
217                 offset = Octal.getOctalBytes(header.mode, outbuf, offset,
218                                 TarHeader.MODELEN);
219                 offset = Octal.getOctalBytes(header.userId, outbuf, offset,
220                                 TarHeader.UIDLEN);
221                 offset = Octal.getOctalBytes(header.groupId, outbuf, offset,
222                                 TarHeader.GIDLEN);
223
224                 long size = header.size;
225
226                 offset = Octal.getLongOctalBytes(size, outbuf, offset,
227                                 TarHeader.SIZELEN);
228                 offset = Octal.getLongOctalBytes(header.modTime, outbuf, offset,
229                                 TarHeader.MODTIMELEN);
230
231                 int csOffset = offset;
232                 for (int c = 0; c < TarHeader.CHKSUMLEN; ++c) {
233                         outbuf[offset++] = (byte) ' ';
234                 }
235
236                 outbuf[offset++] = header.linkFlag;
237
238                 offset = TarHeader.getNameBytes(header.linkName, outbuf, offset,
239                                 TarHeader.NAMELEN);
240                 offset = TarHeader.getNameBytes(header.magic, outbuf, offset,
241                                 TarHeader.USTAR_MAGICLEN);
242                 offset = TarHeader.getNameBytes(header.userName, outbuf, offset,
243                                 TarHeader.USTAR_USER_NAMELEN);
244                 offset = TarHeader.getNameBytes(header.groupName, outbuf, offset,
245                                 TarHeader.USTAR_GROUP_NAMELEN);
246                 offset = Octal.getOctalBytes(header.devMajor, outbuf, offset,
247                                 TarHeader.USTAR_DEVLEN);
248                 offset = Octal.getOctalBytes(header.devMinor, outbuf, offset,
249                                 TarHeader.USTAR_DEVLEN);
250                 offset = TarHeader.getNameBytes(header.namePrefix, outbuf, offset,
251                                 TarHeader.USTAR_FILENAME_PREFIX);
252
253                 for (; offset < outbuf.length;) {
254                         outbuf[offset++] = 0;
255                 }
256
257                 long checkSum = this.computeCheckSum(outbuf);
258
259                 Octal.getCheckSumOctalBytes(checkSum, outbuf, csOffset,
260                                 TarHeader.CHKSUMLEN);
261         }
262
263         /**
264          * Parses the tar header to the byte buffer
265          * 
266          * @param header
267          * @param bh
268          */
269         public void parseTarHeader(byte[] bh) {
270                 int offset = 0;
271
272                 header.name = TarHeader.parseName(bh, offset, TarHeader.NAMELEN);
273                 offset += TarHeader.NAMELEN;
274
275                 header.mode = (int) Octal.parseOctal(bh, offset, TarHeader.MODELEN);
276                 offset += TarHeader.MODELEN;
277
278                 header.userId = (int) Octal.parseOctal(bh, offset, TarHeader.UIDLEN);
279                 offset += TarHeader.UIDLEN;
280
281                 header.groupId = (int) Octal.parseOctal(bh, offset, TarHeader.GIDLEN);
282                 offset += TarHeader.GIDLEN;
283
284                 header.size = Octal.parseOctal(bh, offset, TarHeader.SIZELEN);
285                 offset += TarHeader.SIZELEN;
286
287                 header.modTime = Octal.parseOctal(bh, offset, TarHeader.MODTIMELEN);
288                 offset += TarHeader.MODTIMELEN;
289
290                 header.checkSum = (int) Octal.parseOctal(bh, offset,
291                                 TarHeader.CHKSUMLEN);
292                 offset += TarHeader.CHKSUMLEN;
293
294                 header.linkFlag = bh[offset++];
295
296                 header.linkName = TarHeader.parseName(bh, offset, TarHeader.NAMELEN);
297                 offset += TarHeader.NAMELEN;
298
299                 header.magic = TarHeader
300                                 .parseName(bh, offset, TarHeader.USTAR_MAGICLEN);
301                 offset += TarHeader.USTAR_MAGICLEN;
302
303                 header.userName = TarHeader.parseName(bh, offset,
304                                 TarHeader.USTAR_USER_NAMELEN);
305                 offset += TarHeader.USTAR_USER_NAMELEN;
306
307                 header.groupName = TarHeader.parseName(bh, offset,
308                                 TarHeader.USTAR_GROUP_NAMELEN);
309                 offset += TarHeader.USTAR_GROUP_NAMELEN;
310
311                 header.devMajor = (int) Octal.parseOctal(bh, offset,
312                                 TarHeader.USTAR_DEVLEN);
313                 offset += TarHeader.USTAR_DEVLEN;
314
315                 header.devMinor = (int) Octal.parseOctal(bh, offset,
316                                 TarHeader.USTAR_DEVLEN);
317                 offset += TarHeader.USTAR_DEVLEN;
318
319                 header.namePrefix = TarHeader.parseName(bh, offset,
320                                 TarHeader.USTAR_FILENAME_PREFIX);
321         }
322 }