Add new CHANGE_ACTIONS option to /changes/X/detail REST API call

This will move action related JSON processing into the ActionJson class
as well.

Change-Id: I291727762d2f08d00484ca8ce8805624042ab4e8
This commit is contained in:
Stefan Beller
2015-02-12 13:40:23 -08:00
committed by David Pursehouse
parent c725966f8b
commit 09cd95dbfd
4 changed files with 69 additions and 39 deletions

View File

@@ -281,8 +281,15 @@ default. Optional fields are:
[[actions]]
--
* `CURRENT_ACTIONS`: include information on available actions
for the change and its current revision. The caller must be
authenticated to obtain the available actions.
for the change and its current revision. Ignored if the caller
is not authenticated.
--
[[change-actions]]
--
* `CHANGE_ACTIONS`: include information on available
change actions for the change. Ignored if the caller
is not authenticated.
--
[[reviewed]]

View File

@@ -55,7 +55,10 @@ public enum ListChangesOption {
WEB_LINKS(14),
/** Include consistency check results. */
CHECK(15);
CHECK(15),
/** Include allowed change actions client could perform. */
CHANGE_ACTIONS(16);
private final int value;

View File

@@ -15,9 +15,15 @@
package com.google.gerrit.server.change;
import com.google.gerrit.extensions.common.ActionInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.RevisionInfo;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.extensions.webui.PrivateInternals_UiActionDescription;
import com.google.gerrit.extensions.webui.UiAction;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.extensions.webui.UiActions;
import com.google.gerrit.server.project.ChangeControl;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@@ -29,16 +35,55 @@ import java.util.Map;
@Singleton
public class ActionJson {
private final Revisions revisions;
private final DynamicMap<RestView<ChangeResource>> changeViews;
@Inject
ActionJson(Revisions revisions) {
ActionJson(
Revisions revisions,
DynamicMap<RestView<ChangeResource>> changeViews) {
this.revisions = revisions;
this.changeViews = changeViews;
}
public Map<String, ActionInfo> format(RevisionResource rsrc) {
return toActionMap(rsrc);
}
public ChangeInfo addChangeActions(ChangeInfo to, ChangeControl ctl) {
to.actions = toActionMap(ctl);
return to;
}
public RevisionInfo addRevisionActions(RevisionInfo to,
RevisionResource rsrc) {
to.actions = toActionMap(rsrc);
return to;
}
private Map<String, ActionInfo> toActionMap(ChangeControl ctl) {
Map<String, ActionInfo> out = new LinkedHashMap<>();
if (!ctl.getCurrentUser().isIdentifiedUser()) {
return out;
}
Provider<CurrentUser> userProvider = Providers.of(ctl.getCurrentUser());
for (UiAction.Description d : UiActions.from(
changeViews,
new ChangeResource(ctl),
userProvider)) {
out.put(d.getId(), new ActionInfo(d));
}
// TODO(sbeller): why do we need to treat followup specially here?
if (ctl.getChange().getStatus().isOpen()) {
UiAction.Description descr = new UiAction.Description();
PrivateInternals_UiActionDescription.setId(descr, "followup");
PrivateInternals_UiActionDescription.setMethod(descr, "POST");
descr.setTitle("Create follow-up change");
out.put(descr.getId(), new ActionInfo(descr));
}
return out;
}
private Map<String, ActionInfo> toActionMap(RevisionResource rsrc) {
Map<String, ActionInfo> out = new LinkedHashMap<>();
if (rsrc.getControl().getCurrentUser().isIdentifiedUser()) {

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.server.change;
import static com.google.gerrit.extensions.client.ListChangesOption.ALL_COMMITS;
import static com.google.gerrit.extensions.client.ListChangesOption.ALL_FILES;
import static com.google.gerrit.extensions.client.ListChangesOption.ALL_REVISIONS;
import static com.google.gerrit.extensions.client.ListChangesOption.CHANGE_ACTIONS;
import static com.google.gerrit.extensions.client.ListChangesOption.CHECK;
import static com.google.gerrit.extensions.client.ListChangesOption.CURRENT_ACTIONS;
import static com.google.gerrit.extensions.client.ListChangesOption.CURRENT_COMMIT;
@@ -59,7 +60,6 @@ import com.google.gerrit.common.data.SubmitRecord;
import com.google.gerrit.extensions.api.changes.FixInput;
import com.google.gerrit.extensions.client.ListChangesOption;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ActionInfo;
import com.google.gerrit.extensions.common.ApprovalInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.ChangeMessageInfo;
@@ -73,10 +73,7 @@ import com.google.gerrit.extensions.common.WebLinkInfo;
import com.google.gerrit.extensions.config.DownloadCommand;
import com.google.gerrit.extensions.config.DownloadScheme;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.extensions.webui.PrivateInternals_UiActionDescription;
import com.google.gerrit.extensions.webui.UiAction;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.ChangeMessage;
@@ -95,7 +92,6 @@ import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.PatchLineCommentsUtil;
import com.google.gerrit.server.WebLinks;
import com.google.gerrit.server.account.AccountLoader;
import com.google.gerrit.server.extensions.webui.UiActions;
import com.google.gerrit.server.git.LabelNormalizer;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
@@ -140,13 +136,12 @@ public class ChangeJson {
private final AccountLoader.Factory accountLoaderFactory;
private final DynamicMap<DownloadScheme> downloadSchemes;
private final DynamicMap<DownloadCommand> downloadCommands;
private final DynamicMap<RestView<ChangeResource>> changeViews;
private final Revisions revisions;
private final WebLinks webLinks;
private final EnumSet<ListChangesOption> options;
private final ChangeMessagesUtil cmUtil;
private final PatchLineCommentsUtil plcUtil;
private final Provider<ConsistencyChecker> checkerProvider;
private final ActionJson actionJson;
private AccountLoader accountLoader;
private FixInput fix;
@@ -164,12 +159,11 @@ public class ChangeJson {
AccountLoader.Factory ailf,
DynamicMap<DownloadScheme> downloadSchemes,
DynamicMap<DownloadCommand> downloadCommands,
DynamicMap<RestView<ChangeResource>> changeViews,
Revisions revisions,
WebLinks webLinks,
ChangeMessagesUtil cmUtil,
PatchLineCommentsUtil plcUtil,
Provider<ConsistencyChecker> checkerProvider) {
Provider<ConsistencyChecker> checkerProvider,
ActionJson actionJson) {
this.db = db;
this.labelNormalizer = ln;
this.userProvider = user;
@@ -181,12 +175,11 @@ public class ChangeJson {
this.accountLoaderFactory = ailf;
this.downloadSchemes = downloadSchemes;
this.downloadCommands = downloadCommands;
this.changeViews = changeViews;
this.revisions = revisions;
this.webLinks = webLinks;
this.cmUtil = cmUtil;
this.plcUtil = plcUtil;
this.checkerProvider = checkerProvider;
this.actionJson = actionJson;
options = EnumSet.noneOf(ListChangesOption.class);
}
@@ -419,22 +412,8 @@ public class ChangeJson {
}
}
if (has(CURRENT_ACTIONS) && userProvider.get().isIdentifiedUser()) {
out.actions = Maps.newTreeMap();
for (UiAction.Description d : UiActions.from(
changeViews,
new ChangeResource(ctl),
userProvider)) {
out.actions.put(d.getId(), new ActionInfo(d));
}
if (userProvider.get().isIdentifiedUser()
&& in.getStatus().isOpen()) {
UiAction.Description descr = new UiAction.Description();
PrivateInternals_UiActionDescription.setId(descr, "followup");
PrivateInternals_UiActionDescription.setMethod(descr, "POST");
descr.setTitle("Create follow-up change");
out.actions.put(descr.getId(), new ActionInfo(descr));
}
if (has(CURRENT_ACTIONS) || has(CHANGE_ACTIONS)) {
actionJson.addChangeActions(out, ctl);
}
return out;
@@ -907,13 +886,9 @@ public class ChangeJson {
if ((out.isCurrent || (out.draft != null && out.draft))
&& has(CURRENT_ACTIONS)
&& userProvider.get().isIdentifiedUser()) {
out.actions = Maps.newTreeMap();
for (UiAction.Description d : UiActions.from(
revisions,
new RevisionResource(new ChangeResource(ctl), in),
userProvider)) {
out.actions.put(d.getId(), new ActionInfo(d));
}
actionJson.addRevisionActions(out,
new RevisionResource(new ChangeResource(ctl), in));
}
if (has(DRAFT_COMMENTS)