This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch 4_1_X
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/4_1_X by this push:
     new f13b9a4cc3 [SYNCOPE-1956] Ensure to build empty multivalue attrs 
(#1324)
f13b9a4cc3 is described below

commit f13b9a4cc34964c6b644b49c370b2afd6eff3893
Author: Francesco Chicchiriccò <[email protected]>
AuthorDate: Fri Mar 20 18:24:43 2026 +0100

    [SYNCOPE-1956] Ensure to build empty multivalue attrs (#1324)
---
 .../wizards/any/LinkedAccountPlainAttrsPanel.java  |  54 ++++---
 .../commons/markup/html/form/AjaxPalettePanel.java |   6 +-
 .../syncope/client/console/PreferenceManager.java  |   6 +-
 .../client/console/layout/AnyLayoutUtils.java      |   6 +-
 .../console/panels/AbstractDisplayModalPanel.java  |   2 +-
 .../client/console/panels/AnyDirectoryPanel.java   |   2 +-
 .../client/console/panels/RealmDirectoryPanel.java |   2 +-
 .../wizards/any/AbstractAttrsWizardStep.java       |  29 ++--
 .../client/console/wizards/any/DerAttrs.java       |   8 +-
 .../client/console/wizards/any/PlainAttrs.java     |  17 +-
 .../syncope/client/console/wizards/any/Roles.java  |  13 --
 .../syncope/client/console/wizards/any/Roles.html  |  13 +-
 .../client/console/wizards/any/Roles.properties    |   1 -
 .../console/wizards/any/Roles_fr_CA.properties     |   3 +-
 .../client/console/wizards/any/Roles_it.properties |   1 -
 .../client/console/wizards/any/Roles_ja.properties |   1 -
 .../console/wizards/any/Roles_pt_BR.properties     |   1 -
 .../client/console/wizards/any/Roles_ru.properties |   4 +-
 .../syncope/client/enduser/PreferenceManager.java  | 174 ---------------------
 .../org/apache/syncope/common/lib/to/UserTO.java   |   8 -
 .../fit/console/AjaxPalettePanelITCase.java        |  15 +-
 21 files changed, 71 insertions(+), 295 deletions(-)

diff --git 
a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java
 
b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java
index 29facf423c..c926f94b4c 100644
--- 
a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java
+++ 
b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountPlainAttrsPanel.java
@@ -25,8 +25,10 @@ import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
+import org.apache.commons.lang3.StringUtils;
 import 
org.apache.syncope.client.console.commons.LinkedAccountPlainAttrProperty;
 import org.apache.syncope.client.ui.commons.Constants;
 import 
org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
@@ -42,6 +44,7 @@ import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.LinkedAccountTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
@@ -81,8 +84,8 @@ public class LinkedAccountPlainAttrsPanel extends 
AbstractAttrsWizardStep<PlainS
 
         this.linkedAccountTO = modelObject.getInnerObject();
         this.fixedAttrs.addAll(this.linkedAccountTO.getPlainAttrs().stream().
-                filter(attrTO -> checkIsReadonlyAttr(attrTO.getSchema())).
-            toList());
+                filter(attr -> isReadonly(attr.getSchema())).
+                toList());
         this.userTO = userTO;
 
         add(new Accordion("plainSchemas", List.of(new AbstractTab(
@@ -97,6 +100,10 @@ public class LinkedAccountPlainAttrsPanel extends 
AbstractAttrsWizardStep<PlainS
         }), Model.of(0)).setOutputMarkupId(true));
     }
 
+    private boolean isReadonly(final String schema) {
+        return schemas.isEmpty() ? true : !schemas.get(schema).isReadonly();
+    }
+
     @Override
     protected FormComponent<?> checkboxToggle(
             final Attr attrTO,
@@ -115,11 +122,10 @@ public class LinkedAccountPlainAttrsPanel extends 
AbstractAttrsWizardStep<PlainS
                     return newProperty;
                 });
 
