SevenZArchiveEntry.java

  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.sevenz;

  18. import java.nio.file.attribute.FileTime;
  19. import java.util.Arrays;
  20. import java.util.Collections;
  21. import java.util.Date;
  22. import java.util.Iterator;
  23. import java.util.LinkedList;
  24. import java.util.Objects;

  25. import org.apache.commons.compress.archivers.ArchiveEntry;
  26. import org.apache.commons.io.file.attribute.FileTimes;

  27. /**
  28.  * An entry in a 7z archive.
  29.  *
  30.  * @NotThreadSafe
  31.  * @since 1.6
  32.  */
  33. public class SevenZArchiveEntry implements ArchiveEntry {

  34.     static final SevenZArchiveEntry[] EMPTY_SEVEN_Z_ARCHIVE_ENTRY_ARRAY = {};

  35.     /**
  36.      * Converts Java time to NTFS time.
  37.      *
  38.      * @param date the Java time
  39.      * @return the NTFS time
  40.      * @deprecated Use {@link FileTimes#toNtfsTime(Date)} instead.
  41.      * @see FileTimes#toNtfsTime(Date)
  42.      */
  43.     @Deprecated
  44.     public static long javaTimeToNtfsTime(final Date date) {
  45.         return FileTimes.toNtfsTime(date);
  46.     }

  47.     /**
  48.      * Converts NTFS time (100 nanosecond units since 1 January 1601) to Java time.
  49.      *
  50.      * @param ntfsTime the NTFS time in 100 nanosecond units
  51.      * @return the Java time
  52.      * @deprecated Use {@link FileTimes#ntfsTimeToDate(long)} instead.
  53.      * @see FileTimes#ntfsTimeToDate(long)
  54.      */
  55.     @Deprecated
  56.     public static Date ntfsTimeToJavaTime(final long ntfsTime) {
  57.         return FileTimes.ntfsTimeToDate(ntfsTime);
  58.     }

  59.     private String name;
  60.     private boolean hasStream;
  61.     private boolean isDirectory;
  62.     private boolean isAntiItem;
  63.     private boolean hasCreationDate;
  64.     private boolean hasLastModifiedDate;
  65.     private boolean hasAccessDate;
  66.     private FileTime creationDate;
  67.     private FileTime lastModifiedDate;
  68.     private FileTime accessDate;
  69.     private boolean hasWindowsAttributes;
  70.     private int windowsAttributes;
  71.     private boolean hasCrc;
  72.     private long crc, compressedCrc;
  73.     private long size, compressedSize;
  74.     private Iterable<? extends SevenZMethodConfiguration> contentMethods;

  75.     /**
  76.      * Constructs a new instance.
  77.      */
  78.     public SevenZArchiveEntry() {
  79.     }

  80.     @Override
  81.     public boolean equals(final Object obj) {
  82.         if (this == obj) {
  83.             return true;
  84.         }
  85.         if (obj == null || getClass() != obj.getClass()) {
  86.             return false;
  87.         }
  88.         final SevenZArchiveEntry other = (SevenZArchiveEntry) obj;
  89.         return Objects.equals(name, other.name) && hasStream == other.hasStream && isDirectory == other.isDirectory && isAntiItem == other.isAntiItem
  90.                 && hasCreationDate == other.hasCreationDate && hasLastModifiedDate == other.hasLastModifiedDate && hasAccessDate == other.hasAccessDate
  91.                 && Objects.equals(creationDate, other.creationDate) && Objects.equals(lastModifiedDate, other.lastModifiedDate)
  92.                 && Objects.equals(accessDate, other.accessDate) && hasWindowsAttributes == other.hasWindowsAttributes
  93.                 && windowsAttributes == other.windowsAttributes && hasCrc == other.hasCrc && crc == other.crc && compressedCrc == other.compressedCrc
  94.                 && size == other.size && compressedSize == other.compressedSize && equalSevenZMethods(contentMethods, other.contentMethods);
  95.     }

  96.     private boolean equalSevenZMethods(final Iterable<? extends SevenZMethodConfiguration> c1, final Iterable<? extends SevenZMethodConfiguration> c2) {
  97.         if (c1 == null) {
  98.             return c2 == null;
  99.         }
  100.         if (c2 == null) {
  101.             return false;
  102.         }
  103.         final Iterator<? extends SevenZMethodConfiguration> i2 = c2.iterator();
  104.         for (final SevenZMethodConfiguration element : c1) {
  105.             if (!i2.hasNext()) {
  106.                 return false;
  107.             }
  108.             if (!element.equals(i2.next())) {
  109.                 return false;
  110.             }
  111.         }
  112.         return !i2.hasNext();
  113.     }

  114.     /**
  115.      * Gets the access date. This is equivalent to {@link SevenZArchiveEntry#getAccessTime()}, but precision is truncated to milliseconds.
  116.      *
  117.      * @throws UnsupportedOperationException if the entry hasn't got an access date.
  118.      * @return the access date
  119.      * @see SevenZArchiveEntry#getAccessTime()
  120.      */
  121.     public Date getAccessDate() {
  122.         return FileTimes.toDate(getAccessTime());
  123.     }

  124.     /**
  125.      * Gets the access time.
  126.      *
  127.      * @throws UnsupportedOperationException if the entry hasn't got an access time.
  128.      * @return the access time
  129.      * @since 1.23
  130.      */
  131.     public FileTime getAccessTime() {
  132.         if (hasAccessDate) {
  133.             return accessDate;
  134.         }
  135.         throw new UnsupportedOperationException("The entry doesn't have this timestamp");
  136.     }

  137.     /**
  138.      * Gets the compressed CRC.
  139.      *
  140.      * @return the compressed CRC
  141.      * @deprecated Use {@link #getCompressedCrcValue()} instead.
  142.      */
  143.     @Deprecated
  144.     int getCompressedCrc() {
  145.         return (int) compressedCrc;
  146.     }

  147.     /**
  148.      * Gets the compressed CRC.
  149.      *
  150.      * @since 1.7
  151.      * @return the CRC
  152.      */
  153.     long getCompressedCrcValue() {
  154.         return compressedCrc;
  155.     }

  156.     /**
  157.      * Gets this entry's compressed file size.
  158.      *
  159.      * @return This entry's compressed file size.
  160.      */
  161.     long getCompressedSize() {
  162.         return compressedSize;
  163.     }

  164.     /**
  165.      * Gets the (compression) methods to use for entry's content - the default is LZMA2.
  166.      *
  167.      * <p>
  168.      * Currently only {@link SevenZMethod#COPY}, {@link SevenZMethod#LZMA2}, {@link SevenZMethod#BZIP2} and {@link SevenZMethod#DEFLATE} are supported when
  169.      * writing archives.
  170.      * </p>
  171.      *
  172.      * <p>
  173.      * The methods will be consulted in iteration order to create the final output.
  174.      * </p>
  175.      *
  176.      * @since 1.8
  177.      * @return the methods to use for the content
  178.      */
  179.     public Iterable<? extends SevenZMethodConfiguration> getContentMethods() {
  180.         return contentMethods;
  181.     }

  182.     /**
  183.      * Gets the CRC.
  184.      *
  185.      * @deprecated use getCrcValue instead.
  186.      * @return the CRC
  187.      */
  188.     @Deprecated
  189.     public int getCrc() {
  190.         return (int) crc;
  191.     }

  192.     /**
  193.      * Gets the CRC.
  194.      *
  195.      * @since 1.7
  196.      * @return the CRC
  197.      */
  198.     public long getCrcValue() {
  199.         return crc;
  200.     }

  201.     /**
  202.      * Gets the creation date. This is equivalent to {@link SevenZArchiveEntry#getCreationTime()}, but precision is truncated to milliseconds.
  203.      *
  204.      * @throws UnsupportedOperationException if the entry hasn't got a creation date.
  205.      * @return the new creation date
  206.      * @see SevenZArchiveEntry#getCreationTime()
  207.      */
  208.     public Date getCreationDate() {
  209.         return FileTimes.toDate(getCreationTime());
  210.     }

  211.     /**
  212.      * Gets the creation time.
  213.      *
  214.      * @throws UnsupportedOperationException if the entry hasn't got a creation time.
  215.      * @return the creation time
  216.      * @since 1.23
  217.      */
  218.     public FileTime getCreationTime() {
  219.         if (hasCreationDate) {
  220.             return creationDate;
  221.         }
  222.         throw new UnsupportedOperationException("The entry doesn't have this timestamp");
  223.     }

  224.     /**
  225.      * Gets whether this entry has got an access date at all.
  226.      *
  227.      * @return whether this entry has got an access date at all.
  228.      */
  229.     public boolean getHasAccessDate() {
  230.         return hasAccessDate;
  231.     }

  232.     /**
  233.      * Gets whether this entry has got a crc.
  234.      *
  235.      * <p>
  236.      * In general entries without streams don't have a CRC either.
  237.      * </p>
  238.      *
  239.      * @return whether this entry has got a crc.
  240.      */
  241.     public boolean getHasCrc() {
  242.         return hasCrc;
  243.     }

  244.     /**
  245.      * Gets whether this entry has got a creation date at all.
  246.      *
  247.      * @return whether the entry has got a creation date
  248.      */
  249.     public boolean getHasCreationDate() {
  250.         return hasCreationDate;
  251.     }

  252.     /**
  253.      * Gets whether this entry has got a last modified date at all.
  254.      *
  255.      * @return whether this entry has got a last modified date at all
  256.      */
  257.     public boolean getHasLastModifiedDate() {
  258.         return hasLastModifiedDate;
  259.     }

  260.     /**
  261.      * Gets whether this entry has windows attributes.
  262.      *
  263.      * @return whether this entry has windows attributes.
  264.      */
  265.     public boolean getHasWindowsAttributes() {
  266.         return hasWindowsAttributes;
  267.     }

  268.     /**
  269.      * Gets the last modified date. This is equivalent to {@link SevenZArchiveEntry#getLastModifiedTime()}, but precision is truncated to milliseconds.
  270.      *
  271.      * @throws UnsupportedOperationException if the entry hasn't got a last modified date.
  272.      * @return the last modified date
  273.      * @see SevenZArchiveEntry#getLastModifiedTime()
  274.      */
  275.     @Override
  276.     public Date getLastModifiedDate() {
  277.         return FileTimes.toDate(getLastModifiedTime());
  278.     }

  279.     /**
  280.      * Gets the last modified time.
  281.      *
  282.      * @throws UnsupportedOperationException if the entry hasn't got a last modified time.
  283.      * @return the last modified time
  284.      * @since 1.23
  285.      */
  286.     public FileTime getLastModifiedTime() {
  287.         if (hasLastModifiedDate) {
  288.             return lastModifiedDate;
  289.         }
  290.         throw new UnsupportedOperationException("The entry doesn't have this timestamp");
  291.     }

  292.     /**
  293.      * Gets this entry's name.
  294.      *
  295.      * <p>
  296.      * This method returns the raw name as it is stored inside of the archive.
  297.      * </p>
  298.      *
  299.      * @return This entry's name.
  300.      */
  301.     @Override
  302.     public String getName() {
  303.         return name;
  304.     }

  305.     /**
  306.      * Gets this entry's file size.
  307.      *
  308.      * @return This entry's file size.
  309.      */
  310.     @Override
  311.     public long getSize() {
  312.         return size;
  313.     }

  314.     /**
  315.      * Gets the windows attributes.
  316.      *
  317.      * @return the windows attributes
  318.      */
  319.     public int getWindowsAttributes() {
  320.         return windowsAttributes;
  321.     }

  322.     @Override
  323.     public int hashCode() {
  324.         final String n = getName();
  325.         return n == null ? 0 : n.hashCode();
  326.     }

  327.     /**
  328.      * Tests whether there is any content associated with this entry.
  329.      *
  330.      * @return whether there is any content associated with this entry.
  331.      */
  332.     public boolean hasStream() {
  333.         return hasStream;
  334.     }

  335.     /**
  336.      * Tests whether this is an "anti-item" used in differential backups, meaning it should delete the same file from a previous backup.
  337.      *
  338.      * @return true if it is an anti-item, false otherwise
  339.      */
  340.     public boolean isAntiItem() {
  341.         return isAntiItem;
  342.     }

  343.     /**
  344.      * Tests whether or not this entry represents a directory.
  345.      *
  346.      * @return True if this entry is a directory.
  347.      */
  348.     @Override
  349.     public boolean isDirectory() {
  350.         return isDirectory;
  351.     }

  352.     /**
  353.      * Sets the access date.
  354.      *
  355.      * @param accessDate the new access date
  356.      * @see SevenZArchiveEntry#setAccessTime(FileTime)
  357.      */
  358.     public void setAccessDate(final Date accessDate) {
  359.         setAccessTime(FileTimes.toFileTime(accessDate));
  360.     }

  361.     /**
  362.      * Sets the access date using NTFS time (100 nanosecond units since 1 January 1601)
  363.      *
  364.      * @param ntfsAccessDate the access date
  365.      */
  366.     public void setAccessDate(final long ntfsAccessDate) {
  367.         this.accessDate = FileTimes.ntfsTimeToFileTime(ntfsAccessDate);
  368.     }

  369.     /**
  370.      * Sets the access time.
  371.      *
  372.      * @param time the new access time
  373.      * @since 1.23
  374.      */
  375.     public void setAccessTime(final FileTime time) {
  376.         hasAccessDate = time != null;
  377.         if (hasAccessDate) {
  378.             this.accessDate = time;
  379.         }
  380.     }

  381.     /**
  382.      * Sets whether this is an "anti-item" used in differential backups, meaning it should delete the same file from a previous backup.
  383.      *
  384.      * @param isAntiItem true if it is an anti-item, false otherwise
  385.      */
  386.     public void setAntiItem(final boolean isAntiItem) {
  387.         this.isAntiItem = isAntiItem;
  388.     }

  389.     /**
  390.      * Sets the compressed CRC.
  391.      *
  392.      * @deprecated use setCompressedCrcValue instead.
  393.      * @param crc the CRC
  394.      */
  395.     @Deprecated
  396.     void setCompressedCrc(final int crc) {
  397.         this.compressedCrc = crc;
  398.     }

  399.     /**
  400.      * Sets the compressed CRC.
  401.      *
  402.      * @since 1.7
  403.      * @param crc the CRC
  404.      */
  405.     void setCompressedCrcValue(final long crc) {
  406.         this.compressedCrc = crc;
  407.     }

  408.     /**
  409.      * Sets this entry's compressed file size.
  410.      *
  411.      * @param size This entry's new compressed file size.
  412.      */
  413.     void setCompressedSize(final long size) {
  414.         this.compressedSize = size;
  415.     }

  416.     /**
  417.      * Sets the (compression) methods to use for entry's content - the default is LZMA2.
  418.      *
  419.      * <p>
  420.      * Currently only {@link SevenZMethod#COPY}, {@link SevenZMethod#LZMA2}, {@link SevenZMethod#BZIP2} and {@link SevenZMethod#DEFLATE} are supported when
  421.      * writing archives.
  422.      * </p>
  423.      *
  424.      * <p>
  425.      * The methods will be consulted in iteration order to create the final output.
  426.      * </p>
  427.      *
  428.      * @param methods the methods to use for the content
  429.      * @since 1.8
  430.      */
  431.     public void setContentMethods(final Iterable<? extends SevenZMethodConfiguration> methods) {
  432.         if (methods != null) {
  433.             final LinkedList<SevenZMethodConfiguration> l = new LinkedList<>();
  434.             methods.forEach(l::addLast);
  435.             contentMethods = Collections.unmodifiableList(l);
  436.         } else {
  437.             contentMethods = null;
  438.         }
  439.     }

  440.     /**
  441.      * Sets the (compression) methods to use for entry's content - the default is LZMA2.
  442.      *
  443.      * <p>
  444.      * Currently only {@link SevenZMethod#COPY}, {@link SevenZMethod#LZMA2}, {@link SevenZMethod#BZIP2} and {@link SevenZMethod#DEFLATE} are supported when
  445.      * writing archives.
  446.      * </p>
  447.      *
  448.      * <p>
  449.      * The methods will be consulted in iteration order to create the final output.
  450.      * </p>
  451.      *
  452.      * @param methods the methods to use for the content
  453.      * @since 1.22
  454.      */
  455.     public void setContentMethods(final SevenZMethodConfiguration... methods) {
  456.         setContentMethods(Arrays.asList(methods));
  457.     }

  458.     /**
  459.      * Sets the CRC.
  460.      *
  461.      * @deprecated use setCrcValue instead.
  462.      * @param crc the CRC
  463.      */
  464.     @Deprecated
  465.     public void setCrc(final int crc) {
  466.         this.crc = crc;
  467.     }

  468.     /**
  469.      * Sets the CRC.
  470.      *
  471.      * @since 1.7
  472.      * @param crc the CRC
  473.      */
  474.     public void setCrcValue(final long crc) {
  475.         this.crc = crc;
  476.     }

  477.     /**
  478.      * Sets the creation date.
  479.      *
  480.      * @param creationDate the new creation date
  481.      * @see SevenZArchiveEntry#setCreationTime(FileTime)
  482.      */
  483.     public void setCreationDate(final Date creationDate) {
  484.         setCreationTime(FileTimes.toFileTime(creationDate));
  485.     }

  486.     /**
  487.      * Sets the creation date using NTFS time (100 nanosecond units since 1 January 1601)
  488.      *
  489.      * @param ntfsCreationDate the creation date
  490.      */
  491.     public void setCreationDate(final long ntfsCreationDate) {
  492.         this.creationDate = FileTimes.ntfsTimeToFileTime(ntfsCreationDate);
  493.     }

  494.     /**
  495.      * Sets the creation time.
  496.      *
  497.      * @param time the new creation time
  498.      * @since 1.23
  499.      */
  500.     public void setCreationTime(final FileTime time) {
  501.         hasCreationDate = time != null;
  502.         if (hasCreationDate) {
  503.             this.creationDate = time;
  504.         }
  505.     }

  506.     /**
  507.      * Sets whether or not this entry represents a directory.
  508.      *
  509.      * @param isDirectory True if this entry is a directory.
  510.      */
  511.     public void setDirectory(final boolean isDirectory) {
  512.         this.isDirectory = isDirectory;
  513.     }

  514.     /**
  515.      * Sets whether this entry has got an access date at all.
  516.      *
  517.      * @param hasAcessDate whether this entry has got an access date at all.
  518.      */
  519.     public void setHasAccessDate(final boolean hasAcessDate) {
  520.         this.hasAccessDate = hasAcessDate;
  521.     }

  522.     /**
  523.      * Sets whether this entry has got a crc.
  524.      *
  525.      * @param hasCrc whether this entry has got a crc.
  526.      */
  527.     public void setHasCrc(final boolean hasCrc) {
  528.         this.hasCrc = hasCrc;
  529.     }

  530.     /**
  531.      * Sets whether this entry has got a creation date at all.
  532.      *
  533.      * @param hasCreationDate whether the entry has got a creation date
  534.      */
  535.     public void setHasCreationDate(final boolean hasCreationDate) {
  536.         this.hasCreationDate = hasCreationDate;
  537.     }

  538.     /**
  539.      * Sets whether this entry has got a last modified date at all.
  540.      *
  541.      * @param hasLastModifiedDate whether this entry has got a last modified date at all
  542.      */
  543.     public void setHasLastModifiedDate(final boolean hasLastModifiedDate) {
  544.         this.hasLastModifiedDate = hasLastModifiedDate;
  545.     }

  546.     /**
  547.      * Sets whether there is any content associated with this entry.
  548.      *
  549.      * @param hasStream whether there is any content associated with this entry.
  550.      */
  551.     public void setHasStream(final boolean hasStream) {
  552.         this.hasStream = hasStream;
  553.     }

  554.     /**
  555.      * Sets whether this entry has windows attributes.
  556.      *
  557.      * @param hasWindowsAttributes whether this entry has windows attributes.
  558.      */
  559.     public void setHasWindowsAttributes(final boolean hasWindowsAttributes) {
  560.         this.hasWindowsAttributes = hasWindowsAttributes;
  561.     }

  562.     /**
  563.      * Sets the last modified date.
  564.      *
  565.      * @param lastModifiedDate the new last modified date
  566.      * @see SevenZArchiveEntry#setLastModifiedTime(FileTime)
  567.      */
  568.     public void setLastModifiedDate(final Date lastModifiedDate) {
  569.         setLastModifiedTime(FileTimes.toFileTime(lastModifiedDate));
  570.     }

  571.     /**
  572.      * Sets the last modified date using NTFS time (100 nanosecond units since 1 January 1601)
  573.      *
  574.      * @param ntfsLastModifiedDate the last modified date
  575.      */
  576.     public void setLastModifiedDate(final long ntfsLastModifiedDate) {
  577.         this.lastModifiedDate = FileTimes.ntfsTimeToFileTime(ntfsLastModifiedDate);
  578.     }

  579.     /**
  580.      * Sets the last modified time.
  581.      *
  582.      * @param time the new last modified time
  583.      * @since 1.23
  584.      */
  585.     public void setLastModifiedTime(final FileTime time) {
  586.         hasLastModifiedDate = time != null;
  587.         if (hasLastModifiedDate) {
  588.             this.lastModifiedDate = time;
  589.         }
  590.     }

  591.     /**
  592.      * Sets this entry's name.
  593.      *
  594.      * @param name This entry's new name.
  595.      */
  596.     public void setName(final String name) {
  597.         this.name = name;
  598.     }

  599.     /**
  600.      * Sets this entry's file size.
  601.      *
  602.      * @param size This entry's new file size.
  603.      */
  604.     public void setSize(final long size) {
  605.         this.size = size;
  606.     }

  607.     /**
  608.      * Sets the windows attributes.
  609.      *
  610.      * @param windowsAttributes the windows attributes
  611.      */
  612.     public void setWindowsAttributes(final int windowsAttributes) {
  613.         this.windowsAttributes = windowsAttributes;
  614.     }
  615. }