Search in sources :

Example 1 with PatchSet

use of com.google.gerrit.entities.PatchSet in project gerrit by GerritCodeReview.

the class CatServlet method doGet.

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
    String keyStr = req.getPathInfo();
    // We shouldn't have to do this extra decode pass, but somehow we
    // are now receiving our "^1" suffix as "%5E1", which confuses us
    // downstream. Other times we get our embedded "," as "%2C", which
    // is equally bad. And yet when these happen a "%2F" is left as-is,
    // rather than escaped as "%252F", which makes me feel really really
    // uncomfortable with a blind decode right here.
    // 
    keyStr = Url.decode(keyStr);
    if (!keyStr.startsWith("/")) {
        rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }
    keyStr = keyStr.substring(1);
    final Patch.Key patchKey;
    final int side;
    {
        final int c = keyStr.lastIndexOf('^');
        if (c == 0) {
            rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        if (c < 0) {
            side = 0;
        } else {
            try {
                side = Integer.parseInt(keyStr.substring(c + 1));
                keyStr = keyStr.substring(0, c);
            } catch (NumberFormatException e) {
                rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
                return;
            }
        }
        try {
            patchKey = Patch.Key.parse(keyStr);
        } catch (NumberFormatException e) {
            rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
    }
    final Change.Id changeId = patchKey.patchSetId().changeId();
    String revision;
    try {
        ChangeNotes notes = changeNotesFactory.createCheckedUsingIndexLookup(changeId);
        permissionBackend.currentUser().change(notes).check(ChangePermission.READ);
        projectCache.get(notes.getProjectName()).orElseThrow(illegalState(notes.getProjectName())).checkStatePermitsRead();
        if (patchKey.patchSetId().get() == 0) {
            // change edit
            Optional<ChangeEdit> edit = changeEditUtil.byChange(notes);
            if (edit.isPresent()) {
                revision = ObjectId.toString(edit.get().getEditCommit());
            } else {
                rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
                return;
            }
        } else {
            PatchSet patchSet = psUtil.get(notes, patchKey.patchSetId());
            if (patchSet == null) {
                rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
                return;
            }
            revision = patchSet.commitId().name();
        }
    } catch (ResourceConflictException | NoSuchChangeException | AuthException e) {
        rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    } catch (PermissionBackendException | IOException e) {
        getServletContext().log("Cannot query database", e);
        rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return;
    }
    String path = patchKey.fileName();
    String restUrl = String.format("%s/changes/%d/revisions/%s/files/%s/download?parent=%d", req.getContextPath(), changeId.get(), revision, Url.encode(path), side);
    rsp.sendRedirect(restUrl);
}
Also used : ChangeEdit(com.google.gerrit.server.edit.ChangeEdit) AuthException(com.google.gerrit.extensions.restapi.AuthException) PatchSet(com.google.gerrit.entities.PatchSet) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) Change(com.google.gerrit.entities.Change) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) IOException(java.io.IOException) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) NoSuchChangeException(com.google.gerrit.server.project.NoSuchChangeException) Patch(com.google.gerrit.entities.Patch)

Example 2 with PatchSet

use of com.google.gerrit.entities.PatchSet in project gerrit by GerritCodeReview.

the class PublishCommentsOp method postUpdate.

@Override
public void postUpdate(PostUpdateContext ctx) {
    if (Strings.isNullOrEmpty(mailMessage) || comments.isEmpty()) {
        return;
    }
    ChangeNotes changeNotes = changeNotesFactory.createChecked(projectNameKey, psId.changeId());
    PatchSet ps = psUtil.get(changeNotes, psId);
    NotifyResolver.Result notify = ctx.getNotify(changeNotes.getChangeId());
    if (notify.shouldNotify()) {
        RepoView repoView;
        try {
            repoView = ctx.getRepoView();
        } catch (IOException ex) {
            throw new StorageException(String.format("Repository %s not found", ctx.getProject().get()), ex);
        }
        email.create(notify, changeNotes, ps, user, mailMessage, ctx.getWhen(), comments, null, labelDelta, repoView).sendAsync();
    }
    commentAdded.fire(ctx.getChangeData(changeNotes), ps, ctx.getAccount(), mailMessage, ImmutableMap.of(), ImmutableMap.of(), ctx.getWhen());
}
Also used : NotifyResolver(com.google.gerrit.server.change.NotifyResolver) PatchSet(com.google.gerrit.entities.PatchSet) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) IOException(java.io.IOException) StorageException(com.google.gerrit.exceptions.StorageException) RepoView(com.google.gerrit.server.update.RepoView)

Example 3 with PatchSet

use of com.google.gerrit.entities.PatchSet in project gerrit by GerritCodeReview.

the class PublishCommentUtil method publish.

