Temporarily remove ProjectAccessScreen

The ref_rights table is about to change its entire data model to
something stored in Git, and which uses a different layout in-memory
and on-disk than the old RefRight object.  Dropping the old web UI
before making the internal API changes reduces the amount of code that
is being modified at once.  A new UI will be built from scratch to
support the new data model more accurately than the old simple table
layout could do.

Change-Id: Idfdebc712b1241a81346084037bc5f6aeab6e42a
Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
Shawn O. Pearce 2010-12-22 17:52:37 -08:00
parent e662fb3d4d
commit 83f6cc14af
11 changed files with 3 additions and 1254 deletions

View File

@ -1,74 +0,0 @@
// Copyright (C) 2010 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.common.data;
import com.google.gerrit.reviewdb.RefRight;
/**
* Additional data about a {@link RefRight} not normally loaded: defines if a
* right is inherited from a parent structure (e.g. a parent project).
*/
public class InheritedRefRight {
private RefRight right;
private boolean inherited;
private boolean owner;
/**
* Creates a instance of a {@link RefRight} with data about inheritance
*/
protected InheritedRefRight() {
}
/**
* Creates a instance of a {@link RefRight} with data about inheritance
*
* @param right the right
* @param inherited true if the right is inherited, false otherwise
* @param owner true if right is owned by current user, false otherwise
*/
public InheritedRefRight(RefRight right, boolean inherited, boolean owner) {
this.right = right;
this.inherited = inherited;
this.owner = owner;
}
public RefRight getRight() {
return right;
}
public boolean isInherited() {
return inherited;
}
public boolean isOwner() {
return owner;
}
@Override
public boolean equals(Object o) {
if (o instanceof InheritedRefRight) {
InheritedRefRight a = this;
InheritedRefRight b = (InheritedRefRight) o;
return a.getRight().equals(b.getRight())
&& a.isInherited() == b.isInherited();
}
return false;
}
@Override
public int hashCode() {
return getRight().hashCode();
}
}

View File

