View Javadoc
1   /*
2    * Copyright (C) 2019, Matthias Sohn <matthias.sohn@sap.com> and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  package org.eclipse.jgit.internal.storage.file;
11  
12  import java.io.File;
13  import java.io.IOException;
14  import java.io.RandomAccessFile;
15  
16  import org.eclipse.jgit.lib.AnyObjectId;
17  import org.eclipse.jgit.lib.ObjectId;
18  
19  class PackFileSnapshot extends FileSnapshot {
20  
21  	private static final ObjectId MISSING_CHECKSUM = ObjectId.zeroId();
22  
23  	/**
24  	 * Record a snapshot for a specific packfile path.
25  	 * <p>
26  	 * This method should be invoked before the packfile is accessed.
27  	 *
28  	 * @param path
29  	 *            the path to later remember. The path's current status
30  	 *            information is saved.
31  	 * @return the snapshot.
32  	 */
33  	public static PackFileSnapshot save(File path) {
34  		return new PackFileSnapshot(path);
35  	}
36  
37  	private AnyObjectId checksum = MISSING_CHECKSUM;
38  
39  	private boolean wasChecksumChanged;
40  
41  
42  	PackFileSnapshot(File packFile) {
43  		super(packFile);
44  	}
45  
46  	void setChecksum(AnyObjectId checksum) {
47  		this.checksum = checksum;
48  	}
49  
50  	/** {@inheritDoc} */
51  	@Override
52  	public boolean isModified(File packFile) {
53  		if (!super.isModified(packFile)) {
54  			return false;
55  		}
56  		if (wasSizeChanged() || wasFileKeyChanged()
57  				|| !wasLastModifiedRacilyClean()) {
58  			return true;
59  		}
60  		return isChecksumChanged(packFile);
61  	}
62  
63  	boolean isChecksumChanged(File packFile) {
64  		return wasChecksumChanged = checksum != MISSING_CHECKSUM
65  				&& !checksum.equals(readChecksum(packFile));
66  	}
67  
68  	private AnyObjectId readChecksum(File packFile) {
69  		try (RandomAccessFile fd = new RandomAccessFile(packFile, "r")) { //$NON-NLS-1$
70  			fd.seek(fd.length() - 20);
71  			final byte[] buf = new byte[20];
72  			fd.readFully(buf, 0, 20);
73  			return ObjectId.fromRaw(buf);
74  		} catch (IOException e) {
75  			return MISSING_CHECKSUM;
76  		}
77  	}
78  
79  	boolean wasChecksumChanged() {
80  		return wasChecksumChanged;
81  	}
82  
83  	@SuppressWarnings("nls")
84  	@Override
85  	public String toString() {
86  		return "PackFileSnapshot [checksum=" + checksum + ", "
87  				+ super.toString() + "]";
88  	}
89  
90  }