• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
18 package org.apache.commons.compress.archivers.sevenz;
19 
20 import java.util.Calendar;
21 import java.util.Collections;
22 import java.util.Date;
23 import java.util.LinkedList;
24 import java.util.TimeZone;
25 
26 import org.apache.commons.compress.archivers.ArchiveEntry;
27 
28 /**
29  * An entry in a 7z archive.
30  *
31  * @NotThreadSafe
32  * @since 1.6
33  */
34 public class SevenZArchiveEntry implements ArchiveEntry {
35     private String name;
36     private boolean hasStream;
37     private boolean isDirectory;
38     private boolean isAntiItem;
39     private boolean hasCreationDate;
40     private boolean hasLastModifiedDate;
41     private boolean hasAccessDate;
42     private long creationDate;
43     private long lastModifiedDate;
44     private long accessDate;
45     private boolean hasWindowsAttributes;
46     private int windowsAttributes;
47     private boolean hasCrc;
48     private long crc, compressedCrc;
49     private long size, compressedSize;
50     private Iterable<? extends SevenZMethodConfiguration> contentMethods;
51 
SevenZArchiveEntry()52     public SevenZArchiveEntry() {
53     }
54 
55     /**
56      * Get this entry's name.
57      *
58      * <p>This method returns the raw name as it is stored inside of the archive.</p>
59      *
60      * @return This entry's name.
61      */
62     @Override
getName()63     public String getName() {
64         return name;
65     }
66 
67     /**
68      * Set this entry's name.
69      *
70      * @param name This entry's new name.
71      */
setName(final String name)72     public void setName(final String name) {
73         this.name = name;
74     }
75 
76     /**
77      * Whether there is any content associated with this entry.
78      * @return whether there is any content associated with this entry.
79      */
hasStream()80     public boolean hasStream() {
81         return hasStream;
82     }
83 
84     /**
85      * Sets whether there is any content associated with this entry.
86      * @param hasStream whether there is any content associated with this entry.
87      */
setHasStream(final boolean hasStream)88     public void setHasStream(final boolean hasStream) {
89         this.hasStream = hasStream;
90     }
91 
92     /**
93      * Return whether or not this entry represents a directory.
94      *
95      * @return True if this entry is a directory.
96      */
97     @Override
isDirectory()98     public boolean isDirectory() {
99         return isDirectory;
100     }
101 
102     /**
103      * Sets whether or not this entry represents a directory.
104      *
105      * @param isDirectory True if this entry is a directory.
106      */
setDirectory(final boolean isDirectory)107     public void setDirectory(final boolean isDirectory) {
108         this.isDirectory = isDirectory;
109     }
110 
111     /**
112      * Indicates whether this is an "anti-item" used in differential backups,
113      * meaning it should delete the same file from a previous backup.
114      * @return true if it is an anti-item, false otherwise
115      */
isAntiItem()116     public boolean isAntiItem() {
117         return isAntiItem;
118     }
119 
120     /**
121      * Sets whether this is an "anti-item" used in differential backups,
122      * meaning it should delete the same file from a previous backup.
123      * @param isAntiItem true if it is an anti-item, false otherwise
124      */
setAntiItem(final boolean isAntiItem)125     public void setAntiItem(final boolean isAntiItem) {
126         this.isAntiItem = isAntiItem;
127     }
128 
129     /**
130      * Returns whether this entry has got a creation date at all.
131      * @return whether the entry has got a creation date
132      */
getHasCreationDate()133     public boolean getHasCreationDate() {
134         return hasCreationDate;
135     }
136 
137     /**
138      * Sets whether this entry has got a creation date at all.
139      * @param hasCreationDate whether the entry has got a creation date
140      */
setHasCreationDate(final boolean hasCreationDate)141     public void setHasCreationDate(final boolean hasCreationDate) {
142         this.hasCreationDate = hasCreationDate;
143     }
144 
145     /**
146      * Gets the creation date.
147      * @throws UnsupportedOperationException if the entry hasn't got a
148      * creation date.
149      * @return the creation date
150      */
getCreationDate()151     public Date getCreationDate() {
152         if (hasCreationDate) {
153             return ntfsTimeToJavaTime(creationDate);
154         }
155         throw new UnsupportedOperationException(
156                 "The entry doesn't have this timestamp");
157     }
158 
159     /**
160      * Sets the creation date using NTFS time (100 nanosecond units
161      * since 1 January 1601)
162      * @param ntfsCreationDate the creation date
163      */
setCreationDate(final long ntfsCreationDate)164     public void setCreationDate(final long ntfsCreationDate) {
165         this.creationDate = ntfsCreationDate;
166     }
167 
168     /**
169      * Sets the creation date,
170      * @param creationDate the creation date
171      */
setCreationDate(final Date creationDate)172     public void setCreationDate(final Date creationDate) {
173         hasCreationDate = creationDate != null;
174         if (hasCreationDate) {
175             this.creationDate = javaTimeToNtfsTime(creationDate);
176         }
177     }
178 
179     /**
180      * Returns whether this entry has got a last modified date at all.
181      * @return whether this entry has got a last modified date at all
182      */
getHasLastModifiedDate()183     public boolean getHasLastModifiedDate() {
184         return hasLastModifiedDate;
185     }
186 
187     /**
188      * Sets whether this entry has got a last modified date at all.
189      * @param hasLastModifiedDate whether this entry has got a last
190      * modified date at all
191      */
setHasLastModifiedDate(final boolean hasLastModifiedDate)192     public void setHasLastModifiedDate(final boolean hasLastModifiedDate) {
193         this.hasLastModifiedDate = hasLastModifiedDate;
194     }
195 
196     /**
197      * Gets the last modified date.
198      * @throws UnsupportedOperationException if the entry hasn't got a
199      * last modified date.
200      * @return the last modified date
201      */
202     @Override
getLastModifiedDate()203     public Date getLastModifiedDate() {
204         if (hasLastModifiedDate) {
205             return ntfsTimeToJavaTime(lastModifiedDate);
206         }
207         throw new UnsupportedOperationException(
208                 "The entry doesn't have this timestamp");
209     }
210 
211     /**
212      * Sets the last modified date using NTFS time (100 nanosecond
213      * units since 1 January 1601)
214      * @param ntfsLastModifiedDate the last modified date
215      */
setLastModifiedDate(final long ntfsLastModifiedDate)216     public void setLastModifiedDate(final long ntfsLastModifiedDate) {
217         this.lastModifiedDate = ntfsLastModifiedDate;
218     }
219 
220     /**
221      * Sets the last modified date,
222      * @param lastModifiedDate the last modified date
223      */
setLastModifiedDate(final Date lastModifiedDate)224     public void setLastModifiedDate(final Date lastModifiedDate) {
225         hasLastModifiedDate = lastModifiedDate != null;
226         if (hasLastModifiedDate) {
227             this.lastModifiedDate = javaTimeToNtfsTime(lastModifiedDate);
228         }
229     }
230 
231     /**
232      * Returns whether this entry has got an access date at all.
233      * @return whether this entry has got an access date at all.
234      */
getHasAccessDate()235     public boolean getHasAccessDate() {
236         return hasAccessDate;
237     }
238 
239     /**
240      * Sets whether this entry has got an access date at all.
241      * @param hasAcessDate whether this entry has got an access date at all.
242      */
setHasAccessDate(final boolean hasAcessDate)243     public void setHasAccessDate(final boolean hasAcessDate) {
244         this.hasAccessDate = hasAcessDate;
245     }
246 
247     /**
248      * Gets the access date.
249      * @throws UnsupportedOperationException if the entry hasn't got a
250      * access date.
251      * @return the access date
252      */
getAccessDate()253     public Date getAccessDate() {
254         if (hasAccessDate) {
255             return ntfsTimeToJavaTime(accessDate);
256         }
257         throw new UnsupportedOperationException(
258                 "The entry doesn't have this timestamp");
259     }
260 
261     /**
262      * Sets the access date using NTFS time (100 nanosecond units
263      * since 1 January 1601)
264      * @param ntfsAccessDate the access date
265      */
setAccessDate(final long ntfsAccessDate)266     public void setAccessDate(final long ntfsAccessDate) {
267         this.accessDate = ntfsAccessDate;
268     }
269 
270     /**
271      * Sets the access date,
272      * @param accessDate the access date
273      */
setAccessDate(final Date accessDate)274     public void setAccessDate(final Date accessDate) {
275         hasAccessDate = accessDate != null;
276         if (hasAccessDate) {
277             this.accessDate = javaTimeToNtfsTime(accessDate);
278         }
279     }
280 
281     /**
282      * Returns whether this entry has windows attributes.
283      * @return whether this entry has windows attributes.
284      */
getHasWindowsAttributes()285     public boolean getHasWindowsAttributes() {
286         return hasWindowsAttributes;
287     }
288 
289     /**
290      * Sets whether this entry has windows attributes.
291      * @param hasWindowsAttributes whether this entry has windows attributes.
292      */
setHasWindowsAttributes(final boolean hasWindowsAttributes)293     public void setHasWindowsAttributes(final boolean hasWindowsAttributes) {
294         this.hasWindowsAttributes = hasWindowsAttributes;
295     }
296 
297     /**
298      * Gets the windows attributes.
299      * @return the windows attributes
300      */
getWindowsAttributes()301     public int getWindowsAttributes() {
302         return windowsAttributes;
303     }
304 
305     /**
306      * Sets the windows attributes.
307      * @param windowsAttributes the windows attributes
308      */
setWindowsAttributes(final int windowsAttributes)309     public void setWindowsAttributes(final int windowsAttributes) {
310         this.windowsAttributes = windowsAttributes;
311     }
312 
313     /**
314      * Returns whether this entry has got a crc.
315      *
316      * <p>In general entries without streams don't have a CRC either.</p>
317      * @return whether this entry has got a crc.
318      */
getHasCrc()319     public boolean getHasCrc() {
320         return hasCrc;
321     }
322 
323     /**
324      * Sets whether this entry has got a crc.
325      * @param hasCrc whether this entry has got a crc.
326      */
setHasCrc(final boolean hasCrc)327     public void setHasCrc(final boolean hasCrc) {
328         this.hasCrc = hasCrc;
329     }
330 
331     /**
332      * Gets the CRC.
333      * @deprecated use getCrcValue instead.
334      * @return the CRC
335      */
336     @Deprecated
getCrc()337     public int getCrc() {
338         return (int) crc;
339     }
340 
341     /**
342      * Sets the CRC.
343      * @deprecated use setCrcValue instead.
344      * @param crc the CRC
345      */
346     @Deprecated
setCrc(final int crc)347     public void setCrc(final int crc) {
348         this.crc = crc;
349     }
350 
351     /**
352      * Gets the CRC.
353      * @since Compress 1.7
354      * @return the CRC
355      */
getCrcValue()356     public long getCrcValue() {
357         return crc;
358     }
359 
360     /**
361      * Sets the CRC.
362      * @since Compress 1.7
363      * @param crc the CRC
364      */
setCrcValue(final long crc)365     public void setCrcValue(final long crc) {
366         this.crc = crc;
367     }
368 
369     /**
370      * Gets the compressed CRC.
371      * @deprecated use getCompressedCrcValue instead.
372      * @return the compressed CRC
373      */
374     @Deprecated
getCompressedCrc()375     int getCompressedCrc() {
376         return (int) compressedCrc;
377     }
378 
379     /**
380      * Sets the compressed CRC.
381      * @deprecated use setCompressedCrcValue instead.
382      * @param crc the CRC
383      */
384     @Deprecated
setCompressedCrc(final int crc)385     void setCompressedCrc(final int crc) {
386         this.compressedCrc = crc;
387     }
388 
389     /**
390      * Gets the compressed CRC.
391      * @since Compress 1.7
392      * @return the CRC
393      */
getCompressedCrcValue()394     long getCompressedCrcValue() {
395         return compressedCrc;
396     }
397 
398     /**
399      * Sets the compressed CRC.
400      * @since Compress 1.7
401      * @param crc the CRC
402      */
setCompressedCrcValue(final long crc)403     void setCompressedCrcValue(final long crc) {
404         this.compressedCrc = crc;
405     }
406 
407     /**
408      * Get this entry's file size.
409      *
410      * @return This entry's file size.
411      */
412     @Override
getSize()413     public long getSize() {
414         return size;
415     }
416 
417     /**
418      * Set this entry's file size.
419      *
420      * @param size This entry's new file size.
421      */
setSize(final long size)422     public void setSize(final long size) {
423         this.size = size;
424     }
425 
426     /**
427      * Get this entry's compressed file size.
428      *
429      * @return This entry's compressed file size.
430      */
getCompressedSize()431     long getCompressedSize() {
432         return compressedSize;
433     }
434 
435     /**
436      * Set this entry's compressed file size.
437      *
438      * @param size This entry's new compressed file size.
439      */
setCompressedSize(final long size)440     void setCompressedSize(final long size) {
441         this.compressedSize = size;
442     }
443 
444     /**
445      * Sets the (compression) methods to use for entry's content - the
446      * default is LZMA2.
447      *
448      * <p>Currently only {@link SevenZMethod#COPY}, {@link
449      * SevenZMethod#LZMA2}, {@link SevenZMethod#BZIP2} and {@link
450      * SevenZMethod#DEFLATE} are supported when writing archives.</p>
451      *
452      * <p>The methods will be consulted in iteration order to create
453      * the final output.</p>
454      *
455      * @param methods the methods to use for the content
456      * @since 1.8
457      */
setContentMethods(final Iterable<? extends SevenZMethodConfiguration> methods)458     public void setContentMethods(final Iterable<? extends SevenZMethodConfiguration> methods) {
459         if (methods != null) {
460             final LinkedList<SevenZMethodConfiguration> l = new LinkedList<>();
461             for (final SevenZMethodConfiguration m : methods) {
462                 l.addLast(m);
463             }
464             contentMethods = Collections.unmodifiableList(l);
465         } else {
466             contentMethods = null;
467         }
468     }
469 
470     /**
471      * Gets the (compression) methods to use for entry's content - the
472      * default is LZMA2.
473      *
474      * <p>Currently only {@link SevenZMethod#COPY}, {@link
475      * SevenZMethod#LZMA2}, {@link SevenZMethod#BZIP2} and {@link
476      * SevenZMethod#DEFLATE} are supported when writing archives.</p>
477      *
478      * <p>The methods will be consulted in iteration order to create
479      * the final output.</p>
480      *
481      * @since 1.8
482      * @return the methods to use for the content
483      */
getContentMethods()484     public Iterable<? extends SevenZMethodConfiguration> getContentMethods() {
485         return contentMethods;
486     }
487 
488     /**
489      * Converts NTFS time (100 nanosecond units since 1 January 1601)
490      * to Java time.
491      * @param ntfsTime the NTFS time in 100 nanosecond units
492      * @return the Java time
493      */
ntfsTimeToJavaTime(final long ntfsTime)494     public static Date ntfsTimeToJavaTime(final long ntfsTime) {
495         final Calendar ntfsEpoch = Calendar.getInstance();
496         ntfsEpoch.setTimeZone(TimeZone.getTimeZone("GMT+0"));
497         ntfsEpoch.set(1601, 0, 1, 0, 0, 0);
498         ntfsEpoch.set(Calendar.MILLISECOND, 0);
499         final long realTime = ntfsEpoch.getTimeInMillis() + (ntfsTime / (10*1000));
500         return new Date(realTime);
501     }
502 
503     /**
504      * Converts Java time to NTFS time.
505      * @param date the Java time
506      * @return the NTFS time
507      */
javaTimeToNtfsTime(final Date date)508     public static long javaTimeToNtfsTime(final Date date) {
509         final Calendar ntfsEpoch = Calendar.getInstance();
510         ntfsEpoch.setTimeZone(TimeZone.getTimeZone("GMT+0"));
511         ntfsEpoch.set(1601, 0, 1, 0, 0, 0);
512         ntfsEpoch.set(Calendar.MILLISECOND, 0);
513         return ((date.getTime() - ntfsEpoch.getTimeInMillis())* 1000 * 10);
514     }
515 }
516