@ -15,10 +15,8 @@
package com.google.gerrit.common.data;
import com.google.gerrit.common.auth.SignInRequired;
import com.google.gerrit.reviewdb.ApprovalCategory;
import com.google.gerrit.reviewdb.Branch;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.RefRight;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwtjsonrpc.client.RemoteJsonService;
import com.google.gwtjsonrpc.client.RpcImpl;
@ -38,15 +36,6 @@ public interface ProjectAdminService extends RemoteJsonService {
void changeProjectSettings(Project update,
AsyncCallback<ProjectDetail> callback);
@SignInRequired
void deleteRight(Project.NameKey projectName, Set<RefRight.Key> ids,
AsyncCallback<ProjectDetail> callback);
@SignInRequired
void addRight(Project.NameKey projectName, ApprovalCategory.Id categoryId,
String groupName, String refName, short min, short max,
AsyncCallback<ProjectDetail> callback);
void listBranches(Project.NameKey projectName,
AsyncCallback<ListBranchesResult> callback);

View File

@ -14,16 +14,10 @@
package com.google.gerrit.common.data;
import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.reviewdb.Project;
import java.util.List;
import java.util.Map;
public class ProjectDetail {
public Project project;
public Map<AccountGroup.Id, AccountGroup> groups;
public List<InheritedRefRight> rights;
public boolean canModifyDescription;
public boolean canModifyMergeType;
public boolean canModifyAgreements;
@ -36,14 +30,6 @@ public class ProjectDetail {
project = p;
}
public void setGroups(final Map<AccountGroup.Id, AccountGroup> g) {
groups = g;
}
public void setRights(final List<InheritedRefRight> r) {
rights = r;
}
public void setCanModifyDescription(final boolean cmd) {
canModifyDescription = cmd;
}

View File

@ -44,7 +44,6 @@ import com.google.gerrit.client.account.RegisterScreen;
import com.google.gerrit.client.account.ValidateEmailScreen;
import com.google.gerrit.client.admin.AccountGroupScreen;
import com.google.gerrit.client.admin.GroupListScreen;
import com.google.gerrit.client.admin.ProjectAccessScreen;
import com.google.gerrit.client.admin.ProjectBranchesScreen;
import com.google.gerrit.client.admin.ProjectInfoScreen;
import com.google.gerrit.client.admin.ProjectListScreen;
@ -432,7 +431,7 @@ public class Dispatcher {
}
if (ProjectScreen.ACCESS.equals(p)) {
return new ProjectAccessScreen(k);
return new NotFoundScreen();
}
return new NotFoundScreen();

View File

@ -1,404 +0,0 @@
// Copyright (C) 2010 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.Gerrit;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.AccountGroupSuggestOracle;
import com.google.gerrit.client.ui.HintTextBox;
import com.google.gerrit.client.ui.RPCSuggestOracle;
import com.google.gerrit.common.data.ApprovalType;
import com.google.gerrit.common.data.ProjectDetail;
import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.reviewdb.ApprovalCategory;
import com.google.gerrit.reviewdb.ApprovalCategoryValue;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.RefRight;
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.event.logical.shared.HasValueChangeHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.SuggestBox;
public class AccessRightEditor extends Composite
implements HasValueChangeHandlers<ProjectDetail> {
private Project.NameKey projectKey;
private ListBox catBox;
private HintTextBox nameTxt;
private SuggestBox nameSug;
private HintTextBox referenceTxt;
private ListBox topBox;
private ListBox botBox;
private Button addBut;
private Button clearBut;
public AccessRightEditor(final Project.NameKey key) {
projectKey = key;
initWidgets();
initCategories();
final Grid grid = new Grid(5, 2);
grid.setText(0, 0, Util.C.columnApprovalCategory() + ":");
grid.setWidget(0, 1, catBox);
grid.setText(1, 0, Util.C.columnGroupName() + ":");
grid.setWidget(1, 1, nameSug);
grid.setText(2, 0, Util.C.columnRefName() + ":");
grid.setWidget(2, 1, referenceTxt);
grid.setText(3, 0, Util.C.columnRightRange() + ":");
grid.setWidget(3, 1, topBox);
grid.setText(4, 0, "");
grid.setWidget(4, 1, botBox);
FlowPanel fp = new FlowPanel();
fp.setStyleName(Gerrit.RESOURCES.css().addSshKeyPanel());
fp.add(grid);
fp.add(addBut);
fp.add(clearBut);
initWidget(fp);
}
protected void initWidgets() {
catBox = new ListBox();
catBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(final ChangeEvent event) {
updateCategorySelection();
}
});
nameTxt = new HintTextBox();
nameSug = new SuggestBox(new RPCSuggestOracle(
new AccountGroupSuggestOracle()), nameTxt);
nameTxt.setVisibleLength(50);
nameTxt.setHintText(Util.C.defaultAccountGroupName());
referenceTxt = new HintTextBox();
referenceTxt.setVisibleLength(50);
referenceTxt.setText("");
referenceTxt.addKeyPressHandler(new KeyPressHandler() {
@Override
public void onKeyPress(KeyPressEvent event) {
if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
doAddNewRight();
}
}
});
topBox = new ListBox();
botBox = new ListBox();
addBut = new Button(Util.C.buttonAddProjectRight());
addBut.addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent event) {
doAddNewRight();
}
});
clearBut = new Button(Util.C.buttonClearProjectRight());
clearBut.addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent event) {
clear();
}
});
}
protected void initCategories() {
for (final ApprovalType at : Gerrit.getConfig().getApprovalTypes()
.getApprovalTypes()) {
final ApprovalCategory c = at.getCategory();
catBox.addItem(c.getName(), c.getId().get());
}
for (final ApprovalType at : Gerrit.getConfig().getApprovalTypes()
.getActionTypes()) {
final ApprovalCategory c = at.getCategory();
if (Gerrit.getConfig().getWildProject().equals(projectKey)
&& !c.getId().canBeOnWildProject()) {
// Giving out control of the WILD_PROJECT to other groups beyond
// Administrators is dangerous. Having control over WILD_PROJECT
// is about the same as having Administrator access as users are
// able to affect grants in all projects on the system.
//
continue;
}
catBox.addItem(c.getName(), c.getId().get());
}
if (catBox.getItemCount() > 0) {
catBox.setSelectedIndex(0);
updateCategorySelection();
}
}
public void enableForm(final boolean on) {
final boolean canAdd = on && catBox.getItemCount() > 0;
addBut.setEnabled(canAdd);
clearBut.setEnabled(canAdd);
nameTxt.setEnabled(canAdd);
referenceTxt.setEnabled(canAdd);
catBox.setEnabled(canAdd);
topBox.setEnabled(canAdd);
botBox.setEnabled(canAdd);
}
public void clear() {
setCat(null);
setName("");
setReference("");
}
public void load(final RefRight right, final AccountGroup group) {
final ApprovalType atype =
Gerrit.getConfig().getApprovalTypes().getApprovalType(
right.getApprovalCategoryId());
setCat(atype != null ? atype.getCategory().getName()
: right.getApprovalCategoryId().get() );
setName(group.getName());
setReference(right.getRefPatternForDisplay());
setRange(atype.getCategory().isRange() ? atype.getValue(right.getMinValue())
: null, atype.getValue(right.getMaxValue()) );
}
protected void doAddNewRight() {
final ApprovalType at = getApprovalType();
ApprovalCategoryValue min = getMin(at);
ApprovalCategoryValue max = getMax(at);
if (at == null || min == null || max == null) {
return;
}
final String groupName = nameSug.getText();
if ("".equals(groupName)
|| Util.C.defaultAccountGroupName().equals(groupName)) {
return;
}
final String refPattern = referenceTxt.getText();
addBut.setEnabled(false);
Util.PROJECT_SVC.addRight(projectKey, at.getCategory().getId(),
groupName, refPattern, min.getValue(), max.getValue(),
new GerritCallback<ProjectDetail>() {
public void onSuccess(final ProjectDetail result) {
addBut.setEnabled(true);
nameSug.setText("");
referenceTxt.setText("");
ValueChangeEvent.fire(AccessRightEditor.this, result);
}
@Override
public void onFailure(final Throwable caught) {
addBut.setEnabled(true);
super.onFailure(caught);
}
});
}
protected void updateCategorySelection() {
final ApprovalType at = getApprovalType();
if (at == null || at.getValues().isEmpty()) {
topBox.setEnabled(false);
botBox.setEnabled(false);
referenceTxt.setEnabled(false);
addBut.setEnabled(false);
clearBut.setEnabled(false);
return;
}
updateRanges(at);
}
protected void updateRanges(final ApprovalType at) {
ApprovalCategoryValue min = null, max = null, last = null;
topBox.clear();
botBox.clear();
for(final ApprovalCategoryValue v : at.getValues()) {
final int nval = v.getValue();
final String vStr = String.valueOf(nval);
String nStr = vStr + ": " + v.getName();
if (nval > 0) {
nStr = "+" + nStr;
}
topBox.addItem(nStr, vStr);
botBox.addItem(nStr, vStr);
if (min == null || nval < 0) {
min = v;
} else if (max == null && nval > 0) {
max = v;
}
last = v;
}
if (max == null) {
max = last;
}
if (ApprovalCategory.READ.equals(at.getCategory().getId())) {
// Special case; for READ the most logical range is just
// +1 READ, so assume that as the default for both.
min = max;
}
if (! at.getCategory().isRange()) {
max = null;
}
setRange(min, max);
}
protected void setCat(final String cat) {
if (cat == null) {
catBox.setSelectedIndex(0);
} else {
setSelectedText(catBox, cat);
}
updateCategorySelection();
}
protected void setName(final String name) {
nameTxt.setText(name);
}
protected void setReference(final String ref) {
referenceTxt.setText(ref);
}
protected void setRange(final ApprovalCategoryValue min,
final ApprovalCategoryValue max) {
if (min == null || max == null) {
botBox.setVisible(false);
if (max != null) {
setSelectedValue(topBox, "" + max.getValue());
return;
}
} else {
botBox.setVisible(true);
setSelectedValue(botBox, "" + max.getValue());
}
setSelectedValue(topBox, "" + min.getValue());
}
private ApprovalType getApprovalType() {
int idx = catBox.getSelectedIndex();
if (idx < 0) {
return null;
}
return Gerrit.getConfig().getApprovalTypes().getApprovalType(
new ApprovalCategory.Id(catBox.getValue(idx)));
}
public ApprovalCategoryValue getMin(ApprovalType at) {
final ApprovalCategoryValue top = getTop(at);
final ApprovalCategoryValue bot = getBot(at);
if (bot == null) {
for (final ApprovalCategoryValue v : at.getValues()) {
if (0 <= v.getValue() && v.getValue() <= top.getValue()) {
return v;
}
}
return at.getMin();
}
if (top.getValue() > bot.getValue()) {
return bot;
}
return top;
}
public ApprovalCategoryValue getMax(ApprovalType at) {
final ApprovalCategoryValue top = getTop(at);
final ApprovalCategoryValue bot = getBot(at);
if (bot == null || bot.getValue() < top.getValue()) {
return top;
}
return bot;
}
protected ApprovalCategoryValue getTop(ApprovalType at) {
int idx = topBox.getSelectedIndex();
if (idx < 0) {
return null;
}
return at.getValue(Short.parseShort(topBox.getValue(idx)));
}
protected ApprovalCategoryValue getBot(ApprovalType at) {
int idx = botBox.getSelectedIndex();
if (idx < 0 || ! botBox.isVisible()) {
return null;
}
return at.getValue(Short.parseShort(botBox.getValue(idx)));
}
public HandlerRegistration addValueChangeHandler(
final ValueChangeHandler<ProjectDetail> handler) {
return addHandler(handler, ValueChangeEvent.getType());
}
public static boolean setSelectedText(ListBox box, String text) {
if (text == null) {
return false;
}
for (int i =0 ; i < box.getItemCount(); i++) {
if (text.equals(box.getItemText(i))) {
box.setSelectedIndex(i);
return true;
}
}
return false;
}
public static boolean setSelectedValue(ListBox box, String value) {
if (value == null) {
return false;
}
for (int i =0 ; i < box.getItemCount(); i++) {
if (value.equals(box.getValue(i))) {
box.setSelectedIndex(i);
return true;
}
}
return false;
}
}

