Search in sources :

Example 11 with CommandContext

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();
            }
        });
    }
}
Also used : CommitBuilder(org.locationtech.geogig.api.CommitBuilder) MergeOp(org.locationtech.geogig.api.porcelain.MergeOp) CommandResponse(org.locationtech.geogig.web.api.CommandResponse) MergeScenarioReport(org.locationtech.geogig.api.plumbing.merge.MergeScenarioReport) NodeRef(org.locationtech.geogig.api.NodeRef) ResolveTreeish(org.locationtech.geogig.api.plumbing.ResolveTreeish) CommandSpecException(org.locationtech.geogig.web.api.CommandSpecException) RevCommit(org.locationtech.geogig.api.RevCommit) Context(org.locationtech.geogig.api.Context) CommandContext(org.locationtech.geogig.web.api.CommandContext) Optional(com.google.common.base.Optional) ObjectId(org.locationtech.geogig.api.ObjectId) FindTreeChild(org.locationtech.geogig.api.plumbing.FindTreeChild) RevTreeBuilder(org.locationtech.geogig.api.RevTreeBuilder) CommandSpecException(org.locationtech.geogig.web.api.CommandSpecException) MergeReport(org.locationtech.geogig.api.porcelain.MergeOp.MergeReport) Ref(org.locationtech.geogig.api.Ref) NodeRef(org.locationtech.geogig.api.NodeRef) ResponseWriter(org.locationtech.geogig.web.api.ResponseWriter) RevObjectParse(org.locationtech.geogig.api.plumbing.RevObjectParse) RevTree(org.locationtech.geogig.api.RevTree)

Example 12 with CommandContext

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();
        }
    });
}
Also used : ParseTimestamp(org.locationtech.geogig.api.plumbing.ParseTimestamp) LogOp(org.locationtech.geogig.api.porcelain.LogOp) CommandResponse(org.locationtech.geogig.web.api.CommandResponse) NodeRef(org.locationtech.geogig.api.NodeRef) RevPerson(org.locationtech.geogig.api.RevPerson) RevParse(org.locationtech.geogig.api.plumbing.RevParse) RevCommit(org.locationtech.geogig.api.RevCommit) DiffEntry(org.locationtech.geogig.api.plumbing.diff.DiffEntry) Context(org.locationtech.geogig.api.Context) CommandContext(org.locationtech.geogig.web.api.CommandContext) ObjectId(org.locationtech.geogig.api.ObjectId) Date(java.util.Date) LsTreeOp(org.locationtech.geogig.api.plumbing.LsTreeOp) ResponseWriter(org.locationtech.geogig.web.api.ResponseWriter)

Example 13 with CommandContext

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();
        }
    });
}
Also used : Context(org.locationtech.geogig.api.Context) CommandContext(org.locationtech.geogig.web.api.CommandContext) Ref(org.locationtech.geogig.api.Ref) SymRef(org.locationtech.geogig.api.SymRef) SymRef(org.locationtech.geogig.api.SymRef) ConflictsReadOp(org.locationtech.geogig.api.plumbing.merge.ConflictsReadOp) ResponseWriter(org.locationtech.geogig.web.api.ResponseWriter) DiffIndex(org.locationtech.geogig.api.plumbing.DiffIndex) DiffWorkTree(org.locationtech.geogig.api.plumbing.DiffWorkTree) CommandResponse(org.locationtech.geogig.web.api.CommandResponse)

Example 14 with CommandContext

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();
        }
    });
}
Also used : Context(org.locationtech.geogig.api.Context) CommandContext(org.locationtech.geogig.web.api.CommandContext) NodeRef(org.locationtech.geogig.api.NodeRef) LsTreeOp(org.locationtech.geogig.api.plumbing.LsTreeOp) ResponseWriter(org.locationtech.geogig.web.api.ResponseWriter) CommandResponse(org.locationtech.geogig.web.api.CommandResponse)

Example 15 with CommandContext

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();
            }
        });
    }
}
Also used : Context(org.locationtech.geogig.api.Context) CommandContext(org.locationtech.geogig.web.api.CommandContext) PullOp(org.locationtech.geogig.api.porcelain.PullOp) Optional(com.google.common.base.Optional) CommandResponse(org.locationtech.geogig.web.api.CommandResponse) MergeScenarioReport(org.locationtech.geogig.api.plumbing.merge.MergeScenarioReport) PullResult(org.locationtech.geogig.api.porcelain.PullResult) MergeConflictsException(org.locationtech.geogig.api.porcelain.MergeConflictsException) SynchronizationException(org.locationtech.geogig.api.porcelain.SynchronizationException) SymRef(org.locationtech.geogig.api.SymRef) MergeConflictsException(org.locationtech.geogig.api.porcelain.MergeConflictsException) ResponseWriter(org.locationtech.geogig.web.api.ResponseWriter) RefParse(org.locationtech.geogig.api.plumbing.RefParse) DiffEntry(org.locationtech.geogig.api.plumbing.diff.DiffEntry) SynchronizationException(org.locationtech.geogig.api.porcelain.SynchronizationException) RevCommit(org.locationtech.geogig.api.RevCommit)

Aggregations

Context (org.locationtech.geogig.api.Context)24 CommandContext (org.locationtech.geogig.web.api.CommandContext)24 CommandResponse (org.locationtech.geogig.web.api.CommandResponse)24 ResponseWriter (org.locationtech.geogig.web.api.ResponseWriter)24 CommandSpecException (org.locationtech.geogig.web.api.CommandSpecException)15 ObjectId (org.locationtech.geogig.api.ObjectId)9 RevCommit (org.locationtech.geogig.api.RevCommit)7 NodeRef (org.locationtech.geogig.api.NodeRef)6 Ref (org.locationtech.geogig.api.Ref)6 DiffEntry (org.locationtech.geogig.api.plumbing.diff.DiffEntry)5 Optional (com.google.common.base.Optional)4 SymRef (org.locationtech.geogig.api.SymRef)4 RevFeature (org.locationtech.geogig.api.RevFeature)3 RevFeatureType (org.locationtech.geogig.api.RevFeatureType)3 RevTree (org.locationtech.geogig.api.RevTree)3 RefParse (org.locationtech.geogig.api.plumbing.RefParse)3 RevObjectParse (org.locationtech.geogig.api.plumbing.RevObjectParse)3 RevParse (org.locationtech.geogig.api.plumbing.RevParse)3 MergeScenarioReport (org.locationtech.geogig.api.plumbing.merge.MergeScenarioReport)3 Geometry (com.vividsolutions.jts.geom.Geometry)2