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 * <p>This method returns the raw name as it is stored inside of the archive.</p> 059 * 060 * @return This entry's name. 061 */ 062 @Override 063 public String getName() { 064 return name; 065 } 066 067 /** 068 * Set this entry's name. 069 * 070 * @param name This entry's new name. 071 */ 072 public void setName(final String name) { 073 this.name = name; 074 } 075 076 /** 077 * Whether there is any content associated with this entry. 078 * @return whether there is any content associated with this entry. 079 */ 080 public boolean hasStream() { 081 return hasStream; 082 } 083 084 /** 085 * Sets whether there is any content associated with this entry. 086 * @param hasStream whether there is any content associated with this entry. 087 */ 088 public void setHasStream(final boolean hasStream) { 089 this.hasStream = hasStream; 090 } 091 092 /** 093 * Return whether or not this entry represents a directory. 094 * 095 * @return True if this entry is a directory. 096 */ 097 @Override 098 public boolean isDirectory() { 099 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 301 public int getWindowsAttributes() { 302 return windowsAttributes; 303 } 304 305 /** 306 * Sets the windows attributes. 307 * @param windowsAttributes the windows attributes 308 */ 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 */ 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 */ 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 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 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 */ 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 */ 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 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 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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}