use of org.locationtech.geogig.web.api.CommandContext in project GeoGig by boundlessgeo.
the class RevertFeatureWebOp method run.
/**
* 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 (this.getTransactionId() == null) {
throw new CommandSpecException("No transaction was specified, revert feature requires a transaction to preserve the stability of the repository.");
}
final Context geogig = this.getCommandLocator(context);
Optional<RevTree> newTree = Optional.absent();
Optional<RevTree> oldTree = Optional.absent();
// get tree from new commit
Optional<ObjectId> treeId = geogig.command(ResolveTreeish.class).setTreeish(newCommitId).call();
Preconditions.checkState(treeId.isPresent(), "New commit id did not resolve to a valid tree.");
newTree = geogig.command(RevObjectParse.class).setRefSpec(treeId.get().toString()).call(RevTree.class);
Preconditions.checkState(newTree.isPresent(), "Unable to read the new commit tree.");
// get tree from old commit
treeId = geogig.command(ResolveTreeish.class).setTreeish(oldCommitId).call();
Preconditions.checkState(treeId.isPresent(), "Old commit id did not resolve to a valid tree.");
oldTree = geogig.command(RevObjectParse.class).setRefSpec(treeId.get().toString()).call(RevTree.class);
Preconditions.checkState(newTree.isPresent(), "Unable to read the old commit tree.");
// get feature from old tree
Optional<NodeRef> node = geogig.command(FindTreeChild.class).setParent(oldTree.get()).setIndex(true).setChildPath(featurePath).call();
boolean delete = false;
if (!node.isPresent()) {
delete = true;
node = geogig.command(FindTreeChild.class).setParent(newTree.get()).setIndex(true).setChildPath(featurePath).call();
Preconditions.checkState(node.isPresent(), "The feature was not found in either commit tree.");
}
// get the new parent tree
ObjectId metadataId = ObjectId.NULL;
Optional<NodeRef> parentNode = geogig.command(FindTreeChild.class).setParent(newTree.get()).setChildPath(node.get().getParentPath()).setIndex(true).call();
RevTreeBuilder treeBuilder = null;
if (parentNode.isPresent()) {
metadataId = parentNode.get().getMetadataId();
Optional<RevTree> parsed = geogig.command(RevObjectParse.class).setObjectId(parentNode.get().getNode().getObjectId()).call(RevTree.class);
checkState(parsed.isPresent(), "Parent tree couldn't be found in the repository.");
treeBuilder = new RevTreeBuilder(geogig.stagingDatabase(), parsed.get());
treeBuilder.remove(node.get().getNode().getName());
} else {
treeBuilder = new RevTreeBuilder(geogig.stagingDatabase());
}
// put the old feature into the new tree
if (!delete) {
treeBuilder.put(node.get().getNode());
}
ObjectId newTreeId = geogig.command(WriteBack.class).setAncestor(newTree.get().builder(geogig.stagingDatabase())).setChildPath(node.get().getParentPath()).setToIndex(true).setTree(treeBuilder.build()).setMetadataId(metadataId).call();
// build new commit with parent of new commit and the newly built tree
CommitBuilder builder = new CommitBuilder();
builder.setParentIds(Lists.newArrayList(newCommitId));
builder.setTreeId(newTreeId);
builder.setAuthor(authorName.orNull());
builder.setAuthorEmail(authorEmail.orNull());
builder.setMessage(commitMessage.or("Reverted changes made to " + featurePath + " at " + newCommitId.toString()));
RevCommit mapped = builder.build();
context.getGeoGIG().getRepository().objectDatabase().put(mapped);
// merge commit into current branch
final Optional<Ref> currHead = geogig.command(RefParse.class).setName(Ref.HEAD).call();
if (!currHead.isPresent()) {
throw new CommandSpecException("Repository has no HEAD, can't merge.");
}
MergeOp merge = geogig.command(MergeOp.class);
merge.setAuthor(authorName.orNull(), authorEmail.orNull());
merge.addCommit(Suppliers.ofInstance(mapped.getId()));
merge.setMessage(mergeMessage.or("Merged revert of " + featurePath));
try {
final MergeReport report = merge.call();
context.setResponseContent(new CommandResponse() {
@Override
public void write(ResponseWriter out) throws Exception {
out.start();
out.writeMergeResponse(Optional.fromNullable(report.getMergeCommit()), report.getReport().get(), geogig, report.getOurs(), report.getPairs().get(0).getTheirs(), report.getPairs().get(0).getAncestor());
out.finish();
}
});
} catch (Exception e) {
final RevCommit ours = context.getGeoGIG().getRepository().getCommit(currHead.get().getObjectId());
final RevCommit theirs = context.getGeoGIG().getRepository().getCommit(mapped.getId());
final Optional<ObjectId> ancestor = geogig.command(FindCommonAncestor.class).setLeft(ours).setRight(theirs).call();
context.setResponseContent(new CommandResponse() {
final MergeScenarioReport report = geogig.command(ReportMergeScenarioOp.class).setMergeIntoCommit(ours).setToMergeCommit(theirs).call();
@Override
public void write(ResponseWriter out) throws Exception {
out.start();
Optional<RevCommit> mergeCommit = Optional.absent();
out.writeMergeResponse(mergeCommit, report, geogig, ours.getId(), theirs.getId(), ancestor.get());
out.finish();
}
});
}
}
use of org.locationtech.geogig.web.api.CommandContext in project GeoGig by boundlessgeo.
the class StatisticsWebOp method run.
/**
* Runs the command and builds the appropriate response
*
* @param context - the context to use for this command
*/
@Override
public void run(CommandContext context) {
final Context geogig = this.getCommandLocator(context);
final List<FeatureTypeStats> stats = Lists.newArrayList();
LogOp logOp = geogig.command(LogOp.class).setFirstParentOnly(true);
final Iterator<RevCommit> log;
if (since != null && !since.trim().isEmpty()) {
Date untilTime = new Date();
Date sinceTime = new Date(geogig.command(ParseTimestamp.class).setString(since).call());
logOp.setTimeRange(new Range<Date>(Date.class, sinceTime, untilTime));
}
if (this.until != null) {
Optional<ObjectId> until;
until = geogig.command(RevParse.class).setRefSpec(this.until).call();
Preconditions.checkArgument(until.isPresent(), "Object not found '%s'", this.until);
logOp.setUntil(until.get());
}
LsTreeOp lsTreeOp = geogig.command(LsTreeOp.class).setStrategy(LsTreeOp.Strategy.TREES_ONLY);
if (path != null && !path.trim().isEmpty()) {
lsTreeOp.setReference(path);
logOp.addPath(path);
}
final Iterator<NodeRef> treeIter = lsTreeOp.call();
while (treeIter.hasNext()) {
NodeRef node = treeIter.next();
stats.add(new FeatureTypeStats(node.path(), context.getGeoGIG().getRepository().getTree(node.objectId()).size()));
}
log = logOp.call();
RevCommit firstCommit = null;
RevCommit lastCommit = null;
int totalCommits = 0;
final List<RevPerson> authors = Lists.newArrayList();
if (log.hasNext()) {
lastCommit = log.next();
authors.add(lastCommit.getAuthor());
totalCommits++;
}
while (log.hasNext()) {
firstCommit = log.next();
RevPerson newAuthor = firstCommit.getAuthor();
// If the author isn't defined, use the committer for the purposes of statistics.
if (!newAuthor.getName().isPresent() && !newAuthor.getEmail().isPresent()) {
newAuthor = firstCommit.getCommitter();
}
if (newAuthor.getName().isPresent() || newAuthor.getEmail().isPresent()) {
boolean authorFound = false;
for (RevPerson author : authors) {
if (newAuthor.getName().equals(author.getName()) && newAuthor.getEmail().equals(author.getEmail())) {
authorFound = true;
break;
}
}
if (!authorFound) {
authors.add(newAuthor);
}
}
totalCommits++;
}
int addedFeatures = 0;
int modifiedFeatures = 0;
int removedFeatures = 0;
if (since != null && !since.trim().isEmpty() && firstCommit != null && lastCommit != null) {
final Iterator<DiffEntry> diff = geogig.command(DiffOp.class).setOldVersion(firstCommit.getId()).setNewVersion(lastCommit.getId()).setFilter(path).call();
while (diff.hasNext()) {
DiffEntry entry = diff.next();
if (entry.changeType() == DiffEntry.ChangeType.ADDED) {
addedFeatures++;
} else if (entry.changeType() == DiffEntry.ChangeType.MODIFIED) {
modifiedFeatures++;
} else {
removedFeatures++;
}
}
}
final RevCommit first = firstCommit;
final RevCommit last = lastCommit;
final int total = totalCommits;
final int added = addedFeatures;
final int modified = modifiedFeatures;
final int removed = removedFeatures;
context.setResponseContent(new CommandResponse() {
@Override
public void write(ResponseWriter out) throws Exception {
out.start(true);
out.writeStatistics(stats, first, last, total, authors, added, modified, removed);
out.finish();
}
});
}
use of org.locationtech.geogig.web.api.CommandContext in project GeoGig by boundlessgeo.
the class Status method run.
/**
* Runs the command builds the appropriate command
*
* @param context - the context to use for this command
*/
@Override
public void run(CommandContext context) {
final Context geogig = this.getCommandLocator(context);
final String pathFilter = null;
final Optional<Ref> currHead = geogig.command(RefParse.class).setName(Ref.HEAD).call();
context.setResponseContent(new CommandResponse() {
@Override
public void write(ResponseWriter writer) throws Exception {
writer.start();
if (!currHead.isPresent()) {
writer.writeErrors("Repository has no HEAD.");
} else {
if (currHead.get() instanceof SymRef) {
final SymRef headRef = (SymRef) currHead.get();
writer.writeHeaderElements("branch", Ref.localName(headRef.getTarget()));
}
}
writer.writeStaged(geogig.command(DiffIndex.class).addFilter(pathFilter), offset, limit);
writer.writeUnstaged(geogig.command(DiffWorkTree.class).setFilter(pathFilter), offset, limit);
writer.writeUnmerged(geogig.command(ConflictsReadOp.class).call(), offset, limit);
writer.finish();
}
});
}
use of org.locationtech.geogig.web.api.CommandContext in project GeoGig by boundlessgeo.
the class LsTree method run.
/**
* Runs the command and builds the appropriate response
*
* @param context - the context to use for this command
*/
@Override
public void run(CommandContext context) {
String ref = null;
if (refList != null && !refList.isEmpty()) {
ref = refList.get(0);
}
LsTreeOp.Strategy lsStrategy = LsTreeOp.Strategy.CHILDREN;
if (recursive) {
if (includeTrees) {
lsStrategy = LsTreeOp.Strategy.DEPTHFIRST;
} else if (onlyTrees) {
lsStrategy = LsTreeOp.Strategy.DEPTHFIRST_ONLY_TREES;
} else {
lsStrategy = LsTreeOp.Strategy.DEPTHFIRST_ONLY_FEATURES;
}
} else {
if (onlyTrees) {
lsStrategy = LsTreeOp.Strategy.TREES_ONLY;
}
}
final Context geogig = this.getCommandLocator(context);
final Iterator<NodeRef> iter = geogig.command(LsTreeOp.class).setReference(ref).setStrategy(lsStrategy).call();
context.setResponseContent(new CommandResponse() {
@Override
public void write(ResponseWriter out) throws Exception {
out.start(true);
out.writeLsTreeResponse(iter, verbose);
out.finish();
}
});
}
use of org.locationtech.geogig.web.api.CommandContext in project GeoGig by boundlessgeo.
the class PullWebOp method run.
/**
* Runs the command and builds the appropriate response.
*
* @param context - the context to use for this command
*/
@Override
public void run(CommandContext context) {
final Context geogig = this.getCommandLocator(context);
PullOp command = geogig.command(PullOp.class).setAuthor(authorName.orNull(), authorEmail.orNull()).setRemote(remoteName).setAll(fetchAll).addRefSpec(refSpec);
try {
final PullResult result = command.call();
final Iterator<DiffEntry> iter;
if (result.getOldRef() != null && result.getNewRef() != null && result.getOldRef().equals(result.getNewRef())) {
iter = null;
} else {
if (result.getOldRef() == null) {
iter = geogig.command(DiffOp.class).setNewVersion(result.getNewRef().getObjectId()).setOldVersion(ObjectId.NULL).call();
} else {
iter = geogig.command(DiffOp.class).setNewVersion(result.getNewRef().getObjectId()).setOldVersion(result.getOldRef().getObjectId()).call();
}
}
context.setResponseContent(new CommandResponse() {
@Override
public void write(ResponseWriter out) throws Exception {
out.start();
out.writePullResponse(result, iter, geogig);
out.finish();
}
});
} catch (SynchronizationException e) {
switch(e.statusCode) {
case HISTORY_TOO_SHALLOW:
default:
context.setResponseContent(CommandResponse.error("Unable to pull, the remote history is shallow."));
}
} catch (MergeConflictsException e) {
String[] refs = refSpec.split(":");
String remoteRef = Ref.REMOTES_PREFIX + remoteName + "/" + refs[0];
Optional<Ref> sourceRef = geogig.command(RefParse.class).setName(remoteRef).call();
String destinationref = "";
if (refs.length == 2) {
destinationref = refs[1];
} else {
final Optional<Ref> currHead = geogig.command(RefParse.class).setName(Ref.HEAD).call();
if (!currHead.isPresent()) {
context.setResponseContent(CommandResponse.error("Repository has no HEAD, can't pull."));
} else if (!(currHead.get() instanceof SymRef)) {
context.setResponseContent(CommandResponse.error("Can't pull from detached HEAD"));
}
final SymRef headRef = (SymRef) currHead.get();
destinationref = headRef.getTarget();
}
Optional<Ref> destRef = geogig.command(RefParse.class).setName(destinationref).call();
final RevCommit theirs = context.getGeoGIG().getRepository().getCommit(sourceRef.get().getObjectId());
final RevCommit ours = context.getGeoGIG().getRepository().getCommit(destRef.get().getObjectId());
final Optional<ObjectId> ancestor = geogig.command(FindCommonAncestor.class).setLeft(ours).setRight(theirs).call();
context.setResponseContent(new CommandResponse() {
final MergeScenarioReport report = geogig.command(ReportMergeScenarioOp.class).setMergeIntoCommit(ours).setToMergeCommit(theirs).call();
@Override
public void write(ResponseWriter out) throws Exception {
out.start();
Optional<RevCommit> mergeCommit = Optional.absent();
out.writeMergeResponse(mergeCommit, report, geogig, ours.getId(), theirs.getId(), ancestor.get());
out.finish();
}
});
}
}
Aggregations