View File

@ -1,327 +0,0 @@
// 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.FancyFlexTable;
import com.google.gerrit.client.ui.Hyperlink;
import com.google.gerrit.client.ui.SmallHeading;
import com.google.gerrit.common.data.ApprovalType;
import com.google.gerrit.common.data.GerritConfig;
import com.google.gerrit.common.data.InheritedRefRight;
import com.google.gerrit.common.data.ProjectDetail;
import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.reviewdb.ApprovalCategoryValue;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.RefRight;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
import com.google.gwtexpui.safehtml.client.SafeHtml;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
public class ProjectAccessScreen extends ProjectScreen {
private Panel parentPanel;
private Hyperlink parentName;
private RightsTable rights;
private Button delRight;
private AccessRightEditor rightEditor;
private CheckBox showInherited;
public ProjectAccessScreen(final Project.NameKey toShow) {
super(toShow);
}
@Override
protected void onInitUI() {
super.onInitUI();
initParent();
initRights();
}
@Override
protected void onLoad() {
super.onLoad();
Util.PROJECT_SVC.projectDetail(getProjectKey(),
new ScreenLoadCallback<ProjectDetail>(this) {
public void preDisplay(final ProjectDetail result) {
enableForm(true);
display(result);
}
});
}
private void enableForm(final boolean on) {
delRight.setEnabled(on);
rightEditor.enableForm(on);
}
private void initParent() {
parentName = new Hyperlink("", "");
showInherited = new CheckBox();
showInherited.setValue(true);
showInherited.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
rights.showInherited(showInherited.getValue());
}
});
Grid g = new Grid(2, 3);
g.setWidget(0, 0, new SmallHeading(Util.C.headingParentProjectName()));
g.setWidget(1, 0, parentName);
g.setWidget(1, 1, showInherited);
g.setText(1, 2, Util.C.headingShowInherited());
parentPanel = new VerticalPanel();
parentPanel.add(g);
add(parentPanel);
}
private void initRights() {
rights = new RightsTable();
delRight = new Button(Util.C.buttonDeleteGroupMembers());
delRight.addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent event) {
final HashSet<RefRight.Key> refRightIds = rights.getRefRightIdsChecked();
doDeleteRefRights(refRightIds);
}
});
rightEditor = new AccessRightEditor(getProjectKey());
rightEditor.addValueChangeHandler(new ValueChangeHandler<ProjectDetail>() {
@Override
public void onValueChange(ValueChangeEvent<ProjectDetail> event) {
display(event.getValue());
}
});
add(new SmallHeading(Util.C.headingAccessRights()));
add(rights);
add(delRight);
add(rightEditor);
}
void display(final ProjectDetail result) {
final Project project = result.project;
final Project.NameKey wildKey = Gerrit.getConfig().getWildProject();
final boolean isWild = wildKey.equals(project.getNameKey());
Project.NameKey parent = project.getParent();
if (parent == null) {
parent = wildKey;
}
parentPanel.setVisible(!isWild);
parentName.setTargetHistoryToken(Dispatcher.toProjectAdmin(parent, ACCESS));
parentName.setText(parent.get());
rights.display(result.groups, result.rights);
rightEditor.setVisible(result.canModifyAccess);
delRight.setVisible(rights.getCanDelete());
}
private void doDeleteRefRights(final HashSet<RefRight.Key> refRightIds) {
if (!refRightIds.isEmpty()) {
Util.PROJECT_SVC.deleteRight(getProjectKey(), refRightIds,
new GerritCallback<ProjectDetail>() {
@Override
public void onSuccess(final ProjectDetail result) {
//The user could no longer modify access after deleting a ref right.
display(result);
}
});
}
}
private class RightsTable extends FancyFlexTable<InheritedRefRight> {
boolean canDelete;
Map<AccountGroup.Id, AccountGroup> groups;
RightsTable() {
table.setWidth("");
table.setText(0, 2, Util.C.columnRightOrigin());
table.setText(0, 3, Util.C.columnApprovalCategory());
table.setText(0, 4, Util.C.columnGroupName());
table.setText(0, 5, Util.C.columnRefName());
table.setText(0, 6, Util.C.columnRightRange());
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());
fmt.addStyleName(0, 4, Gerrit.RESOURCES.css().dataHeader());
fmt.addStyleName(0, 5, Gerrit.RESOURCES.css().dataHeader());
fmt.addStyleName(0, 6, Gerrit.RESOURCES.css().dataHeader());
table.addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent event) {
onOpenRow(table.getCellForEvent(event).getRowIndex());
}
});
}
HashSet<RefRight.Key> getRefRightIdsChecked() {
final HashSet<RefRight.Key> refRightIds = new HashSet<RefRight.Key>();
for (int row = 1; row < table.getRowCount(); row++) {
RefRight r = getRowItem(row).getRight();
if (r != null && table.getWidget(row, 1) instanceof CheckBox
&& ((CheckBox) table.getWidget(row, 1)).getValue()) {
refRightIds.add(r.getKey());
}
}
return refRightIds;
}
void display(final Map<AccountGroup.Id, AccountGroup> grps,
final List<InheritedRefRight> refRights) {
groups = grps;
canDelete = false;
while (1 < table.getRowCount())
table.removeRow(table.getRowCount() - 1);
for (final InheritedRefRight r : refRights) {
final int row = table.getRowCount();
table.insertRow(row);
if (! showInherited.getValue() && r.isInherited()) {
table.getRowFormatter().setVisible(row, false);
}
applyDataRowStyle(row);
populate(row, r);
}
}
protected void onOpenRow(final int row) {
if (row > 0) {
RefRight right = getRowItem(row).getRight();
rightEditor.load(right, groups.get(right.getAccountGroupId()));
}
}
void populate(final int row, final InheritedRefRight r) {
final GerritConfig config = Gerrit.getConfig();
final RefRight right = r.getRight();
final ApprovalType ar =
config.getApprovalTypes().getApprovalType(
right.getApprovalCategoryId());
final AccountGroup group = groups.get(right.getAccountGroupId());
if (r.isInherited() || !r.isOwner()) {
table.setText(row, 1, "");
} else {
table.setWidget(row, 1, new CheckBox());
canDelete = true;
}
if (r.isInherited()) {
Project.NameKey fromProject = right.getKey().getProjectNameKey();
table.setWidget(row, 2, new Hyperlink(fromProject.get(), Dispatcher
.toProjectAdmin(fromProject, ACCESS)));
} else {
table.setText(row, 2, "");
}
table.setText(row, 3, ar != null ? ar.getCategory().getName()
: right.getApprovalCategoryId().get() );
if (group != null) {
table.setWidget(row, 4, new Hyperlink(group.getName(), Dispatcher
.toAccountGroup(group.getId())));
} else {
table.setText(row, 4, Util.M.deletedGroup(right.getAccountGroupId()
.get()));
}
table.setText(row, 5, right.getRefPatternForDisplay());
{
final SafeHtmlBuilder m = new SafeHtmlBuilder();
final ApprovalCategoryValue min, max;
min = ar != null ? ar.getValue(right.getMinValue()) : null;
max = ar != null ? ar.getValue(right.getMaxValue()) : null;
if (ar != null && ar.getCategory().isRange()) {
formatValue(m, right.getMinValue(), min);
m.br();
}
formatValue(m, right.getMaxValue(), max);
SafeHtml.set(table, row, 6, m);
}
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());
fmt.addStyleName(row, 4, Gerrit.RESOURCES.css().dataCell());
fmt.addStyleName(row, 5, Gerrit.RESOURCES.css().dataCell());
fmt.addStyleName(row, 6, Gerrit.RESOURCES.css().dataCell());
fmt.addStyleName(row, 6, Gerrit.RESOURCES.css()
.projectAdminApprovalCategoryRangeLine());
setRowItem(row, r);
}
public void showInherited(boolean visible) {
for (int r = 0; r < table.getRowCount(); r++) {
if (getRowItem(r) != null && getRowItem(r).isInherited()) {
table.getRowFormatter().setVisible(r, visible);
}
}
}
private void formatValue(final SafeHtmlBuilder m, final short v,
final ApprovalCategoryValue e) {
m.openSpan();
m
.setStyleName(Gerrit.RESOURCES.css()
.projectAdminApprovalCategoryValue());
if (v == 0) {
m.append(' ');
} else if (v > 0) {
m.append('+');
}
m.append(v);
m.closeSpan();
if (e != null) {
m.append(": ");
m.append(e.getName());
}
}
private boolean getCanDelete() {
return canDelete;
}
}
}

