package com.beijunyi.parallelgit.filesystem; import java.io.Closeable; import java.io.IOException; import java.nio.file.ClosedFileSystemException; import java.util.concurrent.locks.ReentrantLock; import javax.annotation.Nonnull; import javax.annotation.Nullable; import com.beijunyi.parallelgit.filesystem.exceptions.NoBranchException; import com.beijunyi.parallelgit.filesystem.exceptions.NoHeadCommitException; import com.beijunyi.parallelgit.filesystem.merge.MergeNote; import com.beijunyi.parallelgit.utils.RefUtils; import org.eclipse.jgit.revwalk.RevCommit; import static org.eclipse.jgit.lib.Constants.R_HEADS; public class GfsStatusProvider implements AutoCloseable { private final ReentrantLock lock = new ReentrantLock(); private final GfsFileStore fileStore; private String branch; private RevCommit commit; private MergeNote mergeNote; private volatile boolean closed = false; public GfsStatusProvider(GfsFileStore fileStore, @Nullable String branch, @Nullable RevCommit commit) { this.fileStore = fileStore; this.commit = commit; this.branch = branch; } public boolean isDirty() throws IOException { return fileStore.getRoot().isModified(); } @Nonnull public Update prepareUpdate() { return new Update(); } @Nonnull public String branch() { checkClosed(); if(branch == null) throw new NoBranchException(); return branch.substring(R_HEADS.length()); } public boolean isAttached() { return branch != null; } @Nonnull public RevCommit commit() { checkClosed(); if(commit == null) throw new NoHeadCommitException(); return commit; } public boolean isInitialized() { return branch != null; } @Nullable public MergeNote mergeNote() { checkClosed(); return mergeNote; } @Override public synchronized void close() { if(!closed) closed = true; } private void checkClosed() { if(closed) throw new ClosedFileSystemException(); } public class Update implements Closeable { private Update() { lock.lock(); } @Override public void close() { lock.unlock(); } @Nonnull public Update branch(String newBranch) { checkClosed(); branch = RefUtils.fullBranchName(newBranch); return this; } @Nonnull public Update detach() { checkClosed(); branch = null; return this; } @Nonnull public Update commit(RevCommit newCommit) { checkClosed(); commit = newCommit; return this; } @Nonnull public Update mergeNote(MergeNote newMergeNote) { checkClosed(); mergeNote = newMergeNote; return this; } @Nonnull public Update clearMergeNote() { checkClosed(); mergeNote = null; return this; } } }