-        final BootstrapToggleConfig config = new BootstrapToggleConfig().
+        BootstrapToggleConfig config = new BootstrapToggleConfig().
                 withOnStyle(BootstrapToggleConfig.Style.success).
                 withOffStyle(BootstrapToggleConfig.Style.danger).
                 withSize(BootstrapToggleConfig.Size.mini);
-
         return new BootstrapToggle("externalAction", new 
PropertyModel<>(property, "overridable"), config) {
 
             private static final long serialVersionUID = -875219845189261873L;
@@ -166,8 +172,8 @@ public class LinkedAccountPlainAttrsPanel extends 
AbstractAttrsWizardStep<PlainS
 
     private void updateAccountPlainSchemas(final 
LinkedAccountPlainAttrProperty property, final Boolean modelObject) {
         Set<Attr> withoutCurrentSchema = new 
HashSet<>(linkedAccountTO.getPlainAttrs().stream().
-                filter(attrTO -> 
!attrTO.getSchema().equals(property.getSchema())
-                && checkIsReadonlyAttr(attrTO.getSchema())).
+                filter(attr -> !attr.getSchema().equals(property.getSchema())
+                && isReadonly(attr.getSchema())).
                 collect(Collectors.toSet()));
         linkedAccountTO.getPlainAttrs().clear();
         linkedAccountTO.getPlainAttrs().addAll(withoutCurrentSchema);
@@ -186,28 +192,28 @@ public class LinkedAccountPlainAttrsPanel extends 
AbstractAttrsWizardStep<PlainS
 
     @Override
     protected void setAttrs() {
-        List<Attr> attrs = new ArrayList<>();
+        List<Attr> plainAttrs = new ArrayList<>();
         List<PlainSchemaTO> notReadonlyValues = schemas.values().stream().
-                filter(schema -> checkIsReadonlyAttr(schema.getKey())).
-                collect(Collectors.toList());
+                filter(schema -> !schema.isReadonly()).
+                toList();
         setFixedAttr(notReadonlyValues);
         Map<String, Attr> attrMap = EntityTOUtils.buildAttrMap(fixedAttrs);
 
-        attrs.addAll(notReadonlyValues.stream().
-                map(schema -> {
-                    Attr attrTO = new Attr();
-                    attrTO.setSchema(schema.getKey());
-                    if (attrMap.get(schema.getKey()) == null || 
attrMap.get(schema.getKey()).getValues().isEmpty()) {
-                        attrTO.getValues().add("");
-                    } else {
-                        attrTO = attrMap.get(schema.getKey());
-                    }
-                    return attrTO;
-                }).
-            toList());
+        plainAttrs.addAll(notReadonlyValues.stream().map(schema -> {
+            Attr attr = 
Optional.ofNullable(attrMap.get(schema.getKey())).orElseGet(() -> {
+                Attr newAttr = new Attr();
+                newAttr.setSchema(schema.getKey());
+                return newAttr;
+            });
+            if ((schema.getType() != AttrSchemaType.Dropdown || 
!schema.isMultivalue()) && attr.getValues().isEmpty()) {
+                attr.getValues().add(StringUtils.EMPTY);
+            }
+
+            return attr;
+        }).toList());
 
         fixedAttrs.clear();
-        fixedAttrs.addAll(attrs);
+        fixedAttrs.addAll(plainAttrs);
     }
 
     @Override
@@ -221,10 +227,6 @@ public class LinkedAccountPlainAttrsPanel extends 
AbstractAttrsWizardStep<PlainS
                 () -> 
userTO.getPlainAttr(schema.getKey()).ifPresent(fixedAttrs::add)));
     }
 