View File

@ -1,207 +0,0 @@
// Copyright (C) 2010 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.httpd.rpc.project;
import com.google.gerrit.common.data.ApprovalType;
import com.google.gerrit.common.data.ApprovalTypes;
import com.google.gerrit.common.data.ProjectDetail;
import com.google.gerrit.common.errors.InvalidNameException;
import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.httpd.rpc.Handler;
import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.reviewdb.ApprovalCategory;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.RefRight;
import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.NoSuchRefException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.RefControl;
import com.google.gwtorm.client.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
import java.util.Collections;
import javax.annotation.Nullable;
class AddRefRight extends Handler<ProjectDetail> {
interface Factory {
AddRefRight create(@Assisted Project.NameKey projectName,
@Assisted ApprovalCategory.Id categoryId,
@Assisted("groupName") String groupName,
@Nullable @Assisted("refPattern") String refPattern,
@Assisted("min") short min, @Assisted("max") short max);
}
private final ProjectDetailFactory.Factory projectDetailFactory;
private final ProjectControl.Factory projectControlFactory;
private final ProjectCache projectCache;
private final GroupCache groupCache;
private final ReviewDb db;
private final ApprovalTypes approvalTypes;
private final Project.NameKey projectName;
private final ApprovalCategory.Id categoryId;
private final AccountGroup.NameKey groupName;
private final String refPattern;
private final short min;
private final short max;
@Inject
AddRefRight(final ProjectDetailFactory.Factory projectDetailFactory,
final ProjectControl.Factory projectControlFactory,
final ProjectCache projectCache, final GroupCache groupCache,
final ReviewDb db, final ApprovalTypes approvalTypes,
@Assisted final Project.NameKey projectName,
@Assisted final ApprovalCategory.Id categoryId,
@Assisted("groupName") final String groupName,
@Nullable @Assisted("refPattern") final String refPattern,
@Assisted("min") final short min, @Assisted("max") final short max) {
this.projectDetailFactory = projectDetailFactory;
this.projectControlFactory = projectControlFactory;
this.projectCache = projectCache;
this.groupCache = groupCache;
this.approvalTypes = approvalTypes;
this.db = db;
this.projectName = projectName;
this.categoryId = categoryId;
this.groupName = new AccountGroup.NameKey(groupName);
this.refPattern = refPattern != null ? refPattern.trim() : null;
if (min <= max) {
this.min = min;
this.max = max;
} else {
this.min = max;
this.max = min;
}
}
@Override
public ProjectDetail call() throws NoSuchProjectException, OrmException,
NoSuchGroupException, InvalidNameException, NoSuchRefException {
final ProjectControl projectControl =
projectControlFactory.controlFor(projectName);
final ApprovalType at = approvalTypes.getApprovalType(categoryId);
if (at == null || at.getValue(min) == null || at.getValue(max) == null) {
throw new IllegalArgumentException("Invalid category " + categoryId
+ " or range " + min + ".." + max);
}
String refPattern = this.refPattern;
if (refPattern == null || refPattern.isEmpty()) {
if (categoryId.equals(ApprovalCategory.SUBMIT)
|| categoryId.equals(ApprovalCategory.PUSH_HEAD)) {
// Explicitly related to a branch head.
refPattern = Constants.R_HEADS + "*";
} else if (!at.getCategory().isAction()) {
// Non actions are approval votes on a change, assume these apply
// to branch heads only.
refPattern = Constants.R_HEADS + "*";
} else if (categoryId.equals(ApprovalCategory.PUSH_TAG)) {
// Explicitly related to the tag namespace.
refPattern = Constants.R_TAGS + "*";
} else if (categoryId.equals(ApprovalCategory.READ)
|| categoryId.equals(ApprovalCategory.OWN)) {
// Currently these are project-wide rights, so apply that way.
refPattern = RefRight.ALL;
} else {
// Assume project wide for the default.
refPattern = RefRight.ALL;
}
}
boolean exclusive = refPattern.startsWith("-");
if (exclusive) {
refPattern = refPattern.substring(1);
}
while (refPattern.startsWith("/")) {
refPattern = refPattern.substring(1);
}
if (refPattern.startsWith(RefRight.REGEX_PREFIX)) {
String example = RefControl.shortestExample(refPattern);
if (!example.startsWith(Constants.R_REFS)) {
refPattern = RefRight.REGEX_PREFIX + Constants.R_HEADS
+ refPattern.substring(RefRight.REGEX_PREFIX.length());
example = RefControl.shortestExample(refPattern);
}
if (!Repository.isValidRefName(example)) {
throw new InvalidNameException();
}
} else {
if (!refPattern.startsWith(Constants.R_REFS)) {
refPattern = Constants.R_HEADS + refPattern;
}
if (refPattern.endsWith("/*")) {
final String prefix = refPattern.substring(0, refPattern.length() - 2);
if (!"refs".equals(prefix) && !Repository.isValidRefName(prefix)) {
throw new InvalidNameException();
}
} else {
if (!Repository.isValidRefName(refPattern)) {
throw new InvalidNameException();
}
}
}
if (!projectControl.controlForRef(refPattern).isOwner()) {
throw new NoSuchRefException(refPattern);
}
if (exclusive) {
refPattern = "-" + refPattern;
}
final AccountGroup group = groupCache.get(groupName);
if (group == null) {
throw new NoSuchGroupException(groupName);
}
final RefRight.Key key =
new RefRight.Key(projectName, new RefRight.RefPattern(refPattern),
categoryId, group.getId());
RefRight rr = db.refRights().get(key);
if (rr == null) {
rr = new RefRight(key);
rr.setMinValue(min);
rr.setMaxValue(max);
db.refRights().insert(Collections.singleton(rr));
} else {
rr.setMinValue(min);
rr.setMaxValue(max);
db.refRights().update(Collections.singleton(rr));
}
projectCache.evictAll();
return projectDetailFactory.create(projectName).call();
}
}

