Winston Li 11 лет назад
Родитель
Сommit
ec13e184b7
37 измененных файлов с 557 добавлено и 921 удалено
  1. 2 2
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/application/WLGitBridgeServer.java
  2. 17 3
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/RawFile.java
  3. 8 7
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/WLBridgedProject.java
  4. 2 1
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/WriteLatexDataSource.java
  5. 8 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/git/util/RepositoryObjectTreeWalker.java
  6. 34 121
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/SnapshotFetcher.java
  7. 55 61
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/WLDirectoryNodeSnapshot.java
  8. 6 5
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/WriteLatexAPI.java
  9. 22 18
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getforversion/SnapshotAttachment.java
  10. 20 24
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getforversion/SnapshotFile.java
  11. 14 1
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getsavedvers/SnapshotInfo.java
  12. 6 7
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/GitDirectoryContents.java
  13. 12 5
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/RepositoryFile.java
  14. 0 15
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/blob/AttachmentBlob.java
  15. 0 29
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/blob/Blob.java
  16. 0 27
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/blob/ByteBlob.java
  17. 0 63
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/blob/ExternalBlob.java
  18. 0 14
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/blob/RawFileBlob.java
  19. 0 79
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/node/AttachmentNode.java
  20. 17 26
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/node/BlobNode.java
  21. 11 12
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/node/FileNode.java
  22. 0 11
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/node/FileNodeIndexer.java
  23. 41 58
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/node/WLDirectoryNode.java
  24. 0 83
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/store/FileIndexStore.java
  25. 30 40
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/store/WLFileStore.java
  26. 80 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/DataStore.java
  27. 68 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/ResourceFetcher.java
  28. 11 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/URLIndexStore.java
  29. 0 70
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/WLDataModel.java
  30. 0 74
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/WLProject.java
  31. 0 52
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/WLProjectStore.java
  32. 18 6
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/db/PersistentStore.java
  33. 10 2
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/SQLiteWLDatabase.java
  34. 1 1
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/query/GetLatestVersionForProjectSQLQuery.java
  35. 38 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/query/GetProjectNamesSQLQuery.java
  36. 25 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/create/CreateIndexURLIndexStore.java
  37. 1 4
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/create/CreateURLIndexStoreSQLUpdate.java

+ 2 - 2
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/application/WLGitBridgeServer.java

@@ -14,7 +14,7 @@ import uk.ac.ic.wlgitbridge.git.servlet.WLGitServlet;
 import uk.ac.ic.wlgitbridge.util.Util;
 import uk.ac.ic.wlgitbridge.writelatex.WriteLatexAPI;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.base.SnapshotAPIRequest;
-import uk.ac.ic.wlgitbridge.writelatex.model.WLDataModel;
+import uk.ac.ic.wlgitbridge.writelatex.model.DataStore;
 
 import javax.servlet.ServletException;
 import java.io.File;
