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 * 017 */ 018package org.apache.commons.compress.archivers.sevenz; 019 020import java.util.Calendar; 021import java.util.Collections; 022import java.util.Date; 023import java.util.LinkedList; 024import java.util.TimeZone; 025 026import org.apache.commons.compress.archivers.ArchiveEntry; 027 028/** 029 * An entry in a 7z archive. 030 * 031 * @NotThreadSafe 032 * @since 1.6 033 */ 034public class SevenZArchiveEntry implements ArchiveEntry { 035 private String name; 036 private boolean hasStream; 037 private boolean isDirectory; 038 private boolean isAntiItem; 039 private boolean hasCreationDate; 040 private boolean hasLastModifiedDate; 041 private boolean hasAccessDate; 042 private long creationDate; 043 private long lastModifiedDate; 044 private long accessDate; 045 private boolean hasWindowsAttributes; 046 private int windowsAttributes; 047 private boolean hasCrc; 048 private long crc, compressedCrc; 049 private long size, compressedSize; 050 private Iterable<? extends SevenZMethodConfiguration> contentMethods; 051 052 public SevenZArchiveEntry() { 053 } 054 055 /** 056 * Get this entry's name. 057 * 058 * @return This entry's name. 059 */ 060 @Override 061 public String getName() { 062 return name; 063 } 064 065 /** 066 * Set this entry's name. 067 * 068 * @param name This entry's new name. 069 */ 070 public void setName(final String name) { 071 this.name = name; 072 } 073 074 /** 075 * Whether there is any content associated with this entry. 076 * @return whether there is any content associated with this entry. 077 */ 078 public boolean hasStream() { 079 return hasStream; 080 } 081 082 /** 083 * Sets whether there is any content associated with this entry. 084 * @param hasStream whether there is any content associated with this entry. 085 */ 086 public void setHasStream(final boolean hasStream) { 087 this.hasStream = hasStream; 088 } 089 090 /** 091 * Return whether or not this entry represents a directory. 092 * 093 * @return True if this entry is a directory. 094 */ 095 @Override 096 public boolean isDirectory() { 097 return isDirectory; 098 } 099 100 /** 101 * Sets whether or not this entry represents a directory. 102 * 103 * @param isDirectory True if this entry is a directory. 104 */ 105 public void setDirectory(final boolean isDirectory) { 106 this.isDirectory = isDirectory; 107 } 108 109 /** 110 * Indicates whether this is an "anti-item" used in differential backups, 111 * meaning it should delete the same file from a previous backup. 112 * @return true if it is an anti-item, false otherwise 113 */ 114 public boolean isAntiItem() { 115 return isAntiItem; 116 } 117 118 /** 119 * Sets whether this is an "anti-item" used in differential backups, 120 * meaning it should delete the same file from a previous backup. 121 * @param isAntiItem true if it is an anti-item, false otherwise 122 */ 123 public void setAntiItem(final boolean isAntiItem) { 124 this.isAntiItem = isAntiItem; 125 } 126 127 /** 128 * Returns whether this entry has got a creation date at all. 129 * @return whether the entry has got a creation date 130 */ 131 public boolean getHasCreationDate() { 132 return hasCreationDate; 133 } 134 135 /** 136 * Sets whether this entry has got a creation date at all. 137 * @param hasCreationDate whether the entry has got a creation date 138 */ 139 public void setHasCreationDate(final boolean hasCreationDate) { 140 this.hasCreationDate = hasCreationDate; 141 } 142 143 /** 144 * Gets the creation date. 145 * @throws UnsupportedOperationException if the entry hasn't got a 146 * creation date. 147 * @return the creation date 148 */ 149 public Date getCreationDate() { 150 if (hasCreationDate) { 151 return ntfsTimeToJavaTime(creationDate); 152 } 153 throw new UnsupportedOperationException( 154 "The entry doesn't have this timestamp"); 155 } 156 157 /** 158 * Sets the creation date using NTFS time (100 nanosecond units 159 * since 1 January 1601) 160 * @param ntfsCreationDate the creation date 161 */ 162 public void setCreationDate(final long ntfsCreationDate) { 163 this.creationDate = ntfsCreationDate; 164 } 165 166 /** 167 * Sets the creation date, 168 * @param creationDate the creation date 169 */ 170 public void setCreationDate(final Date creationDate) { 171 hasCreationDate = creationDate != null; 172 if (hasCreationDate) { 173 this.creationDate = javaTimeToNtfsTime(creationDate); 174 } 175 } 176 177 /** 178 * Returns whether this entry has got a last modified date at all. 179 * @return whether this entry has got a last modified date at all 180 */ 181 public boolean getHasLastModifiedDate() { 182 return hasLastModifiedDate; 183 } 184 185 /** 186 * Sets whether this entry has got a last modified date at all. 187 * @param hasLastModifiedDate whether this entry has got a last 188 * modified date at all 189 */ 190 public void setHasLastModifiedDate(final boolean hasLastModifiedDate) { 191 this.hasLastModifiedDate = hasLastModifiedDate; 192 } 193 194 /** 195 * Gets the last modified date. 196 * @throws UnsupportedOperationException if the entry hasn't got a 197 * last modified date. 198 * @return the last modified date 199 */ 200 @Override 201 public Date getLastModifiedDate() { 202 if (hasLastModifiedDate) { 203 return ntfsTimeToJavaTime(lastModifiedDate); 204 } 205 throw new UnsupportedOperationException( 206 "The entry doesn't have this timestamp"); 207 } 208 209 /** 210 * Sets the last modified date using NTFS time (100 nanosecond 211 * units since 1 January 1601) 212 * @param ntfsLastModifiedDate the last modified date 213 */ 214 public void setLastModifiedDate(final long ntfsLastModifiedDate) { 215 this.lastModifiedDate = ntfsLastModifiedDate; 216 } 217 218 /** 219 * Sets the last modified date, 220 * @param lastModifiedDate the last modified date 221 */ 222 public void setLastModifiedDate(final Date lastModifiedDate) { 223 hasLastModifiedDate = lastModifiedDate != null; 224 if (hasLastModifiedDate) { 225 this.lastModifiedDate = javaTimeToNtfsTime(lastModifiedDate); 226 } 227 } 228 229 /** 230 * Returns whether this entry has got an access date at all. 231 * @return whether this entry has got an access date at all. 232 */ 233 public boolean getHasAccessDate() { 234 return hasAccessDate; 235 } 236 237 /** 238 * Sets whether this entry has got an access date at all. 239 * @param hasAcessDate whether this entry has got an access date at all. 240 */ 241 public void setHasAccessDate(final boolean hasAcessDate) { 242 this.hasAccessDate = hasAcessDate; 243 } 244 245 /** 246 * Gets the access date. 247 * @throws UnsupportedOperationException if the entry hasn't got a 248 * access date. 249 * @return the access date 250 */ 251 public Date getAccessDate() { 252 if (hasAccessDate) { 253 return ntfsTimeToJavaTime(accessDate); 254 } 255 throw new UnsupportedOperationException( 256 "The entry doesn't have this timestamp"); 257 } 258 259 /** 260 * Sets the access date using NTFS time (100 nanosecond units 261 * since 1 January 1601) 262 * @param ntfsAccessDate the access date 263 */ 264 public void setAccessDate(final long ntfsAccessDate) { 265 this.accessDate = ntfsAccessDate; 266 } 267 268 /** 269 * Sets the access date, 270 * @param accessDate the access date 271 */ 272 public void setAccessDate(final Date accessDate) { 273 hasAccessDate = accessDate != null; 274 if (hasAccessDate) { 275 this.accessDate = javaTimeToNtfsTime(accessDate); 276 } 277 } 278 279 /** 280 * Returns whether this entry has windows attributes. 281 * @return whether this entry has windows attributes. 282 */ 283 public boolean getHasWindowsAttributes() { 284 return hasWindowsAttributes; 285 } 286 287 /** 288 * Sets whether this entry has windows attributes. 289 * @param hasWindowsAttributes whether this entry has windows attributes. 290 */ 291 public void setHasWindowsAttributes(final boolean hasWindowsAttributes) { 292 this.hasWindowsAttributes = hasWindowsAttributes; 293 } 294 295 /** 296 * Gets the windows attributes. 297 * @return the windows attributes 298 */ 299 public int getWindowsAttributes() { 300 return windowsAttributes; 301 } 302 303 /** 304 * Sets the windows attributes. 305 * @param windowsAttributes the windows attributes 306 */ 307 public void setWindowsAttributes(final int windowsAttributes) { 308 this.windowsAttributes = windowsAttributes; 309 } 310 311 /** 312 * Returns whether this entry has got a crc. 313 * 314 * <p>In general entries without streams don't have a CRC either.</p> 315 * @return whether this entry has got a crc. 316 */ 317 public boolean getHasCrc() { 318 return hasCrc; 319 } 320 321 /** 322 * Sets whether this entry has got a crc. 323 * @param hasCrc whether this entry has got a crc. 324 */ 325 public void setHasCrc(final boolean hasCrc) { 326 this.hasCrc = hasCrc; 327 } 328 329 /** 330 * Gets the CRC. 331 * @deprecated use getCrcValue instead. 332 * @return the CRC 333 */ 334 @Deprecated 335 public int getCrc() { 336 return (int) crc; 337 } 338 339 /** 340 * Sets the CRC. 341 * @deprecated use setCrcValue instead. 342 * @param crc the CRC 343 */ 344 @Deprecated 345 public void setCrc(final int crc) { 346 this.crc = crc; 347 } 348 349 /** 350 * Gets the CRC. 351 * @since Compress 1.7 352 * @return the CRC 353 */ 354 public long getCrcValue() { 355 return crc; 356 } 357 358 /** 359 * Sets the CRC. 360 * @since Compress 1.7 361 * @param crc the CRC 362 */ 363 public void setCrcValue(final long crc) { 364 this.crc = crc; 365 } 366 367 /** 368 * Gets the compressed CRC. 369 * @deprecated use getCompressedCrcValue instead. 370 * @return the compressed CRC 371 */ 372 @Deprecated 373 int getCompressedCrc() { 374 return (int) compressedCrc; 375 } 376 377 /** 378 * Sets the compressed CRC. 379 * @deprecated use setCompressedCrcValue instead. 380 * @param crc the CRC 381 */ 382 @Deprecated 383 void setCompressedCrc(final int crc) { 384 this.compressedCrc = crc; 385 } 386 387 /** 388 * Gets the compressed CRC. 389 * @since Compress 1.7 390 * @return the CRC 391 */ 392 long getCompressedCrcValue() { 393 return compressedCrc; 394 } 395 396 /** 397 * Sets the compressed CRC. 398 * @since Compress 1.7 399 * @param crc the CRC 400 */ 401 void setCompressedCrcValue(final long crc) { 402 this.compressedCrc = crc; 403 } 404 405 /** 406 * Get this entry's file size. 407 * 408 * @return This entry's file size. 409 */ 410 @Override 411 public long getSize() { 412 return size; 413 } 414 415 /** 416 * Set this entry's file size. 417 * 418 * @param size This entry's new file size. 419 */ 420 public void setSize(final long size) { 421 this.size = size; 422 } 423 424 /** 425 * Get this entry's compressed file size. 426 * 427 * @return This entry's compressed file size. 428 */ 429 long getCompressedSize() { 430 return compressedSize; 431 } 432 433 /** 434 * Set this entry's compressed file size. 435 * 436 * @param size This entry's new compressed file size. 437 */ 438 void setCompressedSize(final long size) { 439 this.compressedSize = size; 440 } 441 442 /** 443 * Sets the (compression) methods to use for entry's content - the 444 * default is LZMA2. 445 * 446 * <p>Currently only {@link SevenZMethod#COPY}, {@link 447 * SevenZMethod#LZMA2}, {@link SevenZMethod#BZIP2} and {@link 448 * SevenZMethod#DEFLATE} are supported when writing archives.</p> 449 * 450 * <p>The methods will be consulted in iteration order to create 451 * the final output.</p> 452 * 453 * @param methods the methods to use for the content 454 * @since 1.8 455 */ 456 public void setContentMethods(final Iterable<? extends SevenZMethodConfiguration> methods) { 457 if (methods != null) { 458 final LinkedList<SevenZMethodConfiguration> l = new LinkedList<>(); 459 for (final SevenZMethodConfiguration m : methods) { 460 l.addLast(m); 461 } 462 contentMethods = Collections.unmodifiableList(l); 463 } else { 464 contentMethods = null; 465 } 466 } 467 468 /** 469 * Gets the (compression) methods to use for entry's content - the 470 * default is LZMA2. 471 * 472 * <p>Currently only {@link SevenZMethod#COPY}, {@link 473 * SevenZMethod#LZMA2}, {@link SevenZMethod#BZIP2} and {@link 474 * SevenZMethod#DEFLATE} are supported when writing archives.</p> 475 * 476 * <p>The methods will be consulted in iteration order to create 477 * the final output.</p> 478 * 479 * @since 1.8 480 * @return the methods to use for the content 481 */ 482 public Iterable<? extends SevenZMethodConfiguration> getContentMethods() { 483 return contentMethods; 484 } 485 486 /** 487 * Converts NTFS time (100 nanosecond units since 1 January 1601) 488 * to Java time. 489 * @param ntfsTime the NTFS time in 100 nanosecond units 490 * @return the Java time 491 */ 492 public static Date ntfsTimeToJavaTime(final long ntfsTime) { 493 final Calendar ntfsEpoch = Calendar.getInstance(); 494 ntfsEpoch.setTimeZone(TimeZone.getTimeZone("GMT+0")); 495 ntfsEpoch.set(1601, 0, 1, 0, 0, 0); 496 ntfsEpoch.set(Calendar.MILLISECOND, 0); 497 final long realTime = ntfsEpoch.getTimeInMillis() + (ntfsTime / (10*1000)); 498 return new Date(realTime); 499 } 500 501 /** 502 * Converts Java time to NTFS time. 503 * @param date the Java time 504 * @return the NTFS time 505 */ 506 public static long javaTimeToNtfsTime(final Date date) { 507 final Calendar ntfsEpoch = Calendar.getInstance(); 508 ntfsEpoch.setTimeZone(TimeZone.getTimeZone("GMT+0")); 509 ntfsEpoch.set(1601, 0, 1, 0, 0, 0); 510 ntfsEpoch.set(Calendar.MILLISECOND, 0); 511 return ((date.getTime() - ntfsEpoch.getTimeInMillis())* 1000 * 10); 512 } 513}