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  import org.eclipse.jgit.util.Equality;
19  
20  class PackFileSnapshot extends FileSnapshot {
21  
22  	private static final ObjectId MISSING_CHECKSUM = ObjectId.zeroId();
23  
24  	/**
25  	 * Record a snapshot for a specific packfile path.
26  	 * <p>
27  	 * This method should be invoked before the packfile is accessed.
28  	 *
29  	 * @param path
30  	 *            the path to later remember. The path's current status
31  	 *            information is saved.
32  	 * @return the snapshot.
33  	 */
34  	public static PackFileSnapshot save(File path) {
35  		return new PackFileSnapshot(path);
36  	}
37  
38  	private AnyObjectId checksum = MISSING_CHECKSUM;
39  
40  	private boolean wasChecksumChanged;
41  
42  
43  	PackFileSnapshot(File packFile) {
44  		super(packFile);
45  	}
46  
47  	void setChecksum(AnyObjectId checksum) {
48  		this.checksum = checksum;
49  	}
50  
51  	/** {@inheritDoc} */
52  	@Override
53  	public boolean isModified(File packFile) {
54  		if (!super.isModified(packFile)) {
55  			return false;
56  		}
57  		if (wasSizeChanged() || wasFileKeyChanged()
58  				|| !wasLastModifiedRacilyClean()) {
59  			return true;
60  		}
61  		return isChecksumChanged(packFile);
62  	}
63  
64  	boolean isChecksumChanged(File packFile) {
65  		return wasChecksumChanged = !Equality.isSameInstance(checksum,
66  				MISSING_CHECKSUM)
67  				&& !checksum.equals(readChecksum(packFile));
68  	}
69  
70  	private AnyObjectId readChecksum(File packFile) {
71  		try (RandomAccessFile fd = new RandomAccessFile(packFile, "r")) { //$NON-NLS-1$
72  			fd.seek(fd.length() - 20);
73  			final byte[] buf = new byte[20];
74  			fd.readFully(buf, 0, 20);
75  			return ObjectId.fromRaw(buf);
76  		} catch (IOException e) {
77  			return MISSING_CHECKSUM;
78  		}
79  	}
80  
81  	boolean wasChecksumChanged() {
82  		return wasChecksumChanged;
83  	}
84  
85  	@SuppressWarnings("nls")
86  	@Override
87  	public String toString() {
88  		return "PackFileSnapshot [checksum=" + checksum + ", "
89  				+ super.toString() + "]";
90  	}
91  
92  }