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

mdisabatino pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/master by this push:
     new 7326c25  [SYNCOPE-1619] SearchPanel improvement (#243)
7326c25 is described below

commit 7326c254f1e3ed1519ccdb7a1e5f26fe23d28d7d
Author: mdisabatino <marco.disabat...@tirasa.net>
AuthorDate: Fri Feb 26 14:29:31 2021 +0100

    [SYNCOPE-1619] SearchPanel improvement (#243)
---
 .../panels/search/ConnObjectSearchPanel.java       |   9 +-
 .../META-INF/resources/ui-commons/css/search.scss  |  12 +-
 .../panels/DisplayAttributesModalPanel.java        |   4 +-
 .../console/panels/search/AbstractSearchPanel.java |  15 +-
 .../console/panels/search/SearchClausePanel.java   | 197 ++++++++++++++++++---
 .../client/console/panels/search/SearchUtils.java  |   8 +-
 .../common/lib/search/SearchableFields.java        |  19 +-
 .../syncope/common/lib/types/AttrSchemaType.java   |   7 +
 8 files changed, 219 insertions(+), 52 deletions(-)

diff --git 
a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/search/ConnObjectSearchPanel.java
 
b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/search/ConnObjectSearchPanel.java
index 833baf1..b078a40 100644
--- 
a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/search/ConnObjectSearchPanel.java
+++ 
b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/search/ConnObjectSearchPanel.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.panels.search;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
@@ -84,17 +85,17 @@ public class ConnObjectSearchPanel extends 
AbstractSearchPanel {
 
             @Override
             protected List<SearchClause.Type> load() {
-                return List.of(SearchClause.Type.ATTRIBUTE);
+                return Collections.singletonList(SearchClause.Type.ATTRIBUTE);
             }
         };
 
-        this.dnames = new LoadableDetachableModel<List<String>>() {
+        this.dnames = new LoadableDetachableModel<Map<String, 
PlainSchemaTO>>() {
 
             private static final long serialVersionUID = 2989042618372L;
 
             @Override
-            protected List<String> load() {
-                return List.of();
+            protected Map<String, PlainSchemaTO> load() {
+                return Collections.emptyMap();
             }
         };
 
diff --git 
a/client/idrepo/common-ui/src/main/resources/META-INF/resources/ui-commons/css/search.scss
 
b/client/idrepo/common-ui/src/main/resources/META-INF/resources/ui-commons/css/search.scss
index 453f5c7..493c7f4 100644
--- 
a/client/idrepo/common-ui/src/main/resources/META-INF/resources/ui-commons/css/search.scss
+++ 
b/client/idrepo/common-ui/src/main/resources/META-INF/resources/ui-commons/css/search.scss
@@ -31,7 +31,7 @@
     }
   }
   .field {
-    line-height: 34px;
+    line-height: 30px;
     float: left;
     padding: 0 3px 0px 0px;
     display: inline-block !important;
@@ -63,7 +63,7 @@
     }
   }
   .value {
-    width: 250px;
+    width: 320px;
   }
   .date {
     width: 160px;
@@ -93,3 +93,11 @@
 .custom-autocomplete-box li.selected {
   background-color: #eee;
 }
+
+.search-spinner {
+  line-height: 23px !important;
+}
+
+.search-spinner span{
+  width: 70% !important;
+}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DisplayAttributesModalPanel.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DisplayAttributesModalPanel.java
index 19d95fe..78f611b 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DisplayAttributesModalPanel.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DisplayAttributesModalPanel.java
@@ -23,6 +23,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 import org.apache.syncope.client.console.PreferenceManager;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
@@ -75,7 +76,8 @@ public abstract class DisplayAttributesModalPanel<T extends 
Serializable> extend
         super(modal, pageRef);
         this.type = type;
 
-        final List<String> detailslList = 
SearchableFields.get(DisplayAttributesModalPanel.getTOClass(type));
+        final List<String> detailslList = 
SearchableFields.get(DisplayAttributesModalPanel.getTOClass(type))
+                .keySet().stream().collect(Collectors.toList());
         Collections.sort(detailslList);
         Collections.sort(pSchemaNames);
         Collections.sort(dSchemaNames);
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
index 1ff07ae..5dff765 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.client.console.panels.search;
 
 import java.io.Serializable;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import org.apache.commons.lang3.tuple.Pair;
@@ -46,7 +47,7 @@ public abstract class AbstractSearchPanel extends Panel {
 
     protected static final Logger LOG = 
LoggerFactory.getLogger(AbstractSearchPanel.class);
 
-    protected IModel<List<String>> dnames;
+    protected IModel<Map<String, PlainSchemaTO>> dnames;
 
     protected IModel<Map<String, PlainSchemaTO>> anames;
 
@@ -178,13 +179,19 @@ public abstract class AbstractSearchPanel extends Panel {
     }
 
     protected void populate() {
-        dnames = new LoadableDetachableModel<List<String>>() {
+        dnames = new LoadableDetachableModel<Map<String, PlainSchemaTO>>() {
 
             private static final long serialVersionUID = 5275935387613157437L;
 
             @Override
-            protected List<String> load() {
-                return SearchableFields.get(typeKind.getTOClass());
+            protected Map<String, PlainSchemaTO> load() {
+                Map<String, PlainSchemaTO> dSchemaNames = new HashMap<>();
+                SearchableFields.get(typeKind.getTOClass()).forEach((key, 
type) -> {
+                            PlainSchemaTO plain = new PlainSchemaTO();
+                            plain.setType(type);
+                            dSchemaNames.put(key, plain);
+                        });
+                return dSchemaNames;
             }
         };
 
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java
index 7e613a6..a9bfc71 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java
@@ -21,7 +21,11 @@ package org.apache.syncope.client.console.panels.search;
 import 
de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggle;
 import 
de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggleConfig;
 import java.io.Serializable;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -29,6 +33,7 @@ import java.util.function.Consumer;
 import java.util.stream.Collectors;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.FastDateFormat;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.console.panels.search.SearchClause.Comparator;
@@ -42,10 +47,14 @@ import 
org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoiceP
 import 
org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.ui.commons.markup.html.form.FieldPanel;
 import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.client.ui.commons.SchemaUtils;
+import 
org.apache.syncope.client.ui.commons.markup.html.form.AjaxDateTimeFieldPanel;
+import 
org.apache.syncope.client.ui.commons.markup.html.form.AjaxSpinnerFieldPanel;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.RelationshipTypeTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
@@ -73,6 +82,8 @@ public class SearchClausePanel extends 
FieldPanel<SearchClause> {
 
     private static final long serialVersionUID = -527351923968737757L;
 
+    private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT = 
ThreadLocal.withInitial(SimpleDateFormat::new);
+
     protected static final AttributeModifier PREVENT_DEFAULT_RETURN = 
AttributeModifier.replace(
             "onkeydown",
             Model.of("if (event.keyCode == 13) { event.preventDefault(); }"));
@@ -111,7 +122,7 @@ public class SearchClausePanel extends 
FieldPanel<SearchClause> {
         }
 
         default void setFieldAccess(
-                AjaxTextFieldPanel value,
+                FieldPanel value,
                 AjaxTextFieldPanel property,
                 LoadableDetachableModel<List<String>> properties) {
 
@@ -133,7 +144,7 @@ public class SearchClausePanel extends 
FieldPanel<SearchClause> {
 
     private final IModel<Map<String, PlainSchemaTO>> anames;
 
-    private final IModel<List<String>> dnames;
+    private final IModel<Map<String, PlainSchemaTO>> dnames;
 
     private final Pair<IModel<List<String>>, IModel<Integer>> groupInfo;
 
@@ -157,6 +168,9 @@ public class SearchClausePanel extends 
FieldPanel<SearchClause> {
 
     private IEventSink resultContainer;
 
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    private FieldPanel value;
+
     private final GroupRestClient groupRestClient = new GroupRestClient();
 
     public SearchClausePanel(
@@ -167,7 +181,7 @@ public class SearchClausePanel extends 
FieldPanel<SearchClause> {
             final IModel<List<SearchClause.Type>> types,
             final Customizer customizer,
             final IModel<Map<String, PlainSchemaTO>> anames,
-            final IModel<List<String>> dnames,
+            final IModel<Map<String, PlainSchemaTO>> dnames,
             final Pair<IModel<List<String>>, IModel<Integer>> groupInfo,
             final IModel<List<String>> roleNames,
             final IModel<List<String>> privilegeNames,
@@ -264,7 +278,7 @@ public class SearchClausePanel extends 
FieldPanel<SearchClause> {
 
                 switch (field.getModel().getObject().getType()) {
                     case ATTRIBUTE:
-                        List<String> names = new 
ArrayList<>(dnames.getObject());
+                        List<String> names = new 
ArrayList<>(dnames.getObject().keySet());
                         if (anames != null && anames.getObject() != null && 
!anames.getObject().isEmpty()) {
                             names.addAll(anames.getObject().keySet());
                         }
@@ -356,6 +370,7 @@ public class SearchClausePanel extends 
FieldPanel<SearchClause> {
     }
 
     @Override
+    @SuppressWarnings({ "rawtypes", "unchecked" })
     public FieldPanel<SearchClause> settingsDependingComponents() {
         SearchClause searchClause = this.clause.getObject();
 
@@ -488,36 +503,25 @@ public class SearchClausePanel extends 
FieldPanel<SearchClause> {
         comparator.setChoiceRenderer(getComparatorRender(field.getModel()));
         field.add(comparator);
 
-        AjaxTextFieldPanel value = new AjaxTextFieldPanel(
-                "value", "value", new PropertyModel<>(searchClause, "value"), 
true);
-        value.hideLabel().setOutputMarkupId(true);
-        field.add(value);
-
-        value.getField().add(PREVENT_DEFAULT_RETURN);
-        value.getField().add(new 
IndicatorAjaxEventBehavior(Constants.ON_KEYDOWN) {
+        renderSearchValueField(searchClause, property);
+        field.addOrReplace(value);
 
-            private static final long serialVersionUID = -7133385027739964990L;
+        property.getField().add(new 
IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
 
-            @Override
-            protected void onEvent(final AjaxRequestTarget target) {
-                target.focusComponent(null);
-                value.getField().inputChanged();
-                value.getField().validate();
-                if (value.getField().isValid()) {
-                    value.getField().valid();
-                    value.getField().updateModel();
-                }
-            }
+            private static final long serialVersionUID = -1107858522700306810L;
 
             @Override
-            protected void updateAjaxAttributes(final AjaxRequestAttributes 
attributes) {
-                super.updateAjaxAttributes(attributes);
-                AJAX_SUBMIT_ON_RETURN.accept(attributes);
+            protected void onUpdate(final AjaxRequestTarget target) {
+                renderSearchValueField(searchClause, property);
+                field.addOrReplace(value);
+                target.add(value);
             }
-        });
+        }
+        );
 
         AjaxDropDownChoicePanel<SearchClause.Type> type = new 
AjaxDropDownChoicePanel<>(
                 "type", "type", new PropertyModel<>(searchClause, "type"));
+
         type.setChoices(types).setChoiceRenderer(customizer.typeRenderer()).
                 hideLabel().setRequired(required).setOutputMarkupId(true);
         type.setNullValid(false);
@@ -583,11 +587,12 @@ public class SearchClausePanel extends 
FieldPanel<SearchClause> {
         return this;
     }
 
+    @SuppressWarnings({ "rawtypes", "unchecked" })
     private void setFieldAccess(
             final Type type,
             final AjaxTextFieldPanel property,
             final FieldPanel<Comparator> comparator,
-            final AjaxTextFieldPanel value) {
+            final FieldPanel value) {
 
         if (type != null) {
             property.setEnabled(true);
@@ -879,6 +884,144 @@ public class SearchClausePanel extends 
FieldPanel<SearchClause> {
         };
     }
 
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    private void renderSearchValueField(
+            final SearchClause searchClause,
+            final AjaxTextFieldPanel property) {
+
+        PlainSchemaTO plainSchemaTO = 
anames.getObject().get(property.getModelObject());
+        if (plainSchemaTO == null) {
+            PlainSchemaTO defaultPlainTO = new PlainSchemaTO();
+            defaultPlainTO.setType(AttrSchemaType.String);
+            plainSchemaTO = 
dnames.getObject().getOrDefault(property.getModelObject(), defaultPlainTO);
+        }
+
+        switch (plainSchemaTO.getType()) {
+            case Boolean:
+                value = new AjaxTextFieldPanel(
+                        "value",
+                        "value",
+                        new PropertyModel<>(searchClause, "value"),
+                        true);
+                ((AjaxTextFieldPanel) value).setChoices(Arrays.asList("true", 
"false"));
+
+                break;
+            case Date:
+                SimpleDateFormat df = DATE_FORMAT.get();
+                df.applyPattern(SyncopeConstants.DEFAULT_DATE_PATTERN);
+
+                value = new AjaxDateTimeFieldPanel(
+                        "value",
+                        "value",
+                        new PropertyModel(searchClause, "value") {
+
+                    private static final long serialVersionUID = 
1177692285167186690L;
+
+                    @Override
+                    public Object getObject() {
+                        String date = (String) super.getObject();
+                        try {
+                            return date != null ? df.parse(date) : null;
+                        } catch (ParseException ex) {
+                            LOG.error("Date parse error {}", date, ex);
+                        }
+                        return null;
+                    }
+
+                    @Override
+                    public void setObject(final Object object) {
+                        if (object instanceof Date) {
+                            String valueDate = df.format(object);
+                            super.setObject(valueDate);
+                        } else {
+                            super.setObject(object);
+                        }
+                    }
+                }, 
FastDateFormat.getInstance(SyncopeConstants.DEFAULT_DATE_PATTERN));
+                break;
+
+            case Enum:
+                value = new AjaxDropDownChoicePanel<>(
+                        "value",
+                        "value",
+                        new PropertyModel(searchClause, "value"),
+                        true);
+                ((AjaxDropDownChoicePanel<String>) 
value).setChoices(SchemaUtils.getEnumeratedValues(plainSchemaTO));
+
+                if 
(StringUtils.isNotBlank(plainSchemaTO.getEnumerationKeys())) {
+                    Map<String, String> valueMap = 
SchemaUtils.getEnumeratedKeyValues(plainSchemaTO);
+                    ((AjaxDropDownChoicePanel) value).setChoiceRenderer(new 
IChoiceRenderer<String>() {
+
+                        private static final long serialVersionUID = 
-3724971416312135885L;
+
+                        @Override
+                        public String getDisplayValue(final String value) {
+                            return valueMap.get(value) == null ? value : 
valueMap.get(value);
+                        }
+
+                        @Override
+                        public String getIdValue(final String value, final int 
i) {
+                            return value;
+                        }
+
+                        @Override
+                        public String getObject(
+                                final String id, final IModel<? extends List<? 
extends String>> choices) {
+                            return id;
+                        }
+                    });
+                }
+                break;
+            case Long:
+                value = new 
AjaxSpinnerFieldPanel.Builder<Long>().enableOnChange().build(
+                        "value",
+                        "Value",
+                        Long.class,
+                        new PropertyModel(searchClause, "value"));
+
+                value.add(new AttributeModifier("class", "field value 
search-spinner"));
+                break;
+
+            case Double:
+                value = new 
AjaxSpinnerFieldPanel.Builder<Double>().enableOnChange().step(0.1).build(
+                        "value",
+                        "value",
+                        Double.class,
+                        new PropertyModel(searchClause, "value"));
+                value.add(new AttributeModifier("class", "field value 
search-spinner"));
+                break;
+
+            default:
+                value = new AjaxTextFieldPanel(
+                        "value", "value", new PropertyModel<>(searchClause, 
"value"), true);
+                break;
+        }
+
+        value.hideLabel().setOutputMarkupId(true);
+        value.getField().add(PREVENT_DEFAULT_RETURN);
+        value.getField().add(new 
IndicatorAjaxEventBehavior(Constants.ON_KEYDOWN) {
+
+            private static final long serialVersionUID = -7133385027739964990L;
+
+            @Override
+            protected void onEvent(final AjaxRequestTarget target) {
+                target.focusComponent(null);
+                value.getField().inputChanged();
+                value.getField().validate();
+                if (value.getField().isValid()) {
+                    value.getField().valid();
+                    value.getField().updateModel();
+                }
+            }
+
+            @Override
+            protected void updateAjaxAttributes(final AjaxRequestAttributes 
attributes) {
+                super.updateAjaxAttributes(attributes);
+                AJAX_SUBMIT_ON_RETURN.accept(attributes);
+            }
+        });
+    }
+
     @Override
     public FieldPanel<SearchClause> clone() {
         SearchClausePanel panel = new SearchClausePanel(
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchUtils.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchUtils.java
index 5c0539b..18c4f42 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchUtils.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchUtils.java
@@ -20,9 +20,9 @@ package org.apache.syncope.client.console.panels.search;
 
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 import java.util.function.Function;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
@@ -220,7 +220,7 @@ public final class SearchUtils implements Serializable {
             final List<SearchClause> clauses,
             final AbstractFiqlSearchConditionBuilder<?, ?, ?> builder) {
 
-        return buildFIQL(clauses, builder, Map.of(), NO_CUSTOM_CONDITION);
+        return buildFIQL(clauses, builder, Collections.emptyMap(), 
NO_CUSTOM_CONDITION);
     }
 
     public static String buildFIQL(
@@ -243,7 +243,7 @@ public final class SearchUtils implements Serializable {
                 String value = clause.getValue() == null
                         ? null
                         : ENCODINGS.keySet().stream().
-                                reduce(clause.getValue(), (s, k) -> 
s.replace(k, ENCODINGS.get(k)));
+                                reduce(clause.getValue().toString(), (s, k) -> 
s.replace(k, ENCODINGS.get(k)));
 
                 switch (clause.getType()) {
                     case GROUP_MEMBER:
@@ -487,7 +487,7 @@ public final class SearchUtils implements Serializable {
             notTheFirst = true;
         }
 
-        String fiql = 
Optional.ofNullable(condition).map(CompleteCondition::query).orElse(null);
+        String fiql = condition == null ? null : condition.query();
         LOG.debug("Generated FIQL: {}", fiql);
 
         return fiql;
diff --git 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java
 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java
index c5102a4..62a9fc9 100644
--- 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java
+++ 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java
@@ -19,18 +19,18 @@
 package org.apache.syncope.common.lib.search;
 
 import java.lang.reflect.Field;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
 
 public final class SearchableFields {
 
@@ -41,17 +41,17 @@ public final class SearchableFields {
     private static final Set<String> ANY_FIELDS = new HashSet<>();
 
     static {
-        ANY_FIELDS.addAll(get(UserTO.class));
-        ANY_FIELDS.addAll(get(GroupTO.class));
-        ANY_FIELDS.addAll(get(AnyObjectTO.class));
+        ANY_FIELDS.addAll(get(UserTO.class).keySet());
+        ANY_FIELDS.addAll(get(GroupTO.class).keySet());
+        ANY_FIELDS.addAll(get(AnyObjectTO.class).keySet());
     }
 
     public static boolean contains(final String schema) {
         return ANY_FIELDS.contains(schema);
     }
 
-    public static List<String> get(final Class<? extends AnyTO> anyRef) {
-        final List<String> fieldNames = new ArrayList<>();
+    public static Map<String, AttrSchemaType> get(final Class<? extends AnyTO> 
anyRef) {
+        final Map<String, AttrSchemaType> fields = new 
TreeMap<>(Collections.reverseOrder());
 
         // loop on class and all superclasses searching for field
         Class<?> clazz = anyRef;
@@ -61,14 +61,13 @@ public final class SearchableFields {
                         && !Collection.class.isAssignableFrom(field.getType())
                         && !Map.class.isAssignableFrom(field.getType())) {
 
-                    fieldNames.add(field.getName());
+                    fields.put(field.getName(), 
AttrSchemaType.getAttrSchemaTypeByClass(field.getType()));
                 }
             }
             clazz = clazz.getSuperclass();
         }
 
-        Collections.reverse(fieldNames);
-        return fieldNames;
+        return fields;
     }
 
     private SearchableFields() {
diff --git 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/AttrSchemaType.java
 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/AttrSchemaType.java
index b8e162d..cf93418 100644
--- 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/AttrSchemaType.java
+++ 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/AttrSchemaType.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.common.lib.types;
 
 import java.util.Date;
+import java.util.stream.Stream;
 
 public enum AttrSchemaType {
 
@@ -46,4 +47,10 @@ public enum AttrSchemaType {
                 || this == AttrSchemaType.Double
                 || this == AttrSchemaType.Long;
     }
+
+    public static AttrSchemaType getAttrSchemaTypeByClass(final Class<?> type) 
{
+        return Stream.of(AttrSchemaType.values())
+                .filter(item -> type == 
item.getType()).findFirst().orElse(AttrSchemaType.String);
+    }
+
 }

Reply via email to