| // Copyright (C) 2009 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package com.google.gerrit.server; |
| |
| import com.google.gerrit.client.changes.ChangeManageService; |
| import com.google.gerrit.client.data.ApprovalType; |
| import com.google.gerrit.client.reviewdb.Account; |
| import com.google.gerrit.client.reviewdb.ApprovalCategory; |
| import com.google.gerrit.client.reviewdb.ApprovalCategoryValue; |
| import com.google.gerrit.client.reviewdb.Change; |
| import com.google.gerrit.client.reviewdb.ChangeApproval; |
| import com.google.gerrit.client.reviewdb.PatchSet; |
| import com.google.gerrit.client.reviewdb.ReviewDb; |
| import com.google.gerrit.client.rpc.BaseServiceImplementation; |
| import com.google.gerrit.client.rpc.Common; |
| import com.google.gerrit.client.rpc.NoSuchEntityException; |
| import com.google.gerrit.client.workflow.FunctionState; |
| import com.google.gerrit.git.MergeQueue; |
| import com.google.gwt.user.client.rpc.AsyncCallback; |
| import com.google.gwtjsonrpc.client.VoidResult; |
| import com.google.gwtorm.client.OrmException; |
| import com.google.gwtorm.client.Transaction; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| |
| public class ChangeManageServiceImpl extends BaseServiceImplementation |
| implements ChangeManageService { |
| |
| public void patchSetAction(final ApprovalCategoryValue.Id value, |
| final PatchSet.Id patchSetId, final AsyncCallback<VoidResult> callback) { |
| run(callback, new Action<VoidResult>() { |
| public VoidResult run(final ReviewDb db) throws OrmException, Failure { |
| final Change change = db.changes().get(patchSetId.getParentKey()); |
| if (change == null) { |
| throw new Failure(new NoSuchEntityException()); |
| } |
| |
| if (!patchSetId.equals(change.currentPatchSetId())) { |
| throw new Failure(new IllegalStateException("Patch set " + patchSetId |
| + " not current")); |
| } |
| if (change.getStatus().isClosed()) { |
| throw new Failure(new IllegalStateException("Change" + change.getId() |
| + " is closed")); |
| } |
| |
| final List<ChangeApproval> allApprovals = |
| new ArrayList<ChangeApproval>(db.changeApprovals().byChange( |
| change.getId()).toList()); |
| |
| final Account.Id me = Common.getAccountId(); |
| final ChangeApproval.Key ak = |
| new ChangeApproval.Key(change.getId(), me, value.getParentKey()); |
| ChangeApproval myAction = null; |
| boolean isnew = true; |
| for (final ChangeApproval ca : allApprovals) { |
| if (ak.equals(ca.getKey())) { |
| isnew = false; |
| myAction = ca; |
| myAction.setValue(value.get()); |
| myAction.setGranted(); |
| break; |
| } |
| } |
| if (myAction == null) { |
| myAction = new ChangeApproval(ak, value.get()); |
| allApprovals.add(myAction); |
| } |
| |
| final ApprovalType actionType = |
| Common.getGerritConfig().getApprovalType(myAction.getCategoryId()); |
| if (actionType == null || !actionType.getCategory().isAction()) { |
| throw new Failure(new IllegalArgumentException(actionType |
| .getCategory().getName() |
| + " not an action")); |
| } |
| |
| final FunctionState fs = new FunctionState(change, allApprovals); |
| for (ApprovalType c : Common.getGerritConfig().getApprovalTypes()) { |
| c.getCategory().getFunction().run(c, fs); |
| } |
| if (!actionType.getCategory().getFunction().isValid(me, actionType, fs)) { |
| throw new Failure(new IllegalStateException(actionType.getCategory() |
| .getName() |
| + " not permitted")); |
| } |
| fs.normalize(actionType, myAction); |
| if (myAction.getValue() <= 0) { |
| throw new Failure(new IllegalStateException(actionType.getCategory() |
| .getName() |
| + " not permitted")); |
| } |
| |
| if (ApprovalCategory.SUBMIT.equals(actionType.getCategory().getId())) { |
| if (change.getStatus() == Change.Status.NEW) { |
| change.setStatus(Change.Status.SUBMITTED); |
| ChangeUtil.updated(change); |
| } |
| } else { |
| throw new Failure(new IllegalArgumentException(actionType |
| .getCategory().getName() |
| + " cannot be perfomed by Gerrit")); |
| } |
| |
| final Transaction txn = db.beginTransaction(); |
| db.changes().update(Collections.singleton(change), txn); |
| if (change.getStatus().isClosed()) { |
| db.changeApprovals().update(fs.getDirtyChangeApprovals(), txn); |
| } |
| if (isnew) { |
| db.changeApprovals().insert(Collections.singleton(myAction), txn); |
| } else { |
| db.changeApprovals().update(Collections.singleton(myAction), txn); |
| } |
| txn.commit(); |
| |
| if (change.getStatus() == Change.Status.SUBMITTED) { |
| MergeQueue.merge(change.getDest()); |
| } |
| |
| return VoidResult.INSTANCE; |
| } |
| }); |
| } |
| } |