public void publish(ChangeContext ctx, ChangeUpdate changeUpdate, Collection<HumanComment> draftComments, @Nullable String tag) {
    ChangeNotes notes = ctx.getNotes();
    checkArgument(notes != null);
    if (draftComments.isEmpty()) {
        return;
    }
    Map<PatchSet.Id, PatchSet> patchSets = psUtil.getAsMap(notes, draftComments.stream().map(d -> psId(notes, d)).collect(toSet()));
    Set<HumanComment> commentsToPublish = new HashSet<>();
    for (HumanComment draftComment : draftComments) {
        PatchSet.Id psIdOfDraftComment = psId(notes, draftComment);
        PatchSet ps = patchSets.get(psIdOfDraftComment);
        if (ps == null) {
            // This can happen if changes with the same numeric ID exist:
            // - change 12345 has 3 patch sets in repo X
            // - another change 12345 has 7 patch sets in repo Y
            // - the user saves a draft comment on patch set 6 of the change in repo Y
            // - this draft comment gets stored in:
            // AllUsers -> refs/draft-comments/45/12345/<account-id>
            // - when posting a review with draft handling PUBLISH_ALL_REVISIONS on the change in
            // repo X, the draft comments are loaded from
            // AllUsers -> refs/draft-comments/45/12345/<account-id>, including the draft
            // comment that was saved for patch set 6 of the change in repo Y
            // - patch set 6 does not exist for the change in repo x, hence we get null for the patch
            // set here
            // Instead of failing hard (and returning an Internal Server Error) to the caller,
            // just ignore that comment.
            // Gerrit ensures that numeric change IDs are unique, but you can get duplicates if
            // change refs of one repo are copied/pushed to another repo on the same host (this
            // should never be done, but we know it happens).
            logger.atWarning().log("Ignoring draft comment %s on non existing patch set %s (repo = %s)", draftComment, psIdOfDraftComment, notes.getProjectName());
            continue;
        }
        draftComment.writtenOn = Timestamp.from(ctx.getWhen());
        draftComment.tag = tag;
        // Draft may have been created by a different real user; copy the current real user. (Only
        // applies to X-Gerrit-RunAs, since modifying drafts via on_behalf_of is not allowed.)
        ctx.getUser().updateRealAccountId(draftComment::setRealAuthor);
        commentsUtil.setCommentCommitId(draftComment, notes.getChange(), ps);
        commentsToPublish.add(draftComment);
    }
    commentsUtil.putHumanComments(changeUpdate, HumanComment.Status.PUBLISHED, commentsToPublish);
}
Also used : PatchSet(com.google.gerrit.entities.PatchSet) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) HumanComment(com.google.gerrit.entities.HumanComment) HashSet(java.util.HashSet)

Example 4 with PatchSet

use of com.google.gerrit.entities.PatchSet in project gerrit by GerritCodeReview.

the class ChangeJson method loadPatchSets.

private Map<PatchSet.Id, PatchSet> loadPatchSets(ChangeData cd, Optional<PatchSet.Id> limitToPsId) {
    Collection<PatchSet> src;
    if (has(ALL_REVISIONS) || has(MESSAGES)) {
        src = cd.patchSets();
    } else {
        PatchSet ps;
        if (limitToPsId.isPresent()) {
            ps = cd.patchSet(limitToPsId.get());
            if (ps == null) {
                throw new StorageException("missing patch set " + limitToPsId.get());
            }
        } else {
            ps = cd.currentPatchSet();
            if (ps == null) {
                throw new StorageException("missing current patch set for change " + cd.getId());
            }
        }
        src = Collections.singletonList(ps);
    }
    Map<PatchSet.Id, PatchSet> map = Maps.newHashMapWithExpectedSize(src.size());
    for (PatchSet patchSet : src) {
        map.put(patchSet.id(), patchSet);
    }
    return map;
}
Also used : PatchSet(com.google.gerrit.entities.PatchSet) ObjectId(org.eclipse.jgit.lib.ObjectId) StorageException(com.google.gerrit.exceptions.StorageException)

Example 5 with PatchSet

use of com.google.gerrit.entities.PatchSet in project gerrit by GerritCodeReview.

the class GroupCollector method create.

/**
 * Returns a new {@link GroupCollector} instance.
 *
 * @see GroupCollector for what this class does.
 */
public static GroupCollector create(ReceivePackRefCache receivePackRefCache, PatchSetUtil psUtil, ChangeNotes.Factory notesFactory, Project.NameKey project) {
    return new GroupCollector(receivePackRefCache, psId -> {
        // TODO(dborowitz): Reuse open repository from caller.
        ChangeNotes notes = notesFactory.createChecked(project, psId.changeId());
        PatchSet ps = psUtil.get(notes, psId);
        return ps != null ? ps.groups() : null;
    });
}
Also used : PatchSet(com.google.gerrit.entities.PatchSet) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes)

Aggregations

PatchSet (com.google.gerrit.entities.PatchSet)123 Change (com.google.gerrit.entities.Change)61 Test (org.junit.Test)48 ChangeNotes (com.google.gerrit.server.notedb.ChangeNotes)41 ObjectId (org.eclipse.jgit.lib.ObjectId)35 RevCommit (org.eclipse.jgit.revwalk.RevCommit)29 AbstractDaemonTest (com.google.gerrit.acceptance.AbstractDaemonTest)28 Project (com.google.gerrit.entities.Project)25 StorageException (com.google.gerrit.exceptions.StorageException)25 Repository (org.eclipse.jgit.lib.Repository)22 IOException (java.io.IOException)20 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)19 ChangeData (com.google.gerrit.server.query.change.ChangeData)18 HumanComment (com.google.gerrit.entities.HumanComment)16 RevWalk (org.eclipse.jgit.revwalk.RevWalk)16 Inject (com.google.inject.Inject)14 Map (java.util.Map)14 List (java.util.List)13 ImmutableList (com.google.common.collect.ImmutableList)12 AuthException (com.google.gerrit.extensions.restapi.AuthException)11