-    private boolean checkIsReadonlyAttr(final String schema) {
-        return schemas.isEmpty() ? true : !schemas.get(schema).isReadonly();
-    }
-
     private class PlainSchemasOwn extends PlainSchemas<List<Attr>> {
 
         private static final long serialVersionUID = -4730563859116024676L;
diff --git 
a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPalettePanel.java
 
b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPalettePanel.java
index 723d813209..2dd541b0cb 100644
--- 
a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPalettePanel.java
+++ 
b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPalettePanel.java
@@ -220,14 +220,10 @@ public class AjaxPalettePanel<T extends Serializable> 
extends AbstractFieldPanel
 
     @Override
     public AjaxPalettePanel<T> setModelObject(final List<T> object) {
-        palette.setDefaultModelObject(object);
+        palette.setModelObject(object);
         return this;
     }
 
-    public Collection<T> getModelCollection() {
-        return palette.getModelCollection();
-    }
-
     public void reload(final AjaxRequestTarget target) {
         target.add(palette);
     }
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/PreferenceManager.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/PreferenceManager.java
index 3624b6e34e..686421732d 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/PreferenceManager.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/PreferenceManager.java
@@ -159,14 +159,10 @@ public final class PreferenceManager implements 
Serializable {
         }
     }
 
-    public static void setList(final String key, final List<String> values) {
+    public static void set(final String key, final List<String> values) {
         set(key, String.join(";", values));
     }
 
-    public static void setList(final Map<String, List<String>> prefs) {
-        set(prefs);
-    }
-
     private PreferenceManager() {
         // private constructor for static utility class
     }
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/layout/AnyLayoutUtils.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/layout/AnyLayoutUtils.java
index 6b39e42a05..7a1eb353a7 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/layout/AnyLayoutUtils.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/layout/AnyLayoutUtils.java
@@ -24,7 +24,6 @@ import java.lang.reflect.InvocationTargetException;
 import java.util.List;
 import java.util.function.Function;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
@@ -73,10 +72,7 @@ public final class AnyLayoutUtils {
     }
 
     public static AnyLayout fetch(final RoleRestClient roleRestClient, final 
List<String> anyTypes) {
-        List<String> ownedRoles = Stream.concat(
-                SyncopeConsoleSession.get().getSelfTO().getRoles().stream(),
-                
SyncopeConsoleSession.get().getSelfTO().getDynRoles().stream()).
-                distinct().toList();
+        List<String> ownedRoles = 
SyncopeConsoleSession.get().getSelfTO().getRoles();
         try {
             AnyLayout anyLayout = null;
             for (int i = 0; i < ownedRoles.size() && anyLayout == null; i++) {
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AbstractDisplayModalPanel.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AbstractDisplayModalPanel.java
index 050c3251d6..9997306968 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AbstractDisplayModalPanel.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AbstractDisplayModalPanel.java
@@ -118,7 +118,7 @@ public abstract class AbstractDisplayModalPanel<T extends 
Serializable> extends
             prefs.put(detailsPreferenceKey, selectedDetails);
             prefs.put(plainAttrsPreferenceKey, selectedPlainSchemas);
             prefs.put(derAttrsPreferenceKey, selectedDerSchemas);
-            PreferenceManager.setList(prefs);
+            PreferenceManager.set(prefs);
 
             
SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
             modal.close(target);
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
index 45f5d16e2e..7f5bedd1c3 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
@@ -204,7 +204,7 @@ public abstract class AnyDirectoryPanel<A extends AnyTO, E 
extends AbstractAnyRe
                         prefcolumns);
             }
 
-            PreferenceManager.setList(
+            PreferenceManager.set(
                     AnyDisplayAttributesModalPanel.getPrefDetailView(type),
                     List.of(getDefaultAttributeSelection()));
         }
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmDirectoryPanel.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmDirectoryPanel.java
index c2b3a3c2b6..52e639c0bf 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmDirectoryPanel.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmDirectoryPanel.java
@@ -193,7 +193,7 @@ public class RealmDirectoryPanel
                         prefcolumns);
             }
 
-            PreferenceManager.setList(
+            PreferenceManager.set(
                     IdRepoConstants.PREF_REALM_DETAILS_VIEW,
                     RealmDisplayAttributesModalPanel.DEFAULT_COLUMNS);
         }
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java
index 005d911401..d67689df00 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java
@@ -184,7 +184,7 @@ public abstract class AbstractAttrsWizardStep<S extends 
SchemaTO> extends Wizard
     }
 
     @SuppressWarnings("unchecked")