View File

@ -1,91 +0,0 @@
// Copyright (C) 2010 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.httpd.rpc.project;
import com.google.gerrit.common.data.ProjectDetail;
import com.google.gerrit.httpd.rpc.Handler;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.RefRight;
import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.NoSuchRefException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gwtorm.client.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.util.Collections;
import java.util.Set;
class DeleteRefRights extends Handler<ProjectDetail> {
interface Factory {
DeleteRefRights create(@Assisted Project.NameKey projectName,
@Assisted Set<RefRight.Key> toRemove);
}
private final ProjectDetailFactory.Factory projectDetailFactory;
private final ProjectControl.Factory projectControlFactory;
private final ProjectCache projectCache;
private final ReviewDb db;
private final Project.NameKey projectName;
private final Set<RefRight.Key> toRemove;
@Inject
DeleteRefRights(final ProjectDetailFactory.Factory projectDetailFactory,
final ProjectControl.Factory projectControlFactory,
final ProjectCache projectCache, final ReviewDb db,
@Assisted final Project.NameKey projectName,
@Assisted final Set<RefRight.Key> toRemove) {
this.projectDetailFactory = projectDetailFactory;
this.projectControlFactory = projectControlFactory;
this.projectCache = projectCache;
this.db = db;
this.projectName = projectName;
this.toRemove = toRemove;
}
@Override
public ProjectDetail call() throws NoSuchProjectException, OrmException,
NoSuchRefException {
final ProjectControl projectControl =
projectControlFactory.controlFor(projectName);
for (final RefRight.Key k : toRemove) {
if (!projectName.equals(k.getProjectNameKey())) {
throw new IllegalArgumentException("All keys must be from same project");
}
String refPattern = k.getRefPattern();
if (refPattern.startsWith("-")) {
refPattern = refPattern.substring(1);
}
if (!projectControl.controlForRef(refPattern).isOwner()) {
throw new NoSuchRefException(refPattern);
}
}
for (final RefRight.Key k : toRemove) {
final RefRight m = db.refRights().get(k);
if (m != null) {
db.refRights().delete(Collections.singleton(m));
}
}
projectCache.evictAll();
return projectDetailFactory.create(projectName).call();
}
}

