Made RepositoryObjectTreeWalker and associated classes and methods.

This commit is contained in:
Winston Li 2014-11-16 12:43:21 +00:00
parent ba7d0d318c
commit 3cd94af7e9
15 changed files with 203 additions and 96 deletions

View file

@ -5,7 +5,7 @@ import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.log.Log;
import uk.ac.ic.wlgitbridge.application.jetty.NullLogger;
import uk.ac.ic.wlgitbridge.git.WLGitServlet;
import uk.ac.ic.wlgitbridge.git.servlet.WLGitServlet;
import uk.ac.ic.wlgitbridge.git.exception.InvalidRootDirectoryPathException;
import uk.ac.ic.wlgitbridge.writelatex.model.WLDataModel;

View file

@ -0,0 +1,15 @@
package uk.ac.ic.wlgitbridge.bridge;
import com.google.gson.JsonElement;
import uk.ac.ic.wlgitbridge.writelatex.filestore.node.WLDirectoryNode;
/**
* Created by Winston on 16/11/14.
*/
public interface CandidateSnapshot {
public JsonElement getJsonRepresentation();
public void approveWithVersionID(int versionID);
public WLDirectoryNode getDirectoryNode();
}

View file

@ -0,0 +1,11 @@
package uk.ac.ic.wlgitbridge.bridge;
import java.util.Map;
/**
* Created by Winston on 16/11/14.
*/
public interface RawDirectoryContents {
public Map<String, byte[]> getFileContentsTable();
}

View file

