This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch 4_0_X
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/4_0_X by this push:
new b35f8309de [SYNCOPE-1882] Fixing multivalue dropdown attribute check +
SearchClausePanel improvements
b35f8309de is described below
commit b35f8309de7227fd53211b1c23564c0774eaf017
Author: Francesco Chicchiriccò <[email protected]>
AuthorDate: Thu May 15 11:14:40 2025 +0200
[SYNCOPE-1882] Fixing multivalue dropdown attribute check +
SearchClausePanel improvements
---
.../commons/markup/html/form/AjaxPalettePanel.java | 8 +-
.../client/ui/commons/panels/SyncopeFormPanel.java | 2 +-
.../console/panels/search/AbstractSearchPanel.java | 7 +-
.../console/panels/search/SearchClausePanel.java | 723 ++++++++++-----------
.../client/console/rest/SchemaRestClient.java | 26 +-
.../client/console/wizards/any/PlainAttrs.java | 4 +-
.../client/enduser/panels/any/PlainAttrs.java | 22 +-
pom.xml | 4 +-
8 files changed, 390 insertions(+), 406 deletions(-)
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 eccd2d51a4..723d813209 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
@@ -158,11 +158,9 @@ public class AjaxPalettePanel<T extends Serializable>
extends AbstractFieldPanel
List<String> ids =
builder.idExtractor.apply(getValue()).toList();
List<T> unselected = new ArrayList<>(choices.size());
- choices.forEach(choice -> {
- if (!ids.contains(renderer.getIdValue(choice, 0)))
{
- unselected.add(choice);
- }
- });
+ choices.stream().
+ filter(choice ->
!ids.contains(renderer.getIdValue(choice, 0))).
+ forEach(unselected::add);
return unselected;
}
diff --git
a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/SyncopeFormPanel.java
b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/SyncopeFormPanel.java
index cf8d4a6b25..386436fbd8 100644
---
a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/SyncopeFormPanel.java
+++
b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/SyncopeFormPanel.java
@@ -165,7 +165,7 @@ public class SyncopeFormPanel<F extends SyncopeForm>
extends Panel {
public List<String> getObject() {
return
Optional.ofNullable(prop.getValue()).
map(v -> List.of(v.split(";"))).
- orElseGet(List::of);
+ orElseGet(List::of);
}
@Override
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 e3185493bf..c399c170ef 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
@@ -247,9 +247,10 @@ public abstract class AbstractSearchPanel extends Panel {
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);
+ PlainSchemaTO plainSchema = new PlainSchemaTO();
+ plainSchema.setType(type);
+ plainSchema.setKey(key);
+ dSchemaNames.put(key, plainSchema);
});
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 b68f0168ef..96262d306c 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
@@ -22,7 +22,6 @@ import
de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.boot
import
de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggleConfig;
import java.io.Serializable;
import java.text.ParseException;
-import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;
@@ -121,18 +120,223 @@ public class SearchClausePanel extends
FieldPanel<SearchClause> {
return List.of();
}
- default void setFieldAccess(
- FieldPanel<String> value,
+ default void adjust(
+ Type type,
AjaxTextFieldPanel property,
+ FieldPanel<Comparator> comparator,
+ FieldPanel<?> value,
LoadableDetachableModel<List<Pair<String, String>>>
properties) {
value.setEnabled(true);
- value.setModelObject(StringUtils.EMPTY);
+ value.setModelObject(null);
property.setEnabled(true);
// reload properties list
properties.detach();
-
property.setChoices(properties.getObject().stream().map(Pair::getKey).collect(Collectors.toList()));
+
property.setChoices(properties.getObject().stream().map(Pair::getKey).toList());
+ }
+ }
+
+ protected class ComparatorRenderer implements
IChoiceRenderer<SearchClause.Comparator> {
+
+ private static final long serialVersionUID = -9086043750227867686L;
+
+ @Override
+ public Object getDisplayValue(final SearchClause.Comparator object) {
+ if (clause == null || clause.getObject() == null ||
clause.getObject().getType() == null) {
+ return object.toString();
+ }
+
+ String display;
+
+ switch (clause.getObject().getType()) {
+ case ATTRIBUTE:
+ switch (object) {
+ case IS_NULL:
+ display = "NULL";
+ break;
+
+ case IS_NOT_NULL:
+ display = "NOT NULL";
+ break;
+
+ case EQUALS:
+ display = "==";
+ break;
+
+ case NOT_EQUALS:
+ display = "!=";
+ break;
+
+ case LESS_THAN:
+ display = "<";
+ break;
+
+ case LESS_OR_EQUALS:
+ display = "<=";
+ break;
+
+ case GREATER_THAN:
+ display = ">";
+ break;
+
+ case GREATER_OR_EQUALS:
+ display = ">=";
+ break;
+
+ default:
+ display = StringUtils.EMPTY;
+ }
+ break;
+
+ case GROUP_MEMBERSHIP:
+ switch (object) {
+ case EQUALS:
+ display = "IN";
+ break;
+
+ case NOT_EQUALS:
+ display = "NOT IN";
+ break;
+
+ default:
+ display = StringUtils.EMPTY;
+ }
+ break;
+
+ case GROUP_MEMBER:
+ switch (object) {
+ case EQUALS:
+ display = "WITH";
+ break;
+
+ case NOT_EQUALS:
+ display = "WITHOUT";
+ break;
+
+ default:
+ display = StringUtils.EMPTY;
+ }
+ break;
+
+ case AUX_CLASS:
+ case ROLE_MEMBERSHIP:
+ case RESOURCE:
+ switch (object) {
+ case EQUALS:
+ display = "HAS";
+ break;
+
+ case NOT_EQUALS:
+ display = "HAS NOT";
+ break;
+
+ default:
+ display = StringUtils.EMPTY;
+ }
+ break;
+
+ case RELATIONSHIP:
+ switch (object) {
+ case IS_NOT_NULL:
+ display = "EXIST";
+ break;
+
+ case IS_NULL:
+ display = "NOT EXIST";
+ break;
+
+ case EQUALS:
+ display = "WITH";
+ break;
+
+ case NOT_EQUALS:
+ display = "WITHOUT";
+ break;
+
+ default:
+ display = StringUtils.EMPTY;
+ }
+ break;
+
+ case CUSTOM:
+ display = customizer.comparatorDisplayValue(object);
+ break;
+
+ default:
+ display = object.toString();
+ }
+ return display;
+ }
+
+ @Override
+ public String getIdValue(final SearchClause.Comparator object, final
int index) {
+ return getDisplayValue(object).toString();
+ }
+
+ @Override
+ public SearchClause.Comparator getObject(
+ final String id, final IModel<? extends List<? extends
SearchClause.Comparator>> choices) {
+
+ if (id == null) {
+ return SearchClause.Comparator.EQUALS;
+ }
+
+ final SearchClause.Comparator comparator;
+ switch (id) {
+ case "HAS":
+ case "IN":
+ case "WITH":
+ comparator = SearchClause.Comparator.EQUALS;
+ break;
+
+ case "HAS NOT":
+ case "NOT IN":
+ case "WITHOUT":
+ comparator = SearchClause.Comparator.NOT_EQUALS;
+ break;
+
+ case "NULL":
+ case "NOT EXIST":
+ comparator = SearchClause.Comparator.IS_NULL;
+ break;
+
+ case "NOT NULL":
+ case "EXIST":
+ comparator = SearchClause.Comparator.IS_NOT_NULL;
+ break;
+
+ case "==":
+ comparator = SearchClause.Comparator.EQUALS;
+ break;
+
+ case "!=":
+ comparator = SearchClause.Comparator.NOT_EQUALS;
+ break;
+
+ case "<":
+ comparator = SearchClause.Comparator.LESS_THAN;
+ break;
+
+ case "<=":
+ comparator = SearchClause.Comparator.LESS_OR_EQUALS;
+ break;
+
+ case ">":
+ comparator = SearchClause.Comparator.GREATER_THAN;
+ break;
+
+ case ">=":
+ comparator = SearchClause.Comparator.GREATER_OR_EQUALS;
+ break;
+
+ default:
+ // EQUALS to be used as default value
+ comparator =
customizer.comparatorGetObject(id).orElse(SearchClause.Comparator.EQUALS);
+ break;
+ }
+
+ return comparator;
}
}
@@ -174,8 +378,7 @@ public class SearchClausePanel extends
FieldPanel<SearchClause> {
protected IEventSink resultContainer;
- @SuppressWarnings({ "rawtypes", "unchecked" })
- private FieldPanel value;
+ private FieldPanel<?> value;
public SearchClausePanel(
final String id,
@@ -193,7 +396,7 @@ public class SearchClausePanel extends
FieldPanel<SearchClause> {
super(id, name, clause);
- this.clause = clause == null ? new Model<>(null) : clause;
+ this.clause = Optional.ofNullable(clause).orElseGet(() -> new
Model<>(null));
this.required = required;
this.types = types;
@@ -211,11 +414,9 @@ public class SearchClausePanel extends
FieldPanel<SearchClause> {
@Override
public void onClick(final AjaxRequestTarget target) {
- if (resultContainer == null) {
- send(SearchClausePanel.this, Broadcast.BUBBLE, new
SearchEvent(target));
- } else {
- send(resultContainer, Broadcast.EXACT, new
SearchEvent(target));
- }
+ Optional.ofNullable(resultContainer).ifPresentOrElse(
+ container -> send(container, Broadcast.EXACT, new
SearchEvent(target)),
+ () -> send(SearchClausePanel.this, Broadcast.BUBBLE,
new SearchEvent(target)));
}
};
@@ -281,7 +482,7 @@ public class SearchClausePanel extends
FieldPanel<SearchClause> {
}
switch (field.getModel().getObject().getType()) {
- case ATTRIBUTE:
+ case ATTRIBUTE -> {
Locale locale =
SyncopeConsoleSession.get().getLocale();
List<Pair<String, String>> names =
dnames.getObject().entrySet().stream().
map(item -> Pair.of(
@@ -293,42 +494,49 @@ public class SearchClausePanel extends
FieldPanel<SearchClause> {
map(item -> Pair.of(
item.getKey(),
Optional.ofNullable(item.getValue().getLabel(locale)).orElseGet(item::getKey))).
- toList());
+ toList());
}
return names.stream().
sorted(java.util.Comparator.comparing(name ->
name.getValue().toLowerCase())).
collect(Collectors.toList());
+ }
- case GROUP_MEMBERSHIP:
- return groupInfo.getLeft().getObject().stream().
- map(item -> Pair.of(item,
item)).collect(Collectors.toList());
+ case GROUP_MEMBERSHIP -> {
+ return
groupInfo.getLeft().getObject().stream().map(item -> Pair.of(item,
item)).toList();
+ }
- case ROLE_MEMBERSHIP:
+ case ROLE_MEMBERSHIP -> {
return Optional.ofNullable(roleNames).
map(r ->
r.getObject().stream().sorted().map(item -> Pair.of(item, item)).
collect(Collectors.toList())).
- orElseGet(List::of);
+ orElseGet(List::of);
+ }
- case AUX_CLASS:
+ case AUX_CLASS -> {
return auxClassNames.getObject().stream().sorted().
- map(item -> Pair.of(item,
item)).collect(Collectors.toList());
+ map(item -> Pair.of(item, item)).toList();
+ }
- case RESOURCE:
+ case RESOURCE -> {
return resourceNames.getObject().stream().sorted().
- map(item -> Pair.of(item,
item)).collect(Collectors.toList());
+ map(item -> Pair.of(item, item)).toList();
+ }
- case RELATIONSHIP:
- return
relationshipTypeRestClient.list().stream().sorted().
+ case RELATIONSHIP -> {
+ return relationshipTypeRestClient.list().stream().
map(item -> Pair.of(item.getKey(),
item.getKey())).
- collect(Collectors.toList());
+ sorted().toList();
+ }
- case CUSTOM:
+ case CUSTOM -> {
return customizer.properties().stream().
map(item -> Pair.of(item, item)).
collect(Collectors.toList());
+ }
- default:
+ default -> {
return List.of();
+ }
}
}
};
@@ -386,7 +594,6 @@ public class SearchClausePanel extends
FieldPanel<SearchClause> {
}
@Override
- @SuppressWarnings({ "rawtypes", "unchecked" })
public FieldPanel<SearchClause> settingsDependingComponents() {
SearchClause searchClause = this.clause.getObject();
@@ -448,8 +655,8 @@ public class SearchClausePanel extends
FieldPanel<SearchClause> {
operatorContainer.add(searchButtonFragment);
}
- AjaxTextFieldPanel property = new AjaxTextFieldPanel("property",
"property",
- new PropertyModel<>(searchClause, "property"), true) {
+ AjaxTextFieldPanel property = new AjaxTextFieldPanel(
+ "property", "property", new PropertyModel<>(searchClause,
"property")) {
private static final long serialVersionUID = -7157802546272668001L;
@@ -479,10 +686,8 @@ public class SearchClausePanel extends
FieldPanel<SearchClause> {
});
}
};
-
- property.hideLabel().setOutputMarkupId(true).setEnabled(true);
-
property.setChoices(properties.getObject().stream().map(Pair::getValue).collect(Collectors.toList()));
- field.add(property);
+
property.setChoices(properties.getObject().stream().map(Pair::getValue).toList());
+
field.add(property.hideLabel().setOutputMarkupId(true).setEnabled(true));
property.getField().add(PREVENT_DEFAULT_RETURN);
property.getField().add(new
IndicatorAjaxEventBehavior(Constants.ON_KEYUP) {
@@ -496,8 +701,7 @@ public class SearchClausePanel extends
FieldPanel<SearchClause> {
String[] inputAsArray =
property.getField().getInputAsArray();
if (ArrayUtils.isEmpty(inputAsArray)) {
-
property.setChoices(properties.getObject().stream().map(Pair::getKey)
- .collect(Collectors.toList()));
+
property.setChoices(properties.getObject().stream().map(Pair::getKey).toList());
} else if (groupInfo.getRight().getObject() >
Constants.MAX_GROUP_LIST_SIZE) {
String inputValue = inputAsArray.length > 1 &&
inputAsArray[1] != null
? inputAsArray[1]
@@ -516,7 +720,7 @@ public class SearchClausePanel extends
FieldPanel<SearchClause> {
1,
Constants.MAX_GROUP_LIST_SIZE,
new SortParam<>(Constants.NAME_FIELD_NAME,
true),
-
null).stream().map(GroupTO::getName).collect(Collectors.toList()));
+ null).stream().map(GroupTO::getName).toList());
}
}
}
@@ -548,21 +752,25 @@ public class SearchClausePanel extends
FieldPanel<SearchClause> {
comparator.setChoices(comparators);
comparator.setNullValid(false).hideLabel().setOutputMarkupId(true);
comparator.setRequired(required);
- comparator.setChoiceRenderer(getComparatorRender(field.getModel()));
+ comparator.setChoiceRenderer(new ComparatorRenderer());
field.add(comparator);
- renderSearchValueField(searchClause, property);
+ value = buildValue(searchClause, property);
field.addOrReplace(value);
+ adjust(searchClause.getType(), property, comparator);
+
property.getField().add(new
IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
private static final long serialVersionUID = -1107858522700306810L;
@Override
protected void onUpdate(final AjaxRequestTarget target) {
- renderSearchValueField(searchClause, property);
+ value = buildValue(searchClause, property);
field.addOrReplace(value);
target.add(value);
+
+ adjust(searchClause.getType(), property, comparator);
}
});
@@ -584,7 +792,7 @@ public class SearchClausePanel extends
FieldPanel<SearchClause> {
}
SearchClausePanel.this.clause.setObject(searchClause);
- setFieldAccess(searchClause.getType(), property, comparator,
value);
+ adjust(searchClause.getType(), property, comparator);
// reset property value in case and just in case of change of
type
property.setModelObject(StringUtils.EMPTY);
@@ -608,7 +816,7 @@ public class SearchClausePanel extends
FieldPanel<SearchClause> {
if (comparator.getModelObject() ==
SearchClause.Comparator.IS_NULL
|| comparator.getModelObject() ==
SearchClause.Comparator.IS_NOT_NULL) {
- value.setModelObject(StringUtils.EMPTY);
+ value.setModelObject(null);
value.setEnabled(false);
} else {
value.setEnabled(true);
@@ -629,373 +837,154 @@ public class SearchClausePanel extends
FieldPanel<SearchClause> {
}
});
- setFieldAccess(searchClause.getType(), property, comparator, value);
-
return this;
}
- @SuppressWarnings({ "rawtypes", "unchecked" })
- private void setFieldAccess(
- final Type type,
- final AjaxTextFieldPanel property,
- final FieldPanel<Comparator> comparator,
- final FieldPanel value) {
-
- if (type != null) {
- property.setEnabled(true);
- comparator.setEnabled(true);
- value.setEnabled(true);
-
- switch (type) {
- case ATTRIBUTE:
- if (!comparator.isEnabled()) {
- comparator.setEnabled(true);
- comparator.setRequired(true);
- }
-
- if (comparator.getModelObject() ==
SearchClause.Comparator.IS_NULL
- || comparator.getModelObject() ==
SearchClause.Comparator.IS_NOT_NULL) {
- value.setEnabled(false);
- value.setModelObject(StringUtils.EMPTY);
- }
-
- // reload properties list
- properties.detach();
- property.setChoices(
- properties.getObject().stream().
-
map(Pair::getValue).collect(Collectors.toList()));
- break;
-
- case ROLE_MEMBERSHIP:
- value.setEnabled(false);
- value.setModelObject(StringUtils.EMPTY);
-
- // reload properties list
- properties.detach();
-
property.setChoices(properties.getObject().stream().map(Pair::getKey).collect(Collectors.toList()));
- break;
-
- case GROUP_MEMBERSHIP:
- value.setEnabled(false);
- value.setModelObject(StringUtils.EMPTY);
-
- // reload properties list
- properties.detach();
-
property.setChoices(properties.getObject().stream().map(Pair::getKey).collect(Collectors.toList()));
- break;
-
- case GROUP_MEMBER:
- value.setEnabled(true);
- property.setEnabled(false);
- property.setModelObject(StringUtils.EMPTY);
- break;
-
- case AUX_CLASS:
- case RESOURCE:
- value.setEnabled(false);
- value.setModelObject(StringUtils.EMPTY);
-
- // reload properties list
- properties.detach();
-
property.setChoices(properties.getObject().stream().map(Pair::getKey).collect(Collectors.toList()));
- break;
-
- case RELATIONSHIP:
- value.setEnabled(true);
- value.setModelObject(StringUtils.EMPTY);
- property.setEnabled(true);
-
- // reload properties list
- properties.detach();
-
property.setChoices(properties.getObject().stream().map(Pair::getKey).collect(Collectors.toList()));
- break;
-
- case CUSTOM:
- customizer.setFieldAccess(value, property, properties);
- break;
-
- default:
- break;
- }
+ @SuppressWarnings("unchecked")
+ protected void adjust(final Type type, final AjaxTextFieldPanel property,
final FieldPanel<Comparator> comparator) {
+ if (type == null) {
+ return;
}
- }
-
- private IChoiceRenderer<SearchClause.Comparator> getComparatorRender(final
IModel<SearchClause> clause) {
- return new IChoiceRenderer<>() {
- private static final long serialVersionUID = -9086043750227867686L;
+ property.setEnabled(true);
+ comparator.setEnabled(true);
+ value.setEnabled(true);
- @Override
- public Object getDisplayValue(final SearchClause.Comparator
object) {
- if (clause == null || clause.getObject() == null ||
clause.getObject().getType() == null) {
- return object.toString();
+ switch (type) {
+ case ATTRIBUTE -> {
+ if (!comparator.isEnabled()) {
+ comparator.setEnabled(true);
+ comparator.setRequired(true);
}
- String display;
-
- switch (clause.getObject().getType()) {
- case ATTRIBUTE:
- switch (object) {
- case IS_NULL:
- display = "NULL";
- break;
-
- case IS_NOT_NULL:
- display = "NOT NULL";
- break;
-
- case EQUALS:
- display = "==";
- break;
-
- case NOT_EQUALS:
- display = "!=";
- break;
-
- case LESS_THAN:
- display = "<";
- break;
-
- case LESS_OR_EQUALS:
- display = "<=";
- break;
-
- case GREATER_THAN:
- display = ">";
- break;
-
- case GREATER_OR_EQUALS:
- display = ">=";
- break;
-
- default:
- display = StringUtils.EMPTY;
- }
- break;
-
- case GROUP_MEMBERSHIP:
- switch (object) {
- case EQUALS:
- display = "IN";
- break;
-
- case NOT_EQUALS:
- display = "NOT IN";
- break;
-
- default:
- display = StringUtils.EMPTY;
- }
- break;
-
- case GROUP_MEMBER:
- switch (object) {
- case EQUALS:
- display = "WITH";
- break;
-
- case NOT_EQUALS:
- display = "WITHOUT";
- break;
-
- default:
- display = StringUtils.EMPTY;
- }
- break;
-
- case AUX_CLASS:
- case ROLE_MEMBERSHIP:
- case RESOURCE:
- switch (object) {
- case EQUALS:
- display = "HAS";
- break;
-
- case NOT_EQUALS:
- display = "HAS NOT";
- break;
-
- default:
- display = StringUtils.EMPTY;
- }
- break;
-
- case RELATIONSHIP:
- switch (object) {
- case IS_NOT_NULL:
- display = "EXIST";
- break;
+ if (comparator.getModelObject() ==
SearchClause.Comparator.IS_NULL
+ || comparator.getModelObject() ==
SearchClause.Comparator.IS_NOT_NULL) {
+ value.setEnabled(false);
+ value.setModelObject(null);
+ }
- case IS_NULL:
- display = "NOT EXIST";
- break;
+ // reload properties list
+ properties.detach();
+
property.setChoices(properties.getObject().stream().map(Pair::getValue).toList());
+ }
- case EQUALS:
- display = "WITH";
- break;
+ case ROLE_MEMBERSHIP -> {
+ value.setEnabled(false);
+ value.setModelObject(null);
- case NOT_EQUALS:
- display = "WITHOUT";
- break;
+ // reload properties list
+ properties.detach();
+
property.setChoices(properties.getObject().stream().map(Pair::getKey).toList());
+ }
- default:
- display = StringUtils.EMPTY;
- }
- break;
+ case GROUP_MEMBERSHIP -> {
+ value.setEnabled(false);
+ value.setModelObject(null);
- case CUSTOM:
- display = customizer.comparatorDisplayValue(object);
- break;
-
- default:
- display = object.toString();
- }
- return display;
+ // reload properties list
+ properties.detach();
+
property.setChoices(properties.getObject().stream().map(Pair::getKey).toList());
}
- @Override
- public String getIdValue(final SearchClause.Comparator object,
final int index) {
- return getDisplayValue(object).toString();
+ case GROUP_MEMBER -> {
+ value.setEnabled(true);
+ property.setEnabled(false);
+ property.setModelObject(StringUtils.EMPTY);
}
- @Override
- public SearchClause.Comparator getObject(
- final String id, final IModel<? extends List<? extends
SearchClause.Comparator>> choices) {
+ case AUX_CLASS, RESOURCE -> {
+ value.setEnabled(false);
+ value.setModelObject(null);
- if (id == null) {
- return SearchClause.Comparator.EQUALS;
- }
+ // reload properties list
+ properties.detach();
+
property.setChoices(properties.getObject().stream().map(Pair::getKey).toList());
+ }
- final SearchClause.Comparator comparator;
- switch (id) {
- case "HAS":
- case "IN":
- case "WITH":
- comparator = SearchClause.Comparator.EQUALS;
- break;
-
- case "HAS NOT":
- case "NOT IN":
- case "WITHOUT":
- comparator = SearchClause.Comparator.NOT_EQUALS;
- break;
-
- case "NULL":
- case "NOT EXIST":
- comparator = SearchClause.Comparator.IS_NULL;
- break;
-
- case "NOT NULL":
- case "EXIST":
- comparator = SearchClause.Comparator.IS_NOT_NULL;
- break;
-
- case "==":
- comparator = SearchClause.Comparator.EQUALS;
- break;
-
- case "!=":
- comparator = SearchClause.Comparator.NOT_EQUALS;
- break;
-
- case "<":
- comparator = SearchClause.Comparator.LESS_THAN;
- break;
-
- case "<=":
- comparator = SearchClause.Comparator.LESS_OR_EQUALS;
- break;
-
- case ">":
- comparator = SearchClause.Comparator.GREATER_THAN;
- break;
-
- case ">=":
- comparator = SearchClause.Comparator.GREATER_OR_EQUALS;
- break;
+ case RELATIONSHIP -> {
+ value.setEnabled(true);
+ value.setModelObject(null);
+ property.setEnabled(true);
- default:
- // EQUALS to be used as default value
- comparator =
customizer.comparatorGetObject(id).orElse(SearchClause.Comparator.EQUALS);
- break;
- }
+ // reload properties list
+ properties.detach();
+
property.setChoices(properties.getObject().stream().map(Pair::getKey).toList());
+ }
+
+ case CUSTOM ->
+ customizer.adjust(type, property, comparator, value,
properties);
- return comparator;
+ default -> {
}
- };
+ }
}
- @SuppressWarnings({ "rawtypes", "unchecked" })
- private void renderSearchValueField(
- final SearchClause searchClause,
- final AjaxTextFieldPanel property) {
-
- PlainSchemaTO plainSchema =
anames.getObject().get(property.getModelObject());
- if (plainSchema == null) {
- PlainSchemaTO defaultPlainTO = new PlainSchemaTO();
- defaultPlainTO.setType(AttrSchemaType.String);
- plainSchema = property.getModelObject() == null ? defaultPlainTO
- :
dnames.getObject().getOrDefault(property.getModelObject(), defaultPlainTO);
- }
+ @SuppressWarnings("unchecked")
+ protected FieldPanel<?> buildValue(final SearchClause searchClause, final
AjaxTextFieldPanel property) {
+ PlainSchemaTO plainSchema =
Optional.ofNullable(anames.getObject().get(property.getModelObject())).
+ orElseGet(() -> {
+ PlainSchemaTO defaultPlainTO = new PlainSchemaTO();
+ defaultPlainTO.setType(AttrSchemaType.String);
+ return Optional.ofNullable(property.getModelObject()).
+ map(k -> dnames.getObject().getOrDefault(k,
defaultPlainTO)).
+ orElse(defaultPlainTO);
+ });
+ FieldPanel<?> result;
switch (plainSchema.getType()) {
case Boolean:
- value = new AjaxTextFieldPanel(
+ result = new AjaxTextFieldPanel(
"value",
"value",
new PropertyModel<>(searchClause, "value"),
true);
- ((AjaxTextFieldPanel) value).setChoices(Arrays.asList("true",
"false"));
+ ((AjaxTextFieldPanel) result).setChoices(List.of("true",
"false"));
break;
case Date:
- FastDateFormat fdf = plainSchema.getConversionPattern() == null
+ FastDateFormat formatter =
StringUtils.isBlank(plainSchema.getConversionPattern())
?
DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT
:
FastDateFormat.getInstance(plainSchema.getConversionPattern());
- value = new AjaxDateTimeFieldPanel(
+ result = new AjaxDateTimeFieldPanel(
"value",
"value",
- new PropertyModel(searchClause, "value") {
+ new PropertyModel<>(searchClause, "value") {
- private static final long serialVersionUID =
1177692285167186690L;
+ private static final long serialVersionUID =
-3743432456095828573L;
@Override
- public Object getObject() {
- String date = (String) super.getObject();
+ public Date getObject() {
try {
- return date != null ? fdf.parse(date) : null;
- } catch (ParseException ex) {
- LOG.error("Date parse error {}", date, ex);
+ return StringUtils.isBlank(searchClause.getValue())
+ ? null
+ : formatter.parse(searchClause.getValue());
+ } catch (ParseException e) {
+ LOG.error("Unparsable date: {}",
searchClause.getValue(), e);
+ return null;
}
- return null;
}
@Override
- public void setObject(final Object object) {
- if (object instanceof Date) {
- String valueDate = fdf.format(object);
- super.setObject(valueDate);
- } else {
- super.setObject(object);
- }
+ public void setObject(final Date object) {
+ Optional.ofNullable(object).ifPresent(date ->
searchClause.setValue(formatter.format(date)));
}
},
DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT);
break;
case Enum:
- value = new AjaxDropDownChoicePanel<>(
+ result = new AjaxDropDownChoicePanel<>(
"value",
"value",
- new PropertyModel(searchClause, "value"),
+ new PropertyModel<>(searchClause, "value"),
true);
- ((AjaxDropDownChoicePanel<String>) value).setChoices(
+ ((AjaxDropDownChoicePanel<String>) result).setChoices(
plainSchema.getEnumValues().keySet().stream().sorted().toList());
if (!plainSchema.getEnumValues().isEmpty()) {
Map<String, String> valueMap = plainSchema.getEnumValues();
- ((AjaxDropDownChoicePanel) value).setChoiceRenderer(new
IChoiceRenderer<String>() {
+ ((AjaxDropDownChoicePanel) result).setChoiceRenderer(new
IChoiceRenderer<String>() {
private static final long serialVersionUID =
-3724971416312135885L;
@@ -1019,44 +1008,44 @@ public class SearchClausePanel extends
FieldPanel<SearchClause> {
break;
case Long:
- value = new
AjaxNumberFieldPanel.Builder<Long>().enableOnChange().build(
+ result = new
AjaxNumberFieldPanel.Builder<Long>().enableOnChange().build(
"value",
"Value",
Long.class,
- new PropertyModel(searchClause, "value"));
+ new PropertyModel<>(searchClause, "value"));
- value.add(new AttributeModifier("class", "field value
search-spinner"));
+ result.add(new AttributeModifier("class", "field value
search-spinner"));
break;
case Double:
- value = new
AjaxNumberFieldPanel.Builder<Double>().enableOnChange().step(0.1).build(
+ result = new
AjaxNumberFieldPanel.Builder<Double>().enableOnChange().step(0.1).build(
"value",
"value",
Double.class,
- new PropertyModel(searchClause, "value"));
- value.add(new AttributeModifier("class", "field value
search-spinner"));
+ new PropertyModel<>(searchClause, "value"));
+ result.add(new AttributeModifier("class", "field value
search-spinner"));
break;
default:
- value = new AjaxTextFieldPanel(
+ result = 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) {
+ result.hideLabel().setOutputMarkupId(true);
+ result.getField().add(PREVENT_DEFAULT_RETURN);
+ result.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();
+ result.getField().inputChanged();
+ result.getField().validate();
+ if (result.getField().isValid()) {
+ result.getField().valid();
+ result.getField().updateModel();
}
}
@@ -1066,6 +1055,8 @@ public class SearchClausePanel extends
FieldPanel<SearchClause> {
AJAX_SUBMIT_ON_RETURN.accept(attributes);
}
});
+
+ return result;
}
@Override
diff --git
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
index 8609cd22b6..8ec815ad15 100644
---
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
+++
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
@@ -20,11 +20,11 @@ package org.apache.syncope.client.console.rest;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.AnyTypeTO;
import org.apache.syncope.common.lib.to.RealmTO;
import org.apache.syncope.common.lib.to.SchemaTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
@@ -40,25 +40,17 @@ public class SchemaRestClient extends BaseRestClient {
private static final long serialVersionUID = -2479730152700312373L;
- public <T extends SchemaTO> List<T> getSchemas(
- final SchemaType schemaType, final AnyTypeKind kind) {
-
- AnyTypeService client = getService(AnyTypeService.class);
-
+ public <T extends SchemaTO> List<T> getSchemas(final SchemaType
schemaType, final AnyTypeKind kind) {
List<String> classes = new ArrayList<>();
switch (kind) {
- case USER:
- case GROUP:
- AnyTypeTO type = client.read(kind.name());
- if (type != null) {
- classes.addAll(type.getClasses());
- }
- break;
-
- default:
- getService(AnyTypeService.class).list().stream().filter(
- anyType -> anyType.getKind() != AnyTypeKind.USER &&
anyType.getKind() != AnyTypeKind.GROUP).
+ case USER, GROUP ->
+
Optional.ofNullable(getService(AnyTypeService.class).read(kind.name())).
+ ifPresent(anyType ->
classes.addAll(anyType.getClasses()));
+
+ default ->
+ getService(AnyTypeService.class).list().stream().
+ filter(anyType -> anyType.getKind() ==
AnyTypeKind.ANY_OBJECT).
forEach(anyType ->
classes.addAll(anyType.getClasses()));
}
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 334f28c229..af58c4ec97 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
@@ -151,7 +151,7 @@ public class PlainAttrs extends
AbstractAttrs<PlainSchemaTO> {
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()) {
+ if (schema.getType() != AttrSchemaType.Dropdown ||
!schema.isMultivalue()) {
attr.getValues().add(StringUtils.EMPTY);
}
} else {
@@ -175,7 +175,7 @@ public class PlainAttrs extends
AbstractAttrs<PlainSchemaTO> {
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()) {
+ if (schema.getType() != AttrSchemaType.Dropdown ||
!schema.isMultivalue()) {
attr.getValues().add(StringUtils.EMPTY);
}
} else {
diff --git
a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/PlainAttrs.java
b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/PlainAttrs.java
index dd715ffd94..45ef210a09 100644
---
a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/PlainAttrs.java
+++
b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/PlainAttrs.java
@@ -134,20 +134,20 @@ public class PlainAttrs extends
AbstractAttrs<PlainSchemaTO> {
@Override
protected void setAttrs() {
- List<Attr> plainAttrs = new ArrayList<>();
-
Map<String, Attr> attrMap =
EntityTOUtils.buildAttrMap(userTO.getPlainAttrs());
- plainAttrs.addAll(schemas.values().stream().map(schema -> {
- Attr attrTO = new Attr();
- attrTO.setSchema(schema.getKey());
+ 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()) {
- attrTO.getValues().add("");
+ if (schema.getType() != AttrSchemaType.Dropdown ||
!schema.isMultivalue()) {
+ attr.getValues().add(StringUtils.EMPTY);
+ }
} else {
- attrTO = attrMap.get(schema.getKey());
+ attr = attrMap.get(schema.getKey());
}
- return attrTO;
- }).toList());
+ return attr;
+ }).toList();
userTO.getPlainAttrs().clear();
userTO.getPlainAttrs().addAll(plainAttrs);
@@ -163,7 +163,9 @@ public class PlainAttrs extends
AbstractAttrs<PlainSchemaTO> {
Attr attr = new Attr();
attr.setSchema(schema.getKey());
if (attrMap.get(schema.getKey()) == null ||
attrMap.get(schema.getKey()).getValues().isEmpty()) {
- attr.getValues().add(StringUtils.EMPTY);
+ if (schema.getType() != AttrSchemaType.Dropdown ||
!schema.isMultivalue()) {
+ attr.getValues().add(StringUtils.EMPTY);
+ }
} else {
attr.getValues().addAll(attrMap.get(schema.getKey()).getValues());
}
diff --git a/pom.xml b/pom.xml
index d10bb6f6e8..236f8f95e8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -446,7 +446,7 @@ under the License.
<cas.version>7.2.2</cas.version>
<cas-client.version>4.0.4</cas-client.version>
- <swagger-core.version>2.2.31</swagger-core.version>
+ <swagger-core.version>2.2.32</swagger-core.version>
<swagger-ui.version>5.21.0</swagger-ui.version>
<jquery-slimscroll.version>1.3.8</jquery-slimscroll.version>
@@ -506,7 +506,7 @@ under the License.
<cargo.deployable.ping.timeout>60000</cargo.deployable.ping.timeout>
<tomcat.version>10.1.41</tomcat.version>
- <wildfly.version>36.0.0.Final</wildfly.version>
+ <wildfly.version>36.0.1.Final</wildfly.version>
<payara.version>6.2025.4</payara.version>
<jakarta.faces.version>4.1.3</jakarta.faces.version>