blob: 9848c1836fb82eecc2f023ae8ac9170b3067e074 [file] [log] [blame]
// Copyright (C) 2011 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.rpc.GerritCallback;
import com.google.gerrit.client.ui.SuggestUtil;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelTypes;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRange;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.common.data.RefConfigSection;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.editor.client.Editor;
import com.google.gwt.editor.client.EditorDelegate;
import com.google.gwt.editor.client.ValueAwareEditor;
import com.google.gwt.editor.client.adapters.EditorSource;
import com.google.gwt.editor.client.adapters.ListEditor;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.ValueLabel;
import java.util.ArrayList;
import java.util.List;
public class PermissionEditor extends Composite implements Editor<Permission>,
ValueAwareEditor<Permission> {
interface Binder extends UiBinder<HTMLPanel, PermissionEditor> {
}
private static final Binder uiBinder = GWT.create(Binder.class);
@UiField(provided = true)
@Path("name")
ValueLabel<String> normalName;
@UiField(provided = true)
@Path("name")
ValueLabel<String> deletedName;
@UiField
CheckBox exclusiveGroup;
@UiField
FlowPanel ruleContainer;
ListEditor<PermissionRule, PermissionRuleEditor> rules;
@UiField
DivElement addContainer;
@UiField
DivElement addStage1;
@UiField
DivElement addStage2;
@UiField
Anchor beginAddRule;
@UiField
@Editor.Ignore
GroupReferenceBox groupToAdd;
@UiField
Button addRule;
@UiField
Anchor deletePermission;
@UiField
DivElement normal;
@UiField
DivElement deleted;
private final Project.NameKey projectName;
private final boolean readOnly;
private final AccessSection section;
private final LabelTypes labelTypes;
private Permission value;
private PermissionRange.WithDefaults validRange;
private boolean isDeleted;
public PermissionEditor(Project.NameKey projectName,
boolean readOnly,
AccessSection section,
LabelTypes labelTypes) {
this.readOnly = readOnly;
this.section = section;
this.projectName = projectName;
this.labelTypes = labelTypes;
normalName = new ValueLabel<String>(PermissionNameRenderer.INSTANCE);
deletedName = new ValueLabel<String>(PermissionNameRenderer.INSTANCE);
initWidget(uiBinder.createAndBindUi(this));
groupToAdd.setProject(projectName);
rules = ListEditor.of(new RuleEditorSource());
exclusiveGroup.setEnabled(!readOnly);
exclusiveGroup.setVisible(RefConfigSection
.isValid(section.getName()));
if (readOnly) {
addContainer.removeFromParent();
addContainer = null;
deletePermission.removeFromParent();
deletePermission = null;
}
}
@UiHandler("deletePermission")
void onDeleteHover(MouseOverEvent event) {
addStyleName(AdminResources.I.css().deleteSectionHover());
}
@UiHandler("deletePermission")
void onDeleteNonHover(MouseOutEvent event) {
removeStyleName(AdminResources.I.css().deleteSectionHover());
}
@UiHandler("deletePermission")
void onDeletePermission(ClickEvent event) {
isDeleted = true;
normal.getStyle().setDisplay(Display.NONE);
deleted.getStyle().setDisplay(Display.BLOCK);
}
@UiHandler("undoDelete")
void onUndoDelete(ClickEvent event) {
isDeleted = false;
deleted.getStyle().setDisplay(Display.NONE);
normal.getStyle().setDisplay(Display.BLOCK);
}
@UiHandler("beginAddRule")
void onBeginAddRule(ClickEvent event) {
beginAddRule();
}
void beginAddRule() {
addStage1.getStyle().setDisplay(Display.NONE);
addStage2.getStyle().setDisplay(Display.BLOCK);
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
groupToAdd.setFocus(true);
}
});
}
@UiHandler("addRule")
void onAddGroupByClick(ClickEvent event) {
GroupReference ref = groupToAdd.getValue();
if (ref != null) {
addGroup(ref);
} else {
groupToAdd.setFocus(true);
}
}
@UiHandler("groupToAdd")
void onAddGroupByEnter(SelectionEvent<GroupReference> event) {
GroupReference ref = event.getSelectedItem();
if (ref != null) {
addGroup(ref);
}
}
@UiHandler("groupToAdd")
void onAbortAddGroup(CloseEvent<GroupReferenceBox> event) {
hideAddGroup();
}
@UiHandler("hideAddGroup")
void hideAddGroup(ClickEvent event) {
hideAddGroup();
}
private void hideAddGroup() {
addStage1.getStyle().setDisplay(Display.BLOCK);
addStage2.getStyle().setDisplay(Display.NONE);
}
private void addGroup(GroupReference ref) {
if (ref.getUUID() != null) {
if (value.getRule(ref) == null) {
PermissionRule newRule = value.getRule(ref, true);
if (validRange != null) {
int min = validRange.getDefaultMin();
int max = validRange.getDefaultMax();
newRule.setRange(min, max);
} else if (GlobalCapability.PRIORITY.equals(value.getName())) {
newRule.setAction(PermissionRule.Action.BATCH);
}
rules.getList().add(newRule);
}
groupToAdd.setValue(null);
groupToAdd.setFocus(true);
} else {
// If the oracle didn't get to complete a UUID, resolve it now.
//
addRule.setEnabled(false);
SuggestUtil.SVC.suggestAccountGroupForProject(
projectName, ref.getName(), 1,
new GerritCallback<List<GroupReference>>() {
@Override
public void onSuccess(List<GroupReference> result) {
addRule.setEnabled(true);
if (result.size() == 1) {
addGroup(result.get(0));
} else {
groupToAdd.setFocus(true);
}
}
@Override
public void onFailure(Throwable caught) {
addRule.setEnabled(true);
super.onFailure(caught);
}
});
}
}
boolean isDeleted() {
return isDeleted;
}
@Override
public void setValue(Permission value) {
this.value = value;
if (value.isLabel()) {
LabelType lt = labelTypes.byLabel(value.getLabel());
if (lt != null) {
validRange = new PermissionRange.WithDefaults(
value.getName(),
lt.getMin().getValue(), lt.getMax().getValue(),
lt.getMin().getValue(), lt.getMax().getValue());
}
} else if (GlobalCapability.isCapability(value.getName())) {
validRange = GlobalCapability.getRange(value.getName());
} else {
validRange = null;
}
if (value != null && Permission.OWNER.equals(value.getName())) {
exclusiveGroup.setEnabled(false);
} else {
exclusiveGroup.setEnabled(!readOnly);
}
}
@Override
public void flush() {
List<PermissionRule> src = rules.getList();
List<PermissionRule> keep = new ArrayList<PermissionRule>(src.size());
for (int i = 0; i < src.size(); i++) {
PermissionRuleEditor e =
(PermissionRuleEditor) ruleContainer.getWidget(i);
if (!e.isDeleted()) {
keep.add(src.get(i));
}
}
value.setRules(keep);
}
@Override
public void onPropertyChange(String... paths) {
}
@Override
public void setDelegate(EditorDelegate<Permission> delegate) {
}
private class RuleEditorSource extends EditorSource<PermissionRuleEditor> {
@Override
public PermissionRuleEditor create(int index) {
PermissionRuleEditor subEditor =
new PermissionRuleEditor(readOnly, section, value, validRange);
ruleContainer.insert(subEditor, index);
return subEditor;
}
@Override
public void dispose(PermissionRuleEditor subEditor) {
subEditor.removeFromParent();
}
@Override
public void setIndex(PermissionRuleEditor subEditor, int index) {
ruleContainer.insert(subEditor, index);
}
}
}