@@ -87,7 +87,7 @@ public class WLGitBridgeServer {
 
     private void configureJettyServer() throws ServletException, InvalidRootDirectoryPathException {
         HandlerCollection handlers = new HandlerCollection();
-        WriteLatexAPI writeLatexDataSource = new WriteLatexAPI(new WLDataModel(rootGitDirectoryPath));
+        WriteLatexAPI writeLatexDataSource = new WriteLatexAPI(new DataStore(rootGitDirectoryPath));
         handlers.setHandlers(new Handler[] {
                 initResourceHandler(writeLatexDataSource),
                 new SnapshotPushPostbackHandler(writeLatexDataSource),

+ 17 - 3
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/RawFile.java

@@ -1,11 +1,25 @@
 package uk.ac.ic.wlgitbridge.bridge;
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
 /**
  * Created by Winston on 16/11/14.
  */
-public interface RawFile {
+public abstract class RawFile {
+
+    public abstract String getPath();
+    public abstract byte[] getContents();
 
-    public String getPath();
-    public byte[] getContents();
+    public final void writeToDisk(File directory) throws IOException {
+        File file = new File(directory, getPath());
+        file.getParentFile().mkdirs();
+        file.createNewFile();
+        OutputStream out = new FileOutputStream(file);
+        out.write(getContents());
+        out.close();
+    }
 
 }

+ 8 - 7
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/WLBridgedProject.java

@@ -7,6 +7,7 @@ import org.eclipse.jgit.lib.PersonIdent;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.transport.ServiceMayNotContinueException;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.InvalidProjectException;
+import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.SnapshotPostException;
 import uk.ac.ic.wlgitbridge.writelatex.filestore.store.WLFileStore;
 
 import java.io.IOException;
@@ -47,11 +48,7 @@ public class WLBridgedProject {
     private void updateRepositoryFromSnapshots(Repository repository) throws RepositoryNotFoundException, ServiceMayNotContinueException {
         List<WritableRepositoryContents> writableRepositories;
         try {
-            writableRepositories = writeLatexDataSource.getWritableRepositories(name);
-        } catch (InvalidProjectException e) {
-            throw new RepositoryNotFoundException(name);
-        }
-        try {
+            writableRepositories = writeLatexDataSource.getWritableRepositories(name, repository);
             for (WritableRepositoryContents contents : writableRepositories) {
                 contents.write();
                 Git git = new Git(repository);
@@ -60,10 +57,14 @@ public class WLBridgedProject {
                 }
                 git.add().addFilepattern(".").call();
                 git.commit().setAuthor(new PersonIdent(contents.getUserName(), contents.getUserEmail(), contents.getWhen(), TimeZone.getDefault()))
-                            .setMessage(contents.getCommitMessage())
-                            .call();
+                        .setMessage(contents.getCommitMessage())
+                        .call();
                 WLFileStore.deleteInDirectoryApartFrom(contents.getDirectory(), ".git");
             }
+        } catch (InvalidProjectException e) {
+            throw new RepositoryNotFoundException(name);
+        } catch (SnapshotPostException e) {
+            throw new RepositoryNotFoundException(name);
         } catch (GitAPIException e) {
             throw new ServiceMayNotContinueException(e);
         } catch (IOException e) {

+ 2 - 1
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/WriteLatexDataSource.java

@@ -1,5 +1,6 @@
 package uk.ac.ic.wlgitbridge.bridge;
 
+import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.transport.ServiceMayNotContinueException;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.InvalidProjectException;
@@ -21,7 +22,7 @@ public interface WriteLatexDataSource {
 
     /* Called by request thread. */
     public boolean repositoryExists(String projectName) throws ServiceMayNotContinueException;
-    public List<WritableRepositoryContents> getWritableRepositories(String projectName) throws FailedConnectionException, InvalidProjectException;
+    public List<WritableRepositoryContents> getWritableRepositories(String projectName, Repository repository) throws IOException, SnapshotPostException;
     public void putDirectoryContentsToProjectWithName(String projectName, RawDirectoryContents directoryContents, String hostname) throws SnapshotPostException, IOException, FailedConnectionException;
 
     void checkPostbackKey(String projectName, String postbackKey) throws InvalidPostbackKeyException;

+ 8 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/git/util/RepositoryObjectTreeWalker.java

@@ -23,6 +23,14 @@ public class RepositoryObjectTreeWalker {
         this.repository = repository;
     }
 
+    public RepositoryObjectTreeWalker(Repository repository) throws IOException {
+        this(repository, 0);
+    }
+
+    public RepositoryObjectTreeWalker(Repository repository, int fromHead) throws IOException {
+        this(repository, repository.resolve("HEAD~" + fromHead));
+    }
+
     public RawDirectoryContents getDirectoryContents() throws IOException {
         return new FileDirectoryContents(walkGitObjectTree());
     }

+ 34 - 121
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/SnapshotFetcher.java

@@ -1,163 +1,76 @@
 package uk.ac.ic.wlgitbridge.writelatex;
 
-import uk.ac.ic.wlgitbridge.util.Util;
 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.SnapshotGetDocResult;
-import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.InvalidProjectException;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotData;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotGetForVersionRequest;
-import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotGetForVersionResult;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.getsavedvers.SnapshotGetSavedVersRequest;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.getsavedvers.SnapshotInfo;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.SnapshotPostException;
 import uk.ac.ic.wlgitbridge.writelatex.model.Snapshot;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreSource;
 
 import java.util.*;
 
 /**
  * Created by Winston on 07/11/14.
  */
-public class SnapshotFetcher implements PersistentStoreSource {
+public class SnapshotFetcher {
 
-    private PersistentStoreAPI persistentStore;
-
-    private final String projectName;
-    private final Map<Integer, Snapshot> snapshots;
-    private final SortedSet<Integer> versions;
-
-    public SnapshotFetcher(String projectName, Map<Integer, Snapshot> snapshots) {
-        this.projectName = projectName;
-        this.snapshots = snapshots;
-        versions = new TreeSet<Integer>();
-    }
-
-    public SortedSet<Snapshot> fetchNewSnapshots() throws FailedConnectionException, InvalidProjectException {
-        SortedSet<Snapshot> newSnapshots = new TreeSet<Snapshot>();
-        while (getNew(newSnapshots));
-        for (Snapshot snapshot : newSnapshots) {
-//            persistentStore.addSnapshot(projectName, snapshot.getVersionID());
-        }
-        Util.sout("Fetched snapshots: " + newSnapshots);
-        return newSnapshots;
-    }
-
-    public Snapshot getLatestSnapshot() {
-        if (versions.isEmpty()) {
-            return null;
-        }
-        return snapshots.get(versions.last());
-    }
-
-    public void putLatestVersion(int versionID) {
-        versions.add(versionID);
-    }
-
-    @Override
-    public void initFromPersistentStore(PersistentStoreAPI persistentStore) {
-        this.persistentStore = persistentStore;
-//        for (Integer savedVersionID : persistentStore.getVersionIDsForProjectName(projectName)) {
-//            snapshots.put(savedVersionID, new Snapshot(savedVersionID));
-//            versions.add(savedVersionID);
-//        }
+    public List<Snapshot> getSnapshotsForProjectAfterVersion(String projectName, int version) throws FailedConnectionException, SnapshotPostException {
+        List<SnapshotInfo> snapshotInfos = getSnapshotInfosAfterVersion(projectName, version);
+        List<SnapshotData> snapshotDatas = getMatchingSnapshotData(projectName, snapshotInfos);
+        List<Snapshot> snapshots = combine(snapshotInfos, snapshotDatas);
+        return snapshots;
     }
 
-    private boolean getNew(SortedSet<Snapshot> newSnapshots) throws FailedConnectionException, InvalidProjectException {
+    private List<SnapshotInfo> getSnapshotInfosAfterVersion(String projectName, int version) throws FailedConnectionException, SnapshotPostException {
+        SortedSet<SnapshotInfo> versions = new TreeSet<SnapshotInfo>();
         SnapshotGetDocRequest getDoc = new SnapshotGetDocRequest(projectName);
         SnapshotGetSavedVersRequest getSavedVers = new SnapshotGetSavedVersRequest(projectName);
-
         getDoc.request();
         getSavedVers.request();
-
-        Set<Integer> fetchedIDs = new HashSet<Integer>();
-        Map<Integer, SnapshotInfo> fetchedSnapshotInfos = new HashMap<Integer, SnapshotInfo>();
-
-        int latestVersionID = putLatestDoc(getDoc, fetchedIDs, fetchedSnapshotInfos);
-
-        putSavedVers(getSavedVers, fetchedIDs, fetchedSnapshotInfos);
-
-        List<Integer> idsToUpdate = getIDsToUpdate(fetchedIDs);
-
-        versions.addAll(fetchedIDs);
-        versions.add(latestVersionID);
-
-        return updateIDs(idsToUpdate, fetchedSnapshotInfos, newSnapshots);
-    }
-
-    private void putFetchedResult(SnapshotInfo snapshotInfo, Set<Integer> ids, Map<Integer, SnapshotInfo> snapshotInfos) {
-        int versionID = snapshotInfo.getVersionId();
-        snapshotInfos.put(versionID, snapshotInfo);
-        ids.add(versionID);
-    }
-
-    private int putLatestDoc(SnapshotGetDocRequest getDoc, Set<Integer> fetchedIDs, Map<Integer, SnapshotInfo> fetchedSnapshotInfos) throws FailedConnectionException, InvalidProjectException {
-        SnapshotGetDocResult result = getDoc.getResult();
-        int latestVersionID = 0;
-        try {
-            latestVersionID = result.getVersionID();
-        } catch (SnapshotPostException e) {
-            throw new RuntimeException(e);
-        }
-        putFetchedResult(new SnapshotInfo(latestVersionID, result.getCreatedAt(), result.getName(), result.getEmail()), fetchedIDs, fetchedSnapshotInfos);
-        return latestVersionID;
-    }
-
-    private void putSavedVers(SnapshotGetSavedVersRequest getSavedVers, Set<Integer> fetchedIDs, Map<Integer, SnapshotInfo> fetchedSnapshotInfos) throws FailedConnectionException {
-        for (SnapshotInfo snapshotInfo : getSavedVers.getResult().getSavedVers()) {
-            putFetchedResult(snapshotInfo, fetchedIDs, fetchedSnapshotInfos);
-        }
-    }
-
-    private List<Integer> getIDsToUpdate(Set<Integer> fetchedIDs) {
-        List<Integer> idsToUpdate = new LinkedList<Integer>();
-        for (Integer id : fetchedIDs) {
-            if (!versions.contains(id)) {
-                idsToUpdate.add(id);
+        SnapshotGetDocResult latestDoc = getDoc.getResult();
+        int latest = latestDoc.getVersionID();
+        if (latest > version) {
+            for (SnapshotInfo snapshotInfo : getSavedVers.getResult().getSavedVers()) {
+                if (snapshotInfo.getVersionId() > version) {
+                    versions.add(snapshotInfo);
+                }
             }
-        }
-        return idsToUpdate;
-    }
+            versions.add(new SnapshotInfo(latest, latestDoc.getCreatedAt(), latestDoc.getName(), latestDoc.getEmail()));
 
-    private boolean updateIDs(List<Integer> idsToUpdate, Map<Integer, SnapshotInfo> fetchedSnapshotInfos, SortedSet<Snapshot> newSnapshots) throws FailedConnectionException {
-        if (idsToUpdate.isEmpty()) {
-            return false;
         }
-        fetchVersions(idsToUpdate, fetchedSnapshotInfos, newSnapshots);
-        return true;
+        return new LinkedList<SnapshotInfo>(versions);
     }
 
-    private void fetchVersions(List<Integer> idsToUpdate, Map<Integer, SnapshotInfo> fetchedSnapshotInfos, SortedSet<Snapshot> newSnapshots) throws FailedConnectionException {
-        List<SnapshotGetForVersionRequest> requests = createFiredRequests(idsToUpdate);
-        processResults(fetchedSnapshotInfos, newSnapshots, requests);
+    private List<SnapshotData> getMatchingSnapshotData(String projectName, List<SnapshotInfo> snapshotInfos) throws FailedConnectionException {
+        List<SnapshotGetForVersionRequest> firedRequests = fireDataRequests(projectName, snapshotInfos);
+        List<SnapshotData> snapshotDataList = new LinkedList<SnapshotData>();
+        for (SnapshotGetForVersionRequest fired : firedRequests) {
+            snapshotDataList.add(fired.getResult().getSnapshotData());
+        }
+        return snapshotDataList;
     }
 
-    private List<SnapshotGetForVersionRequest> createFiredRequests(List<Integer> idsToUpdate) {
+    private List<SnapshotGetForVersionRequest> fireDataRequests(String projectName, List<SnapshotInfo> snapshotInfos) {
         List<SnapshotGetForVersionRequest> requests = new LinkedList<SnapshotGetForVersionRequest>();
-        for (int id : idsToUpdate) {
-            SnapshotGetForVersionRequest request = new SnapshotGetForVersionRequest(projectName, id);
+        for (SnapshotInfo snapshotInfo : snapshotInfos) {
+            SnapshotGetForVersionRequest request = new SnapshotGetForVersionRequest(projectName, snapshotInfo.getVersionId());
             requests.add(request);
             request.request();
         }
         return requests;
     }
 
-    private void processResults(Map<Integer, SnapshotInfo> fetchedSnapshotInfos, SortedSet<Snapshot> newSnapshots, List<SnapshotGetForVersionRequest> requests) throws FailedConnectionException {
-        for (SnapshotGetForVersionRequest request : requests) {
-            processResult(fetchedSnapshotInfos, newSnapshots, request);
+    private List<Snapshot> combine(List<SnapshotInfo> snapshotInfos, List<SnapshotData> snapshotDatas) {
+        List<Snapshot> snapshots = new LinkedList<Snapshot>();
+        Iterator<SnapshotInfo> infos = snapshotInfos.iterator();
+        Iterator<SnapshotData> datas = snapshotDatas.iterator();
+        while (infos.hasNext()) {
+            snapshots.add(new Snapshot(infos.next(), datas.next()));
         }
+        return snapshots;
     }
 
-    private void processResult(Map<Integer, SnapshotInfo> fetchedSnapshotInfos, SortedSet<Snapshot> newSnapshots, SnapshotGetForVersionRequest request) throws FailedConnectionException {
-        SnapshotGetForVersionResult result = request.getResult();
-        SnapshotData data = result.getSnapshotData();
-        Snapshot snapshot = new Snapshot(fetchedSnapshotInfos.get(request.getVersionID()), data);
-        snapshots.put(request.getVersionID(), snapshot);
-        newSnapshots.add(snapshot);
-    }
-
-    public SortedSet<Integer> getVersions() {
-        return versions;
-    }
 }

+ 55 - 61
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/WLDirectoryNodeSnapshot.java

@@ -3,84 +3,78 @@ package uk.ac.ic.wlgitbridge.writelatex;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
-import uk.ac.ic.wlgitbridge.bridge.CandidateSnapshot;
-import uk.ac.ic.wlgitbridge.bridge.CandidateSnapshotCallback;
-import uk.ac.ic.wlgitbridge.util.Util;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.node.FileNode;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.node.WLDirectoryNode;
-import uk.ac.ic.wlgitbridge.writelatex.model.WLProject;
 
 /**
  * Created by Winston on 16/11/14.
  */
-public class WLDirectoryNodeSnapshot implements CandidateSnapshot {
+public class WLDirectoryNodeSnapshot /*implements CandidateSnapshot*/ {
 
-    private final int previousVersionID;
-    private final String projectName;
-    private final String projectURL;
-    private final WLDirectoryNode directoryNode;
-    private final String postbackKey;
-    private final CandidateSnapshotCallback callback;
+//    private final int previousVersionID;
+//    private final String projectName;
+//    private final String projectURL;
+//    private final WLDirectoryNode directoryNode;
+//    private final String postbackKey;
+//    private final CandidateSnapshotCallback callback;
 
-    public WLDirectoryNodeSnapshot(WLProject project, WLDirectoryNode directoryNode, String hostname, String postbackKey, CandidateSnapshotCallback callback) {
-        previousVersionID = project.getLatestSnapshotID();
-        projectName = project.getName();
-        projectURL = Util.getPostbackURL() + projectName;
+//    public WLDirectoryNodeSnapshot(WLProject project, WLDirectoryNode directoryNode, String hostname, String postbackKey, CandidateSnapshotCallback callback) {
+//        previousVersionID = project.getLatestSnapshotID();
+//        projectName = project.getName();
+//        projectURL = Util.getPostbackURL() + projectName;
+//
+//        this.directoryNode = directoryNode;
+//        this.postbackKey = postbackKey;
+//        this.callback = callback;
+//    }
 
-        this.directoryNode = directoryNode;
-        this.postbackKey = postbackKey;
-        this.callback = callback;
-    }
-
-    @Override
+//    @Override
     public JsonElement getJsonRepresentation() {
         JsonObject jsonObject = new JsonObject();
-        jsonObject.addProperty("latestVerId", previousVersionID);
-        jsonObject.add("files", getFilesAsJson());
-        jsonObject.addProperty("postbackUrl", projectURL + "/" + postbackKey + "/postback");
+//        jsonObject.addProperty("latestVerId", previousVersionID);
+//        jsonObject.add("files", getFilesAsJson());
+//        jsonObject.addProperty("postbackUrl", projectURL + "/" + postbackKey + "/postback");
         return jsonObject;
     }
 
     private JsonArray getFilesAsJson() {
         JsonArray filesArray = new JsonArray();
-        for (FileNode fileNode : directoryNode.getFileNodes()) {
-            filesArray.add(getFileAsJson(fileNode));
-        }
+//        for (FileNode fileNode : directoryNode.getFileNodes()) {
+//            filesArray.add(getFileAsJson(fileNode));
+//        }
         return filesArray;
     }
 
-    private JsonObject getFileAsJson(FileNode fileNode) {
-        JsonObject file = new JsonObject();
-        file.addProperty("name", fileNode.getFilePath());
-        if (fileNode.isChanged()) {
-            file.addProperty("url", projectURL + "/" + fileNode.getFilePath() + "?key=" + postbackKey);
-        }
-        return file;
-    }
-
-    @Override
-    public int getPreviousVersionID() {
-        return previousVersionID;
-    }
-
-    @Override
-    public String getProjectURL() {
-        return projectURL;
-    }
-
-    @Override
-    public void approveWithVersionID(int versionID) {
-        callback.approveSnapshot(versionID, this);
-    }
+//    private JsonObject getFileAsJson(FileNode fileNode) {
+//        JsonObject file = new JsonObject();
+//        file.addProperty("name", fileNode.getFilePath());
+//        if (fileNode.isChanged()) {
+//            file.addProperty("url", projectURL + "/" + fileNode.getFilePath() + "?key=" + postbackKey);
+//        }
+//        return file;
+//    }
 
-    @Override
-    public String getProjectName() {
-        return projectName;
-    }
-
-    @Override
-    public WLDirectoryNode getDirectoryNode() {
-        return directoryNode;
-    }
+//    @Override
+//    public int getPreviousVersionID() {
+//        return previousVersionID;
+//    }
+//
+//    @Override
+//    public String getProjectURL() {
+//        return projectURL;
+//    }
+//
+//    @Override
+//    public void approveWithVersionID(int versionID) {
+//        callback.approveSnapshot(versionID, this);
+//    }
+//
+//    @Override
+//    public String getProjectName() {
+//        return projectName;
+//    }
+//
+//    @Override
+//    public WLDirectoryNode getDirectoryNode() {
+//        return directoryNode;
+//    }
 
 }

+ 6 - 5
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/WriteLatexAPI.java

@@ -1,5 +1,6 @@
 package uk.ac.ic.wlgitbridge.writelatex;
 
+import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.transport.ServiceMayNotContinueException;
 import uk.ac.ic.wlgitbridge.bridge.CandidateSnapshot;
 import uk.ac.ic.wlgitbridge.bridge.RawDirectoryContents;
@@ -13,7 +14,7 @@ import uk.ac.ic.wlgitbridge.writelatex.api.request.push.PostbackManager;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.push.SnapshotPushRequest;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.push.SnapshotPushRequestResult;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.*;
-import uk.ac.ic.wlgitbridge.writelatex.model.WLDataModel;
+import uk.ac.ic.wlgitbridge.writelatex.model.DataStore;
 
 import java.io.IOException;
 import java.util.List;
@@ -23,11 +24,11 @@ import java.util.List;
  */
 public class WriteLatexAPI implements WriteLatexDataSource {
 
-    private final WLDataModel dataModel;
+    private final DataStore dataModel;
     private final PostbackManager postbackManager;
     private final ProjectLock mainProjectLock;
 
-    public WriteLatexAPI(WLDataModel dataModel) {
+    public WriteLatexAPI(DataStore dataModel) {
         this.dataModel = dataModel;
         postbackManager = new PostbackManager();
         mainProjectLock = new ProjectLock();
@@ -64,9 +65,9 @@ public class WriteLatexAPI implements WriteLatexDataSource {
     }
 
     @Override
-    public List<WritableRepositoryContents> getWritableRepositories(String projectName) throws FailedConnectionException, InvalidProjectException {
+    public List<WritableRepositoryContents> getWritableRepositories(String projectName, Repository repository) throws IOException, SnapshotPostException {
         Util.sout("Fetching project: " + projectName);
-        List<WritableRepositoryContents> writableRepositoryContents = dataModel.updateProjectWithName(projectName);
+        List<WritableRepositoryContents> writableRepositoryContents = dataModel.updateProjectWithName(projectName, repository);
         return writableRepositoryContents;
     }
 

+ 22 - 18
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getforversion/SnapshotAttachment.java

@@ -3,24 +3,42 @@ package uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonPrimitive;
+import uk.ac.ic.wlgitbridge.writelatex.api.request.base.JSONSource;
 
 /**
  * Created by Winston on 06/11/14.
  */
-public class SnapshotAttachment extends SnapshotFile {
+public class SnapshotAttachment implements JSONSource {
 
     private String url;
+    private String path;
 
     public SnapshotAttachment(JsonElement json) {
-        super(json);
+        fromJSON(json);
     }
 
+    @Override
+    public void fromJSON(JsonElement json) {
+        JsonArray jsonArray = json.getAsJsonArray();
+        url = jsonArray.get(0).getAsString();
+        path = jsonArray.get(1).getAsString();
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    /* For the Mock Snapshot server */
+
     public SnapshotAttachment(String url, String path) {
-        super(null, path);
         this.url = url;
+        this.path = path;
     }
 
-    @Override
     public JsonElement toJson() {
         JsonArray jsonThis = new JsonArray();
         jsonThis.add(new JsonPrimitive(url));
@@ -28,18 +46,4 @@ public class SnapshotAttachment extends SnapshotFile {
         return jsonThis;
     }
 
-    @Override
-    public byte[] getContents() {
-        return null;
-    }
-
-    @Override
-    protected void getContentsFromJSON(JsonArray jsonArray) {
-        url = jsonArray.get(0).getAsString();
-    }
-
-    public String getUrl() {
-        return url;
-    }
-
 }

+ 20 - 24
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getforversion/SnapshotFile.java

@@ -9,27 +9,20 @@ import uk.ac.ic.wlgitbridge.writelatex.api.request.base.JSONSource;
 /**
  * Created by Winston on 06/11/14.
  */
-public class SnapshotFile implements JSONSource, RawFile {
+public class SnapshotFile extends RawFile implements JSONSource {
 
-    protected byte[] contents;
     private String path;
+    private byte[] contents;
 
     public SnapshotFile(JsonElement json) {
         fromJSON(json);
     }
 
-    public SnapshotFile(String contents, String path) {
-        this.path = path;
-        if (contents != null) {
-            this.contents = contents.getBytes();
-        }
-    }
-
-    public JsonElement toJson() {
-        JsonArray jsonThis = new JsonArray();
-        jsonThis.add(new JsonPrimitive(new String(contents)));
-        jsonThis.add(new JsonPrimitive(path));
-        return jsonThis;
+    @Override
+    public void fromJSON(JsonElement json) {
+        JsonArray jsonArray = json.getAsJsonArray();
+        contents = jsonArray.get(0).getAsString().getBytes();
+        path = jsonArray.get(1).getAsString();
     }
 
     @Override
@@ -42,19 +35,22 @@ public class SnapshotFile implements JSONSource, RawFile {
         return contents;
     }
 
-    @Override
-    public void fromJSON(JsonElement json) {
-        JsonArray jsonArray = json.getAsJsonArray();
-        getContentsFromJSON(jsonArray);
-        getPathFromJSON(jsonArray);
-    }
+    /* Mock server */
 
-    protected void getContentsFromJSON(JsonArray jsonArray) {
-        contents = jsonArray.get(0).getAsString().getBytes();
+    public SnapshotFile(String contents, String path) {
+        this.path = path;
+        if (contents != null) {
+            this.contents = contents.getBytes();
+        } else {
+            this.contents = new byte[0];
+        }
     }
 
-    protected void getPathFromJSON(JsonArray jsonArray) {
-        path = jsonArray.get(1).getAsString();
+    public JsonElement toJson() {
+        JsonArray jsonThis = new JsonArray();
+        jsonThis.add(new JsonPrimitive(new String(contents)));
+        jsonThis.add(new JsonPrimitive(path));
+        return jsonThis;
     }
 
 }

+ 14 - 1
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getsavedvers/SnapshotInfo.java

@@ -5,7 +5,7 @@ import uk.ac.ic.wlgitbridge.util.Util;
 /**
  * Created by Winston on 06/11/14.
  */
-public class SnapshotInfo {
+public class SnapshotInfo implements Comparable<SnapshotInfo> {
 
     private int versionId;
     private String comment;
@@ -39,4 +39,17 @@ public class SnapshotInfo {
         return createdAt;
     }
 
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof SnapshotInfo)) {
+            return false;
+        }
+        SnapshotInfo that = (SnapshotInfo) obj;
+        return versionId == that.versionId;
+    }
+
+    @Override
+    public int compareTo(SnapshotInfo o) {
+        return Integer.compare(versionId, o.versionId);
+    }
 }

+ 6 - 7
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/GitDirectoryContents.java

@@ -1,8 +1,7 @@
 package uk.ac.ic.wlgitbridge.writelatex.filestore;
 
+import uk.ac.ic.wlgitbridge.bridge.RawFile;
 import uk.ac.ic.wlgitbridge.bridge.WritableRepositoryContents;
-import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.node.FileNode;
 import uk.ac.ic.wlgitbridge.writelatex.filestore.store.WLFileStore;
 import uk.ac.ic.wlgitbridge.writelatex.model.Snapshot;
 
@@ -16,15 +15,15 @@ import java.util.List;
  */
 public class GitDirectoryContents implements WritableRepositoryContents {
 
-    private final List<FileNode> fileNodes;
+    private final List<RawFile> files;
     private final File gitDirectory;
     private final String userName;
     private final String userEmail;
     private final String commitMessage;
     private final Date when;
 
-    public GitDirectoryContents(List<FileNode> fileNodes, File rootGitDirectory, String projectName, Snapshot snapshot) {
-        this.fileNodes = fileNodes;
+    public GitDirectoryContents(List<RawFile> files, File rootGitDirectory, String projectName, Snapshot snapshot) {
+        this.files = files;
         gitDirectory = new File(rootGitDirectory, projectName);
         userName = snapshot.getUserName();
         userEmail = snapshot.getUserEmail();
@@ -33,9 +32,9 @@ public class GitDirectoryContents implements WritableRepositoryContents {
     }
 
     @Override
-    public void write() throws IOException, FailedConnectionException {
+    public void write() throws IOException {
         WLFileStore.deleteInDirectoryApartFrom(gitDirectory, ".git");
-        for (FileNode fileNode : fileNodes) {
+        for (RawFile fileNode : files) {
             fileNode.writeToDisk(gitDirectory);
         }
     }

+ 12 - 5
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/RepositoryFile.java

@@ -7,22 +7,29 @@ import java.util.Map.Entry;
 /**
  * Created by Winston on 16/11/14.
  */
-public class RepositoryFile implements RawFile {
+public class RepositoryFile extends RawFile {
 
-    private final Entry<String, byte[]> fileContents;
+    private final String path;
+    private final byte[] contents;
 
     public RepositoryFile(Entry<String, byte[]> fileContents) {
-        this.fileContents = fileContents;
+        path = fileContents.getKey();
+        contents = fileContents.getValue();
+    }
+
+    public RepositoryFile(String path, byte[] contents) {
+        this.path = path;
+        this.contents = contents;
     }
 
     @Override
     public String getPath() {
-        return fileContents.getKey();
+        return path;
     }
 
     @Override
     public byte[] getContents() {
-        return fileContents.getValue();
+        return contents;
     }
 
 }

+ 0 - 15
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/blob/AttachmentBlob.java

@@ -1,15 +0,0 @@
-package uk.ac.ic.wlgitbridge.writelatex.filestore.blob;
-
-import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.node.FileNode;
-
-/**
- * Created by Winston on 14/11/14.
- */
-public class AttachmentBlob extends ByteBlob {
-
-    public AttachmentBlob(FileNode fileNode) throws FailedConnectionException {
-        super(fileNode.getContents());
-    }
-
-}

+ 0 - 29
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/blob/Blob.java

@@ -1,29 +0,0 @@
-package uk.ac.ic.wlgitbridge.writelatex.filestore.blob;
-
-import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.node.AttachmentNode;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreUpdater;
-
-import java.util.Arrays;
-
-/**
- * Created by Winston on 14/11/14.
- */
-public abstract class Blob implements PersistentStoreUpdater<AttachmentNode> {
-
-    public abstract byte[] getContents() throws FailedConnectionException;
-
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof Blob)) {
-            return false;
-        }
-        Blob that = (Blob) obj;
-        try {
-            return Arrays.equals(getContents(), that.getContents());
-        } catch (FailedConnectionException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-}

+ 0 - 27
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/blob/ByteBlob.java

@@ -1,27 +0,0 @@
-package uk.ac.ic.wlgitbridge.writelatex.filestore.blob;
-
-import uk.ac.ic.wlgitbridge.writelatex.filestore.node.AttachmentNode;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
-
-/**
- * Created by Winston on 14/11/14.
- */
-public class ByteBlob extends Blob {
-
-    private final byte[] contents;
-
-    public ByteBlob(byte[] contents) {
-        this.contents = contents;
-    }
-
-    @Override
-    public byte[] getContents() {
-        return contents;
-    }
-
-    @Override
-    public void updatePersistentStore(PersistentStoreAPI persistentStore, AttachmentNode node) {
-//        persistentStore.addFileNodeBlob(node.getProjectName(), node.getFilePath(), node.isChanged(), contents);
-    }
-
-}

+ 0 - 63
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/blob/ExternalBlob.java

@@ -1,63 +0,0 @@
-package uk.ac.ic.wlgitbridge.writelatex.filestore.blob;
-
-import com.ning.http.client.AsyncCompletionHandler;
-import com.ning.http.client.AsyncHttpClient;
-import com.ning.http.client.HttpResponseBodyPart;
-import com.ning.http.client.Response;
-import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.node.AttachmentNode;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
-
-import java.io.ByteArrayOutputStream;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-
-/**
- * Created by Winston on 14/11/14.
- */
-public class ExternalBlob extends Blob {
-
-    private Future<byte[]> future;
-
-    public ExternalBlob(String url) throws FailedConnectionException {
-        super();
-        fetchContents(url);
-    }
-
-    @Override
-    public byte[] getContents() throws FailedConnectionException {
-        try {
-            return future.get();
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
-        } catch (ExecutionException e) {
-            throw new FailedConnectionException();
-        }
-    }
-
-    private void fetchContents(String url) throws FailedConnectionException {
-        AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
-        future = asyncHttpClient.prepareGet(url).execute(new AsyncCompletionHandler<byte[]>() {
-
-            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
-
-            @Override
-            public STATE onBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception {
-                bytes.write(bodyPart.getBodyPartBytes());
-                return STATE.CONTINUE;
-            }
-
-            @Override
-            public byte[] onCompleted(Response response) throws Exception {
-                return bytes.toByteArray();
-            }
-
-        });
-    }
-
-    @Override
-    public void updatePersistentStore(PersistentStoreAPI persistentStore, AttachmentNode node) {
-//        persistentStore.addFileNodeExternal(node.getProjectName(), node.getFilePath(), node.isChanged(), node.getURL());
-    }
-
-}

+ 0 - 14
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/blob/RawFileBlob.java

@@ -1,14 +0,0 @@
-package uk.ac.ic.wlgitbridge.writelatex.filestore.blob;
-
-import uk.ac.ic.wlgitbridge.bridge.RawFile;
-
-/**
- * Created by Winston on 14/11/14.
- */
-public class RawFileBlob extends ByteBlob {
-
-    public RawFileBlob(RawFile rawFile) {
-        super(rawFile.getContents());
-    }
-
-}

+ 0 - 79
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/node/AttachmentNode.java

@@ -1,79 +0,0 @@
-package uk.ac.ic.wlgitbridge.writelatex.filestore.node;
-
-import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
-import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotAttachment;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.blob.AttachmentBlob;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.blob.Blob;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.blob.ByteBlob;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.blob.ExternalBlob;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.store.FileIndexStore;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
-
-import java.util.Map;
-
-/**
- * Created by Winston on 12/11/14.
- */
-public class AttachmentNode extends FileNode {
-
-    private String projectName;
-
-    private final String url;
-    private Blob blob;
-
-    public AttachmentNode(SnapshotAttachment snapshotAttachment, Map<String, FileNode> context, FileIndexStore fileIndexes) throws FailedConnectionException {
-        super(snapshotAttachment, context);
-        url = snapshotAttachment.getUrl();
-        initBlob(fileIndexes);
-    }
-
-    public AttachmentNode(String filePath, boolean changed, String url, FileIndexStore fileIndexStore) {
-        super(filePath, changed);
-        this.url = url;
-        try {
-            initBlob(fileIndexStore);
-        } catch (FailedConnectionException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public AttachmentNode(String url, byte[] blob) {
-        super();
-        this.url = url;
-        this.blob = new ByteBlob(blob);
-    }
-
-    @Override
-    public void indexWith(FileNodeIndexer fileNodeIndexer) {
-        fileNodeIndexer.index(this);
-    }
-
-    @Override
-    public Blob getBlob() {
-        return blob;
-    }
-
-    @Override
-    public void updatePersistentStore(PersistentStoreAPI persistentStore, String projectName) {
-        this.projectName = projectName;
-        getBlob().updatePersistentStore(persistentStore, this);
-    }
-
-    public String getURL() {
-        return url;
-    }
-
-    private void initBlob(FileIndexStore fileIndexes) throws FailedConnectionException {
-        if (fileIndexes.hasAttachmentWithURL(url)) {
-            FileNode attachment = fileIndexes.getAttachment(url);
-            blob = new AttachmentBlob(attachment);
-        } else {
-            blob = new ExternalBlob(url);
-        }
-    }
-
-    public String getProjectName() {
-        return projectName;
-    }
-
-}

+ 17 - 26
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/node/BlobNode.java

@@ -3,10 +3,6 @@ package uk.ac.ic.wlgitbridge.writelatex.filestore.node;
 import uk.ac.ic.wlgitbridge.bridge.RawFile;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
 import uk.ac.ic.wlgitbridge.writelatex.filestore.RepositoryFile;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.blob.Blob;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.blob.ByteBlob;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.blob.RawFileBlob;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
 
 import java.io.File;
 import java.io.IOException;
@@ -15,48 +11,43 @@ import java.util.Map;
 /**
  * Created by Winston on 12/11/14.
  */
-public class BlobNode extends FileNode {
+public class BlobNode /*extends FileNode*/ {
 
-    private ByteBlob blob;
+//    private ByteBlob blob;
 
     public BlobNode(RawFile rawFile, Map<String, FileNode> context) {
-        super(rawFile, context);
-        blob = new RawFileBlob(rawFile);
+//        super(rawFile, context);
+//        blob = new RawFileBlob(rawFile);
     }
 
     public BlobNode(RepositoryFile repositoryFile, Map<String, FileNode> fileNodeTable, File projectAttDirectory) throws IOException, FailedConnectionException {
         this(repositoryFile, fileNodeTable);
-        blob = new RawFileBlob(repositoryFile);
+//        blob = new RawFileBlob(repositoryFile);
         writeChanged(projectAttDirectory);
     }
 
     public BlobNode(String fileName, boolean changed, byte[] blob) {
-        super(fileName, changed);
-        this.blob = new ByteBlob(blob);
+//        super(fileName, changed);
+//        this.blob = new ByteBlob(blob);
     }
 
-    @Override
-    public void indexWith(FileNodeIndexer fileNodeIndexer) {
-        fileNodeIndexer.index(this);
-    }
-
-    @Override
-    protected Blob getBlob() {
-        return blob;
-    }
+//    @Override
+//    protected Blob getBlob() {
+//        return blob;
+//    }
 
-    @Override
-    public void updatePersistentStore(PersistentStoreAPI persistentStore, String projectName) {
+//    @Override
+//    public void updatePersistentStore(PersistentStoreAPI persistentStore, String projectName) {
 //        try {
 //            persistentStore.addFileNodeBlob(projectName, getFilePath(), isChanged(), getBlob().getContents());
 //        } catch (FailedConnectionException e) {
 //            throw new RuntimeException(e);
 //        }
-    }
+//    }
 
     private void writeChanged(File projectAttDirectory) throws FailedConnectionException, IOException {
-        if (isChanged()) {
-            writeToDisk(projectAttDirectory);
-        }
+//        if (isChanged()) {
+//            writeToDisk(projectAttDirectory);
+//        }
     }
 }

+ 11 - 12
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/node/FileNode.java

@@ -2,7 +2,6 @@ package uk.ac.ic.wlgitbridge.writelatex.filestore.node;
 
 import uk.ac.ic.wlgitbridge.bridge.RawFile;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.blob.Blob;
 import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreUpdater;
 
 import java.io.File;
@@ -41,7 +40,8 @@ public abstract class FileNode implements PersistentStoreUpdater<String> {
     }
 
     public byte[] getContents() throws FailedConnectionException {
-        return getBlob().getContents();
+//        return getBlob().getContents();
+        return null;
     }
 
     public void writeToDisk(File directory) throws FailedConnectionException, IOException {
@@ -61,17 +61,16 @@ public abstract class FileNode implements PersistentStoreUpdater<String> {
         return changed || previous == null || !equals(previous);
     }
 
-    public abstract void indexWith(FileNodeIndexer indexer);
-    protected abstract Blob getBlob();
+//    protected abstract Blob getBlob();
 
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof FileNode)) {
-            return false;
-        }
-        FileNode that = (FileNode) obj;
-        return filePath.equals(that.filePath) && getBlob().equals(that.getBlob());
-    }
+//    @Override
+//    public boolean equals(Object obj) {
+//        if (!(obj instanceof FileNode)) {
+//            return false;
+//        }
+//        FileNode that = (FileNode) obj;
+//        return filePath.equals(that.filePath) && getBlob().equals(that.getBlob());
+//    }
 
     @Override
     public String toString() {

+ 0 - 11
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/node/FileNodeIndexer.java

@@ -1,11 +0,0 @@
-package uk.ac.ic.wlgitbridge.writelatex.filestore.node;
-
-/**
- * Created by Winston on 14/11/14.
- */
-public interface FileNodeIndexer {
-
-    public void index(BlobNode blobNode);
-    public void index(AttachmentNode attachmentNode);
-
-}

+ 41 - 58
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/node/WLDirectoryNode.java

@@ -1,72 +1,56 @@
 package uk.ac.ic.wlgitbridge.writelatex.filestore.node;
 
-import uk.ac.ic.wlgitbridge.bridge.RawDirectoryContents;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotAttachment;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotFile;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.RepositoryFile;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.store.FileIndexStore;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.store.WLFileStore;
 import uk.ac.ic.wlgitbridge.writelatex.model.Snapshot;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreSource;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreUpdater;
 
 import java.io.File;
-import java.io.IOException;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 
 /**
  * Created by Winston on 08/11/14.
  */
-public class WLDirectoryNode implements PersistentStoreSource, PersistentStoreUpdater<Void> {
+public class WLDirectoryNode /*implements PersistentStoreSource, PersistentStoreUpdater<Void>*/ {
 
-    private final String projectName;
+//    private final String projectName;
     private Map<String, FileNode> fileNodeTable;
-    private FileIndexStore fileIndexStore;
 
-    public WLDirectoryNode(String projectName, File attsDirectory, File rootGitDirectory, PersistentStoreAPI persistentStore) {
-        this(projectName, attsDirectory, rootGitDirectory);
-        initFromPersistentStore(persistentStore);
-    }
+//    public WLDirectoryNode(String projectName, File attsDirectory, File rootGitDirectory, PersistentStoreAPI persistentStore) {
+//        this(projectName, attsDirectory, rootGitDirectory);
+//        initFromPersistentStore(persistentStore);
+//    }
 
     private WLDirectoryNode(String projectName, File attsDirectory, File rootGitDirectory) {
-        this.projectName = projectName;
+//        this.projectName = projectName;
         new File(attsDirectory, projectName).mkdirs();
         new File(rootGitDirectory, projectName).mkdirs();
     }
 
-    private WLDirectoryNode(String projectName, Map<String, FileNode> fileNodeTable, FileIndexStore fileIndexStore) {
-        this.projectName = projectName;
-        this.fileNodeTable = fileNodeTable;
-        this.fileIndexStore = fileIndexStore;
-    }
-
-    @Override
-    public void initFromPersistentStore(PersistentStoreAPI persistentStore) {
-        fileIndexStore = new FileIndexStore(projectName, persistentStore);
-        fileNodeTable = new HashMap<String, FileNode>();
+//    @Override
+//    public void initFromPersistentStore(PersistentStoreAPI persistentStore) {
+//        fileIndexStore = new FileIndexStore(projectName, persistentStore);
+//        fileNodeTable = new HashMap<String, FileNode>();
 //        for (FileNode fileNode : persistentStore.getFileNodesForProjectName(projectName, fileIndexStore)) {
 //            fileNodeTable.put(fileNode.getFilePath(), fileNode);
 //        }
-    }
+//    }
 
-    @Override
-    public void updatePersistentStore(PersistentStoreAPI persistentStore, Void info) {
-        updateFileNodeTableInPersistentStore(persistentStore);
-        fileIndexStore.updatePersistentStore(persistentStore, projectName);
-    }
+//    @Override
+//    public void updatePersistentStore(PersistentStoreAPI persistentStore, Void info) {
+//        updateFileNodeTableInPersistentStore(persistentStore);
+//        fileIndexStore.updatePersistentStore(persistentStore, projectName);
+//    }
 
-    private void updateFileNodeTableInPersistentStore(PersistentStoreAPI persistentStore) {
+//    private void updateFileNodeTableInPersistentStore(PersistentStoreAPI persistentStore) {
 //        persistentStore.deleteFileNodesForProjectName(projectName);
-        for (FileNode fileNode : fileNodeTable.values()) {
-            fileNode.updatePersistentStore(persistentStore, projectName);
-        }
-    }
+//        for (FileNode fileNode : fileNodeTable.values()) {
+//            fileNode.updatePersistentStore(persistentStore, projectName);
+//        }
+//    }
 
     public List<FileNode> getFileNodes() {
         return new LinkedList<FileNode>(fileNodeTable.values());
@@ -78,34 +62,33 @@ public class WLDirectoryNode implements PersistentStoreSource, PersistentStoreUp
         List<SnapshotAttachment> atts = snapshot.getAtts();
         for (SnapshotFile src : srcs) {
             BlobNode blobNode = new BlobNode(src, fileNodeTable);
-            updatedFileNodeTable.put(blobNode.getFilePath(), blobNode);
+//            updatedFileNodeTable.put(blobNode.getFilePath(), blobNode);
         }
         for (SnapshotAttachment att : atts) {
-            AttachmentNode attachmentNode = new AttachmentNode(att, fileNodeTable, fileIndexStore);
-            updatedFileNodeTable.put(attachmentNode.getFilePath(), attachmentNode);
+//            AttachmentNode attachmentNode = new AttachmentNode(att, fileNodeTable, fileIndexStore);
+//            updatedFileNodeTable.put(attachmentNode.getFilePath(), attachmentNode);
         }
         LinkedList<FileNode> fileNodes = new LinkedList<FileNode>(updatedFileNodeTable.values());
         fileNodeTable = updatedFileNodeTable;
-        fileIndexStore = new FileIndexStore(fileNodes);
         return fileNodes;
     }
 
-    public WLDirectoryNode createFromRawDirectoryContents(RawDirectoryContents rawDirectoryContents, File attachmentDirectory) throws IOException, FailedConnectionException {
-        Map<String, FileNode> candidateFileNodeTable = new HashMap<String, FileNode>();
-        File projectAttDirectory = new File(attachmentDirectory, projectName);
-        projectAttDirectory.mkdirs();
-        WLFileStore.deleteInDirectory(projectAttDirectory);
-        for (Entry<String, byte[]> fileContents : rawDirectoryContents.getFileContentsTable().entrySet()) {
-            BlobNode blobNode = new BlobNode(new RepositoryFile(fileContents), fileNodeTable, projectAttDirectory);
-            candidateFileNodeTable.put(blobNode.getFilePath(), blobNode);
-        }
-        return new WLDirectoryNode(projectName, candidateFileNodeTable,
-                                   new FileIndexStore(new LinkedList<FileNode>(candidateFileNodeTable.values())));
-    }
+//    public WLDirectoryNode createFromRawDirectoryContents(RawDirectoryContents rawDirectoryContents, File attachmentDirectory) throws IOException, FailedConnectionException {
+//        Map<String, FileNode> candidateFileNodeTable = new HashMap<String, FileNode>();
+//        File projectAttDirectory = new File(attachmentDirectory, projectName);
+//        projectAttDirectory.mkdirs();
+//        WLFileStore.deleteInDirectory(projectAttDirectory);
+//        for (Entry<String, byte[]> fileContents : rawDirectoryContents.getFileContentsTable().entrySet()) {
+//            BlobNode blobNode = new BlobNode(new RepositoryFile(fileContents), fileNodeTable, projectAttDirectory);
+//            candidateFileNodeTable.put(blobNode.getFilePath(), blobNode);
+//        }
+//        return new WLDirectoryNode(projectName, candidateFileNodeTable,
+//                                   new FileIndexStore(new LinkedList<FileNode>(candidateFileNodeTable.values())));
+//    }
 
-    @Override
-    public String toString() {
-        return fileNodeTable.toString();
-    }
+//    @Override
+//    public String toString() {
+//        return fileNodeTable.toString();
+//    }
 
 }

+ 0 - 83
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/store/FileIndexStore.java

@@ -1,83 +0,0 @@
-package uk.ac.ic.wlgitbridge.writelatex.filestore.store;
-
-import uk.ac.ic.wlgitbridge.writelatex.filestore.node.AttachmentNode;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.node.BlobNode;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.node.FileNode;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.node.FileNodeIndexer;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreSource;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreUpdater;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Created by Winston on 08/11/14.
- */
-public class FileIndexStore implements FileNodeIndexer, PersistentStoreSource, PersistentStoreUpdater<String> {
-
-    private final Map<BlobHash, FileNode> blobHashMappings;
-    private Map<String, FileNode> urlMappings;
-
-    private String projectName;
-
-    public FileIndexStore(List<FileNode> fileNodes) {
-        blobHashMappings = new HashMap<BlobHash, FileNode>();
-        urlMappings = new HashMap<String, FileNode>();
-        for (FileNode fileNode : fileNodes) {
-            fileNode.indexWith(this);
-        }
-    }
-
-    public FileIndexStore(String projectName, PersistentStoreAPI persistentStore) {
-        this.projectName = projectName;
-        blobHashMappings = new HashMap<BlobHash, FileNode>();
-        initFromPersistentStore(persistentStore);
-    }
-
-    @Override
-    public void index(BlobNode blobNode) {
-
-    }
-
-    @Override
-    public void index(AttachmentNode attachmentNode) {
-        urlMappings.put(attachmentNode.getURL(), attachmentNode);
-    }
-
-    @Override
-    public void initFromPersistentStore(PersistentStoreAPI persistentStore) {
-//        urlMappings = persistentStore.getURLIndexTableForProjectName(projectName);
-    }
-
-    public boolean hasAttachmentWithURL(String url) {
-        return urlMappings.containsKey(url);
-    }
-
-    public FileNode getAttachment(String url) {
-        return urlMappings.get(url);
-    }
-
-    @Override
-    public void updatePersistentStore(PersistentStoreAPI persistentStore, String projectName) {
-//        persistentStore.deleteURLIndexesForProjectName(projectName);
-        for (Entry<String, FileNode> urlMapping : urlMappings.entrySet()) {
-//            try {
-//                persistentStore.addURLIndex(projectName, urlMapping.getKey(), urlMapping.getValue().getContents());
-//            } catch (FailedConnectionException e) {
-//                throw new RuntimeException(e);
-//            }
-        }
-    }
-
-}
-
-/*Winston is really cool
-        and he's a cat
-meow
-miaow
-meaaaoowww
-=^.^=
-*/

+ 30 - 40
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/filestore/store/WLFileStore.java

@@ -1,31 +1,21 @@
 package uk.ac.ic.wlgitbridge.writelatex.filestore.store;
 
 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.request.exception.FailedConnectionException;
-import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.InvalidProjectException;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.GitDirectoryContents;
 import uk.ac.ic.wlgitbridge.writelatex.filestore.node.WLDirectoryNode;
-import uk.ac.ic.wlgitbridge.writelatex.model.Snapshot;
-import uk.ac.ic.wlgitbridge.writelatex.model.WLProject;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreSource;
 
 import java.io.File;
-import java.io.IOException;
 import java.util.*;
 
 /**
  * Created by Winston on 08/11/14.
  */
-public class WLFileStore implements PersistentStoreSource {
+public class WLFileStore /*implements PersistentStoreSource*/ {
 
     private final Map<String, WLDirectoryNode> fileStore;
     private final File rootGitDirectory;
     private final File attDirectory;
 
-    private PersistentStoreAPI persistentStore;
+//    private PersistentStoreAPI persistentStore;
 
     public WLFileStore(File rootGitDirectory) {
         fileStore = new HashMap<String, WLDirectoryNode>();
@@ -34,18 +24,18 @@ public class WLFileStore implements PersistentStoreSource {
         attDirectory.mkdirs();
     }
 
-    public WLFileStore(File rootGitDirectory, PersistentStoreAPI persistentStoreAPI) {
-        this(rootGitDirectory);
-        initFromPersistentStore(persistentStoreAPI);
-    }
+//    public WLFileStore(File rootGitDirectory, PersistentStoreAPI persistentStoreAPI) {
+//        this(rootGitDirectory);
+//        initFromPersistentStore(persistentStoreAPI);
+//    }
 
-    @Override
-    public void initFromPersistentStore(PersistentStoreAPI persistentStore) {
-        this.persistentStore = persistentStore;
+//    @Override
+//    public void initFromPersistentStore(PersistentStoreAPI persistentStore) {
+//        this.persistentStore = persistentStore;
 //        for (String projectName : persistentStore.getProjectNames()) {
 //            fileStore.put(projectName, new WLDirectoryNode(projectName, attDirectory, rootGitDirectory, persistentStore));
 //        }
-    }
+//    }
 
     public static void deleteInDirectory(File directory) {
         deleteInDirectoryApartFrom(directory);
@@ -63,36 +53,36 @@ public class WLFileStore implements PersistentStoreSource {
         }
     }
 
-    public List<WritableRepositoryContents> updateForProject(WLProject project) throws FailedConnectionException,
-                                                                                       InvalidProjectException {
-        SortedSet<Snapshot> snapshots = project.fetchNewSnapshots();
-        String projectName = project.getName();
-        WLDirectoryNode directoryNode = getDirectoryNodeForProjectName(projectName);
-        List<WritableRepositoryContents> writableRepositories = new LinkedList<WritableRepositoryContents>();
-        for (Snapshot snapshot : snapshots) {
-            writableRepositories.add(new GitDirectoryContents(directoryNode.updateFromSnapshot(snapshot),
-                                                              rootGitDirectory,
-                                                              projectName,
-                                                              snapshot));
-        }
-        directoryNode.updatePersistentStore(persistentStore, null);
-        return writableRepositories;
-    }
+//    public List<WritableRepositoryContents> updateForProject(WLProject project) throws FailedConnectionException,
+//                                                                                       InvalidProjectException {
+//        SortedSet<Snapshot> snapshots = project.fetchNewSnapshots();
+//        String projectName = project.getName();
+//        WLDirectoryNode directoryNode = getDirectoryNodeForProjectName(projectName);
+//        List<WritableRepositoryContents> writableRepositories = new LinkedList<WritableRepositoryContents>();
+//        for (Snapshot snapshot : snapshots) {
+//            writableRepositories.add(new GitDirectoryContents(directoryNode.updateFromSnapshot(snapshot),
+//                                                              rootGitDirectory,
+//                                                              projectName,
+//                                                              snapshot));
+//        }
+//        directoryNode.updatePersistentStore(persistentStore, null);
+//        return writableRepositories;
+//    }
 
-    public WLDirectoryNode createNextDirectoryNodeInProjectFromContents(WLProject project, RawDirectoryContents directoryContents) throws IOException, FailedConnectionException {
-        return getDirectoryNodeForProjectName(project.getName()).createFromRawDirectoryContents(directoryContents, attDirectory);
-    }
+//    public WLDirectoryNode createNextDirectoryNodeInProjectFromContents(WLProject project, RawDirectoryContents directoryContents) throws IOException, FailedConnectionException {
+//        return getDirectoryNodeForProjectName(project.getName()).createFromRawDirectoryContents(directoryContents, attDirectory);
+//    }
 
     public void approveCandidateSnapshot(CandidateSnapshot candidateSnapshot) {
         WLDirectoryNode directoryNode = candidateSnapshot.getDirectoryNode();
         fileStore.put(candidateSnapshot.getProjectName(), directoryNode);
-        directoryNode.updatePersistentStore(persistentStore, null);
+//        directoryNode.updatePersistentStore(persistentStore, null);
     }
 
     private WLDirectoryNode getDirectoryNodeForProjectName(String projectName) {
         WLDirectoryNode directoryNode = fileStore.get(projectName);
         if (directoryNode == null) {
-            directoryNode = new WLDirectoryNode(projectName, attDirectory, rootGitDirectory, persistentStore);
+//            directoryNode = new WLDirectoryNode(projectName, attDirectory, rootGitDirectory, persistentStore);
             fileStore.put(projectName, directoryNode);
         }
         return directoryNode;

+ 80 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/DataStore.java

@@ -0,0 +1,80 @@
+package uk.ac.ic.wlgitbridge.writelatex.model;
+
+import org.eclipse.jgit.lib.Repository;
+import uk.ac.ic.wlgitbridge.bridge.*;
+import uk.ac.ic.wlgitbridge.writelatex.SnapshotFetcher;
+import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
+import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotAttachment;
+import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.SnapshotPostException;
+import uk.ac.ic.wlgitbridge.writelatex.filestore.GitDirectoryContents;
+import uk.ac.ic.wlgitbridge.writelatex.filestore.store.WLFileStore;
+import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStore;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Created by Winston on 06/11/14.
+ */
+public class DataStore implements CandidateSnapshotCallback {
+
+    private final File rootGitDirectory;
+    private final PersistentStore persistentStore;
+    private final SnapshotFetcher snapshotFetcher;
+    private final ResourceFetcher resourceFetcher;
+
+    public DataStore(String rootGitDirectoryPath) {
+        rootGitDirectory = initRootGitDirectory(rootGitDirectoryPath);
+        persistentStore = new PersistentStore(rootGitDirectory);
+        List<String> excludedFromDeletion = persistentStore.getProjectNames();
+        excludedFromDeletion.add(".wlgb");
+        WLFileStore.deleteInDirectoryApartFrom(rootGitDirectory, excludedFromDeletion.toArray(new String[] {}));
+
+        snapshotFetcher = new SnapshotFetcher();
+        resourceFetcher = new ResourceFetcher(persistentStore);
+    }
+
+    public List<WritableRepositoryContents> updateProjectWithName(String name, Repository repository) throws IOException, SnapshotPostException {
+        List<Snapshot> snapshots = snapshotFetcher.getSnapshotsForProjectAfterVersion(name, persistentStore.getLatestVersionForProject(name));
+        List<WritableRepositoryContents> commits = makeCommitsFromSnapshots(name, repository, snapshots);
+        return commits;
+    }
+
+    private List<WritableRepositoryContents> makeCommitsFromSnapshots(String name, Repository repository, List<Snapshot> snapshots) throws IOException {
+        List<WritableRepositoryContents> commits = new LinkedList<WritableRepositoryContents>();
+        for (Snapshot snapshot : snapshots) {
+            List<RawFile> files = new LinkedList<RawFile>();
+            files.addAll(snapshot.getSrcs());
+            for (SnapshotAttachment snapshotAttachment : snapshot.getAtts()) {
+                files.add(resourceFetcher.get(name, snapshotAttachment.getUrl(), snapshotAttachment.getPath(), repository));
+            }
+            commits.add(new GitDirectoryContents(files, rootGitDirectory, name, snapshot));
+        }
+        return commits;
+    }
+
+    public CandidateSnapshot createCandidateSnapshotFromProjectWithContents(String projectName, RawDirectoryContents directoryContents, String hostname, String postbackKey) throws SnapshotPostException, IOException, FailedConnectionException {
+//        return new WLDirectoryNodeSnapshot(getProjectWithName(projectName),
+//                                           fileStore.createNextDirectoryNodeInProjectFromContents(getProjectWithName(projectName),
+//                                                                                                  directoryContents),
+//                                           hostname,
+//                                           postbackKey,
+//                                           this);
+        return null;
+    }
+
+    @Override
+    public void approveSnapshot(int versionID, CandidateSnapshot candidateSnapshot) {
+//        getProjectWithName(candidateSnapshot.getProjectName()).putLatestSnapshot(versionID);
+//        fileStore.approveCandidateSnapshot(candidateSnapshot);
+    }
+
+    private File initRootGitDirectory(String rootGitDirectoryPath) {
+        File rootGitDirectory = new File(rootGitDirectoryPath);
+        rootGitDirectory.mkdirs();
+        return rootGitDirectory;
+    }
+
+}

+ 68 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/ResourceFetcher.java

@@ -0,0 +1,68 @@
+package uk.ac.ic.wlgitbridge.writelatex.model;
+
+import com.ning.http.client.AsyncCompletionHandler;
+import com.ning.http.client.AsyncHttpClient;
+import com.ning.http.client.HttpResponseBodyPart;
+import com.ning.http.client.Response;
+import org.eclipse.jgit.lib.Repository;
+import uk.ac.ic.wlgitbridge.bridge.RawFile;
+import uk.ac.ic.wlgitbridge.git.util.RepositoryObjectTreeWalker;
+import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
+import uk.ac.ic.wlgitbridge.writelatex.filestore.RepositoryFile;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Created by Winston on 21/02/15.
+ */
+public class ResourceFetcher {
+
+    private final URLIndexStore urlIndexStore;
+
+    public ResourceFetcher(URLIndexStore urlIndexStore) {
+        this.urlIndexStore = urlIndexStore;
+    }
+
+    public RawFile get(String projectName, String url, String newPath, Repository repository) throws IOException {
+        String path = urlIndexStore.getPathForURLInProject(projectName, url);
+        byte[] contents;
+        if (path == null) {
+            path = newPath;
+            contents = fetch(projectName, url, path);
+        } else {
+            contents = new RepositoryObjectTreeWalker(repository).getDirectoryContents().getFileContentsTable().get(path);
+        }
+        return new RepositoryFile(path, contents);
+    }
+
+    private byte[] fetch(String projectName, String url, String path) throws FailedConnectionException {
+        byte[] contents;
+        try {
+            contents = new AsyncHttpClient().prepareGet(url).execute(new AsyncCompletionHandler<byte[]>() {
+
+                ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+
+                @Override
+                public STATE onBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception {
+                    bytes.write(bodyPart.getBodyPartBytes());
+                    return STATE.CONTINUE;
+                }
+
+                @Override
+                public byte[] onCompleted(Response response) throws Exception {
+                    return bytes.toByteArray();
+                }
+
+            }).get();
+        } catch (InterruptedException e) {
+            throw new FailedConnectionException();
+        } catch (ExecutionException e) {
+            throw new FailedConnectionException();
+        }
+        urlIndexStore.addURLIndexForProject(projectName, url, path);
+        return contents;
+    }
+
+}

+ 11 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/URLIndexStore.java

@@ -0,0 +1,11 @@
+package uk.ac.ic.wlgitbridge.writelatex.model;
+
+/**
+ * Created by Winston on 21/02/15.
+ */
+public interface URLIndexStore {
+
+    public void addURLIndexForProject(String projectName, String url, String path);
+    public String getPathForURLInProject(String projectName, String url);
+
+}

+ 0 - 70
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/WLDataModel.java

@@ -1,70 +0,0 @@
-package uk.ac.ic.wlgitbridge.writelatex.model;
-
-import uk.ac.ic.wlgitbridge.bridge.CandidateSnapshot;
-import uk.ac.ic.wlgitbridge.bridge.CandidateSnapshotCallback;
-import uk.ac.ic.wlgitbridge.bridge.RawDirectoryContents;
-import uk.ac.ic.wlgitbridge.bridge.WritableRepositoryContents;
-import uk.ac.ic.wlgitbridge.util.Util;
-import uk.ac.ic.wlgitbridge.writelatex.WLDirectoryNodeSnapshot;
-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.api.request.push.exception.SnapshotPostException;
-import uk.ac.ic.wlgitbridge.writelatex.filestore.store.WLFileStore;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStore;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-/**
- * Created by Winston on 06/11/14.
- */
-public class WLDataModel implements CandidateSnapshotCallback {
-
-    private final PersistentStoreAPI persistentStore;
-    private final WLProjectStore projectStore;
-    private final WLFileStore fileStore;
-
-    public WLDataModel(String rootGitDirectoryPath) {
-        File rootGitDirectory = initRootGitDirectory(rootGitDirectoryPath);
-        persistentStore = new PersistentStore(rootGitDirectory);
-        projectStore = null;//persistentStore.loadProjectStore();
-        Util.sout("Loaded projects: " + projectStore.getProjectNames().size() + ".");
-        fileStore = null;//persistentStore.loadFileStore();
-        Util.sout("Loaded file store and index tables.");
-        List<String> excludedFromDeletion = projectStore.getProjectNames();
-        excludedFromDeletion.add(".wlgb");
-        WLFileStore.deleteInDirectoryApartFrom(rootGitDirectory, excludedFromDeletion.toArray(new String[] {}));
-    }
-
-    public List<WritableRepositoryContents> updateProjectWithName(String name) throws FailedConnectionException, InvalidProjectException {
-        return fileStore.updateForProject(getProjectWithName(name));
-    }
-
-    public WLProject getProjectWithName(String name) {
-        return projectStore.getProjectWithName(name);
-    }
-
-    public CandidateSnapshot createCandidateSnapshotFromProjectWithContents(String projectName, RawDirectoryContents directoryContents, String hostname, String postbackKey) throws SnapshotPostException, IOException, FailedConnectionException {
-        return new WLDirectoryNodeSnapshot(getProjectWithName(projectName),
-                                           fileStore.createNextDirectoryNodeInProjectFromContents(getProjectWithName(projectName),
-                                                                                                  directoryContents),
-                                           hostname,
-                                           postbackKey,
-                                           this);
-    }
-
-    @Override
-    public void approveSnapshot(int versionID, CandidateSnapshot candidateSnapshot) {
-        getProjectWithName(candidateSnapshot.getProjectName()).putLatestSnapshot(versionID);
-        fileStore.approveCandidateSnapshot(candidateSnapshot);
-    }
-
-    private File initRootGitDirectory(String rootGitDirectoryPath) {
-        File rootGitDirectory = new File(rootGitDirectoryPath);
-        rootGitDirectory.mkdirs();
-        return rootGitDirectory;
-    }
-
-}

+ 0 - 74
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/WLProject.java

@@ -1,74 +0,0 @@
-package uk.ac.ic.wlgitbridge.writelatex.model;
-
-import uk.ac.ic.wlgitbridge.writelatex.SnapshotFetcher;
-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.db.PersistentStoreAPI;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreSource;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.SortedSet;
-
-/**
- * Created by Winston on 06/11/14.
- */
-public class WLProject implements PersistentStoreSource {
-
-    public static final int INVALID_VERSION_ID = -1;
-    private final String name;
-    private final Map<Integer, Snapshot> snapshots;
-    private final SnapshotFetcher snapshotFetcher;
-
-    private int latestSnapshotID;
-    private PersistentStoreAPI persistentStore;
-
-    public WLProject(String name) {
-        this.name = name;
-        snapshots = new HashMap<Integer, Snapshot>();
-        snapshotFetcher = new SnapshotFetcher(name, snapshots);
-    }
-
-    public WLProject(String projectName, PersistentStoreAPI database) {
-        this(projectName);
-        initFromPersistentStore(database);
-    }
-
-    public SortedSet<Snapshot> fetchNewSnapshots() throws FailedConnectionException, InvalidProjectException {
-        SortedSet<Snapshot> newSnapshots = snapshotFetcher.fetchNewSnapshots();
-        updateLatestSnapshot();
-        return newSnapshots;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public int getLatestSnapshotID() {
-        return latestSnapshotID;
-    }
-
-    private void updateLatestSnapshot() {
-        Snapshot latest = snapshotFetcher.getLatestSnapshot();
-        if (latest == null) {
-            latestSnapshotID = INVALID_VERSION_ID;
-        } else {
-            latestSnapshotID = latest.getVersionID();
-        }
-    }
-
-    public void putLatestSnapshot(int versionID) {
-        snapshots.put(versionID, new Snapshot(versionID));
-        snapshotFetcher.putLatestVersion(versionID);
-        latestSnapshotID = versionID;
-//        persistentStore.addSnapshot(name, versionID);
-    }
-
-    @Override
-    public void initFromPersistentStore(PersistentStoreAPI persistentStore) {
-        this.persistentStore = persistentStore;
-        snapshotFetcher.initFromPersistentStore(persistentStore);
-        updateLatestSnapshot();
-    }
-
-}

+ 0 - 52
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/WLProjectStore.java

@@ -1,52 +0,0 @@
-package uk.ac.ic.wlgitbridge.writelatex.model;
-
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreSource;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Created by Winston on 17/11/14.
- */
-public class WLProjectStore implements PersistentStoreSource {
-
-    private PersistentStoreAPI persistentStore;
-    private final Map<String, WLProject> projects;
-
-    public WLProjectStore() {
-        projects = new HashMap<String, WLProject>();
-    }
-
-    public WLProjectStore(PersistentStoreAPI persistentStore) {
-        this();
-        initFromPersistentStore(persistentStore);
-    }
-
-    public WLProject getProjectWithName(String name) {
-        WLProject project;
-        if (projects.containsKey(name)) {
-            project = projects.get(name);
-        } else {
-            project = new WLProject(name, persistentStore);
-            projects.put(name, project);
-//            persistentStore.addProject(name);
-        }
-        return project;
-    }
-
-    public List<String> getProjectNames() {
-        return new ArrayList<String>(projects.keySet());
-    }
-
-    @Override
-    public void initFromPersistentStore(PersistentStoreAPI persistentStore) {
-        this.persistentStore = persistentStore;
-//        for (String projectName : persistentStore.getProjectNames()) {
-//            projects.put(projectName, new WLProject(projectName, persistentStore));
-//        }
-    }
-
-}

+ 18 - 6
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/db/PersistentStore.java

@@ -1,14 +1,16 @@
 package uk.ac.ic.wlgitbridge.writelatex.model.db;
 
+import uk.ac.ic.wlgitbridge.writelatex.model.URLIndexStore;
 import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLiteWLDatabase;
 
 import java.io.File;
 import java.sql.SQLException;
+import java.util.List;
 
 /**
  * Created by Winston on 19/11/14.
  */
-public class PersistentStore {
+public class PersistentStore implements URLIndexStore {
 
     private final SQLiteWLDatabase database;
 
@@ -21,6 +23,14 @@ public class PersistentStore {
             throw new RuntimeException(e);
         }
     }
+
+    public List<String> getProjectNames() {
+        try {
+            return database.getProjectNames();
+        } catch (SQLException e) {
+            throw new RuntimeException(e);
+        }
+    }
     public void setLatestVersionForProject(String project, int versionID) {
         try {
             database.setVersionIDForProject(project, versionID);
@@ -29,15 +39,16 @@ public class PersistentStore {
         }
     }
 
-    public void deleteFilesForProject(String project, String... files) {
+    public int getLatestVersionForProject(String project) {
         try {
-            database.deleteFilesForProject(project, files);
+            return database.getVersionIDForProjectName(project);
         } catch (SQLException e) {
             throw new RuntimeException(e);
         }
     }
 
-    public void addURLIndexesForProject(String projectName, String url, String path) {
+    @Override
+    public void addURLIndexForProject(String projectName, String url, String path) {
         try {
             database.addURLIndex(projectName, url, path);
         } catch (SQLException e) {
@@ -45,14 +56,15 @@ public class PersistentStore {
         }
     }
 
-    public int getLatestVersionForProject(String project) {
+    public void deleteFilesForProject(String project, String... files) {
         try {
-            return database.getVersionIDForProjectName(project);
+            database.deleteFilesForProject(project, files);
         } catch (SQLException e) {
             throw new RuntimeException(e);
         }
     }
 
+    @Override
     public String getPathForURLInProject(String projectName, String url) {
         try {
             return database.getPathForURLInProject(projectName, url);

+ 10 - 2
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/SQLiteWLDatabase.java

@@ -1,8 +1,10 @@
 package uk.ac.ic.wlgitbridge.writelatex.model.db.sql;
 
 import uk.ac.ic.wlgitbridge.util.Util;
-import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query.GetPathForURLInProjectSQLQuery;
 import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query.GetLatestVersionForProjectSQLQuery;
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query.GetPathForURLInProjectSQLQuery;
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query.GetProjectNamesSQLQuery;
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.create.CreateIndexURLIndexStore;
 import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.create.CreateProjectsTableSQLUpdate;
 import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.create.CreateURLIndexStoreSQLUpdate;
 import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.delete.DeleteFilesForProjectSQLUpdate;
@@ -11,6 +13,7 @@ import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.insert.SetProjectSQLU
 
 import java.io.File;
 import java.sql.*;
+import java.util.List;
 
 /**
  * Created by Winston on 17/11/14.
@@ -48,10 +51,15 @@ public class SQLiteWLDatabase {
         return query(new GetPathForURLInProjectSQLQuery(projectName, url));
     }
 
+    public List<String> getProjectNames() throws SQLException {
+        return query(new GetProjectNamesSQLQuery());
+    }
+
     private void createTables() throws SQLException {
         final SQLUpdate[] createTableUpdates = {
                 new CreateProjectsTableSQLUpdate(),
-                new CreateURLIndexStoreSQLUpdate()
+                new CreateURLIndexStoreSQLUpdate(),
+                new CreateIndexURLIndexStore()
         };
 
         for (SQLUpdate update : createTableUpdates) {

+ 1 - 1
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/query/GetLatestVersionForProjectSQLQuery.java

@@ -12,7 +12,7 @@ import java.sql.SQLException;
 public class GetLatestVersionForProjectSQLQuery implements SQLQuery<Integer> {
 
     private static final String GET_VERSION_IDS_FOR_PROJECT_NAME =
-            "SELECT `version_id` FROM `projects` WHERE `project_name` = ?";
+            "SELECT `version_id` FROM `projects` WHERE `name` = ?";
 
     private final String projectName;
 

+ 38 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/query/GetProjectNamesSQLQuery.java

@@ -0,0 +1,38 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query;
+
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLQuery;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Created by Winston on 21/02/15.
+ */
+public class GetProjectNamesSQLQuery implements SQLQuery<List<String>> {
+
+    private static final String GET_URL_INDEXES_FOR_PROJECT_NAME =
+            "SELECT `name` FROM `projects`";
+
+    @Override
+    public List<String> processResultSet(ResultSet resultSet) throws SQLException {
+        List<String> projectNames = new LinkedList<String>();
+        while (resultSet.next()) {
+            projectNames.add(resultSet.getString("name"));
+        }
+        return projectNames;
+    }
+
+    @Override
+    public String getSQL() {
+        return GET_URL_INDEXES_FOR_PROJECT_NAME;
+    }
+
+    @Override
+    public void addParametersToStatement(PreparedStatement statement) throws SQLException {
+
+    }
+
+}

+ 25 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/create/CreateIndexURLIndexStore.java

@@ -0,0 +1,25 @@
+package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.create;
+
+import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLUpdate;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Created by Winston on 21/02/15.
+ */
+public class CreateIndexURLIndexStore implements SQLUpdate {
+
+    public static final String CREATE_INDEX_URL_INDEX_STORE = "CREATE INDEX `project_path_index` ON `url_index_store`(`project_name`, `path`);\n";
+
+    @Override
+    public String getSQL() {
+        return CREATE_INDEX_URL_INDEX_STORE;
+    }
+
+    @Override
+    public void addParametersToStatement(PreparedStatement statement) throws SQLException {
+
+    }
+
+}

+ 1 - 4
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/model/db/sql/update/create/CreateURLIndexStoreSQLUpdate.java

@@ -11,16 +11,13 @@ import java.sql.SQLException;
 public class CreateURLIndexStoreSQLUpdate implements SQLUpdate {
 
     private static final String CREATE_URL_INDEX_STORE =
-            "BEGIN;\n"+
             "CREATE TABLE IF NOT EXISTS `url_index_store` (\n"+
             "  `project_name` varchar(10) NOT NULL DEFAULT '',\n"+
             "  `url` text NOT NULL,\n"+
             "  `path` text NOT NULL,\n"+
             "  PRIMARY KEY (`project_name`,`url`),\n"+
             "  CONSTRAINT `url_index_store_ibfk_1` FOREIGN KEY (`project_name`) REFERENCES `projects` (`name`) ON DELETE CASCADE ON UPDATE CASCADE\n"+
-            ");\n"+
-            "CREATE INDEX `project_path_index` ON `url_index_store`(`project_name`, `path`);\n"+
-            "COMMIT;\n";
+            ");\n";
 
     @Override
     public String getSQL() {