View File

@ -17,10 +17,8 @@ package com.google.gerrit.httpd.rpc.project;
import com.google.gerrit.common.data.ListBranchesResult;
import com.google.gerrit.common.data.ProjectAdminService;
import com.google.gerrit.common.data.ProjectDetail;
import com.google.gerrit.reviewdb.ApprovalCategory;
import com.google.gerrit.reviewdb.Branch;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.RefRight;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
@ -34,8 +32,6 @@ class ProjectAdminServiceImpl implements ProjectAdminService {
private final ListBranches.Factory listBranchesFactory;
private final VisibleProjects.Factory visibleProjectsFactory;
private final ProjectDetailFactory.Factory projectDetailFactory;
private final AddRefRight.Factory addRefRightFactory;
private final DeleteRefRights.Factory deleteRefRightsFactory;
@Inject
ProjectAdminServiceImpl(final AddBranch.Factory addBranchFactory,
@ -43,17 +39,13 @@ class ProjectAdminServiceImpl implements ProjectAdminService {
final DeleteBranches.Factory deleteBranchesFactory,
final ListBranches.Factory listBranchesFactory,
final VisibleProjects.Factory visibleProjectsFactory,
final ProjectDetailFactory.Factory projectDetailFactory,
final AddRefRight.Factory addRefRightFactory,
final DeleteRefRights.Factory deleteRefRightsFactory) {
final ProjectDetailFactory.Factory projectDetailFactory) {
this.addBranchFactory = addBranchFactory;
this.changeProjectSettingsFactory = changeProjectSettingsFactory;
this.deleteBranchesFactory = deleteBranchesFactory;
this.listBranchesFactory = listBranchesFactory;
this.visibleProjectsFactory = visibleProjectsFactory;
this.projectDetailFactory = projectDetailFactory;
this.addRefRightFactory = addRefRightFactory;
this.deleteRefRightsFactory = deleteRefRightsFactory;
}
@Override
@ -73,21 +65,6 @@ class ProjectAdminServiceImpl implements ProjectAdminService {
changeProjectSettingsFactory.create(update).to(callback);
}
@Override
public void deleteRight(final Project.NameKey projectName,
final Set<RefRight.Key> toRemove, final AsyncCallback<ProjectDetail> callback) {
deleteRefRightsFactory.create(projectName, toRemove).to(callback);
}
@Override
public void addRight(final Project.NameKey projectName,
final ApprovalCategory.Id categoryId, final String groupName,
final String refPattern, final short min, final short max,
final AsyncCallback<ProjectDetail> callback) {
addRefRightFactory.create(projectName, categoryId, groupName, refPattern,
min, max).to(callback);
}
@Override
public void listBranches(final Project.NameKey projectName,
final AsyncCallback<ListBranchesResult> callback) {

View File

@ -14,50 +14,28 @@
package com.google.gerrit.httpd.rpc.project;
import com.google.gerrit.common.data.ApprovalType;
import com.google.gerrit.common.data.ApprovalTypes;
import com.google.gerrit.common.data.InheritedRefRight;
import com.google.gerrit.common.data.ProjectDetail;
import com.google.gerrit.httpd.rpc.Handler;
import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.RefRight;
import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.project.RefControl;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
class ProjectDetailFactory extends Handler<ProjectDetail> {
interface Factory {
ProjectDetailFactory create(@Assisted Project.NameKey name);
}
private final ApprovalTypes approvalTypes;
private final GroupCache groupCache;
private final ProjectControl.Factory projectControlFactory;
private final Project.NameKey projectName;
private Map<AccountGroup.Id, AccountGroup> groups;
@Inject
ProjectDetailFactory(final ApprovalTypes approvalTypes,
final GroupCache groupCache,
final ProjectControl.Factory projectControlFactory,
ProjectDetailFactory(final ProjectControl.Factory projectControlFactory,
@Assisted final Project.NameKey name) {
this.approvalTypes = approvalTypes;
this.groupCache = groupCache;
this.projectControlFactory = projectControlFactory;
this.projectName = name;
@ -72,88 +50,13 @@ class ProjectDetailFactory extends Handler<ProjectDetail> {
final ProjectDetail detail = new ProjectDetail();
detail.setProject(projectState.getProject());
groups = new HashMap<AccountGroup.Id, AccountGroup>();
final List<InheritedRefRight> refRights = new ArrayList<InheritedRefRight>();
for (final RefRight r : projectState.getInheritedRights()) {
RefControl rc = pc.controlForRef(r.getRefPattern());
boolean isOwner = rc.isOwner();
if (!isOwner && !rc.isVisible()) {
continue;
}
InheritedRefRight refRight = new InheritedRefRight(r, true, isOwner);
if (!refRights.contains(refRight)) {
refRights.add(refRight);
wantGroup(r.getAccountGroupId());
}
}
for (final RefRight r : projectState.getLocalRights()) {
RefControl rc = pc.controlForRef(r.getRefPattern());
boolean isOwner = rc.isOwner();
if (!isOwner && !rc.isVisible()) {
continue;
}
refRights.add(new InheritedRefRight(r, false, isOwner));
wantGroup(r.getAccountGroupId());
}
loadGroups();
Collections.sort(refRights, new Comparator<InheritedRefRight>() {
@Override
public int compare(final InheritedRefRight a, final InheritedRefRight b) {
final RefRight right1 = a.getRight();
final RefRight right2 = b.getRight();
int rc = categoryOf(right1).compareTo(categoryOf(right2));
if (rc == 0) {
rc = right1.getRefPattern().compareTo(right2.getRefPattern());
}
if (rc == 0) {
rc = groupOf(right1).compareTo(groupOf(right2));
}
return rc;
}
private String categoryOf(final RefRight r) {
final ApprovalType type =
approvalTypes.getApprovalType(r.getApprovalCategoryId());
if (type == null) {
return r.getApprovalCategoryId().get();
}
return type.getCategory().getName();
}
private String groupOf(final RefRight r) {
return groups.get(r.getAccountGroupId()).getName();
}
});
final boolean userIsOwner = pc.isOwner();
final boolean userIsOwnerAnyRef = pc.isOwnerAnyRef();
detail.setRights(refRights);
detail.setGroups(groups);
detail.setCanModifyAccess(userIsOwnerAnyRef);
detail.setCanModifyAgreements(userIsOwner);
detail.setCanModifyDescription(userIsOwner);
detail.setCanModifyMergeType(userIsOwner);
return detail;
}
private void wantGroup(final AccountGroup.Id id) {
groups.put(id, null);
}
private void loadGroups() {
final Set<AccountGroup.Id> toGet = groups.keySet();
groups = new HashMap<AccountGroup.Id, AccountGroup>();
for (AccountGroup.Id groupId : toGet) {
groups.put(groupId, groupCache.get(groupId));
}
}
}

View File

@ -29,10 +29,8 @@ public class ProjectModule extends RpcServletModule {
@Override
protected void configure() {
factory(AddBranch.Factory.class);
factory(AddRefRight.Factory.class);
factory(ChangeProjectSettings.Factory.class);
factory(DeleteBranches.Factory.class);
factory(DeleteRefRights.Factory.class);
factory(ListBranches.Factory.class);
factory(VisibleProjects.Factory.class);
factory(ProjectDetailFactory.Factory.class);