package com.beijunyi.parallelgit.filesystem;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.UserPrincipalLookupService;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.beijunyi.parallelgit.filesystem.io.RootNode;
import com.beijunyi.parallelgit.filesystem.utils.GfsConfiguration;
import com.beijunyi.parallelgit.utils.RefUtils;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import static com.beijunyi.parallelgit.filesystem.io.GfsFileAttributeView.Basic.BASIC_VIEW;
import static com.beijunyi.parallelgit.filesystem.io.GfsFileAttributeView.Posix.POSIX_VIEW;
import static java.util.Arrays.asList;
import static java.util.Collections.unmodifiableSet;
import static org.eclipse.jgit.lib.Constants.MASTER;
public class GitFileSystem extends FileSystem {
public static final Set<String> SUPPORTED_VIEWS = unmodifiableSet(new HashSet<>(asList(BASIC_VIEW, POSIX_VIEW)));
private final String sid;
private final GfsObjectService objService;
private final GfsFileStore fileStore;
private final GfsStatusProvider statusProvider;
private boolean closed = false;
public GitFileSystem(GfsConfiguration cfg, String sid) throws IOException {
this.sid = sid;
objService = new GfsObjectService(cfg.repository());
RevCommit commit = cfg.commit();
String branch = cfg.branch();
if(branch == null && commit == null)
branch = RefUtils.fullBranchName(MASTER);
fileStore = new GfsFileStore(commit, objService);
statusProvider = new GfsStatusProvider(fileStore, branch, commit);
}
@Nonnull
@Override
public GitFileSystemProvider provider() {
return GitFileSystemProvider.getDefault();
}
@Override
public synchronized void close() {
if(!closed) {
closed = true;
objService.close();
statusProvider.close();
GitFileSystemProvider.getDefault().unregister(this);
}
}
@Override
public synchronized boolean isOpen() {
return !closed;
}
@Override
public boolean isReadOnly() {
return false;
}
@Nonnull
@Override
public String getSeparator() {
return "/";
}
@Nonnull
@Override
public Iterable<Path> getRootDirectories() {
return Collections.<Path>singleton(getRootPath());
}
@Nonnull
@Override
public Iterable<FileStore> getFileStores() {
return Collections.<FileStore>singleton(fileStore);
}
@Nonnull
@Override
public Set<String> supportedFileAttributeViews() {
return SUPPORTED_VIEWS;
}
@Nonnull
@Override
public GitPath getPath(String first, String... more) {
String path;
if(more.length == 0) {
path = first;
} else {
StringBuilder sb = new StringBuilder();
sb.append(first);
for(String segment: more) {
if(segment.length() > 0) {
if(sb.length() > 0) sb.append('/');
sb.append(segment);
}
}
path = sb.toString();
}
return new GitPath(this, path);
}
@Nonnull
@Override
public PathMatcher getPathMatcher(String syntaxAndInput) {
return GfsPathMatcher.newMatcher(syntaxAndInput);
}
@Nullable
@Override
public UserPrincipalLookupService getUserPrincipalLookupService() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
@Nullable
@Override
public WatchService newWatchService() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
@Nonnull
public Repository getRepository() {
return objService.getRepository();
}
@Nonnull
public String getSessionId() {
return sid;
}
@Nonnull
public GitPath getRootPath() {
return getPath("/");
}
@Nonnull
public GfsObjectService getObjectService() {
return objService;
}
@Nonnull
public GfsFileStore getFileStore() {
return fileStore;
}
@Nonnull
public GfsStatusProvider getStatusProvider() {
return statusProvider;
}
@Nonnull
public ObjectId flush() throws IOException {
RootNode root = fileStore.getRoot();
ObjectId ret = root.getObjectId(true);
objService.flush();
return ret;
}
public void updateOrigin(ObjectId rootTree) throws IOException {
RootNode root = fileStore.getRoot();
root.updateOrigin(rootTree);
}
public void reset() throws IOException {
RootNode root = fileStore.getRoot();
root.reset();
}
@Override
public boolean equals(@Nullable Object that) {
return this == that
|| (that != null && getClass() == that.getClass() && sid.equals(((GitFileSystem)that).sid));
}
@Override
public int hashCode() {
return sid.hashCode();
}
@Override
protected void finalize() throws Throwable {
super.finalize();
close();
}
}