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:
		@@ -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();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user