@ -5,11 +5,9 @@ import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
import uk.ac.ic.wlgitbridge.writelatex.api.SnapshotDBAPI;
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.InvalidProjectException;
import java.io.File;
import java.io.IOException;
import java.util.List;
@ -20,14 +18,12 @@ public class WLBridgedProject {
private final Repository repository;
private final String name;
private final File repositoryDirectory;
private final SnapshotDBAPI snapshotDBAPI;
private final WriteLatexDataSource writeLatexDataSource;
public WLBridgedProject(Repository repository, String name, File repositoryDirectory, SnapshotDBAPI snapshotDBAPI) {
public WLBridgedProject(Repository repository, String name, WriteLatexDataSource writeLatexDataSource) {
this.repository = repository;
this.name = name;
this.repositoryDirectory = repositoryDirectory;
this.snapshotDBAPI = snapshotDBAPI;
this.writeLatexDataSource = writeLatexDataSource;
}
public void buildRepository() throws RepositoryNotFoundException, ServiceNotEnabledException, FailedConnectionException {
@ -41,7 +37,7 @@ public class WLBridgedProject {
private void updateRepositoryFromSnapshots(Repository repository) throws ServiceNotEnabledException, RepositoryNotFoundException, FailedConnectionException {
List<WritableRepositoryContents> writableRepositories;
try {
writableRepositories = snapshotDBAPI.getWritableRepositories(name);
writableRepositories = writeLatexDataSource.getWritableRepositories(name);
} catch (InvalidProjectException e) {
throw new RepositoryNotFoundException(name);
}
@ -63,13 +59,13 @@ public class WLBridgedProject {
}
private void buildRepositoryFromScratch(Repository repository) throws RepositoryNotFoundException, ServiceNotEnabledException, FailedConnectionException {
if (!snapshotDBAPI.repositoryExists(name)) {
if (!writeLatexDataSource.repositoryExists(name)) {
throw new RepositoryNotFoundException(name);
}
try {
repository.create();
} catch (IOException e) {
e.printStackTrace();
throw new ServiceNotEnabledException();
}
updateRepositoryFromSnapshots(repository);
}

View file

@ -1,18 +1,18 @@
package uk.ac.ic.wlgitbridge.writelatex.api;
package uk.ac.ic.wlgitbridge.bridge;
import uk.ac.ic.wlgitbridge.bridge.WritableRepositoryContents;
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.InvalidProjectException;
import uk.ac.ic.wlgitbridge.writelatex.model.Snapshot;
import java.util.List;
/**
* Created by Winston on 03/11/14.
*/
public interface SnapshotDBAPI {
public interface WriteLatexDataSource {
public boolean repositoryExists(String name) throws FailedConnectionException;
public List<WritableRepositoryContents> getWritableRepositories(String name) throws FailedConnectionException, InvalidProjectException;
public CandidateSnapshot createCandidateSnapshot(RawDirectoryContents rawDirectoryContents);
public void approveCandidateSnapshot(CandidateSnapshot candidateSnapshot);
}

View file

@ -5,8 +5,8 @@ import org.eclipse.jgit.transport.ReceivePack;
import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
import uk.ac.ic.wlgitbridge.git.handler.hook.CheckNonFastForwardHook;
import uk.ac.ic.wlgitbridge.writelatex.api.SnapshotDBAPI;
import uk.ac.ic.wlgitbridge.git.handler.hook.WriteLatexPutHook;
import uk.ac.ic.wlgitbridge.bridge.WriteLatexDataSource;
import javax.servlet.http.HttpServletRequest;
@ -16,14 +16,16 @@ import javax.servlet.http.HttpServletRequest;
/* */
public class WLReceivePackFactory implements ReceivePackFactory<HttpServletRequest> {
public WLReceivePackFactory(SnapshotDBAPI snapshotDBAPI) {
private final WriteLatexDataSource writeLatexDataSource;
public WLReceivePackFactory(WriteLatexDataSource writeLatexDataSource) {
this.writeLatexDataSource = writeLatexDataSource;
}
@Override
public ReceivePack create(HttpServletRequest httpServletRequest, Repository repository) throws ServiceNotEnabledException, ServiceNotAuthorizedException {
ReceivePack receivePack = new ReceivePack(repository);
receivePack.setPreReceiveHook(new CheckNonFastForwardHook());
receivePack.setPreReceiveHook(new WriteLatexPutHook(writeLatexDataSource));
return receivePack;
}

View file

@ -1,63 +0,0 @@
package uk.ac.ic.wlgitbridge.git.handler.hook;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.PreReceiveHook;
import org.eclipse.jgit.transport.ReceiveCommand;
import org.eclipse.jgit.transport.ReceivePack;
import org.eclipse.jgit.treewalk.TreeWalk;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;
/**
* Created by Winston on 03/11/14.
*/
public class CheckNonFastForwardHook implements PreReceiveHook {
@Override
public void onPreReceive(ReceivePack receivePack, Collection<ReceiveCommand> receiveCommands) {
System.out.println("There are " + receiveCommands.size() + " receive commands.");
System.out.println("All commits: ");
System.out.println(receiveCommands);
for (ReceiveCommand receiveCommand : receiveCommands) {
// receiveCommand.setResult(RefUpdate.Result.REJECTED);
try {
System.out.println("Old: " + receiveCommand.getOldId());
System.out.println("New: " + receiveCommand.getNewId());
// a RevWalk allows to walk over commits based on some filtering that is
// defined
RevWalk walk = new RevWalk(receivePack.getRepository());
RevCommit commit = walk.parseCommit(receiveCommand.getNewId());
System.out.println("Parent commit: " + commit.getParents()[0].getId());
RevTree tree = commit.getTree();
System.out.println("Having tree: " + tree);
// now use a TreeWalk to iterate over all files in the Tree recursively
// you can set Filters to narrow down the results if needed
TreeWalk treeWalk = new TreeWalk(receivePack.getRepository());
treeWalk.addTree(tree);
treeWalk.setRecursive(true);
while (treeWalk.next()) {
File file = new File("/Users/Roxy/git/testing/" + treeWalk.getPathString());
file.getParentFile().mkdirs();
FileOutputStream out = new FileOutputStream(file);
receivePack.getRepository().open(treeWalk.getObjectId(0)).copyTo(out);
}
} catch (IOException e) {
e.printStackTrace();
}
if (receiveCommand.getType() == ReceiveCommand.Type.UPDATE_NONFASTFORWARD) {
receivePack.sendError("You can't do a force push");
receiveCommand.setResult(RefUpdate.Result.REJECTED);
}
}
System.out.println("Pre receive");
}
}

View file

@ -0,0 +1,58 @@
package uk.ac.ic.wlgitbridge.git.handler.hook;
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.transport.PreReceiveHook;
import org.eclipse.jgit.transport.ReceiveCommand;
import org.eclipse.jgit.transport.ReceivePack;
import uk.ac.ic.wlgitbridge.bridge.RawDirectoryContents;
import uk.ac.ic.wlgitbridge.bridge.WriteLatexDataSource;
import uk.ac.ic.wlgitbridge.git.handler.hook.exception.ForcedPushException;
import uk.ac.ic.wlgitbridge.git.util.RepositoryObjectTreeWalker;
import java.io.IOException;
import java.util.Collection;
/**
* Created by Winston on 03/11/14.
*/
public class WriteLatexPutHook implements PreReceiveHook {
private final WriteLatexDataSource writeLatexDataSource;
public WriteLatexPutHook(WriteLatexDataSource writeLatexDataSource) {
this.writeLatexDataSource = writeLatexDataSource;
}
@Override
public void onPreReceive(ReceivePack receivePack, Collection<ReceiveCommand> receiveCommands) {
for (ReceiveCommand receiveCommand : receiveCommands) {
try {
handleReceiveCommand(receivePack, receiveCommand);
} catch (ForcedPushException e) {
receivePack.sendError("You can't do a force push");
receiveCommand.setResult(Result.REJECTED);
} catch (IOException e) {
receivePack.sendError("IOException");
receiveCommand.setResult(Result.REJECTED);
}
}
}
private void handleReceiveCommand(ReceivePack receivePack, ReceiveCommand receiveCommand) throws ForcedPushException, IOException {
checkForcedPush(receiveCommand);
RawDirectoryContents directoryContents = getPushedDirectoryContents(receivePack, receiveCommand);
}
private void checkForcedPush(ReceiveCommand receiveCommand) throws ForcedPushException {
if (receiveCommand.getType() == ReceiveCommand.Type.UPDATE_NONFASTFORWARD) {
throw new ForcedPushException();
}
}
private RawDirectoryContents getPushedDirectoryContents(ReceivePack receivePack, ReceiveCommand receiveCommand) throws IOException {
return new RepositoryObjectTreeWalker(receivePack.getRepository(),
receiveCommand.getNewId())
.getDirectoryContents();
}
}

View file

@ -0,0 +1,7 @@
package uk.ac.ic.wlgitbridge.git.handler.hook.exception;
/**
* Created by Winston on 16/11/14.
*/
public class ForcedPushException extends Exception {
}

View file

@ -1,4 +1,4 @@
package uk.ac.ic.wlgitbridge.git;
package uk.ac.ic.wlgitbridge.git.servlet;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jgit.http.server.GitServlet;
@ -7,7 +7,7 @@ import uk.ac.ic.wlgitbridge.git.handler.WLReceivePackFactory;
import uk.ac.ic.wlgitbridge.git.handler.WLRepositoryResolver;
import uk.ac.ic.wlgitbridge.git.handler.WLUploadPackFactory;
import uk.ac.ic.wlgitbridge.writelatex.SnapshotRepositoryBuilder;
import uk.ac.ic.wlgitbridge.writelatex.api.SnapshotDBAPI;
import uk.ac.ic.wlgitbridge.bridge.WriteLatexDataSource;
import javax.servlet.ServletException;
@ -16,9 +16,9 @@ import javax.servlet.ServletException;
*/
public class WLGitServlet extends GitServlet {
public WLGitServlet(ServletContextHandler servletContextHandler, SnapshotDBAPI snapshotDBAPI, String rootGitDirectoryPath) throws ServletException, InvalidRootDirectoryPathException {
setRepositoryResolver(new WLRepositoryResolver(rootGitDirectoryPath, new SnapshotRepositoryBuilder(snapshotDBAPI)));
setReceivePackFactory(new WLReceivePackFactory(snapshotDBAPI));
public WLGitServlet(ServletContextHandler servletContextHandler, WriteLatexDataSource writeLatexDataSource, String rootGitDirectoryPath) throws ServletException, InvalidRootDirectoryPathException {
setRepositoryResolver(new WLRepositoryResolver(rootGitDirectoryPath, new SnapshotRepositoryBuilder(writeLatexDataSource)));
setReceivePackFactory(new WLReceivePackFactory(writeLatexDataSource));
setUploadPackFactory(new WLUploadPackFactory());
init(new WLGitServletConfig(servletContextHandler));
}

View file

@ -1,4 +1,4 @@
package uk.ac.ic.wlgitbridge.git;
package uk.ac.ic.wlgitbridge.git.servlet;
import org.eclipse.jetty.servlet.ServletContextHandler;

View file

@ -0,0 +1,23 @@
package uk.ac.ic.wlgitbridge.git.util;
import uk.ac.ic.wlgitbridge.bridge.RawDirectoryContents;
import java.util.Map;
/**
* Created by Winston on 16/11/14.
*/
public class FileDirectoryContents implements RawDirectoryContents {
private final Map<String, byte[]> fileContentsTable;
public FileDirectoryContents(Map<String, byte[]> fileContentsTable) {
this.fileContentsTable = fileContentsTable;
}
@Override
public Map<String, byte[]> getFileContentsTable() {
return fileContentsTable;
}
}

View file

@ -0,0 +1,46 @@
package uk.ac.ic.wlgitbridge.git.util;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import uk.ac.ic.wlgitbridge.bridge.RawDirectoryContents;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Winston on 16/11/14.
*/
public class RepositoryObjectTreeWalker {
private final TreeWalk treeWalk;
private final Repository repository;
public RepositoryObjectTreeWalker(Repository repository, ObjectId objectId) throws IOException {
treeWalk = initTreeWalk(repository, objectId);
this.repository = repository;
}
public RawDirectoryContents getDirectoryContents() throws IOException {
return new FileDirectoryContents(walkGitObjectTree());
}
private TreeWalk initTreeWalk(Repository repository, ObjectId objectId) throws IOException {
RevWalk walk = new RevWalk(repository);
TreeWalk treeWalk = new TreeWalk(repository);
treeWalk.addTree(walk.parseCommit(objectId).getTree());
treeWalk.setRecursive(true);
return treeWalk;
}
private Map<String, byte[]> walkGitObjectTree() throws IOException {
Map<String, byte[]> fileContentsTable = new HashMap<String, byte[]>();
while (treeWalk.next()) {
fileContentsTable.put(treeWalk.getPathString(), repository.open(treeWalk.getObjectId(0)).getBytes());
}
return fileContentsTable;
}
}

View file

@ -6,7 +6,7 @@ import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
import uk.ac.ic.wlgitbridge.bridge.RepositorySource;
import uk.ac.ic.wlgitbridge.bridge.WLBridgedProject;
import uk.ac.ic.wlgitbridge.writelatex.api.SnapshotDBAPI;
import uk.ac.ic.wlgitbridge.bridge.WriteLatexDataSource;
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
import java.io.File;
@ -17,20 +17,20 @@ import java.io.IOException;
*/
public class SnapshotRepositoryBuilder implements RepositorySource {
private final SnapshotDBAPI snapshotDBAPI;
private final WriteLatexDataSource writeLatexDataSource;
public SnapshotRepositoryBuilder(SnapshotDBAPI snapshotDBAPI) {
this.snapshotDBAPI = snapshotDBAPI;
public SnapshotRepositoryBuilder(WriteLatexDataSource writeLatexDataSource) {
this.writeLatexDataSource = writeLatexDataSource;
}
@Override
public Repository getRepositoryWithNameAtRootDirectory(String name, File rootDirectory) throws RepositoryNotFoundException, ServiceNotEnabledException {
File repositoryDirectory = new File(rootDirectory.getAbsolutePath(), name);
File repositoryDirectory = new File(rootDirectory, name);
Repository repository = null;
try {
repository = new FileRepositoryBuilder().setWorkTree(repositoryDirectory).build();
new WLBridgedProject(repository, name, repositoryDirectory, snapshotDBAPI).buildRepository();
new WLBridgedProject(repository, name, writeLatexDataSource).buildRepository();
} catch (FailedConnectionException e) {
throw new ServiceNotEnabledException();
} catch (IOException e) {

View file

@ -1,7 +1,9 @@
package uk.ac.ic.wlgitbridge.writelatex.model;
import uk.ac.ic.wlgitbridge.bridge.CandidateSnapshot;
import uk.ac.ic.wlgitbridge.bridge.RawDirectoryContents;
import uk.ac.ic.wlgitbridge.bridge.WritableRepositoryContents;
import uk.ac.ic.wlgitbridge.writelatex.api.SnapshotDBAPI;
import uk.ac.ic.wlgitbridge.bridge.WriteLatexDataSource;
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.SnapshotGetDocRequest;
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.InvalidProjectException;
@ -14,7 +16,7 @@ import java.util.Map;
/**
* Created by Winston on 06/11/14.
*/
public class WLDataModel implements SnapshotDBAPI {
public class WLDataModel implements WriteLatexDataSource {
private final Map<String, WLProject> projects;
private final WLFileStore fileStore;
@ -41,6 +43,16 @@ public class WLDataModel implements SnapshotDBAPI {
return updateProjectWithName(name);
}
@Override
public CandidateSnapshot createCandidateSnapshot(RawDirectoryContents rawDirectoryContents) {
return null;
}
@Override
public void approveCandidateSnapshot(CandidateSnapshot candidateSnapshot) {
}
private List<WritableRepositoryContents> updateProjectWithName(String name) throws FailedConnectionException, InvalidProjectException {
return fileStore.updateForProject(getProjectWithName(name));
}