-    protected AbstractFieldPanel<?> getFieldPanel(final PlainSchemaTO 
plainSchema) {
+    protected AbstractFieldPanel<?> getFieldPanel(final PlainSchemaTO 
plainSchema, final ListItem<Attr> item) {
         final boolean required;
         final boolean readOnly;
         final AttrSchemaType type;
@@ -281,8 +281,10 @@ public abstract class AbstractAttrsWizardStep<S extends 
SchemaTO> extends Wizard
                                 : List.of();
                 if (plainSchema.isMultivalue()) {
                     panel = new AjaxPalettePanel.Builder<String>().
-                            
setName(plainSchema.getLabel(SyncopeConsoleSession.get().getLocale())).
-                            build("panel", new ListModel<>(), new 
ListModel<>(dropdownValues));
+                            
setName(plainSchema.getLabel(SyncopeConsoleSession.get().getLocale())).build(
+                            "panel",
+                            new PropertyModel<>(item.getModelObject(), 
"values"),
+                            new ListModel<>(dropdownValues));
                 } else {
                     panel = new AjaxDropDownChoicePanel<>("panel",
                             
plainSchema.getLabel(SyncopeConsoleSession.get().getLocale()), new Model<>(), 
true);
@@ -432,20 +434,15 @@ public abstract class AbstractAttrsWizardStep<S extends 
SchemaTO> extends Wizard
             Attr attr = item.getModelObject();
             PlainSchemaTO schema = schemas.get(attr.getSchema());
 
-            AbstractFieldPanel<?> panel = getFieldPanel(schema);
-            panel.setReadOnly(setReadOnly);
-            if (mode != AjaxWizard.Mode.TEMPLATE
-                    && schema.isMultivalue()
-                    && schema.getType() != AttrSchemaType.Dropdown) {
-
+            AbstractFieldPanel<?> panel = getFieldPanel(schema, 
item).setReadOnly(setReadOnly);
+            if (panel instanceof FieldPanel fieldPanel && mode != 
AjaxWizard.Mode.TEMPLATE && schema.isMultivalue()) {
                 // SYNCOPE-1476 set form as multipart to properly manage 
membership attributes
-                panel = new MultiFieldPanel.Builder<>(
-                        new PropertyModel<>(attr, "values")).build(
+                panel = new MultiFieldPanel.Builder<>(new 
PropertyModel<>(attr, "values")).build(
                         "panel",
                         
schema.getLabel(SyncopeConsoleSession.get().getLocale()),
-                        FieldPanel.class.cast(panel)).setFormAsMultipart(true);
-                // SYNCOPE-1215 the entire multifield panel must be readonly, 
not only its field
-                MultiFieldPanel.class.cast(panel).setFormReadOnly(setReadOnly);
+                        fieldPanel).
+                        setFormAsMultipart(true).
+                        setFormReadOnly(setReadOnly);
             } else if (panel instanceof AjaxPalettePanel ajaxPalettePanel) {
                 ajaxPalettePanel.setModelObject(attr.getValues());
             } else {
@@ -465,8 +462,8 @@ public abstract class AbstractAttrsWizardStep<S extends 
SchemaTO> extends Wizard
 
             Optional<Attr> prevAttr = 
previousObject.getPlainAttr(attr.getSchema());
             if (prevAttr.map(a -> !ListUtils.isEqualList(
-                    
a.getValues().stream().filter(StringUtils::isNotBlank).collect(Collectors.toList()),
-                    
attr.getValues().stream().filter(StringUtils::isNotBlank).collect(Collectors.toList()))).
+                    
a.getValues().stream().filter(StringUtils::isNotBlank).toList(),
+                    
attr.getValues().stream().filter(StringUtils::isNotBlank).toList())).
                     orElseGet(() -> 
attr.getValues().stream().anyMatch(StringUtils::isNotBlank))) {
 
                 List<String> oldValues = 
prevAttr.map(Attr::getValues).orElseGet(List::of);
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java
index e41ab711d9..a907487081 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java
@@ -127,13 +127,13 @@ public class DerAttrs extends AbstractAttrs<DerSchemaTO> {
         Map<String, Attr> attrMap = 
EntityTOUtils.buildAttrMap(attributable.getDerAttrs());
 
         schemas.values().forEach(schema -> {
-            Attr attrTO = new Attr();
-            attrTO.setSchema(schema.getKey());
+            Attr attr = new Attr();
+            attr.setSchema(schema.getKey());
             if (attrMap.containsKey(schema.getKey())) {
-                
attrTO.getValues().addAll(attrMap.get(schema.getKey()).getValues());
+                
attr.getValues().addAll(attrMap.get(schema.getKey()).getValues());
             }
 
-            derAttrs.add(attrTO);
+            derAttrs.add(attr);
         });
 
         attributable.getDerAttrs().clear();
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
index f44a5e0234..bbfb9b0f3d 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
@@ -21,6 +21,7 @@ package org.apache.syncope.client.console.wizards.any;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.stream.Collectors;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
@@ -186,15 +187,15 @@ public class PlainAttrs extends 
AbstractAttrs<PlainSchemaTO> {
         Map<String, Attr> attrMap = 
EntityTOUtils.buildAttrMap(attributable.getPlainAttrs());
 
         List<Attr> plainAttrs = schemas.values().stream().map(schema -> {
-            Attr attr = new Attr();
-            attr.setSchema(schema.getKey());
-            if (attrMap.get(schema.getKey()) == null || 
attrMap.get(schema.getKey()).getValues().isEmpty()) {
-                if (schema.getType() != AttrSchemaType.Dropdown || 
!schema.isMultivalue()) {
-                    attr.getValues().add(StringUtils.EMPTY);
-                }
-            } else {
-                attr = attrMap.get(schema.getKey());
+            Attr attr = 
Optional.ofNullable(attrMap.get(schema.getKey())).orElseGet(() -> {
+                Attr newAttr = new Attr();
+                newAttr.setSchema(schema.getKey());
+                return newAttr;
+            });
+            if ((schema.getType() != AttrSchemaType.Dropdown || 
!schema.isMultivalue()) && attr.getValues().isEmpty()) {
+                attr.getValues().add(StringUtils.EMPTY);
             }
+
             return attr;
         }).toList();
 
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java
index 4ec12af8cf..469c5690a8 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java
@@ -38,10 +38,8 @@ import 
org.apache.wicket.authroles.authorization.strategies.role.metadata.Action
 import 
org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
 import org.apache.wicket.extensions.wizard.WizardModel.ICondition;
 import org.apache.wicket.extensions.wizard.WizardStep;
-import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.model.PropertyModel;
-import org.apache.wicket.model.util.ListModel;
 import org.apache.wicket.spring.injection.annot.SpringBean;
 
 public class Roles extends WizardStep implements ICondition {
@@ -55,8 +53,6 @@ public class Roles extends WizardStep implements ICondition {
 
     protected final UserTO userTO;
 
-    protected WebMarkupContainer dynrolesContainer;
-
     public <T extends AnyTO> Roles(final UserWrapper modelObject) {
         if (modelObject.getPreviousUserTO() != null
                 && 
!modelObject.getInnerObject().getRoles().equals(modelObject.getPreviousUserTO().getRoles()))
 {
@@ -82,15 +78,6 @@ public class Roles extends WizardStep implements ICondition {
         allRoles = getManagedRoles();
 
         add(buildRolesSelector(modelObject));
-
-        dynrolesContainer = new WebMarkupContainer("dynrolesContainer");
-        dynrolesContainer.setOutputMarkupId(true);
-        dynrolesContainer.setOutputMarkupPlaceholderTag(true);
-        add(dynrolesContainer);
-
-        dynrolesContainer.add(new 
AjaxPalettePanel.Builder<String>().build("dynroles",
-                new PropertyModel<>(userTO, "dynRoles"),
-                new 
ListModel<>(allRoles)).hideLabel().setEnabled(false).setOutputMarkupId(true));
     }
 
     protected List<String> getManagedRoles() {
diff --git 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.html
 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.html
index 976a73584e..4810faf137 100644
--- 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.html
+++ 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.html
@@ -29,16 +29,5 @@ under the License.
         <span wicket:id="roles">[ROLES]</span>
       </div>
     </div>
-
-    <div class="col-xs-12" wicket:id="dynrolesContainer">
-      <div class="card-header">
-        <h3 class="card-title">
-          <wicket:message key="dynroles.palette">[ROLES]</wicket:message>
-        </h3>
-      </div>
-      <div class="card-body">
-        <span wicket:id="dynroles">[ROLES]</span>
-      </div>
-    </div>
   </wicket:panel>
-</html>
\ No newline at end of file
+</html>
diff --git 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.properties
 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.properties
index ac181cb0e2..6c58f15c78 100644
--- 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.properties
+++ 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.properties
@@ -15,4 +15,3 @@
 # specific language governing permissions and limitations
 # under the License.
 roles.palette=Roles
-dynroles.palette=Dynamic Roles
diff --git 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_fr_CA.properties
 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_fr_CA.properties
index 2afd540d67..1ec3e29e69 100644
--- 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_fr_CA.properties
+++ 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_fr_CA.properties
@@ -14,5 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-roles.palette=R�les
-dynroles.palette=R�les dynamiques
+roles.palette=R\u00f4les
diff --git 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_it.properties
 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_it.properties
index cad6d2b3a5..b350ed3888 100644
--- 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_it.properties
+++ 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_it.properties
@@ -15,4 +15,3 @@
 # specific language governing permissions and limitations
 # under the License.
 roles.palette=Ruoli
-dynroles.palette=Ruoli Dinamici
diff --git 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_ja.properties
 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_ja.properties
index fbc21cdd52..71ffa39e8e 100644
--- 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_ja.properties
+++ 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_ja.properties
@@ -15,4 +15,3 @@
 # specific language governing permissions and limitations
 # under the License.
 roles.palette=\u30ed\u30fc\u30eb
-dynroles.palette=\u52d5\u7684\u30ed\u30fc\u30eb
diff --git 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_pt_BR.properties
 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_pt_BR.properties
index eb7d07bb6f..e36fce3721 100644
--- 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_pt_BR.properties
+++ 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_pt_BR.properties
@@ -15,4 +15,3 @@
 # specific language governing permissions and limitations
 # under the License.
 roles.palette=Fun\u00e7\u00e3o
-dynroles.palette=Fun\u00e7\u00e3o Din\u00e2micos
diff --git 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_ru.properties
 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_ru.properties
index f3affa533d..41ef2d0177 100644
--- 
a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_ru.properties
+++ 
b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles_ru.properties
@@ -15,7 +15,5 @@
 # specific language governing permissions and limitations
 # under the License.
 #
-# roles.palette=Роли
+# roles.palette=\u00d0\u00a0\u00d0\u00be\u00d0\u00bb\u00d0\u00b8
 roles.palette=\u0420\u043e\u043b\u0438
-# dynroles.palette=Динамические роли
-dynroles.palette=\u0414\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0435
 \u0440\u043e\u043b\u0438
diff --git 
a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/PreferenceManager.java
 
b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/PreferenceManager.java
deleted file mode 100644
index 36282f2e78..0000000000
--- 
a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/PreferenceManager.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.syncope.client.enduser;
-
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.json.JsonMapper;
-import java.io.IOException;
-import java.io.Serializable;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.math.NumberUtils;
-import org.apache.wicket.util.cookies.CookieDefaults;
-import org.apache.wicket.util.cookies.CookieUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public final class PreferenceManager implements Serializable {
-
-    private static final long serialVersionUID = 3581434664555284193L;
-
-    private static final Logger LOG = 
LoggerFactory.getLogger(PreferenceManager.class);
-
-    private static final String COOKIE_NAME = "syncope2EnduserPrefs";
-
-    private static final int ONE_YEAR_TIME = 60 * 60 * 24 * 365;
-
-    private static final JsonMapper MAPPER = 
JsonMapper.builder().findAndAddModules().build();
-
-    private static final TypeReference<Map<String, String>> MAP_TYPE_REF = new 
TypeReference<>() {
-    };
-
-    private static final List<Integer> PAGINATOR_CHOICES = Arrays.asList(new 
Integer[] { 10, 25, 50 });
-
-    private static final CookieUtils COOKIE_UTILS;
-
-    static {
-        CookieDefaults cookieDefaults = new CookieDefaults();
-        cookieDefaults.setMaxAge(ONE_YEAR_TIME);
-        COOKIE_UTILS = new CookieUtils(cookieDefaults);
-    }
-
-    public List<Integer> getPaginatorChoices() {
-        return PAGINATOR_CHOICES;
-    }
-
-    private Map<String, String> getPrefs(final String value) {
-        Map<String, String> prefs;
-        try {
-            if (StringUtils.isNotBlank(value)) {
-                prefs = MAPPER.readValue(value, MAP_TYPE_REF);
-            } else {
-                throw new Exception("Invalid cookie value '" + value + "'");
-            }
-        } catch (Exception e) {
-            LOG.debug("No preferences found", e);
-            prefs = new HashMap<>();
-        }
-
-        return prefs;
-    }
-
-    private String setPrefs(final Map<String, String> prefs) throws 
IOException {
-        StringWriter writer = new StringWriter();
-        MAPPER.writeValue(writer, prefs);
-
-        return writer.toString();
-    }
-
-    public String get(final String key) {
-        String result = null;
-
-        String prefString = COOKIE_UTILS.load(COOKIE_NAME);
-        if (prefString != null) {
-            Map<String, String> prefs = getPrefs(new 
String(Base64.getDecoder().decode(prefString.getBytes())));
-            result = prefs.get(key);
-        }
-
-        return result;
-    }
-
-    public Integer getPaginatorRows(final String key) {
-        Integer result = getPaginatorChoices().getFirst();
-
-        String value = get(key);
-        if (value != null) {
-            result = NumberUtils.toInt(value, 10);
-        }
-
-        return result;
-    }
-
-    public List<String> getList(final String key) {
-        List<String> result = new ArrayList<>();
-
-        String compound = get(key);
-
-        if (StringUtils.isNotBlank(compound)) {
-            String[] items = compound.split(";");
-            result.addAll(Arrays.asList(items));
-        }
-
-        return result;
-    }
-
-    public void set(final Map<String, List<String>> prefs) {
-        Map<String, String> current = new HashMap<>();
-
-        String prefString = COOKIE_UTILS.load(COOKIE_NAME);
-        if (prefString != null) {
-            current.putAll(getPrefs(new 
String(Base64.getDecoder().decode(prefString.getBytes()))));
-        }
-
-        // after retrieved previous setting in order to overwrite the key ...
-        prefs.forEach((key, values) -> current.put(key, String.join(";", 
values)));
-
-        try {
-            COOKIE_UTILS.save(COOKIE_NAME, 
Base64.getEncoder().encodeToString(setPrefs(current).getBytes()));
-        } catch (IOException e) {
-            LOG.error("Could not save {} info: {}", 
getClass().getSimpleName(), current, e);
-        }
-    }
-
-    public void set(final String key, final String value) {
-        String prefString = COOKIE_UTILS.load(COOKIE_NAME);
-
-        final Map<String, String> current = new HashMap<>();
-        if (prefString != null) {
-            current.putAll(getPrefs(new 
String(Base64.getDecoder().decode(prefString.getBytes()))));
-        }
-
-        // after retrieved previous setting in order to overwrite the key ...
-        current.put(key, value);
-
-        try {
-            COOKIE_UTILS.save(COOKIE_NAME, 
Base64.getEncoder().encodeToString(setPrefs(current).getBytes()));
-        } catch (IOException e) {
-            LOG.error("Could not save {} info: {}", 
getClass().getSimpleName(), current, e);
-        }
-    }
-
-    public void setList(final String key, final List<String> values) {
-        set(key, String.join(";", values));
-    }
-
-    public void setList(final Map<String, List<String>> prefs) {
-        set(prefs);
-    }
-
-    private PreferenceManager() {
-        // private constructor for static utility class
-    }
-}
diff --git 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
index 2b58a9eebe..8afceec7af 100644
--- 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
+++ 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
@@ -60,8 +60,6 @@ public class UserTO extends AnyTO implements 
GroupableRelatableTO {
 
     private final List<String> roles = new ArrayList<>();
 
-    private final List<String> dynRoles = new ArrayList<>();
-
     private final List<LinkedAccountTO> linkedAccounts = new ArrayList<>();
 
     private final List<String> delegatingDelegations = new ArrayList<>();
@@ -190,10 +188,6 @@ public class UserTO extends AnyTO implements 
GroupableRelatableTO {
         return roles;
     }
 
-    public List<String> getDynRoles() {
-        return dynRoles;
-    }
-
     public List<LinkedAccountTO> getLinkedAccounts() {
         return linkedAccounts;
     }
@@ -214,7 +208,6 @@ public class UserTO extends AnyTO implements 
GroupableRelatableTO {
                 appendSuper(super.hashCode()).
                 append(username).
                 append(roles).
-                append(dynRoles).
                 append(token).
                 append(tokenExpireTime).
                 append(lastLoginDate).
@@ -247,7 +240,6 @@ public class UserTO extends AnyTO implements 
GroupableRelatableTO {
                 appendSuper(super.equals(obj)).
                 append(username, other.username).
                 append(roles, other.roles).
-                append(dynRoles, other.dynRoles).
                 append(token, other.token).
                 append(tokenExpireTime, other.tokenExpireTime).
                 append(lastLoginDate, other.lastLoginDate).
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AjaxPalettePanelITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AjaxPalettePanelITCase.java
index 2918c1d906..f67dffeb3e 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AjaxPalettePanelITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AjaxPalettePanelITCase.java
@@ -24,29 +24,30 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPalettePanel;
-import org.apache.wicket.model.IModel;
+import org.apache.wicket.extensions.markup.html.form.palette.Palette;
 import org.apache.wicket.model.util.ListModel;
 import org.apache.wicket.util.tester.FormTester;
 import org.junit.jupiter.api.Test;
+import org.springframework.test.util.ReflectionTestUtils;
 
 public class AjaxPalettePanelITCase extends AbstractConsoleITCase {
 
-    private static final IModel<List<String>> SELECTED = new 
ListModel<>(List.of("A", "D"));
-
-    private static final ListModel<String> ALL = new ListModel<>(List.of("A", 
"B", "C", "D"));
-
     @Test
     public void isRendered() {
         TestPage<String, AjaxPalettePanel<String>> testPage =
                 new TestPage.Builder<String, AjaxPalettePanel<String>>().build(
                         new 
AjaxPalettePanel.Builder<String>().setAllowOrder(true).build(
-                                TestPage.FIELD, SELECTED, ALL));
+                                TestPage.FIELD,
+                                new ListModel<>(List.of("A", "D")),
+                                new ListModel<>(List.of("A", "B", "C", "D"))));
         TESTER.startPage(testPage);
 
         FormTester formTester = 
TESTER.newFormTester(testPage.getForm().getId());
         formTester.submit();
 
-        Collection<String> list = 
testPage.getFieldPanel().getModelCollection();
+        @SuppressWarnings("unchecked")
+        Palette<String> palette = (Palette<String>) 
ReflectionTestUtils.getField(testPage.getFieldPanel(), "palette");
+        Collection<String> list = palette.getModelCollection();
         assertEquals(2, list.size());
         Iterator<String> iterator = list.iterator();
         assertEquals("A", iterator.next());


Reply via email to