Use new REST API to show and add included groups in WebUI

Another step to port the group related screens of the WebUI to the new
REST API.

The old RPC to add included groups was removed as it is now not used
anymore.

Change-Id: I9b364c221609a50d694e9d3fad1d3a2fa8f58f8b
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
This commit is contained in:
Edwin Kempin
2013-01-31 15:31:52 +01:00
committed by David Pursehouse
parent df8449be82
commit 6a09040248
8 changed files with 86 additions and 122 deletions

View File

@@ -39,9 +39,4 @@ public interface GroupAdminService extends RemoteJsonService {
@SignInRequired
void changeGroupOptions(AccountGroup.Id groupId, GroupOptions groupOptions,
AsyncCallback<VoidResult> callback);
@Audit
@SignInRequired
void addGroupInclude(AccountGroup.Id groupId, AccountGroup.UUID incGroupUUID,
String incGroupName, AsyncCallback<GroupDetail> callback);
}

View File

@@ -22,7 +22,6 @@ import java.util.List;
public class GroupDetail {
public AccountInfoCache accounts;
public GroupInfoCache groups;
public AccountGroup group;
public List<AccountGroupMember> members;
public List<AccountGroupIncludeByUuid> includes;
@@ -36,10 +35,6 @@ public class GroupDetail {
accounts = c;
}
public void setGroups(GroupInfoCache c) {
groups = c;
}
public void setGroup(AccountGroup g) {
group = g;
}

View File

@@ -18,6 +18,8 @@ import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.VoidResult;
import com.google.gerrit.client.groups.GroupApi;
import com.google.gerrit.client.groups.GroupInfo;
import com.google.gerrit.client.groups.GroupList;
import com.google.gerrit.client.groups.MemberInfo;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.AccountGroupSuggestOracle;
@@ -28,11 +30,8 @@ import com.google.gerrit.client.ui.Hyperlink;
import com.google.gerrit.client.ui.SmallHeading;
import com.google.gerrit.common.data.AccountInfoCache;
import com.google.gerrit.common.data.GroupDetail;
import com.google.gerrit.common.data.GroupInfo;
import com.google.gerrit.common.data.GroupInfoCache;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.AccountGroupIncludeByUuid;
import com.google.gerrit.reviewdb.client.AccountGroupMember;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
@@ -43,13 +42,13 @@ import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Panel;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
public class AccountGroupMembersScreen extends AccountGroupScreen {
private AccountInfoCache accounts = AccountInfoCache.empty();
private GroupInfoCache groups = GroupInfoCache.empty();
private MemberTable members;
private IncludeTable includes;
@@ -113,15 +112,14 @@ public class AccountGroupMembersScreen extends AccountGroupScreen {
}
private void initIncludeList() {
final AccountGroupSuggestOracle oracle = new AccountGroupSuggestOracle();
addIncludeBox =
new AddMemberBox(Util.C.buttonAddIncludedGroup(),
Util.C.defaultAccountGroupName(), oracle);
new AddMemberBox(Util.C.buttonAddIncludedGroup(),
Util.C.defaultAccountGroupName(), new AccountGroupSuggestOracle());
addIncludeBox.addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent event) {
doAddNewInclude(oracle);
doAddNewInclude();
}
});
@@ -156,9 +154,15 @@ public class AccountGroupMembersScreen extends AccountGroupScreen {
switch (groupDetail.group.getType()) {
case INTERNAL:
accounts = groupDetail.accounts;
groups = groupDetail.groups;
members.display(groupDetail.members);
includes.display(groupDetail.includes);
GroupList.included(getGroupUUID(), new GerritCallback<GroupList>() {
@Override
public void onSuccess(GroupList result) {
includes.display(result.asList());
}
});
break;
default:
memberPanel.setVisible(false);
@@ -193,22 +197,19 @@ public class AccountGroupMembersScreen extends AccountGroupScreen {
});
}
void doAddNewInclude(final AccountGroupSuggestOracle oracle) {
void doAddNewInclude() {
final String groupName = addIncludeBox.getText();
if (groupName.length() == 0) {
return;
}
addIncludeBox.setEnabled(false);
Util.GROUP_SVC.addGroupInclude(getGroupId(), oracle.getUUID(groupName), groupName,
new GerritCallback<GroupDetail>() {
public void onSuccess(final GroupDetail result) {
GroupApi.addIncludedGroup(getGroupUUID(), groupName,
new GerritCallback<GroupInfo>() {
public void onSuccess(final GroupInfo result) {
addIncludeBox.setEnabled(true);
addIncludeBox.setText("");
if (result.groups != null && result.includes != null) {
groups.merge(result.groups);
includes.display(result.includes);
}
includes.insert(result);
}
@Override
@@ -296,7 +297,7 @@ public class AccountGroupMembersScreen extends AccountGroupScreen {
}
}
private class IncludeTable extends FancyFlexTable<AccountGroupIncludeByUuid> {
private class IncludeTable extends FancyFlexTable<GroupInfo> {
private boolean enabled = true;
IncludeTable() {
@@ -312,29 +313,28 @@ public class AccountGroupMembersScreen extends AccountGroupScreen {
void setEnabled(final boolean enabled) {
this.enabled = enabled;
for (int row = 1; row < table.getRowCount(); row++) {
final AccountGroupIncludeByUuid k = getRowItem(row);
if (k != null) {
final GroupInfo i = getRowItem(row);
if (i != null) {
((CheckBox) table.getWidget(row, 1)).setEnabled(enabled);
}
}
}
void deleteChecked() {
final HashSet<AccountGroupIncludeByUuid.Key> keys =
new HashSet<AccountGroupIncludeByUuid.Key>();
final HashSet<AccountGroup.UUID> ids = new HashSet<AccountGroup.UUID>();
for (int row = 1; row < table.getRowCount(); row++) {
final AccountGroupIncludeByUuid k = getRowItem(row);
if (k != null && ((CheckBox) table.getWidget(row, 1)).getValue()) {
keys.add(k.getKey());
final GroupInfo i = getRowItem(row);
if (i != null && ((CheckBox) table.getWidget(row, 1)).getValue()) {
ids.add(i.getGroupUUID());
}
}
if (!keys.isEmpty()) {
GroupApi.removeIncludedGroups(getGroupUUID(), keys,
if (!ids.isEmpty()) {
GroupApi.removeIncludedGroups(getGroupUUID(), ids,
new GerritCallback<VoidResult>() {
public void onSuccess(final VoidResult result) {
for (int row = 1; row < table.getRowCount();) {
final AccountGroupIncludeByUuid k = getRowItem(row);
if (k != null && keys.contains(k.getKey())) {
final GroupInfo i = getRowItem(row);
if (i != null && ids.contains(i.getGroupUUID())) {
table.removeRow(row);
} else {
row++;
@@ -345,40 +345,72 @@ public class AccountGroupMembersScreen extends AccountGroupScreen {
}
}
void display(final List<AccountGroupIncludeByUuid> result) {
void display(List<GroupInfo> list) {
while (1 < table.getRowCount())
table.removeRow(table.getRowCount() - 1);
for (final AccountGroupIncludeByUuid k : result) {
for (final GroupInfo i : list) {
final int row = table.getRowCount();
table.insertRow(row);
applyDataRowStyle(row);
populate(row, k);
populate(row, i);
}
}
void populate(final int row, final AccountGroupIncludeByUuid k) {
void insert(GroupInfo info) {
Comparator<GroupInfo> c = new Comparator<GroupInfo>() {
@Override
public int compare(GroupInfo a, GroupInfo b) {
int cmp = nullToEmpty(a.name()).compareTo(nullToEmpty(b.name()));
if (cmp != 0) {
return cmp;
}
return a.getGroupUUID().compareTo(b.getGroupUUID());
}
public String nullToEmpty(String str) {
return str == null ? "" : str;
}
};
for (int row = 1; row < table.getRowCount(); row++) {
final GroupInfo i = getRowItem(row);
if (i != null) {
if (c.compare(info, i) < 0) {
table.insertRow(row);
applyDataRowStyle(row);
populate(row, info);
return;
}
}
}
final int row = table.getRowCount();
table.insertRow(row);
applyDataRowStyle(row);
populate(row, info);
}
void populate(final int row, final GroupInfo i) {
final FlexCellFormatter fmt = table.getFlexCellFormatter();
AccountGroup.UUID uuid = k.getIncludeUUID();
GroupInfo info = groups.get(uuid);
AccountGroup.UUID uuid = i.getGroupUUID();
CheckBox checkBox = new CheckBox();
table.setWidget(row, 1, checkBox);
checkBox.setEnabled(enabled);
if (AccountGroup.isInternalGroup(uuid)) {
table.setWidget(row, 2,
new Hyperlink(info.getName(), Dispatcher.toGroup(uuid)));
new Hyperlink(i.name(), Dispatcher.toGroup(uuid)));
fmt.getElement(row, 2).setTitle(null);
table.setText(row, 3, info.getDescription());
} else if (info.getUrl() != null) {
table.setText(row, 3, i.description());
} else if (i.url() != null) {
Anchor a = new Anchor();
a.setText(info.getName());
a.setHref(info.getUrl());
a.setText(i.name());
a.setHref(i.url());
a.setTitle("UUID " + uuid.get());
table.setWidget(row, 2, a);
fmt.getElement(row, 2).setTitle(null);
} else {
table.setText(row, 2, info.getName());
table.setText(row, 2, i.name());
fmt.getElement(row, 2).setTitle("UUID " + uuid.get());
}
@@ -386,7 +418,7 @@ public class AccountGroupMembersScreen extends AccountGroupScreen {
fmt.addStyleName(row, 2, Gerrit.RESOURCES.css().dataCell());
fmt.addStyleName(row, 3, Gerrit.RESOURCES.css().dataCell());
setRowItem(row, k);
setRowItem(row, i);
}
}
}

View File

@@ -19,7 +19,6 @@ import com.google.gerrit.client.rpc.NativeList;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.AccountGroupIncludeByUuid;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.rpc.AsyncCallback;
@@ -148,14 +147,14 @@ public class GroupApi {
/** Remove included groups from a group. */
public static void removeIncludedGroups(AccountGroup.UUID group,
Set<AccountGroupIncludeByUuid.Key> ids, final AsyncCallback<VoidResult> cb) {
Set<AccountGroup.UUID> ids, final AsyncCallback<VoidResult> cb) {
if (ids.size() == 1) {
AccountGroupIncludeByUuid.Key g = ids.iterator().next();
groups(group).id(g.getIncludeUUID().get()).delete(cb);
AccountGroup.UUID g = ids.iterator().next();
groups(group).id(g.get()).delete(cb);
} else {
IncludedGroupInput in = IncludedGroupInput.create();
for (AccountGroupIncludeByUuid.Key g : ids) {
in.add_group(g.getIncludeUUID().get());
for (AccountGroup.UUID g : ids) {
in.add_group(g.get());
}
group(group).view("groups.delete").post(in, cb);
}

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.client.groups;
import com.google.gerrit.client.rpc.NativeList;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gwt.user.client.rpc.AsyncCallback;
/** Groups available from {@code /groups/} or {@code /accounts/{id}/groups}. */
@@ -24,6 +25,11 @@ public class GroupList extends NativeList<GroupInfo> {
new RestApi("/accounts/self/groups").get(callback);
}
public static void included(AccountGroup.UUID group,
AsyncCallback<GroupList> callback) {
new RestApi("/groups/").id(group.get()).view("groups").get(callback);
}
protected GroupList() {
}
}

View File

@@ -17,18 +17,13 @@ package com.google.gerrit.httpd.rpc.account;
import com.google.gerrit.common.data.GroupAdminService;
import com.google.gerrit.common.data.GroupDetail;
import com.google.gerrit.common.data.GroupOptions;
import com.google.gerrit.common.errors.NameAlreadyUsedException;
import com.google.gerrit.common.errors.NoSuchEntityException;
import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.httpd.rpc.BaseServiceImplementation;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.AccountGroupIncludeByUuid;
import com.google.gerrit.reviewdb.client.AccountGroupIncludeByUuidAudit;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.account.GroupControl;
import com.google.gerrit.server.account.GroupIncludeCache;
import com.google.gwtjsonrpc.common.AsyncCallback;
import com.google.gwtjsonrpc.common.VoidResult;
import com.google.gwtorm.server.OrmException;
@@ -40,7 +35,6 @@ import java.util.Collections;
class GroupAdminServiceImpl extends BaseServiceImplementation implements
GroupAdminService {
private final GroupCache groupCache;
private final GroupIncludeCache groupIncludeCache;
private final GroupControl.Factory groupControlFactory;
private final GroupDetailHandler.Factory groupDetailFactory;
@@ -48,12 +42,10 @@ class GroupAdminServiceImpl extends BaseServiceImplementation implements
@Inject
GroupAdminServiceImpl(final Provider<ReviewDb> schema,
final Provider<IdentifiedUser> currentUser,
final GroupIncludeCache groupIncludeCache,
final GroupCache groupCache,
final GroupControl.Factory groupControlFactory,
final GroupDetailHandler.Factory groupDetailFactory) {
super(schema, currentUser);
this.groupIncludeCache = groupIncludeCache;
this.groupCache = groupCache;
this.groupControlFactory = groupControlFactory;
this.groupDetailFactory = groupDetailFactory;
@@ -98,44 +90,6 @@ class GroupAdminServiceImpl extends BaseServiceImplementation implements
});
}
public void addGroupInclude(final AccountGroup.Id groupId,
final AccountGroup.UUID incGroupUUID, final String incGroupName,
final AsyncCallback<GroupDetail> callback) {
run(callback, new Action<GroupDetail>() {
public GroupDetail run(ReviewDb db) throws OrmException, Failure,
NoSuchGroupException {
final GroupControl control = groupControlFactory.validateFor(groupId);
AccountGroup group = groupCache.get(groupId);
if (group.getType() != AccountGroup.Type.INTERNAL) {
throw new Failure(new NameAlreadyUsedException());
}
if (incGroupUUID == null) {
throw new Failure(new NoSuchGroupException(incGroupName));
}
if (!control.canAddGroup(incGroupUUID)) {
throw new Failure(new NoSuchEntityException());
}
final AccountGroupIncludeByUuid.Key key =
new AccountGroupIncludeByUuid.Key(groupId, incGroupUUID);
AccountGroupIncludeByUuid m = db.accountGroupIncludesByUuid().get(key);
if (m == null) {
m = new AccountGroupIncludeByUuid(key);
db.accountGroupIncludesByUuidAudit().insert(
Collections.singleton(new AccountGroupIncludeByUuidAudit(m,
getAccountId())));
db.accountGroupIncludesByUuid().insert(Collections.singleton(m));
groupIncludeCache.evictMemberIn(incGroupUUID);
groupIncludeCache.evictMembersOf(group.getGroupUUID());
}
return groupDetailFactory.create(groupId).call();
}
});
}
private void assertAmGroupOwner(final ReviewDb db, final AccountGroup group)
throws Failure {
try {

View File

@@ -85,7 +85,6 @@ public class GroupDetailFactory implements Callable<GroupDetail> {
}
detail.setAccounts(aic.create());
detail.setCanModify(control.isOwner());
detail.setGroups(gic.create());
return detail;
}

View File

@@ -14,15 +14,12 @@
package com.google.gerrit.server.account;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gerrit.common.data.GroupDescription;
import com.google.gerrit.common.data.GroupInfo;
import com.google.gerrit.common.data.GroupInfoCache;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.inject.Inject;
import java.util.List;
import java.util.Map;
/** Efficiently builds a {@link GroupInfoCache}. */
@@ -62,17 +59,4 @@ public class GroupInfoCacheFactory {
want(uuid);
return out.get(uuid);
}
/**
* Create an GroupInfoCache with the currently loaded AccountGroup entities.
* */
public GroupInfoCache create() {
List<GroupInfo> r = Lists.newArrayListWithCapacity(out.size());
for (GroupDescription.Basic a : out.values()) {
if (a != null) {
r.add(new GroupInfo(a));
}
}
return new GroupInfoCache(r);
}
}