Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -682,9 +682,7 @@ public static String createMappingTypeDescription(MappingType mapping, boolean s
if (showExpression) {
ExpressionUtil.ExpressionEvaluatorType evaluatorType = null;
if (expressionBean != null) {
String expression = ExpressionUtil.loadExpression(expressionBean, PrismContext.get(), LOGGER);
evaluatorType = ExpressionUtil.getExpressionType(expression);

evaluatorType = ExpressionUtil.getExpressionType(expressionBean);
}

if (evaluatorType == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssociationFromLinkExpressionEvaluatorType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionType;

import javax.xml.namespace.QName;

import org.apache.wicket.MarkupContainer;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
Expand All @@ -23,7 +25,11 @@ public class AssociationFromLinkPanel extends EvaluatorExpressionPanel {
private static final Trace LOGGER = TraceManager.getTrace(AssociationFromLinkPanel.class);

public AssociationFromLinkPanel(String id, IModel<ExpressionType> model) {
super(id, model);
this(id, model, null);
}

public AssociationFromLinkPanel(String id, IModel<ExpressionType> model, IModel<QName> expressionTargetTypeModel) {
super(id, model, expressionTargetTypeModel);
updateEvaluatorValue();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

package com.evolveum.midpoint.gui.impl.component.input.expression;

import javax.xml.namespace.QName;

import com.evolveum.midpoint.gui.api.component.BasePanel;
import com.evolveum.midpoint.gui.api.page.PageBase;
import com.evolveum.midpoint.gui.impl.component.message.FeedbackLabels;
Expand All @@ -24,8 +26,29 @@ public abstract class EvaluatorExpressionPanel extends BasePanel<ExpressionType>
private static final String ID_VALUE_CONTAINER = "valueContainer";
private static final String ID_FEEDBACK = "feedback";

/**
* Type of the object the expression is evaluated against. Null when the context does not tell us.
*/
private final IModel<QName> expressionTargetTypeModel;

public EvaluatorExpressionPanel(String id, IModel<ExpressionType> model) {
this(id, model, null);
}

public EvaluatorExpressionPanel(String id, IModel<ExpressionType> model, IModel<QName> expressionTargetTypeModel) {
super(id, model);
this.expressionTargetTypeModel = expressionTargetTypeModel;
}

/**
* Type of the object the expression is evaluated against, for panels that need to know the
* schema they work with.
*
* @return the type, or null when the context does not tell us and the panel has to manage
* without it.
*/
protected QName getExpressionTargetType() {
return expressionTargetTypeModel != null ? expressionTargetTypeModel.getObject() : null;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
import com.evolveum.midpoint.web.util.ExpressionUtil.ExpressionEvaluatorType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionType;

import javax.xml.namespace.QName;

import org.apache.wicket.model.StringResourceModel;
import org.jetbrains.annotations.NotNull;

Expand Down Expand Up @@ -97,6 +99,9 @@ public enum RecognizedEvaluator {
PATH(ExpressionEvaluatorType.PATH,
PathExpressionPanel.class,
"ExpressionEvaluatorType.PATH.show.button"),
FILTER(ExpressionEvaluatorType.FILTER,
FilterExpressionPanel.class,
"ExpressionEvaluatorType.FILTER.show.button"),
NULL(ExpressionEvaluatorType.NULL,
null, null);

Expand Down Expand Up @@ -159,9 +164,7 @@ private void initTypeModels() {
typeModel = new LoadableModel<>(false) {
@Override
protected RecognizedEvaluator load() {
String expression = ExpressionUtil.loadExpression(getModelObject(), PrismContext.get(), LOGGER);

ExpressionEvaluatorType type = ExpressionUtil.getExpressionType(expression);
ExpressionEvaluatorType type = ExpressionUtil.getExpressionType(getModelObject());
return recognizeEvaluator(type);
}

Expand Down Expand Up @@ -435,6 +438,28 @@ public void onClick(AjaxRequestTarget target) {
return typeButton;
}

/**
* Returns type of the object the expression is evaluated against, taken from the schema context of the item.
*
* @return target object type of expression or null while the schema context is not defined for the expression.
*/
private QName resolveExpressionTargetType() {
PrismPropertyWrapper<ExpressionType> wrapper = parent != null ? parent.getObject() : null;
if (wrapper == null) {
return null;
}

var item = wrapper.getItem();
if (item == null || item.getValue() == null) {
return null;
}
var schemaContext = item.getValue().getSchemaContext();
if (schemaContext == null || schemaContext.getItemDefinition() == null) {
return null;
}
return schemaContext.getItemDefinition().getTypeName();
}

private WebMarkupContainer createEvaluatorPanel() {
return createEvaluatorPanel(ExpressionPanel.ID_EVALUATOR_PANEL, false);
}
Expand All @@ -443,8 +468,10 @@ private WebMarkupContainer createEvaluatorPanel(String id, boolean isInPopup) {
RecognizedEvaluator type = typeModel.getObject();
if (type != null && type.evaluatorPanel != null) {
try {
Constructor<? extends BasePanel<ExpressionType>> constructor = type.evaluatorPanel.getConstructor(String.class, IModel.class);
BasePanel<ExpressionType> evaluatorPanel = constructor.newInstance(id, getModel());
Constructor<? extends BasePanel<ExpressionType>> constructor =
type.evaluatorPanel.getConstructor(String.class, IModel.class, IModel.class);
BasePanel<ExpressionType> evaluatorPanel =
constructor.newInstance(id, getModel(), (IModel<QName>) this::resolveExpressionTargetType);
evaluatorPanel.setOutputMarkupId(true);
evaluatorPanel.add(new VisibleBehaviour(() -> isInPopup || isEvaluatorPanelExpanded()));
if (!isInTable()) {
Expand All @@ -453,7 +480,7 @@ private WebMarkupContainer createEvaluatorPanel(String id, boolean isInPopup) {
return evaluatorPanel;
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
LOGGER.error("Couldn't create panel for expression evaluator by constructor for class {} with parameters type: "
+ "String, IModel", type.evaluatorPanel.getSimpleName());
+ "String, IModel, IModel", type.evaluatorPanel.getSimpleName());
}
}
WebMarkupContainer invisiblePanel = new WebMarkupContainer(id);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<!--
~ Copyright (c) 2026 Evolveum
~
~ Licensed under the EUPL-1.2 or later.
-->

<html xmlns:wicket="http://wicket.apache.org">
<wicket:extend>
<div class="pb-2">
<div class="prism-property-label p-0">
<span><wicket:message key="FilterExpressionEvaluatorType.filter"/></span>
</div>
<div class="prism-property-value" wicket:id="filterInput"/>
</div>
</wicket:extend>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright (c) 2026 Evolveum and contributors
*
* Licensed under the EUPL-1.2 or later.
*/

package com.evolveum.midpoint.gui.impl.component.input.expression;

import javax.xml.namespace.QName;

import org.apache.wicket.MarkupContainer;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LambdaModel;
import org.apache.wicket.model.StringResourceModel;

import com.evolveum.midpoint.gui.api.page.PageBase;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.web.page.admin.reports.component.SearchFilterConfigurationPanel;
import com.evolveum.midpoint.web.util.ExpressionUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FilterExpressionEvaluatorType;
import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType;

public class FilterExpressionPanel extends EvaluatorExpressionPanel {

private static final Trace LOGGER = TraceManager.getTrace(FilterExpressionPanel.class);

private static final String ID_FILTER_INPUT = "filterInput";

public FilterExpressionPanel(String id, IModel<ExpressionType> model, IModel<QName> expressionTargetTypeModel) {
super(id, model, expressionTargetTypeModel);
}

@Override
public IModel<String> getValueContainerLabelModel(PageBase pageBase) {
return pageBase.createStringResource("FilterExpressionPanel.label");
}

@Override
protected void initLayout(MarkupContainer parent) {
parent.add(new SearchFilterConfigurationPanel<>(
ID_FILTER_INPUT, null, createFilterModel(), this::getExpressionTargetType) {

@Override
protected StringResourceModel getConfigPanelTitle() {
return createStringResource("FilterExpressionPanel.configureFilter");
}

@Override
protected boolean addEmptyBlumBehaviourToTextField() {
return true;
}
});
}

/**
* Model of the filter of the expression. {@link LambdaModel} skips the setter when its target
* object is null, and the expression of an empty condition is null, so the target falls back to
* a fresh expression. Without it the first filter the user configures is silently dropped.
*/
private IModel<SearchFilterType> createFilterModel() {
return LambdaModel.of(
getModel().orElseGet(ExpressionType::new), FilterExpressionPanel::readFilter, this::writeFilter);
}

private static SearchFilterType readFilter(ExpressionType expression) {
FilterExpressionEvaluatorType evaluator = ExpressionUtil.getFilterExpressionValue(expression);
return evaluator != null ? evaluator.getFilter() : null;
}

private void writeFilter(ExpressionType expression, SearchFilterType filter) {
try {
FilterExpressionEvaluatorType evaluator = filter == null
? null
: new FilterExpressionEvaluatorType().filter(filter);
getModel().setObject(
ExpressionUtil.updateFilterExpressionValue(expression, evaluator));
} catch (SchemaException ex) {
LOGGER.error("Couldn't update filter expression value: {}", ex.getLocalizedMessage());
getPageBase().error("Couldn't update filter expression value: " + ex.getLocalizedMessage());
}
}

/**
* Description of the filter shown in the tooltip of the collapsed expression. Looked up by class
* and method name from {@link ExpressionPanel}, do not remove.
*
* @param expression expression the filter belongs to.
* @param pageBase page the description is created for.
* @return the query text of the filter, or an empty string when there is none.
*/
public static String getInfoDescription(ExpressionType expression, PageBase pageBase) {
FilterExpressionEvaluatorType evaluator = ExpressionUtil.getFilterExpressionValue(expression);
if (evaluator == null || evaluator.getFilter() == null) {
return "";
}
String text = evaluator.getFilter().getText();
return text != null ? text : "";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ public class GenerateExpressionPanel extends EvaluatorExpressionPanel {
private static final String ID_VALUE_POLICY = "valuePolicy";

public GenerateExpressionPanel(String id, IModel<ExpressionType> model) {
super(id, model);
this(id, model, null);
}

public GenerateExpressionPanel(String id, IModel<ExpressionType> model, IModel<QName> expressionTargetTypeModel) {
super(id, model, expressionTargetTypeModel);
GenerateExpressionWrapper wrapper = getEvaluatorValue();
if (wrapper == null || wrapper.isEmpty()) {
updateEvaluatorValue((GenerateExpressionEvaluatorModeType) null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

import com.evolveum.prism.xml.ns._public.types_3.ItemPathType;

import javax.xml.namespace.QName;

import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.ajax.AjaxRequestTarget;
Expand All @@ -33,7 +35,11 @@ public class PathExpressionPanel extends EvaluatorExpressionPanel {
private static final String ID_PATH_LABEL = "pathLabel";

public PathExpressionPanel(String id, IModel<ExpressionType> model) {
super(id, model);
this(id, model, null);
}

public PathExpressionPanel(String id, IModel<ExpressionType> model, IModel<QName> expressionTargetTypeModel) {
super(id, model, expressionTargetTypeModel);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import com.evolveum.midpoint.web.page.admin.reports.component.SimpleAceEditorPanel;
import com.evolveum.midpoint.web.util.ExpressionUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionType;

import javax.xml.namespace.QName;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ScriptExpressionEvaluatorType;

import org.apache.commons.lang3.StringUtils;
Expand Down Expand Up @@ -47,7 +49,11 @@ public class ScriptExpressionPanel extends EvaluatorExpressionPanel {
private static final String C_DATA_SUFFIX = "]]>";

public ScriptExpressionPanel(String id, IModel<ExpressionType> model) {
super(id, model);
this(id, model, null);
}

public ScriptExpressionPanel(String id, IModel<ExpressionType> model, IModel<QName> expressionTargetTypeModel) {
super(id, model, expressionTargetTypeModel);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ public class ShadowOwnerReferenceSearchExpressionPanel extends EvaluatorExpressi
private static final String ID_RELATION_EXPRESSION_LABEL = "relationExpressionLabel";

public ShadowOwnerReferenceSearchExpressionPanel(String id, IModel<ExpressionType> model) {
super(id, model);
this(id, model, null);
}

public ShadowOwnerReferenceSearchExpressionPanel(
String id, IModel<ExpressionType> model, IModel<QName> expressionTargetTypeModel) {
super(id, model, expressionTargetTypeModel);
updateEvaluatorValue();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import com.evolveum.midpoint.web.util.ExpressionUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionType;

import javax.xml.namespace.QName;

import org.jetbrains.annotations.NotNull;

public class SimpleValueExpressionPanel extends EvaluatorExpressionPanel {
Expand All @@ -46,7 +48,11 @@ public class SimpleValueExpressionPanel extends EvaluatorExpressionPanel {
private static final String ID_REMOVE_BUTTON = "remove";

public SimpleValueExpressionPanel(String id, IModel<ExpressionType> model) {
super(id, model);
this(id, model, null);
}

public SimpleValueExpressionPanel(String id, IModel<ExpressionType> model, IModel<QName> expressionTargetTypeModel) {
super(id, model, expressionTargetTypeModel);
if (getEvaluatorValues().isEmpty()) {
updateEvaluatorValue(List.of());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
package com.evolveum.midpoint.gui.impl.factory.panel.expression;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import com.evolveum.midpoint.gui.api.prism.wrapper.PrismValueWrapper;

import com.evolveum.midpoint.gui.impl.component.input.expression.ScriptExpressionPanel;
import com.evolveum.midpoint.gui.impl.component.input.expression.ExpressionPanel;
import com.evolveum.midpoint.gui.impl.factory.panel.PrismPropertyPanelContext;
import com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType;

Expand All @@ -33,7 +35,14 @@ public void register() {

@Override
protected Panel getPanel(PrismPropertyPanelContext<ExpressionType> panelCtx) {
return new ScriptExpressionPanel(panelCtx.getComponentId(), panelCtx.getRealValueModel());
return new ExpressionPanel(
panelCtx.getComponentId(), panelCtx.getItemWrapperModel(), panelCtx.getRealValueModel()) {

@Override
protected List<RecognizedEvaluator> getChoices() {
return new ArrayList<>(List.of(RecognizedEvaluator.SCRIPT, RecognizedEvaluator.FILTER));
}
};
}

@Override
Expand Down
Loading
Loading