Java tutorial
// Copyright (C) 2008 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.client.admin; import com.google.gerrit.client.Dispatcher; import com.google.gerrit.client.Gerrit; import com.google.gerrit.client.rpc.GerritCallback; import com.google.gerrit.client.rpc.ScreenLoadCallback; import com.google.gerrit.client.ui.AccountDashboardLink; import com.google.gerrit.client.ui.AccountGroupSuggestOracle; import com.google.gerrit.client.ui.AccountScreen; import com.google.gerrit.client.ui.AddMemberBox; import com.google.gerrit.client.ui.AddIncludedGroupBox; import com.google.gerrit.client.ui.FancyFlexTable; import com.google.gerrit.client.ui.Hyperlink; import com.google.gerrit.client.ui.OnEditEnabler; import com.google.gerrit.client.ui.RPCSuggestOracle; 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.GroupOptions; import com.google.gerrit.common.data.GroupInfo; import com.google.gerrit.common.data.GroupInfoCache; import com.google.gerrit.reviewdb.Account; import com.google.gerrit.reviewdb.AccountGroup; import com.google.gerrit.reviewdb.AccountGroupInclude; import com.google.gerrit.reviewdb.AccountGroupMember; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyPressEvent; import com.google.gwt.event.dom.client.KeyPressHandler; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.CheckBox; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Grid; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.ListBox; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.SuggestBox; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter; import com.google.gwt.user.client.ui.HTMLTable.CellFormatter; import com.google.gwtexpui.globalkey.client.NpTextArea; import com.google.gwtexpui.globalkey.client.NpTextBox; import com.google.gwtjsonrpc.client.VoidResult; import java.util.HashSet; import java.util.List; public class AccountGroupScreen extends AccountScreen { private AccountGroup.Id groupId; private AccountGroup.UUID groupUUID; private AccountInfoCache accounts = AccountInfoCache.empty(); private GroupInfoCache groups = GroupInfoCache.empty(); private MemberTable members; private IncludeTable includes; private NpTextBox groupNameTxt; private Button saveName; private NpTextBox ownerTxtBox; private SuggestBox ownerTxt; private Button saveOwner; private NpTextArea descTxt; private Button saveDesc; private Label typeSystem; private ListBox typeSelect; private Button saveType; private Panel memberPanel; private AddMemberBox addMemberBox; private Button delMember; private Panel includePanel; private AddIncludedGroupBox addIncludeBox; private Button delInclude; private Panel externalPanel; private Label externalName; private NpTextBox externalNameFilter; private Button externalNameSearch; private Grid externalMatches; private Panel groupOptionsPanel; private CheckBox visibleToAllCheckBox; private CheckBox emailOnlyAuthors; private Button saveGroupOptions; public AccountGroupScreen(final AccountGroup.Id toShow) { groupId = toShow; } public AccountGroupScreen(final AccountGroup.UUID toShow) { groupUUID = toShow; } @Override protected void onLoad() { super.onLoad(); Util.GROUP_SVC.groupDetail(groupId, groupUUID, new ScreenLoadCallback<GroupDetail>(this) { @Override protected void preDisplay(final GroupDetail result) { groupId = result.group.getId(); groupUUID = result.group.getGroupUUID(); display(result); enableForm(result.canModify); saveName.setVisible(result.canModify); saveOwner.setVisible(result.canModify); saveDesc.setVisible(result.canModify); saveGroupOptions.setVisible(result.canModify); delMember.setVisible(result.canModify); saveType.setVisible(result.canModify); delInclude.setVisible(result.canModify); } }); } @Override protected void onInitUI() { super.onInitUI(); initName(); initOwner(); initDescription(); initGroupOptions(); initGroupType(); initMemberList(); initIncludeList(); initExternal(); } private void enableForm(final boolean canModify) { groupNameTxt.setEnabled(canModify); ownerTxtBox.setEnabled(canModify); descTxt.setEnabled(canModify); typeSelect.setEnabled(canModify); addMemberBox.setEnabled(canModify); members.setEnabled(canModify); externalNameFilter.setEnabled(canModify); externalNameSearch.setEnabled(canModify); visibleToAllCheckBox.setEnabled(canModify); emailOnlyAuthors.setEnabled(canModify); addIncludeBox.setEnabled(canModify); includes.setEnabled(canModify); } private void initName() { final VerticalPanel groupNamePanel = new VerticalPanel(); groupNameTxt = new NpTextBox(); groupNameTxt.setVisibleLength(60); groupNamePanel.add(groupNameTxt); saveName = new Button(Util.C.buttonRenameGroup()); saveName.setEnabled(false); saveName.addClickHandler(new ClickHandler() { @Override public void onClick(final ClickEvent event) { final String newName = groupNameTxt.getText().trim(); Util.GROUP_SVC.renameGroup(groupId, newName, new GerritCallback<GroupDetail>() { public void onSuccess(final GroupDetail groupDetail) { saveName.setEnabled(false); display(groupDetail); } }); } }); groupNamePanel.add(saveName); add(groupNamePanel); new OnEditEnabler(saveName, groupNameTxt); } private void initOwner() { final VerticalPanel ownerPanel = new VerticalPanel(); ownerPanel.add(new SmallHeading(Util.C.headingOwner())); ownerTxtBox = new NpTextBox(); ownerTxtBox.setVisibleLength(60); ownerTxt = new SuggestBox(new RPCSuggestOracle(new AccountGroupSuggestOracle()), ownerTxtBox); ownerPanel.add(ownerTxt); saveOwner = new Button(Util.C.buttonChangeGroupOwner()); saveOwner.setEnabled(false); saveOwner.addClickHandler(new ClickHandler() { @Override public void onClick(final ClickEvent event) { final String newOwner = ownerTxt.getText().trim(); if (newOwner.length() > 0) { Util.GROUP_SVC.changeGroupOwner(groupId, newOwner, new GerritCallback<VoidResult>() { public void onSuccess(final VoidResult result) { saveOwner.setEnabled(false); } }); } } }); ownerPanel.add(saveOwner); add(ownerPanel); new OnEditEnabler(saveOwner, ownerTxtBox); } private void initDescription() { final VerticalPanel vp = new VerticalPanel(); vp.add(new SmallHeading(Util.C.headingDescription())); descTxt = new NpTextArea(); descTxt.setVisibleLines(6); descTxt.setCharacterWidth(60); vp.add(descTxt); saveDesc = new Button(Util.C.buttonSaveDescription()); saveDesc.setEnabled(false); saveDesc.addClickHandler(new ClickHandler() { @Override public void onClick(final ClickEvent event) { final String txt = descTxt.getText().trim(); Util.GROUP_SVC.changeGroupDescription(groupId, txt, new GerritCallback<VoidResult>() { public void onSuccess(final VoidResult result) { saveDesc.setEnabled(false); } }); } }); vp.add(saveDesc); add(vp); new OnEditEnabler(saveDesc, descTxt); } private void initGroupOptions() { groupOptionsPanel = new VerticalPanel(); groupOptionsPanel.add(new SmallHeading(Util.C.headingGroupOptions())); visibleToAllCheckBox = new CheckBox(Util.C.isVisibleToAll()); groupOptionsPanel.add(visibleToAllCheckBox); emailOnlyAuthors = new CheckBox(Util.C.emailOnlyAuthors()); final VerticalPanel vp = new VerticalPanel(); vp.add(new Label(Util.C.descriptionNotifications())); vp.add(emailOnlyAuthors); groupOptionsPanel.add(vp); saveGroupOptions = new Button(Util.C.buttonSaveGroupOptions()); saveGroupOptions.setEnabled(false); saveGroupOptions.addClickHandler(new ClickHandler() { @Override public void onClick(final ClickEvent event) { final GroupOptions groupOptions = new GroupOptions(visibleToAllCheckBox.getValue(), emailOnlyAuthors.getValue()); Util.GROUP_SVC.changeGroupOptions(groupId, groupOptions, new GerritCallback<VoidResult>() { public void onSuccess(final VoidResult result) { saveGroupOptions.setEnabled(false); } }); } }); groupOptionsPanel.add(saveGroupOptions); add(groupOptionsPanel); final OnEditEnabler enabler = new OnEditEnabler(saveGroupOptions); enabler.listenTo(visibleToAllCheckBox); enabler.listenTo(emailOnlyAuthors); } private void initGroupType() { typeSystem = new Label(Util.C.groupType_SYSTEM()); typeSelect = new ListBox(); typeSelect.addItem(Util.C.groupType_INTERNAL(), AccountGroup.Type.INTERNAL.name()); typeSelect.addItem(Util.C.groupType_LDAP(), AccountGroup.Type.LDAP.name()); typeSelect.addChangeHandler(new ChangeHandler() { @Override public void onChange(ChangeEvent event) { saveType.setEnabled(true); } }); saveType = new Button(Util.C.buttonChangeGroupType()); saveType.setEnabled(false); saveType.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { onSaveType(); } }); switch (Gerrit.getConfig().getAuthType()) { case HTTP_LDAP: case LDAP: case LDAP_BIND: case CLIENT_SSL_CERT_LDAP: break; default: return; } final VerticalPanel fp = new VerticalPanel(); fp.add(new SmallHeading(Util.C.headingGroupType())); fp.add(typeSystem); fp.add(typeSelect); fp.add(saveType); add(fp); } private void initMemberList() { addMemberBox = new AddMemberBox(); addMemberBox.addClickHandler(new ClickHandler() { @Override public void onClick(final ClickEvent event) { doAddNewMember(); } }); members = new MemberTable(); delMember = new Button(Util.C.buttonDeleteGroupMembers()); delMember.addClickHandler(new ClickHandler() { @Override public void onClick(final ClickEvent event) { members.deleteChecked(); } }); memberPanel = new FlowPanel(); memberPanel.add(new SmallHeading(Util.C.headingMembers())); memberPanel.add(addMemberBox); memberPanel.add(members); memberPanel.add(delMember); add(memberPanel); } private void initIncludeList() { addIncludeBox = new AddIncludedGroupBox(); addIncludeBox.addClickHandler(new ClickHandler() { @Override public void onClick(final ClickEvent event) { doAddNewInclude(); } }); includes = new IncludeTable(); delInclude = new Button(Util.C.buttonDeleteIncludedGroup()); delInclude.addClickHandler(new ClickHandler() { @Override public void onClick(final ClickEvent event) { includes.deleteChecked(); } }); includePanel = new FlowPanel(); includePanel.add(new SmallHeading(Util.C.headingIncludedGroups())); includePanel.add(addIncludeBox); includePanel.add(includes); includePanel.add(delInclude); add(includePanel); } private void initExternal() { externalName = new Label(); externalNameFilter = new NpTextBox(); externalNameFilter.setVisibleLength(30); externalNameFilter.addKeyPressHandler(new KeyPressHandler() { @Override public void onKeyPress(final KeyPressEvent event) { if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) { doExternalSearch(); } } }); externalNameSearch = new Button(Gerrit.C.searchButton()); externalNameSearch.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { doExternalSearch(); } }); externalMatches = new Grid(); externalMatches.setStyleName(Gerrit.RESOURCES.css().infoTable()); externalMatches.setVisible(false); final FlowPanel searchLine = new FlowPanel(); searchLine.add(externalNameFilter); searchLine.add(externalNameSearch); externalPanel = new VerticalPanel(); externalPanel.add(new SmallHeading(Util.C.headingExternalGroup())); externalPanel.add(externalName); externalPanel.add(searchLine); externalPanel.add(externalMatches); add(externalPanel); } private void setType(final AccountGroup.Type newType) { final boolean system = newType == AccountGroup.Type.SYSTEM; typeSystem.setVisible(system); typeSelect.setVisible(!system); saveType.setVisible(!system); memberPanel.setVisible(newType == AccountGroup.Type.INTERNAL); includePanel.setVisible(newType == AccountGroup.Type.INTERNAL); externalPanel.setVisible(newType == AccountGroup.Type.LDAP); externalNameFilter.setText(groupNameTxt.getText()); if (!system) { for (int i = 0; i < typeSelect.getItemCount(); i++) { if (newType.name().equals(typeSelect.getValue(i))) { typeSelect.setSelectedIndex(i); break; } } } saveType.setEnabled(false); } private void onSaveType() { final int idx = typeSelect.getSelectedIndex(); final AccountGroup.Type newType = AccountGroup.Type.valueOf(typeSelect.getValue(idx)); typeSelect.setEnabled(false); saveType.setEnabled(false); Util.GROUP_SVC.changeGroupType(groupId, newType, new GerritCallback<VoidResult>() { @Override public void onSuccess(VoidResult result) { typeSelect.setEnabled(true); setType(newType); } @Override public void onFailure(Throwable caught) { typeSelect.setEnabled(true); saveType.setEnabled(true); super.onFailure(caught); } }); } private void doExternalSearch() { externalNameFilter.setEnabled(false); externalNameSearch.setEnabled(false); Util.GROUP_SVC.searchExternalGroups(externalNameFilter.getText(), new GerritCallback<List<AccountGroup.ExternalNameKey>>() { @Override public void onSuccess(List<AccountGroup.ExternalNameKey> result) { final CellFormatter fmt = externalMatches.getCellFormatter(); if (result.isEmpty()) { externalMatches.resize(1, 1); externalMatches.setText(0, 0, Util.C.errorNoMatchingGroups()); fmt.setStyleName(0, 0, Gerrit.RESOURCES.css().header()); return; } externalMatches.resize(1 + result.size(), 2); externalMatches.setText(0, 0, Util.C.columnGroupName()); externalMatches.setText(0, 1, ""); fmt.setStyleName(0, 0, Gerrit.RESOURCES.css().header()); fmt.setStyleName(0, 1, Gerrit.RESOURCES.css().header()); for (int row = 0; row < result.size(); row++) { final AccountGroup.ExternalNameKey key = result.get(row); final Button b = new Button(Util.C.buttonSelectGroup()); b.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { setExternalGroup(key); } }); externalMatches.setText(1 + row, 0, key.get()); externalMatches.setWidget(1 + row, 1, b); fmt.setStyleName(1 + row, 1, Gerrit.RESOURCES.css().rightmost()); } externalMatches.setVisible(true); externalNameFilter.setEnabled(true); externalNameSearch.setEnabled(true); } @Override public void onFailure(Throwable caught) { externalNameFilter.setEnabled(true); externalNameSearch.setEnabled(true); super.onFailure(caught); } }); } private void setExternalGroup(final AccountGroup.ExternalNameKey key) { externalMatches.setVisible(false); Util.GROUP_SVC.changeExternalGroup(groupId, key, new GerritCallback<VoidResult>() { @Override public void onSuccess(VoidResult result) { externalName.setText(key.get()); } @Override public void onFailure(Throwable caught) { externalMatches.setVisible(true); super.onFailure(caught); } }); } private void display(final GroupDetail result) { final AccountGroup group = result.group; setPageTitle(Util.M.group(group.getName())); groupNameTxt.setText(group.getName()); if (result.ownerGroup != null) { ownerTxt.setText(result.ownerGroup.getName()); } else { ownerTxt.setText(Util.M.deletedGroup(group.getOwnerGroupId().get())); } descTxt.setText(group.getDescription()); visibleToAllCheckBox.setValue(group.isVisibleToAll()); emailOnlyAuthors.setValue(group.isEmailOnlyAuthors()); switch (group.getType()) { case INTERNAL: accounts = result.accounts; groups = result.groups; members.display(result.members); includes.display(result.includes); break; case LDAP: externalName.setText(group.getExternalNameKey() != null ? group.getExternalNameKey().get() : Util.C.noGroupSelected()); break; } setType(group.getType()); } void doAddNewMember() { final String nameEmail = addMemberBox.getText(); if (nameEmail.length() == 0) { return; } addMemberBox.setEnabled(false); Util.GROUP_SVC.addGroupMember(groupId, nameEmail, new GerritCallback<GroupDetail>() { public void onSuccess(final GroupDetail result) { addMemberBox.setEnabled(true); addMemberBox.setText(""); if (result.accounts != null && result.members != null) { accounts.merge(result.accounts); members.display(result.members); } } @Override public void onFailure(final Throwable caught) { addMemberBox.setEnabled(true); super.onFailure(caught); } }); } void doAddNewInclude() { final String groupName = addIncludeBox.getText(); if (groupName.length() == 0) { return; } addIncludeBox.setEnabled(false); Util.GROUP_SVC.addGroupInclude(groupId, groupName, new GerritCallback<GroupDetail>() { public void onSuccess(final GroupDetail result) { addIncludeBox.setEnabled(true); addIncludeBox.setText(""); if (result.groups != null && result.includes != null) { groups.merge(result.groups); includes.display(result.includes); } } @Override public void onFailure(final Throwable caught) { addIncludeBox.setEnabled(true); super.onFailure(caught); } }); } private class MemberTable extends FancyFlexTable<AccountGroupMember> { private boolean enabled = true; MemberTable() { table.setText(0, 2, Util.C.columnMember()); table.setText(0, 3, Util.C.columnEmailAddress()); final FlexCellFormatter fmt = table.getFlexCellFormatter(); fmt.addStyleName(0, 1, Gerrit.RESOURCES.css().iconHeader()); fmt.addStyleName(0, 2, Gerrit.RESOURCES.css().dataHeader()); fmt.addStyleName(0, 3, Gerrit.RESOURCES.css().dataHeader()); } void setEnabled(final boolean enabled) { this.enabled = enabled; for (int row = 1; row < table.getRowCount(); row++) { final AccountGroupMember k = getRowItem(row); if (k != null) { ((CheckBox) table.getWidget(row, 1)).setEnabled(enabled); } } } void deleteChecked() { final HashSet<AccountGroupMember.Key> ids = new HashSet<AccountGroupMember.Key>(); for (int row = 1; row < table.getRowCount(); row++) { final AccountGroupMember k = getRowItem(row); if (k != null && ((CheckBox) table.getWidget(row, 1)).getValue()) { ids.add(k.getKey()); } } if (!ids.isEmpty()) { Util.GROUP_SVC.deleteGroupMembers(groupId, ids, new GerritCallback<VoidResult>() { public void onSuccess(final VoidResult result) { for (int row = 1; row < table.getRowCount();) { final AccountGroupMember k = getRowItem(row); if (k != null && ids.contains(k.getKey())) { table.removeRow(row); } else { row++; } } } }); } } void display(final List<AccountGroupMember> result) { while (1 < table.getRowCount()) table.removeRow(table.getRowCount() - 1); for (final AccountGroupMember k : result) { final int row = table.getRowCount(); table.insertRow(row); applyDataRowStyle(row); populate(row, k); } } void populate(final int row, final AccountGroupMember k) { final Account.Id accountId = k.getAccountId(); CheckBox checkBox = new CheckBox(); table.setWidget(row, 1, checkBox); checkBox.setEnabled(enabled); table.setWidget(row, 2, AccountDashboardLink.link(accounts, accountId)); table.setText(row, 3, accounts.get(accountId).getPreferredEmail()); final FlexCellFormatter fmt = table.getFlexCellFormatter(); fmt.addStyleName(row, 1, Gerrit.RESOURCES.css().iconCell()); fmt.addStyleName(row, 2, Gerrit.RESOURCES.css().dataCell()); fmt.addStyleName(row, 3, Gerrit.RESOURCES.css().dataCell()); setRowItem(row, k); } } private class IncludeTable extends FancyFlexTable<AccountGroupInclude> { private boolean enabled = true; IncludeTable() { table.setText(0, 2, Util.C.columnGroupName()); table.setText(0, 3, Util.C.columnGroupDescription()); final FlexCellFormatter fmt = table.getFlexCellFormatter(); fmt.addStyleName(0, 1, Gerrit.RESOURCES.css().iconHeader()); fmt.addStyleName(0, 2, Gerrit.RESOURCES.css().dataHeader()); fmt.addStyleName(0, 3, Gerrit.RESOURCES.css().dataHeader()); } void setEnabled(final boolean enabled) { this.enabled = enabled; for (int row = 1; row < table.getRowCount(); row++) { final AccountGroupInclude k = getRowItem(row); if (k != null) { ((CheckBox) table.getWidget(row, 1)).setEnabled(enabled); } } } void deleteChecked() { final HashSet<AccountGroupInclude.Key> keys = new HashSet<AccountGroupInclude.Key>(); for (int row = 1; row < table.getRowCount(); row++) { final AccountGroupInclude k = getRowItem(row); if (k != null && ((CheckBox) table.getWidget(row, 1)).getValue()) { keys.add(k.getKey()); } } if (!keys.isEmpty()) { Util.GROUP_SVC.deleteGroupIncludes(groupId, keys, new GerritCallback<VoidResult>() { public void onSuccess(final VoidResult result) { for (int row = 1; row < table.getRowCount();) { final AccountGroupInclude k = getRowItem(row); if (k != null && keys.contains(k.getKey())) { table.removeRow(row); } else { row++; } } } }); } } void display(final List<AccountGroupInclude> result) { while (1 < table.getRowCount()) table.removeRow(table.getRowCount() - 1); for (final AccountGroupInclude k : result) { final int row = table.getRowCount(); table.insertRow(row); applyDataRowStyle(row); populate(row, k); } } void populate(final int row, final AccountGroupInclude k) { AccountGroup.Id id = k.getIncludeId(); GroupInfo group = groups.get(id); CheckBox checkBox = new CheckBox(); table.setWidget(row, 1, checkBox); checkBox.setEnabled(enabled); table.setWidget(row, 2, new Hyperlink(group.getName(), Dispatcher.toAccountGroup(id))); table.setText(row, 3, groups.get(id).getDescription()); final FlexCellFormatter fmt = table.getFlexCellFormatter(); fmt.addStyleName(row, 1, Gerrit.RESOURCES.css().iconCell()); fmt.addStyleName(row, 2, Gerrit.RESOURCES.css().dataCell()); fmt.addStyleName(row, 3, Gerrit.RESOURCES.css().dataCell()); setRowItem(row, k); } } }