Java tutorial
/** * This file is part of git-as-svn. It is subject to the license terms * in the LICENSE file found in the top-level directory of this distribution * and at http://www.gnu.org/licenses/gpl-2.0.html. No part of git-as-svn, * including this file, may be copied, modified, propagated, or distributed * except according to the terms contained in the LICENSE file. */ package svnserver.repository.git; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.revwalk.RevTree; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNProperty; import org.tmatesoft.svn.core.internal.wc.SVNFileUtil; import svnserver.repository.VcsCopyFrom; import svnserver.repository.VcsSupplier; import svnserver.repository.git.filter.GitFilter; import svnserver.repository.git.prop.GitProperty; import svnserver.repository.git.prop.PropertyMapping; import java.io.IOException; import java.io.InputStream; import java.util.*; /** * Git file. * * @author Artem V. Navrotskiy <bozaro@users.noreply.github.com> */ public class GitFileTreeEntry extends GitEntryImpl implements GitFile { @NotNull private final GitRepository repo; @NotNull private final GitFilter filter; @NotNull private final GitTreeEntry treeEntry; private final int revision; // Cache @NotNull private final EntriesCache entriesCache; @Nullable private Iterable<GitFile> treeEntriesCache; private GitFileTreeEntry(@NotNull GitRepository repo, @NotNull GitProperty[] parentProps, @NotNull String parentPath, @NotNull GitTreeEntry treeEntry, int revision, @NotNull EntriesCache entriesCache) throws IOException, SVNException { super(parentProps, parentPath, repo.collectProperties(treeEntry, entriesCache), treeEntry.getFileName(), treeEntry.getFileMode()); this.repo = repo; this.revision = revision; this.treeEntry = treeEntry; this.entriesCache = entriesCache; this.filter = repo.getFilter(treeEntry.getFileMode(), this.getRawProperties()); } @NotNull public static GitFile create(@NotNull GitRepository repo, @NotNull RevTree tree, int revision) throws IOException, SVNException { return create(repo, PropertyMapping.getRootProperties(), "", new GitTreeEntry(repo.getRepository(), FileMode.TREE, tree, ""), revision); } @NotNull private static GitFile create(@NotNull GitRepository repo, @NotNull GitProperty[] parentProps, @NotNull String parentPath, @NotNull GitTreeEntry treeEntry, int revision) throws IOException, SVNException { return new GitFileTreeEntry(repo, parentProps, parentPath, treeEntry, revision, new EntriesCache(repo, treeEntry)); } @NotNull @Override public GitRepository getRepo() { return repo; } @Override public int getRevision() { return revision; } @NotNull public GitFilter getFilter() { return filter; } @NotNull public GitTreeEntry getTreeEntry() { return treeEntry; } @NotNull public FileMode getFileMode() { return treeEntry.getFileMode(); } @NotNull public GitObject<ObjectId> getObjectId() { return treeEntry.getObjectId(); } @NotNull @Override public Map<String, String> getProperties() throws IOException, SVNException { final Map<String, String> props = getUpstreamProperties(); final FileMode fileMode = getFileMode(); if (fileMode.equals(FileMode.SYMLINK)) { props.remove(SVNProperty.EOL_STYLE); props.remove(SVNProperty.MIME_TYPE); props.put(SVNProperty.SPECIAL, "*"); } else { if (fileMode.equals(FileMode.EXECUTABLE_FILE)) { props.put(SVNProperty.EXECUTABLE, "*"); } if (fileMode.getObjectType() == Constants.OBJ_BLOB && repo.isObjectBinary(filter, getObjectId())) { props.remove(SVNProperty.EOL_STYLE); props.put(SVNProperty.MIME_TYPE, SVNFileUtil.BINARY_MIME_TYPE); } } return props; } @NotNull @Override public String getMd5() throws IOException, SVNException { return filter.getMd5(treeEntry.getObjectId()); } @NotNull @Override public String getContentHash() throws IOException, SVNException { return filter.getContentHash(treeEntry.getObjectId()); } @Override public long getSize() throws IOException, SVNException { return isDirectory() ? 0L : filter.getSize(treeEntry.getObjectId()); } @NotNull @Override public InputStream openStream() throws IOException, SVNException { return filter.inputStream(treeEntry.getObjectId()); } @NotNull @Override public Iterable<GitFile> getEntries() throws IOException, SVNException { if (treeEntriesCache == null) { final List<GitFile> result = new ArrayList<>(); final String fullPath = getFullPath(); for (GitTreeEntry entry : entriesCache.get()) { result.add(GitFileTreeEntry.create(repo, getRawProperties(), fullPath, entry, revision)); } treeEntriesCache = result; } return treeEntriesCache; } @Nullable public GitFile getEntry(@NotNull String name) throws IOException, SVNException { for (GitTreeEntry entry : entriesCache.get()) { if (entry.getFileName().equals(name)) { return create(repo, getRawProperties(), getFullPath(), entry, revision); } } return null; } @Nullable @Override public VcsCopyFrom getCopyFrom() throws IOException { return getLastChange().getCopyFrom(getFullPath()); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; GitFileTreeEntry that = (GitFileTreeEntry) o; return Objects.equals(treeEntry, that.treeEntry) && Arrays.equals(getRawProperties(), that.getRawProperties()); } @Override public int hashCode() { return treeEntry.hashCode() + Arrays.hashCode(getRawProperties()) * 31; } @Override public String toString() { return "GitFileInfo{" + "fullPath='" + getFullPath() + '\'' + ", objectId=" + treeEntry + '}'; } private static class EntriesCache implements VcsSupplier<Iterable<GitTreeEntry>> { private final GitRepository repo; private final GitTreeEntry treeEntry; public Iterable<GitTreeEntry> rawEntriesCache; public EntriesCache(GitRepository repo, GitTreeEntry treeEntry) { this.repo = repo; this.treeEntry = treeEntry; } @Override public Iterable<GitTreeEntry> get() throws SVNException, IOException { if (rawEntriesCache == null) { rawEntriesCache = repo.loadTree(treeEntry); } return rawEntriesCache; } } }