io.imunity.scim.console.OptionalGroupWithWildcardSelection Maven / Gradle / Ivy
/*
* Copyright (c) 2021 Bixbit - Krzysztof Benedyczak. All rights reserved.
* See LICENCE.txt file for licensing information.
*/
package io.imunity.scim.console;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.util.StringUtils;
import com.vaadin.flow.component.combobox.MultiSelectComboBox;
import com.vaadin.flow.component.combobox.dataview.ComboBoxListDataView;
import com.vaadin.flow.data.selection.MultiSelectionEvent;
import elemental.json.Json;
import elemental.json.JsonArray;
import elemental.json.JsonObject;
import pl.edu.icm.unity.base.group.Group;
import pl.edu.icm.unity.base.message.MessageSource;
import pl.edu.icm.unity.engine.api.registration.GroupPatternMatcher;
import io.imunity.vaadin.auth.services.idp.GroupSelectionHelper;
import io.imunity.vaadin.auth.services.idp.GroupSelectionHelper.GroupNameComparator;
class OptionalGroupWithWildcardSelection extends MultiSelectComboBox
{
private Set items;
private MessageSource msg;
OptionalGroupWithWildcardSelection(MessageSource msg)
{
this.msg = msg;
items = new HashSet<>();
setAllowCustomValue(true);
addCustomValueSetListener(event ->
{
HashSet values = new HashSet<>(getValue());
values.add(new Group(event.getDetail()));
setValue(values);
});
addSelectionListener(e ->
{
if (!e.isFromClient())
{
refresh();
return;
}
if (e.getAddedSelection() != null && !e.getAddedSelection()
.isEmpty())
{
onAddedGroupSelection(e);
}
refresh();
});
}
private void refresh()
{
refreshValue();
List setItems = checkAvailableItems(items, getValue());
GroupSelectionHelper.sort(setItems, new GroupSelectionHelper.GroupNameComparator(msg));
final int min = GroupSelectionHelper.getMinIndent(setItems);
super.setItems(setItems);
setItemLabelGenerator(
g -> GroupSelectionHelper.generateIndent(StringUtils.countOccurrencesOf(g.toString(), "/") - min)
+ g.getDisplayedName()
.getValue(msg));
}
private void onAddedGroupSelection(MultiSelectionEvent, Group> event)
{
Group newGroup = event.getAddedSelection()
.iterator()
.next();
if (newGroup == null)
return;
Set newGroups = evalSelected(event.getAddedSelection());
List selected = new ArrayList<>(getSelectedItems());
for (Group g : evalSelected(getSelectedItems()))
{
if (!g.getPathEncoded()
.equals(newGroup.getPathEncoded()))
{
newGroups.forEach(ng ->
{
if (g.isChild(ng))
{
selected.remove(g);
}
});
}
}
setValue(selected.stream()
.collect(Collectors.toSet()));
}
protected List checkAvailableItems(Set allItems, Set selected)
{
Set remaining = allItems.stream()
.filter(i -> !selected.contains(i))
.collect(Collectors.toSet());
Set ret = new HashSet<>(remaining);
selected.forEach(selG -> remaining.forEach(remG ->
{
if (remG.isChild(selG))
ret.remove(remG);
}));
return ret.stream()
.collect(Collectors.toList());
}
private Set evalSelected(Collection selected)
{
List all = items.stream()
.collect(Collectors.toList());
Set rselected = new HashSet<>();
selected.forEach(s -> rselected.addAll(GroupPatternMatcher.filterMatching(all, s.getPathEncoded())));
return rselected;
}
@Override
protected void refreshValue()
{
Set value = getValue();
if (value == null || value.isEmpty())
{
return;
}
JsonArray selectedItems = modelToPresentation(this, value, msg);
getElement().setPropertyJson("selectedItems", selectedItems);
}
private static JsonArray modelToPresentation(OptionalGroupWithWildcardSelection multiSelectComboBox,
Set model, MessageSource msg)
{
JsonArray array = Json.createArray();
if (model == null || model.isEmpty())
{
return array;
}
List sortedModel = new ArrayList(model);
GroupSelectionHelper.sort(sortedModel, new GroupNameComparator(msg));
sortedModel.stream()
.map(g -> multiSelectComboBox.generateJson(g))
.forEach(jsonObject -> array.set(array.length(), jsonObject));
return array;
}
private JsonObject generateJson(Group item)
{
JsonObject jsonObject = Json.createObject();
jsonObject.put("key", getKeyMapper().key(item));
getDataGenerator().generateData(item, jsonObject);
jsonObject.put("label", jsonObject.getString("label")
.replace(GroupSelectionHelper.GROUPS_TREE_INDENT_CHAR, ""));
return jsonObject;
}
@Override
public ComboBoxListDataView setItems(Collection items)
{
List sorted = items.stream()
.collect(Collectors.toList());
GroupSelectionHelper.sort(sorted, new GroupSelectionHelper.GroupNameComparator(msg));
ComboBoxListDataView stringComboBoxListDataView = super.setItems(sorted);
this.items = stringComboBoxListDataView.getItems()
.collect(Collectors.toSet());
final int min = GroupSelectionHelper.getMinIndent(sorted);
setItemLabelGenerator(
g -> GroupSelectionHelper.generateIndent(StringUtils.countOccurrencesOf(g.toString(), "/") - min)
+ g.getDisplayedName()
.getValue(msg));
return stringComboBoxListDataView;
}
@Override
public void setValue(Set values)
{
if (values == null)
return;
items.addAll(values);
setItems(items);
super.setValue(values);
}
}