/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE file at the root of the source
* tree and available online at
*
* https://github.com/keeps/roda
*/
/**
*
*/
package org.roda.wui.client.management;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.MissingResourceException;
import java.util.Set;
import java.util.Vector;
import org.roda.wui.client.common.UserLogin;
import org.roda.wui.common.client.ClientLogger;
import org.roda.wui.common.client.widgets.LoadingPopup;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
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.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import config.i18n.client.ClientMessages;
/**
* @author Luis Faria
*
*/
public class PermissionsPanel extends FlowPanel implements HasValueChangeHandlers<List<String>> {
private class Permission extends HorizontalPanel implements HasValueChangeHandlers<String>, Comparable<Permission> {
private final String sortingkeyword;
private final String role;
private boolean locked;
private boolean enabled;
private final CheckBox checkbox;
private final Label descriptionLabel;
public Permission(String role, String description, String sortingkeyword) {
this.role = role;
this.checkbox = new CheckBox();
this.descriptionLabel = new Label(description);
this.sortingkeyword = sortingkeyword;
this.add(checkbox);
this.add(descriptionLabel);
this.locked = false;
this.enabled = true;
this.descriptionLabel.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if (isEnabled() && !locked) {
checkbox.setValue(!checkbox.getValue());
onChange();
}
}
});
this.checkbox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
onChange();
}
});
this.addStyleName("permission");
checkbox.addStyleName("permission-checkbox");
descriptionLabel.setStylePrimaryName("permission-description");
}
public boolean isLocked() {
return locked;
}
public void setLocked(boolean locked) {
this.locked = locked;
checkbox.setEnabled(!locked);
}
public boolean isChecked() {
return checkbox.getValue();
}
public void setChecked(boolean checked) {
checkbox.setValue(checked);
}
public String getRole() {
return role;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
if (!locked) {
this.checkbox.setEnabled(enabled);
if (enabled) {
this.descriptionLabel.removeStyleDependentName("off");
this.descriptionLabel.addStyleDependentName("on");
} else {
this.descriptionLabel.removeStyleDependentName("on");
this.descriptionLabel.addStyleDependentName("off");
}
}
}
@Override
public int compareTo(Permission permission) {
return sortingkeyword.compareTo(permission.sortingkeyword);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result + ((checkbox == null) ? 0 : checkbox.hashCode());
result = prime * result + ((descriptionLabel == null) ? 0 : descriptionLabel.hashCode());
result = prime * result + (enabled ? 1231 : 1237);
result = prime * result + (locked ? 1231 : 1237);
result = prime * result + ((role == null) ? 0 : role.hashCode());
result = prime * result + ((sortingkeyword == null) ? 0 : sortingkeyword.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Permission other = (Permission) obj;
if (!getOuterType().equals(other.getOuterType()))
return false;
if (enabled != other.enabled)
return false;
if (locked != other.locked)
return false;
if (role == null) {
if (other.role != null)
return false;
} else if (!role.equals(other.role))
return false;
if (sortingkeyword == null) {
if (other.sortingkeyword != null)
return false;
} else if (!sortingkeyword.equals(other.sortingkeyword))
return false;
return true;
}
@SuppressWarnings("unused")
public String getSortingkeyword() {
return sortingkeyword;
}
@Override
public HandlerRegistration addValueChangeHandler(ValueChangeHandler<String> handler) {
return addHandler(handler, ValueChangeEvent.getType());
}
protected void onChange() {
ValueChangeEvent.fire(this, getValue());
}
public String getValue() {
return getRole();
}
private PermissionsPanel getOuterType() {
return PermissionsPanel.this;
}
}
private static ClientMessages messages = (ClientMessages) GWT.create(ClientMessages.class);
@SuppressWarnings("unused")
private final ClientLogger logger = new ClientLogger(getClass().getName());
private final List<Permission> permissions;
private List<String> userSelections;
private boolean enabled;
private final LoadingPopup loading;
/**
*
*/
public PermissionsPanel() {
this.permissions = new Vector<>();
this.userSelections = new Vector<>();
loading = new LoadingPopup(this);
loading.show();
this.enabled = true;
this.addStyleName("permissions");
}
public void init(final AsyncCallback<Boolean> callback) {
UserLogin.getRodaProperties(new AsyncCallback<Map<String, String>>() {
@Override
public void onFailure(Throwable caught) {
loading.hide();
callback.onFailure(caught);
}
@Override
public void onSuccess(Map<String, String> rodaProperties) {
for (Entry<String, String> entry : rodaProperties.entrySet()) {
String key = entry.getKey();
if (key.startsWith("ui.role.")) {
String role = entry.getValue();
String description;
try {
description = messages.role(role);
} catch (MissingResourceException e) {
description = role + " (needs translation)";
}
Permission permission = new Permission(role, description, key);
permissions.add(permission);
}
}
Collections.sort(permissions);
for (final Permission permission : permissions) {
PermissionsPanel.this.add(permission);
permission.addValueChangeHandler(new ValueChangeHandler<String>() {
@Override
public void onValueChange(ValueChangeEvent<String> event) {
if (userSelections.contains(event.getValue())) {
userSelections.remove(event.getValue());
} else {
userSelections.add(event.getValue());
}
onChange();
}
});
}
loading.hide();
callback.onSuccess(true);
}
});
}
public List<String> getUserSelections() {
return userSelections;
}
/**
* Set all permissions defined by roles checked and set locked with parameters
*
* @param roles
* roles of the permissions to check
* @param lock
* if permissions should also be locked
*/
public void checkPermissions(Set<String> roles, boolean lock) {
Iterator<String> it = roles.iterator();
while (it.hasNext()) {
String role = it.next();
boolean foundit = false;
for (Iterator<Permission> j = permissions.iterator(); j.hasNext() && !foundit;) {
Permission p = j.next();
if (p.getRole().equals(role)) {
foundit = true;
p.setChecked(true);
p.setLocked(lock);
}
}
}
}
@Override
public void clear() {
for (Permission p : permissions) {
p.setChecked(false);
p.setLocked(false);
}
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
for (Permission p : permissions) {
p.setEnabled(enabled);
}
}
public void updateLockedPermissions(Set<String> memberGroups) {
if (!memberGroups.isEmpty()) {
this.setEnabled(false);
loading.show();
}
}
/**
* Get roles that are directly defined, i.e. are not inherited
*
* @return
*/
public Set<String> getDirectRoles() {
List<Permission> checkedPermissions = new ArrayList<>();
for (Permission p : permissions) {
if (p.isChecked() && !p.isLocked()) {
checkedPermissions.add(p);
}
}
Set<String> specialRoles = new HashSet<>();
for (int i = 0; i < checkedPermissions.size(); i++) {
specialRoles.add(checkedPermissions.get(i).getRole());
}
return specialRoles;
}
@Override
public HandlerRegistration addValueChangeHandler(ValueChangeHandler<List<String>> handler) {
return addHandler(handler, ValueChangeEvent.getType());
}
protected void onChange() {
ValueChangeEvent.fire(this, getValue());
}
public List<String> getValue() {
return getUserSelections();
}
}