/* Copyright (c) 2013-2014 Boundless and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/edl-v10.html
*
* Contributors:
* Kelsey Ishmael (LMN Solutions) - initial implementation
*/
package org.locationtech.geogig.web.api.commands;
import java.util.Iterator;
import java.util.List;
import org.locationtech.geogig.api.GeoGIG;
import org.locationtech.geogig.api.ObjectId;
import org.locationtech.geogig.api.RevCommit;
import org.locationtech.geogig.web.api.AbstractWebAPICommand;
import org.locationtech.geogig.web.api.CommandContext;
import org.locationtech.geogig.web.api.CommandResponse;
import org.locationtech.geogig.web.api.CommandSpecException;
import org.locationtech.geogig.web.api.ResponseWriter;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
/**
* Lists all commits from a given commitId through to a certain depth.
*
*/
public class GetCommitGraph extends AbstractWebAPICommand {
private String commitId;
private int depth;
private int page;
private int elementsPerPage;
/**
* Mutator for the commitId variable
*
* @param commitId - the id of the commit to start at
*/
public void setCommitId(String commitId) {
this.commitId = commitId;
}
/**
* Mutator for the depth variable
*
* @param depth - the depth to search to
*/
public void setDepth(int depth) {
this.depth = depth;
}
/**
* Mutator for the page variable
*
* @param page - the page number to build in the response
*/
public void setPage(int page) {
this.page = page;
}
/**
* Mutator for the elementsPerPage variable
*
* @param elementsPerPage - the number of elements to list per page
*/
public void setElementsPerPage(int elementsPerPage) {
this.elementsPerPage = elementsPerPage;
}
/**
* Runs the command and builds the appropriate response.
*
* @param context - the context to use for this command
*
* @throws CommandSpecException
*/
@Override
public void run(CommandContext context) {
if (commitId.equals(ObjectId.NULL.toString())) {
throw new CommandSpecException("No commitId was given.");
}
final GeoGIG geogig = context.getGeoGIG();
RevCommit commit = geogig.getRepository().getCommit(ObjectId.valueOf(commitId));
final List<RevCommit> history = Lists.newLinkedList();
List<CommitNode> nodes = Lists.newLinkedList();
CommitNode node = new CommitNode(commit, 1);
nodes.add(node);
while (!nodes.isEmpty()) {
node = nodes.remove(0);
if (!history.contains(node.commit)) {
history.add(node.commit);
}
if (this.depth == 0 || node.depth < this.depth) {
for (ObjectId id : node.commit.getParentIds()) {
nodes.add(new CommitNode(geogig.getRepository().getCommit(id), node.depth + 1));
}
}
}
final Iterator<RevCommit> historyIterator = history.iterator();
Iterators.advance(historyIterator, page * elementsPerPage);
context.setResponseContent(new CommandResponse() {
@Override
public void write(ResponseWriter out) throws Exception {
out.start();
out.writeCommits(history.iterator(), elementsPerPage, false);
out.finish();
}
});
}
/**
* Private helper class to store the information needed to traverse the commit graph properly.
*
*/
private class CommitNode {
public RevCommit commit;
public int depth;
CommitNode(RevCommit commit, int depth) {
this.commit = commit;
this.depth = depth;
}
}
}