Line data Source code
1 : // Copyright (C) 2022 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.server.restapi.change; 16 : 17 : import static com.google.gerrit.server.project.ProjectCache.illegalState; 18 : 19 : import com.google.gerrit.entities.Comment.Range; 20 : import com.google.gerrit.entities.FixReplacement; 21 : import com.google.gerrit.entities.PatchSet; 22 : import com.google.gerrit.entities.Project; 23 : import com.google.gerrit.extensions.common.ApplyProvidedFixInput; 24 : import com.google.gerrit.extensions.common.EditInfo; 25 : import com.google.gerrit.extensions.restapi.AuthException; 26 : import com.google.gerrit.extensions.restapi.BadRequestException; 27 : import com.google.gerrit.extensions.restapi.ResourceConflictException; 28 : import com.google.gerrit.extensions.restapi.ResourceNotFoundException; 29 : import com.google.gerrit.extensions.restapi.Response; 30 : import com.google.gerrit.extensions.restapi.RestModifyView; 31 : import com.google.gerrit.server.change.RevisionResource; 32 : import com.google.gerrit.server.edit.ChangeEdit; 33 : import com.google.gerrit.server.edit.ChangeEditJson; 34 : import com.google.gerrit.server.edit.ChangeEditModifier; 35 : import com.google.gerrit.server.edit.CommitModification; 36 : import com.google.gerrit.server.fixes.FixReplacementInterpreter; 37 : import com.google.gerrit.server.git.GitRepositoryManager; 38 : import com.google.gerrit.server.notedb.ChangeNotes; 39 : import com.google.gerrit.server.permissions.PermissionBackendException; 40 : import com.google.gerrit.server.project.InvalidChangeOperationException; 41 : import com.google.gerrit.server.project.ProjectCache; 42 : import com.google.gerrit.server.project.ProjectState; 43 : import com.google.inject.Inject; 44 : import com.google.inject.Singleton; 45 : import java.io.IOException; 46 : import java.util.List; 47 : import java.util.stream.Collectors; 48 : import org.eclipse.jgit.lib.Repository; 49 : 50 : /** Applies a fix that is provided as part of the request body. */ 51 : @Singleton 52 : public class ApplyProvidedFix implements RestModifyView<RevisionResource, ApplyProvidedFixInput> { 53 : private final GitRepositoryManager gitRepositoryManager; 54 : private final FixReplacementInterpreter fixReplacementInterpreter; 55 : private final ChangeEditModifier changeEditModifier; 56 : private final ChangeEditJson changeEditJson; 57 : private final ProjectCache projectCache; 58 : 59 : @Inject 60 : public ApplyProvidedFix( 61 : GitRepositoryManager gitRepositoryManager, 62 : FixReplacementInterpreter fixReplacementInterpreter, 63 : ChangeEditModifier changeEditModifier, 64 : ChangeEditJson changeEditJson, 65 145 : ProjectCache projectCache) { 66 145 : this.gitRepositoryManager = gitRepositoryManager; 67 145 : this.fixReplacementInterpreter = fixReplacementInterpreter; 68 145 : this.changeEditModifier = changeEditModifier; 69 145 : this.changeEditJson = changeEditJson; 70 145 : this.projectCache = projectCache; 71 145 : } 72 : 73 : @Override 74 : public Response<EditInfo> apply( 75 : RevisionResource revisionResource, ApplyProvidedFixInput applyProvidedFixInput) 76 : throws AuthException, BadRequestException, ResourceConflictException, IOException, 77 : ResourceNotFoundException, PermissionBackendException { 78 2 : if (applyProvidedFixInput == null) { 79 1 : throw new BadRequestException("applyProvidedFixInput is required"); 80 : } 81 2 : if (applyProvidedFixInput.fixReplacementInfos == null) { 82 2 : throw new BadRequestException("applyProvidedFixInput.fixReplacementInfos is required"); 83 : } 84 1 : Project.NameKey project = revisionResource.getProject(); 85 1 : ProjectState projectState = projectCache.get(project).orElseThrow(illegalState(project)); 86 1 : PatchSet patchSet = revisionResource.getPatchSet(); 87 : 88 1 : ChangeNotes changeNotes = revisionResource.getNotes(); 89 : 90 1 : List<FixReplacement> fixReplacements = 91 1 : applyProvidedFixInput.fixReplacementInfos.stream() 92 1 : .map(fix -> new FixReplacement(fix.path, new Range(fix.range), fix.replacement)) 93 1 : .collect(Collectors.toList()); 94 : 95 1 : try (Repository repository = gitRepositoryManager.openRepository(project)) { 96 1 : CommitModification commitModification = 97 1 : fixReplacementInterpreter.toCommitModification( 98 1 : repository, projectState, patchSet.commitId(), fixReplacements); 99 1 : ChangeEdit changeEdit = 100 1 : changeEditModifier.combineWithModifiedPatchSetTree( 101 : repository, changeNotes, patchSet, commitModification); 102 : 103 1 : return Response.ok(changeEditJson.toEditInfo(changeEdit, false)); 104 1 : } catch (InvalidChangeOperationException e) { 105 1 : throw new ResourceConflictException(e.getMessage()); 106 : } 107 : } 108 : }