Implement no_mem git-uploads.

This commit is contained in:
Winston Li 2015-02-21 22:30:47 +00:00
parent 4110dcc2a9
commit ec13e184b7
37 changed files with 572 additions and 936 deletions

View file

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

View file

@ -1,11 +1,25 @@
package uk.ac.ic.wlgitbridge.bridge; 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. * Created by Winston on 16/11/14.
*/ */
public interface RawFile { public abstract class RawFile {
public String getPath(); public abstract String getPath();
public byte[] getContents(); public abstract 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();
}
} }

View file

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

View file

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

View file

@ -23,6 +23,14 @@ public class RepositoryObjectTreeWalker {
this.repository = repository; 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 { public RawDirectoryContents getDirectoryContents() throws IOException {
return new FileDirectoryContents(walkGitObjectTree()); return new FileDirectoryContents(walkGitObjectTree());
} }

View file

@ -1,163 +1,76 @@
package uk.ac.ic.wlgitbridge.writelatex; 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.exception.FailedConnectionException;
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.SnapshotGetDocRequest; 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.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.SnapshotData;
import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotGetForVersionRequest; 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.SnapshotGetSavedVersRequest;
import uk.ac.ic.wlgitbridge.writelatex.api.request.getsavedvers.SnapshotInfo; 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.api.request.push.exception.SnapshotPostException;
import uk.ac.ic.wlgitbridge.writelatex.model.Snapshot; 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.*; import java.util.*;
/** /**
* Created by Winston on 07/11/14. * Created by Winston on 07/11/14.
*/ */
public class SnapshotFetcher implements PersistentStoreSource { public class SnapshotFetcher {
private PersistentStoreAPI persistentStore; public List<Snapshot> getSnapshotsForProjectAfterVersion(String projectName, int version) throws FailedConnectionException, SnapshotPostException {
List<SnapshotInfo> snapshotInfos = getSnapshotInfosAfterVersion(projectName, version);
private final String projectName; List<SnapshotData> snapshotDatas = getMatchingSnapshotData(projectName, snapshotInfos);
private final Map<Integer, Snapshot> snapshots; List<Snapshot> snapshots = combine(snapshotInfos, snapshotDatas);
private final SortedSet<Integer> versions; return snapshots;
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 { private List<SnapshotInfo> getSnapshotInfosAfterVersion(String projectName, int version) throws FailedConnectionException, SnapshotPostException {
SortedSet<Snapshot> newSnapshots = new TreeSet<Snapshot>(); SortedSet<SnapshotInfo> versions = new TreeSet<SnapshotInfo>();
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);
// }
}
private boolean getNew(SortedSet<Snapshot> newSnapshots) throws FailedConnectionException, InvalidProjectException {
SnapshotGetDocRequest getDoc = new SnapshotGetDocRequest(projectName); SnapshotGetDocRequest getDoc = new SnapshotGetDocRequest(projectName);
SnapshotGetSavedVersRequest getSavedVers = new SnapshotGetSavedVersRequest(projectName); SnapshotGetSavedVersRequest getSavedVers = new SnapshotGetSavedVersRequest(projectName);
getDoc.request(); getDoc.request();
getSavedVers.request(); getSavedVers.request();
SnapshotGetDocResult latestDoc = getDoc.getResult();
Set<Integer> fetchedIDs = new HashSet<Integer>(); int latest = latestDoc.getVersionID();
Map<Integer, SnapshotInfo> fetchedSnapshotInfos = new HashMap<Integer, SnapshotInfo>(); if (latest > version) {
for (SnapshotInfo snapshotInfo : getSavedVers.getResult().getSavedVers()) {
int latestVersionID = putLatestDoc(getDoc, fetchedIDs, fetchedSnapshotInfos); if (snapshotInfo.getVersionId() > version) {
versions.add(snapshotInfo);
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);
} }
versions.add(new SnapshotInfo(latest, latestDoc.getCreatedAt(), latestDoc.getName(), latestDoc.getEmail()));
} }
return idsToUpdate; return new LinkedList<SnapshotInfo>(versions);
} }
private boolean updateIDs(List<Integer> idsToUpdate, Map<Integer, SnapshotInfo> fetchedSnapshotInfos, SortedSet<Snapshot> newSnapshots) throws FailedConnectionException { private List<SnapshotData> getMatchingSnapshotData(String projectName, List<SnapshotInfo> snapshotInfos) throws FailedConnectionException {
if (idsToUpdate.isEmpty()) { List<SnapshotGetForVersionRequest> firedRequests = fireDataRequests(projectName, snapshotInfos);
return false; List<SnapshotData> snapshotDataList = new LinkedList<SnapshotData>();
for (SnapshotGetForVersionRequest fired : firedRequests) {
snapshotDataList.add(fired.getResult().getSnapshotData());
} }
fetchVersions(idsToUpdate, fetchedSnapshotInfos, newSnapshots); return snapshotDataList;
return true;
} }
private void fetchVersions(List<Integer> idsToUpdate, Map<Integer, SnapshotInfo> fetchedSnapshotInfos, SortedSet<Snapshot> newSnapshots) throws FailedConnectionException { private List<SnapshotGetForVersionRequest> fireDataRequests(String projectName, List<SnapshotInfo> snapshotInfos) {
List<SnapshotGetForVersionRequest> requests = createFiredRequests(idsToUpdate);
processResults(fetchedSnapshotInfos, newSnapshots, requests);
}
private List<SnapshotGetForVersionRequest> createFiredRequests(List<Integer> idsToUpdate) {
List<SnapshotGetForVersionRequest> requests = new LinkedList<SnapshotGetForVersionRequest>(); List<SnapshotGetForVersionRequest> requests = new LinkedList<SnapshotGetForVersionRequest>();
for (int id : idsToUpdate) { for (SnapshotInfo snapshotInfo : snapshotInfos) {
SnapshotGetForVersionRequest request = new SnapshotGetForVersionRequest(projectName, id); SnapshotGetForVersionRequest request = new SnapshotGetForVersionRequest(projectName, snapshotInfo.getVersionId());
requests.add(request); requests.add(request);
request.request(); request.request();
} }
return requests; return requests;
} }
private void processResults(Map<Integer, SnapshotInfo> fetchedSnapshotInfos, SortedSet<Snapshot> newSnapshots, List<SnapshotGetForVersionRequest> requests) throws FailedConnectionException { private List<Snapshot> combine(List<SnapshotInfo> snapshotInfos, List<SnapshotData> snapshotDatas) {
for (SnapshotGetForVersionRequest request : requests) { List<Snapshot> snapshots = new LinkedList<Snapshot>();
processResult(fetchedSnapshotInfos, newSnapshots, request); 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;
}
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -5,7 +5,7 @@ import uk.ac.ic.wlgitbridge.util.Util;
/** /**
* Created by Winston on 06/11/14. * Created by Winston on 06/11/14.
*/ */
public class SnapshotInfo { public class SnapshotInfo implements Comparable<SnapshotInfo> {
private int versionId; private int versionId;
private String comment; private String comment;
@ -39,4 +39,17 @@ public class SnapshotInfo {
return createdAt; 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);
}
} }

View file

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

View file

@ -7,22 +7,29 @@ import java.util.Map.Entry;
/** /**
* Created by Winston on 16/11/14. * 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) { 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 @Override
public String getPath() { public String getPath() {
return fileContents.getKey(); return path;
} }
@Override @Override
public byte[] getContents() { public byte[] getContents() {
return fileContents.getValue(); return contents;
} }
} }

View file

@ -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());
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}

View file

@ -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());
}
}

View file

@ -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());
}
}

View file

@ -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;
}
}

View file

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

View file

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

View file

@ -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);
}

View file

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

View file

@ -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
=^.^=
*/

View file

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

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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));
// }
}
}

View file

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

View file

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

View file

@ -12,7 +12,7 @@ import java.sql.SQLException;
public class GetLatestVersionForProjectSQLQuery implements SQLQuery<Integer> { public class GetLatestVersionForProjectSQLQuery implements SQLQuery<Integer> {
private static final String GET_VERSION_IDS_FOR_PROJECT_NAME = 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; private final String projectName;

View file

@ -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 {
}
}

View file

@ -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 {
}
}

View file

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