diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java index fb5e3c5faf6..95b14014609 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java @@ -4396,6 +4396,20 @@ public static Class resolveSelfPage() { return null; } + public static PrismObject findLookupTable(ItemDefinition definition, PageBase page) { + PrismReferenceValue valueEnumerationRef = definition.getValueEnumerationRef(); + if (valueEnumerationRef == null) { + return null; + } + + String lookupTableUid = valueEnumerationRef.getOid(); + Task task = page.createSimpleTask("loadLookupTable"); + OperationResult result = task.getResult(); + + Collection> options = WebModelServiceUtils.createLookupTableRetrieveOptions(page.getSchemaHelper()); + return WebModelServiceUtils.loadObject(LookupTableType.class, lookupTableUid, options, page, task, result); + } + public static boolean hasAnyArchetypeAssignemnt(AH assignmentHolder) { if (assignmentHolder.getAssignment() == null) { return false; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/SearchFilterPanelFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/SearchFilterPanelFactory.java index 1d543adc758..07636e1ac46 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/SearchFilterPanelFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/panel/SearchFilterPanelFactory.java @@ -9,6 +9,15 @@ import javax.annotation.PostConstruct; +import com.evolveum.midpoint.gui.api.prism.wrapper.PrismContainerValueWrapper; +import com.evolveum.midpoint.gui.api.prism.wrapper.PrismPropertyWrapper; + +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.web.page.admin.reports.component.SearchFilterConfigurationPanel; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectCollectionType; + +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; + import org.apache.wicket.markup.html.panel.Panel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -34,6 +43,14 @@ public boolean match(IW wrapper) { @Override protected Panel getPanel(PrismPropertyPanelContext panelCtx) { + PrismPropertyWrapper searchFilterItemWrapper = panelCtx.unwrapWrapperModel(); + PrismContainerValueWrapper containerWrapper = searchFilterItemWrapper.getParent(); + if (containerWrapper != null && containerWrapper.getRealValue() instanceof ObjectCollectionType){ + ObjectCollectionType collectionObj = (ObjectCollectionType) containerWrapper.getRealValue(); + return new SearchFilterConfigurationPanel(panelCtx.getComponentId(), panelCtx.getRealValueModel(), + (Class)WebComponentUtil.qnameToClass(panelCtx.getPageBase().getPrismContext(), + collectionObj.getType() != null ? collectionObj.getType() : ObjectType.COMPLEX_TYPE)); + } return new AceEditorPanel(panelCtx.getComponentId(), null, new SearchFilterTypeModel(panelCtx.getRealValueModel(), panelCtx.getPageBase()), 10); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/AbstractSearchConfigurationPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/AbstractSearchConfigurationPanel.html index c58bfdb42f3..2c4e6a63384 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/AbstractSearchConfigurationPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/AbstractSearchConfigurationPanel.html @@ -13,8 +13,9 @@ diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/AbstractSearchConfigurationPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/AbstractSearchConfigurationPanel.java index 315371d54d8..be0f2b44ab1 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/AbstractSearchConfigurationPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/AbstractSearchConfigurationPanel.java @@ -6,6 +6,10 @@ */ package com.evolveum.midpoint.web.component.search; +import com.evolveum.midpoint.prism.query.ObjectFilter; +import com.evolveum.midpoint.web.component.search.filter.SearchFilter; +import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; + import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.model.IModel; @@ -20,19 +24,23 @@ /** * @author Kateryna Honchar */ -public abstract class AbstractSearchConfigurationPanel extends BasePanel { +public abstract class AbstractSearchConfigurationPanel extends BasePanel { private static final long serialVersionUID = 1L; private static final Trace LOG = TraceManager.getTrace(AbstractSearchConfigurationPanel.class); protected static final String ID_CONFIGURATION_PANEL = "configurationPanel"; private static final String ID_BUTTONS_PANEL = "buttonsPanel"; - private static final String ID_APPLY_FILTER_BUTTON = "applyFilterButton"; - private static final String ID_SAVE_FILTER_BUTTON = "saveFilterButton"; + private static final String ID_OK_BUTTON = "okButton"; +// private static final String ID_APPLY_FILTER_BUTTON = "applyFilterButton"; +// private static final String ID_SAVE_FILTER_BUTTON = "saveFilterButton"; private static final String ID_CANCEL_BUTTON = "cancelButton"; - public AbstractSearchConfigurationPanel(String id, IModel searchModel) { + private Class type; + + public AbstractSearchConfigurationPanel(String id, IModel searchModel, Class type) { super(id, searchModel); + this.type = type; } @Override @@ -56,27 +64,38 @@ private void initButtonsPanel() { buttonsPanel.setOutputMarkupId(true); add(buttonsPanel); - AjaxButton applyFilterButton = new AjaxButton(ID_APPLY_FILTER_BUTTON, createStringResource("SearchPropertiesConfigPanel.applyFilterButton")) { + AjaxButton applyFilterButton = new AjaxButton(ID_OK_BUTTON, createStringResource("Button.ok")) { private static final long serialVersionUID = 1L; @Override public void onClick(AjaxRequestTarget ajaxRequestTarget) { - //todo + okButtonClicked(ajaxRequestTarget); } }; applyFilterButton.setOutputMarkupId(true); buttonsPanel.add(applyFilterButton); - AjaxButton saveFilterButton = new AjaxButton(ID_SAVE_FILTER_BUTTON, createStringResource("SearchPropertiesConfigPanel.saveFilterButton")) { - private static final long serialVersionUID = 1L; - - @Override - public void onClick(AjaxRequestTarget ajaxRequestTarget) { - //todo - } - }; - saveFilterButton.setOutputMarkupId(true); - buttonsPanel.add(saveFilterButton); +// AjaxButton applyFilterButton = new AjaxButton(ID_APPLY_FILTER_BUTTON, createStringResource("SearchPropertiesConfigPanel.applyFilterButton")) { +// private static final long serialVersionUID = 1L; +// +// @Override +// public void onClick(AjaxRequestTarget ajaxRequestTarget) { +// //todo +// } +// }; +// applyFilterButton.setOutputMarkupId(true); +// buttonsPanel.add(applyFilterButton); +// +// AjaxButton saveFilterButton = new AjaxButton(ID_SAVE_FILTER_BUTTON, createStringResource("SearchPropertiesConfigPanel.saveFilterButton")) { +// private static final long serialVersionUID = 1L; +// +// @Override +// public void onClick(AjaxRequestTarget ajaxRequestTarget) { +// //todo +// } +// }; +// saveFilterButton.setOutputMarkupId(true); +// buttonsPanel.add(saveFilterButton); AjaxButton cancelButton = new AjaxButton(ID_CANCEL_BUTTON, createStringResource("SearchPropertiesConfigPanel.cancelButton")) { private static final long serialVersionUID = 1L; @@ -92,6 +111,11 @@ public void onClick(AjaxRequestTarget ajaxRequestTarget) { protected abstract void initConfigurationPanel(WebMarkupContainer configPanel); - @NotNull - protected abstract Class getObjectClass(); + protected void okButtonClicked(AjaxRequestTarget target){ + + } + + public Class getType() { + return type; + } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/BasicSearchFilterModel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/BasicSearchFilterModel.java new file mode 100644 index 00000000000..487b3aaf34b --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/BasicSearchFilterModel.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2010-2019 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ +package com.evolveum.midpoint.web.component.search; + +import com.evolveum.midpoint.gui.api.page.PageBase; +import com.evolveum.midpoint.gui.impl.factory.panel.SearchFilterTypeModel; +import com.evolveum.midpoint.prism.query.ObjectFilter; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.logging.LoggingUtils; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.web.component.search.filter.BasicSearchFilter; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; + +import org.apache.commons.lang3.StringUtils; +import org.apache.wicket.model.IModel; + +/** + * @author honchar + */ +public class BasicSearchFilterModel implements IModel> { + + private static final Trace LOGGER = TraceManager.getTrace(SearchFilterTypeModel.class); + + private static final long serialVersionUID = 1L; + + private IModel baseModel; + private PageBase pageBase; + private Class type; + private BasicSearchFilter basicSearchFilter; + + public BasicSearchFilterModel(IModel valueWrapper, Class type, PageBase pageBase) { + this.baseModel = valueWrapper; + this.pageBase = pageBase; + this.type = type; + } + + @Override + public void detach() { + // TODO Auto-generated method stub + + } + + @Override + public BasicSearchFilter getObject() { + if (basicSearchFilter == null){ + basicSearchFilter = loadBasicSearchFilter(); + } + return basicSearchFilter; + } + + private BasicSearchFilter loadBasicSearchFilter(){ + try { +// SearchFilterType value = baseModel.getObject(); +// if (value == null) { +// return new BasicSearchFilter(pageBase.getPrismContext(), null, type); +// } + + ObjectFilter objectFilter = pageBase.getPrismContext().getQueryConverter().createObjectFilter(type, baseModel.getObject()); + return new BasicSearchFilter(pageBase.getPrismContext(), objectFilter, type); + } catch (SchemaException e) { + // TODO handle + LoggingUtils.logUnexpectedException(LOGGER, "Cannot serialize filter", e); + } + return null; + } + + @Override + public void setObject(BasicSearchFilter object) { + } +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceValueSearchPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceValueSearchPanel.html new file mode 100644 index 00000000000..634aa62edcd --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceValueSearchPanel.html @@ -0,0 +1,27 @@ + + + + + +
+
+
+ + + +
+
+ +
+
+
+
+
+
+ + diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceValueSearchPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceValueSearchPanel.java new file mode 100644 index 00000000000..26fc348d728 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceValueSearchPanel.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2010-2020 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ +package com.evolveum.midpoint.web.component.search; + +import com.evolveum.midpoint.gui.api.component.BasePanel; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.prism.PrismReferenceDefinition; +import com.evolveum.midpoint.web.component.AjaxButton; +import com.evolveum.midpoint.web.component.input.TextPanel; + +import com.evolveum.midpoint.xml.ns._public.common.common_3.AreaCategoryType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; + +import org.apache.commons.lang.StringUtils; +import org.apache.wicket.Component; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; + +import javax.xml.namespace.QName; +import java.util.List; + +/** + * @author honchar + */ +public class ReferenceValueSearchPanel extends BasePanel { + + private static final long serialVersionUID = 1L; + + private static final String ID_REFERENCE_VALUE_TEXT_FIELD = "referenceValueTextField"; + private static final String ID_EDIT_BUTTON = "editButton"; + private static final String ID_REF_POPOVER_PANEL = "refPopoverPanel"; + private static final String ID_REF_POPOVER_BODY = "refPopoverBody"; + private static final String ID_REF_POPOVER = "refPopover"; + private PrismReferenceDefinition referenceDef; + + public ReferenceValueSearchPanel(String id, IModel model, PrismReferenceDefinition referenceDef) { + super(id, model); + this.referenceDef = referenceDef; + } + + @Override + protected void onInitialize(){ + super.onInitialize(); + initLayout(); + } + + private void initLayout(){ + setOutputMarkupId(true); + + TextPanel referenceTextValueField = new TextPanel(ID_REFERENCE_VALUE_TEXT_FIELD, Model.of(getReferenceTextModel())); + referenceTextValueField.setOutputMarkupId(true); + add(referenceTextValueField); + + AjaxButton editButton = new AjaxButton(ID_EDIT_BUTTON) { + private static final long serialVersionUID = 1L; + + @Override + public void onClick(AjaxRequestTarget target) { + togglePopover(target, ReferenceValueSearchPanel.this.get(ID_REFERENCE_VALUE_TEXT_FIELD), + ReferenceValueSearchPanel.this.get(createComponentPath(ID_REF_POPOVER)), 0); + } + }; + editButton.setOutputMarkupId(true); + add(editButton); + + WebMarkupContainer popover = new WebMarkupContainer(ID_REF_POPOVER); + popover.setOutputMarkupId(true); + add(popover); + + WebMarkupContainer popoverBody = new WebMarkupContainer(ID_REF_POPOVER_BODY); + popoverBody.setOutputMarkupId(true); + popover.add(popoverBody); + + ReferenceValueSearchPopupPanel value = + new ReferenceValueSearchPopupPanel(ID_REF_POPOVER_PANEL, getModel()) { + + private static final long serialVersionUID = 1L; + + @Override + protected List getAllowedRelations() { + return WebComponentUtil.getCategoryRelationChoices(AreaCategoryType.ADMINISTRATION, getPageBase()); + } + + @Override + protected List getSupportedTargetList() { + return WebComponentUtil.createSupportedTargetTypeList((referenceDef).getTargetTypeName()); + } + + @Override + protected void confirmPerformed(AjaxRequestTarget target) { + target.add(ReferenceValueSearchPanel.this); + } + }; + value.setRenderBodyOnly(true); + popoverBody.add(value); + + } + + private String getReferenceTextModel(){ + ObjectReferenceType ref = getModelObject(); + if (ref == null){ + return null; + } + StringBuilder sb = new StringBuilder(); + if (StringUtils.isNotEmpty(ref.getOid())){ + sb.append(createStringResource("ReferencePopupPanel.oid").getString()); + sb.append(ref.getOid()); + } + if (ref.getRelation() != null){ + if (sb.length() > 0){ + sb.append("; "); + } + sb.append(createStringResource("ReferencePopupPanel.relation").getString()); + sb.append(ref.getRelation().getLocalPart()); + } + if (ref.getType() != null){ + if (sb.length() > 0){ + sb.append("; "); + } + sb.append(ref.getType().getLocalPart()); + } + return sb.toString(); + } + + public void togglePopover(AjaxRequestTarget target, Component button, Component popover, int paddingRight) { + StringBuilder script = new StringBuilder(); + script.append("toggleSearchPopover('"); + script.append(button.getMarkupId()).append("','"); + script.append(popover.getMarkupId()).append("',"); + script.append(paddingRight).append(");"); + + target.appendJavaScript(script.toString()); + } + +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferencePopupPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceValueSearchPopupPanel.html similarity index 100% rename from gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferencePopupPanel.html rename to gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceValueSearchPopupPanel.html diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferencePopupPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceValueSearchPopupPanel.java similarity index 77% rename from gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferencePopupPanel.java rename to gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceValueSearchPopupPanel.java index 510077a4313..caf8bce3dd9 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferencePopupPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceValueSearchPopupPanel.java @@ -33,7 +33,7 @@ import com.evolveum.midpoint.web.page.admin.configuration.component.EmptyOnBlurAjaxFormUpdatingBehaviour; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; -public class ReferencePopupPanel extends BasePanel> { +public class ReferenceValueSearchPopupPanel extends BasePanel { private static final long serialVersionUID = 1L; @@ -43,11 +43,8 @@ public class ReferencePopupPanel extends BasePanel allowedRelations; - - public ReferencePopupPanel(String id, IModel> model) { + public ReferenceValueSearchPopupPanel(String id, IModel model) { super(id, model); -// this.allowedRelations = allowedRelations; } @Override @@ -58,7 +55,7 @@ protected void onInitialize() { private void initLayout() { - TextField oidField = new TextField(ID_OID, new PropertyModel<>(getModel(), SearchValue.F_VALUE + ".oid")); + TextField oidField = new TextField(ID_OID, new PropertyModel<>(getModel(), "oid")); oidField.add(new AjaxFormComponentUpdatingBehavior("blur") { @@ -73,23 +70,7 @@ protected void onUpdate(AjaxRequestTarget target) { oidField.add(new EmptyOnBlurAjaxFormUpdatingBehaviour()); add(oidField); - ReferenceAutocomplete nameField = new ReferenceAutocomplete(ID_NAME, new IModel() { - private static final long serialVersionUID = 1L; - - @Override - public ObjectReferenceType getObject() { - return getModelObject().getValue(); - } - - @Override - public void setObject(ObjectReferenceType ref) { - if (ref == null){ - return; - } - getModelObject().getValue().setOid(ref.getOid()); - getModelObject().getValue().setType(ref.getType()); - } - }, + ReferenceAutocomplete nameField = new ReferenceAutocomplete(ID_NAME, Model.of(getModelObject()), new AutoCompleteReferenceRenderer(), getPageBase()){ @@ -106,20 +87,20 @@ protected Class getReferenceTargetObjectType(){ }; - nameField.getBaseFormComponent().add(new AjaxFormComponentUpdatingBehavior("change") { - - private static final long serialVersionUID = 1L; - - @Override - protected void onUpdate(AjaxRequestTarget target) { - - } - }); +// nameField.add(new AjaxFormComponentUpdatingBehavior("blur") { +// +// private static final long serialVersionUID = 1L; +// +// @Override +// protected void onUpdate(AjaxRequestTarget target) { +// +// } +// }); nameField.setOutputMarkupId(true); nameField.getBaseFormComponent().add(new EmptyOnBlurAjaxFormUpdatingBehaviour()); add(nameField); - DropDownChoice type = new DropDownChoice<>(ID_TYPE, new PropertyModel(getModel(), SearchValue.F_VALUE + ".type"), + DropDownChoice type = new DropDownChoice<>(ID_TYPE, new PropertyModel(getModel(), "type"), getSupportedTargetList(), new QNameObjectTypeChoiceRenderer()); type.setNullValid(true); type.setOutputMarkupId(true); @@ -135,15 +116,15 @@ public boolean isEnabled() { type.add(new EmptyOnBlurAjaxFormUpdatingBehaviour()); add(type); - if (getModelObject() != null && getModelObject().getValue() != null && getModelObject().getValue().getRelation() == null){ - getModelObject().getValue().setRelation(PrismConstants.Q_ANY); + if (getModelObject() != null && getModelObject().getRelation() == null){ + getModelObject().setRelation(PrismConstants.Q_ANY); } List allowedRelations = new ArrayList(); allowedRelations.addAll(getAllowedRelations()); if (!allowedRelations.contains(PrismConstants.Q_ANY)) { allowedRelations.add(0, PrismConstants.Q_ANY); } - DropDownChoice relation = new DropDownChoice<>(ID_RELATION, new PropertyModel(getModel(), SearchValue.F_VALUE + ".relation"), + DropDownChoice relation = new DropDownChoice<>(ID_RELATION, new PropertyModel(getModel(), "relation"), allowedRelations, new QNameObjectTypeChoiceRenderer()); // relation.setNullValid(true); relation.setOutputMarkupId(true); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchItemPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchItemPanel.java index f87a316a26f..c317cd3b795 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchItemPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchItemPanel.java @@ -15,17 +15,14 @@ import javax.xml.namespace.QName; import com.evolveum.midpoint.gui.api.component.autocomplete.AutoCompleteTextPanel; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import org.apache.commons.lang.StringUtils; import org.apache.wicket.AttributeModifier; import org.apache.wicket.Component; -import org.apache.wicket.ajax.AjaxEventBehavior; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; import org.apache.wicket.behavior.AttributeAppender; import org.apache.wicket.behavior.Behavior; -import org.apache.wicket.markup.ComponentTag; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.IChoiceRenderer; @@ -181,11 +178,6 @@ public void onSubmit(AjaxRequestTarget target) { AjaxSubmitButton removeButton = new AjaxSubmitButton(ID_REMOVE_BUTTON) { private static final long serialVersionUID = 1L; - @Override - public void onError(AjaxRequestTarget target){ - String e =""; - } - @Override public void onSubmit(AjaxRequestTarget target) { deletePerformed(target); @@ -200,10 +192,9 @@ private void initSearchItemField(WebMarkupContainer searchItemContainer) { Component searchItemField = null; SearchItem item = getModelObject(); IModel>> choices = null; - PrismObject lookupTable = findLookupTable(item.getDefinition()); + PrismObject lookupTable = WebComponentUtil.findLookupTable(item.getDefinition(), getPageBase()); switch (item.getType()) { case REFERENCE: - //TODO change probably to another component searchItemField = new TextPanel(ID_SEARCH_ITEM_FIELD, new PropertyModel(getModel(), "value.value"){ private static final long serialVersionUID = 1L; @@ -360,21 +351,9 @@ private void initPopover() { popoverBody.setOutputMarkupId(true); popover.add(popoverBody); - - DisplayableValue val = SearchItemPanel.this.getModelObject().getValue(); - IModel> refModel = new IModel>() { - @Override - public DisplayableValue getObject() { - if (val.getValue() instanceof ObjectReferenceType){ - return val; - } else { - return null; - } - } - }; if (getModelObject() != null && SearchItem.Type.REFERENCE.equals(getModelObject().getType())) { - ReferencePopupPanel value = - new ReferencePopupPanel(ID_VALUE, new PropertyModel<>(getModel(), "value")) { + ReferenceValueSearchPopupPanel value = + new ReferenceValueSearchPopupPanel(ID_VALUE, new PropertyModel<>(getModel(), "value.value")) { private static final long serialVersionUID = 1L; @@ -408,22 +387,6 @@ protected void confirmPerformed(AjaxRequestTarget target) { } } - private PrismObject findLookupTable(ItemDefinition definition) { - PrismReferenceValue valueEnumerationRef = definition.getValueEnumerationRef(); - if (valueEnumerationRef == null) { - return null; - } - - PageBase page = getPageBase(); - - String lookupTableUid = valueEnumerationRef.getOid(); - Task task = page.createSimpleTask("loadLookupTable"); - OperationResult result = task.getResult(); - - Collection> options = WebModelServiceUtils.createLookupTableRetrieveOptions(getSchemaHelper()); - return WebModelServiceUtils.loadObject(LookupTableType.class, lookupTableUid, options, page, task, result); - } - private IModel>> createBooleanChoices() { List> list = new ArrayList<>(); list.add(new SearchValue<>(Boolean.TRUE, getString("Boolean.TRUE"))); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPanel.java index 1ccb1e72f90..da75d1b865b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPanel.java @@ -785,14 +785,14 @@ private boolean isFullTextSearchEnabled(){ } private void searchConfigurationPerformed(AjaxRequestTarget target){ - SearchPropertiesConfigPanel configPanel = new SearchPropertiesConfigPanel(getPageBase().getMainPopupBodyId(), getModel()) { - private static final long serialVersionUID = 1L; - - @Override - protected @NotNull Class getObjectClass() { - return SearchPanel.this.getModelObject().getType(); - } - }; - getPageBase().showMainPopup(configPanel, target); +// SearchPropertiesConfigPanel configPanel = new SearchPropertiesConfigPanel(getPageBase().getMainPopupBodyId(), getModel()) { +// private static final long serialVersionUID = 1L; +// +// @Override +// protected @NotNull Class getObjectClass() { +// return SearchPanel.this.getModelObject().getType(); +// } +// }; +// getPageBase().showMainPopup(configPanel, target); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPropertiesConfigPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPropertiesConfigPanel.html index f1b1160229d..6521ead6309 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPropertiesConfigPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPropertiesConfigPanel.html @@ -11,10 +11,6 @@
- - - -
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPropertiesConfigPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPropertiesConfigPanel.java index 2965f419c92..81537fe87b7 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPropertiesConfigPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPropertiesConfigPanel.java @@ -8,8 +8,10 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Iterator; import java.util.List; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; @@ -26,9 +28,14 @@ import org.apache.wicket.model.PropertyModel; import org.apache.wicket.model.StringResourceModel; +import com.evolveum.midpoint.gui.api.component.autocomplete.AutoCompleteTextPanel; import com.evolveum.midpoint.gui.api.model.LoadableModel; +import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; -import com.evolveum.midpoint.prism.PrismObjectDefinition; +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.query.ObjectFilter; +import com.evolveum.midpoint.util.DisplayableValue; +import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.web.component.AjaxButton; import com.evolveum.midpoint.web.component.data.BoxedTablePanel; import com.evolveum.midpoint.web.component.data.column.CheckBoxColumn; @@ -36,39 +43,45 @@ import com.evolveum.midpoint.web.component.dialog.Popupable; import com.evolveum.midpoint.web.component.input.DropDownChoicePanel; import com.evolveum.midpoint.web.component.input.TextPanel; +import com.evolveum.midpoint.web.component.prism.InputPanel; +import com.evolveum.midpoint.web.component.search.filter.BasicSearchFilter; +import com.evolveum.midpoint.web.component.search.filter.ValueSearchFilterItem; +import com.evolveum.midpoint.web.component.util.EnableBehaviour; import com.evolveum.midpoint.web.component.util.SelectableBean; import com.evolveum.midpoint.web.component.util.SelectableListDataProvider; import com.evolveum.midpoint.web.page.admin.configuration.component.EmptyOnBlurAjaxFormUpdatingBehaviour; +import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; /** * @author Kateryna Honchar */ -public abstract class SearchPropertiesConfigPanel extends AbstractSearchConfigurationPanel implements Popupable { +public class SearchPropertiesConfigPanel extends AbstractSearchConfigurationPanel, O> implements Popupable { private static final long serialVersionUID = 1L; private static final String ID_PROPERTY_CONFIG_CONTAINER = "propertyConfigContainer"; private static final String ID_PROPERTY_CHOICE = "propertyChoice"; - private static final String ID_PROPERTY_VALUE = "propertyValue"; - private static final String ID_FILTER = "filter"; - private static final String ID_MATCHING_RULE = "matchingRule"; - private static final String ID_NEGATION = "negation"; private static final String ID_PROPERTIES_TABLE = "propertiesTable"; private static final String ID_ADD_BUTTON = "addButton"; - IModel propertyChoiceModel = Model.of(); + private SelectableListDataProvider, ValueSearchFilterItem> provider; - public SearchPropertiesConfigPanel(String id, IModel searchModel) { - super(id, searchModel); + public SearchPropertiesConfigPanel(String id, IModel> searchModel, Class type) { + super(id, searchModel, type); } @Override protected void initConfigurationPanel(WebMarkupContainer configPanel) { + provider = + new SelectableListDataProvider, ValueSearchFilterItem>(getPageBase(), getSearchFilterItemModel()); + WebMarkupContainer propertyConfigContainer = new WebMarkupContainer(ID_PROPERTY_CONFIG_CONTAINER); propertyConfigContainer.setOutputMarkupId(true); configPanel.add(propertyConfigContainer); DropDownChoicePanel propertyChoicePanel = new DropDownChoicePanel(ID_PROPERTY_CHOICE, - propertyChoiceModel, Model.ofList(getAvailablePropertiesList()), new IChoiceRenderer() { + Model.of(getDefaultPropertyChoice()), getAvailablePropertiesListModel(), new IChoiceRenderer() { private static final long serialVersionUID = 1L; @@ -98,26 +111,6 @@ protected String getNullValidDisplayValue() { propertyChoicePanel.getBaseFormComponent().add(new EmptyOnBlurAjaxFormUpdatingBehaviour()); propertyConfigContainer.add(propertyChoicePanel); -// TextPanel valuePanel = new TextPanel(ID_PROPERTY_VALUE, Model.of()); -// valuePanel.setOutputMarkupId(true); -// propertyConfigContainer.add(valuePanel); -// -// DropDownChoicePanel filterChoice = WebComponentUtil.createEnumPanel(ID_FILTER, -// Model.ofList(Arrays.asList(SearchConfigDto.FilterType.values())), Model.of(), -// SearchPropertiesConfigPanel.this, true, "Select"); //todo allow null? -// filterChoice.setOutputMarkupId(true); -// propertyConfigContainer.add(filterChoice); -// -// DropDownChoicePanel matchingRuleChoice = WebComponentUtil.createEnumPanel(ID_MATCHING_RULE, -// Model.ofList(Arrays.asList(SearchConfigDto.MatchingRule.values())), Model.of(), -// SearchPropertiesConfigPanel.this, true, "Select"); //todo allow null? -// matchingRuleChoice.setOutputMarkupId(true); -// propertyConfigContainer.add(matchingRuleChoice); -// -// CheckBoxPanel negationChoice = new CheckBoxPanel(ID_NEGATION, Model.of()); -// negationChoice.setOutputMarkupId(true); -// propertyConfigContainer.add(negationChoice); - AjaxButton addButton = new AjaxButton(ID_ADD_BUTTON) { private static final long serialVersionUID = 1L; @@ -132,12 +125,18 @@ public void onClick(AjaxRequestTarget ajaxRequestTarget) { initTable(configPanel); } + private Property getDefaultPropertyChoice() { + List availablePropertiesList = getAvailablePropertiesListModel().getObject(); + if (CollectionUtils.isNotEmpty(availablePropertiesList)) { + return availablePropertiesList.get(0); + } + return null; + } + private void initTable(WebMarkupContainer configPanel) { - SelectableListDataProvider, SearchConfigDto> provider = - new SelectableListDataProvider, SearchConfigDto>(getPageBase(), getSearchConfigModel()); - List, String>> columns = getTableColumns(); - BoxedTablePanel> table = - new BoxedTablePanel>(ID_PROPERTIES_TABLE, provider, columns, null, 20) { + List, String>> columns = getTableColumns(); + BoxedTablePanel> table = + new BoxedTablePanel>(ID_PROPERTIES_TABLE, provider, columns, null, 20) { private static final long serialVersionUID = 1L; @Override @@ -182,62 +181,61 @@ public boolean isAutoRefreshEnabled() { } }; table.setOutputMarkupId(true); - configPanel.addOrReplace(table); + configPanel.add(table); } - private List, String>> getTableColumns() { - List, String>> columns = new ArrayList<>(); + private List, String>> getTableColumns() { + List, String>> columns = new ArrayList<>(); - CheckBoxHeaderColumn> checkboxColumn = new CheckBoxHeaderColumn<>(); + CheckBoxHeaderColumn> checkboxColumn = new CheckBoxHeaderColumn<>(); columns.add(checkboxColumn); - IColumn, String> propertyColumn = new PropertyColumn, String>(getPageBase() + IColumn, String> propertyColumn = new PropertyColumn, String>(getPageBase() .createStringResource("SearchPropertiesConfigPanel.table.column.property"), - "value." + SearchConfigDto.F_PROPERTY + "." + Property.F_NAME); + "value." + ValueSearchFilterItem.F_PROPERTY_NAME); columns.add(propertyColumn); - IColumn, String> valueColumn = new AbstractColumn, String>(getPageBase() + IColumn, String> valueColumn = new AbstractColumn, String>(getPageBase() .createStringResource("SearchPropertiesConfigPanel.table.column.value")) { private static final long serialVersionUID = 1L; @Override - public void populateItem(Item>> item, String id, IModel> rowModel) { - TextPanel valuePanel = new TextPanel(id, new PropertyModel(rowModel, "value." + SearchConfigDto.F_VALUE)); - valuePanel.setOutputMarkupId(true); - valuePanel.getBaseFormComponent().add(new EmptyOnBlurAjaxFormUpdatingBehaviour()); - item.add(valuePanel); + public void populateItem(Item>> item, String id, IModel> rowModel) { + item.add(getPropertyValueField( id, rowModel)); } }; columns.add(valueColumn); - IColumn, String> filterColumn = new AbstractColumn, String>(getPageBase() + IColumn, String> filterColumn = new AbstractColumn, String>(getPageBase() .createStringResource("SearchPropertiesConfigPanel.table.column.filter")) { private static final long serialVersionUID = 1L; @Override - public void populateItem(Item>> item, String id, IModel> rowModel) { - DropDownChoicePanel filterPanel = WebComponentUtil.createEnumPanel(id, - Model.ofList(Arrays.asList(SearchConfigDto.FilterType.values())), - new PropertyModel<>(rowModel, "value." + SearchConfigDto.F_FILTER_TYPE), - SearchPropertiesConfigPanel.this, true, + public void populateItem(Item>> item, String id, IModel> rowModel) { + List availableFilterNames = rowModel.getObject().getValue().getAvailableFilterNameList(); + DropDownChoicePanel filterPanel = WebComponentUtil.createEnumPanel(id, + Model.ofList(availableFilterNames), + new PropertyModel<>(rowModel, "value." + ValueSearchFilterItem.F_FILTER_TYPE_NAME), + SearchPropertiesConfigPanel.this, false, getPageBase().createStringResource("SearchPropertiesConfigPanel.selectFilter").getString()); filterPanel.setOutputMarkupId(true); filterPanel.getBaseFormComponent().add(new EmptyOnBlurAjaxFormUpdatingBehaviour()); + filterPanel.getBaseFormComponent().add(new EnableBehaviour(() -> availableFilterNames.size() > 1)); item.add(filterPanel); } }; columns.add(filterColumn); - IColumn, String> matchingRuleColumn = new AbstractColumn, String>(getPageBase() + IColumn, String> matchingRuleColumn = new AbstractColumn, String>(getPageBase() .createStringResource("SearchPropertiesConfigPanel.table.column.matchingRule")) { private static final long serialVersionUID = 1L; @Override - public void populateItem(Item>> item, String id, IModel> rowModel) { - DropDownChoicePanel matchingRulePanel = WebComponentUtil.createEnumPanel(id, - Model.ofList(Arrays.asList(SearchConfigDto.FilterType.values())), - new PropertyModel<>(rowModel, "value." + SearchConfigDto.F_MATCHING_RULE), + public void populateItem(Item>> item, String id, IModel> rowModel) { + DropDownChoicePanel matchingRulePanel = WebComponentUtil.createEnumPanel(id, + Model.ofList(Arrays.asList(ValueSearchFilterItem.MatchingRule.values())), + new PropertyModel<>(rowModel, "value." + ValueSearchFilterItem.F_MATCHING_RULE), SearchPropertiesConfigPanel.this, true, getPageBase().createStringResource("SearchPropertiesConfigPanel.selectMatchingRule").getString()); matchingRulePanel.setOutputMarkupId(true); @@ -247,50 +245,143 @@ public void populateItem(Item>> i }; columns.add(matchingRuleColumn); - CheckBoxColumn> negationColumn = new CheckBoxColumn>(getPageBase() + CheckBoxColumn> negationColumn = new CheckBoxColumn>(getPageBase() .createStringResource("SearchPropertiesConfigPanel.table.column.applyNegotiation"), - "value." + SearchConfigDto.F_NEGATION); + "value." + ValueSearchFilterItem.F_APPLY_NEGATION); columns.add(negationColumn); return columns; } - private List getAvailablePropertiesList() { - PrismObjectDefinition objectDef = SearchFactory.findObjectDefinition(getObjectClass(), null, getPageBase()); - List availableDefs = SearchFactory.getAvailableDefinitions(objectDef, true); - List propertiesList = new ArrayList<>(); - availableDefs.forEach(searchItemDef -> propertiesList.add(new Property(searchItemDef.getDef()))); - return propertiesList; + private LoadableModel> getAvailablePropertiesListModel() { + return new LoadableModel>() { + @Override + protected List load() { + PrismObjectDefinition objectDef = SearchFactory.findObjectDefinition(getType(), null, getPageBase()); + List availableDefs = SearchFactory.getAvailableDefinitions(objectDef, true); + List propertiesList = new ArrayList<>(); + availableDefs.forEach(searchItemDef -> { + if (!isPropertyAlreadyAdded(searchItemDef.getDef())) { + propertiesList.add(new Property(searchItemDef.getDef())); + } + }); + return propertiesList; + } + }; + } + + private boolean isPropertyAlreadyAdded(ItemDefinition def){ + List> properties = provider.getAvailableData(); + for (SelectableBean prop : properties){ + if (QNameUtil.match(prop.getValue().getPropertyPath(), def.getItemName())){ + return true; + } + } + return false; } - private LoadableModel> getSearchConfigModel() { - return new LoadableModel>(true) { + private LoadableModel> getSearchFilterItemModel() { + return new LoadableModel>(true) { private static final long serialVersionUID = 1L; @Override - protected List load() { - List searchConfigDtos = new ArrayList<>(); - getModelObject().getItems().forEach(searchItem -> { - searchConfigDtos.add(SearchConfigDto.createSearchConfigDto(searchItem)); - }); - return searchConfigDtos; + protected List load() { + BasicSearchFilter basicSearchFilter = getModelObject(); + if (basicSearchFilter == null){ + return new ArrayList<>(); + } + return basicSearchFilter.getValueSearchFilterItems(); } }; } private void propertyAddedPerformed(AjaxRequestTarget target) { - Property newPropertyValue = propertyChoiceModel.getObject(); + Property newPropertyValue = getPropertyChoicePanel().getBaseFormComponent().getModelObject(); if (newPropertyValue != null) { - getModelObject().addItem(newPropertyValue.getDefinition()); - initTable((WebMarkupContainer) get(ID_CONFIGURATION_PANEL)); //todo don't re-init table! - target.add(get(createComponentPath(ID_CONFIGURATION_PANEL, ID_PROPERTIES_TABLE))); + getModelObject().addSearchFilterItem(createDefaultValueFilter(newPropertyValue)); } target.add(SearchPropertiesConfigPanel.this); } - private Property getSelectedProperty() { - DropDownChoicePanel propertyChoicePanel = (DropDownChoicePanel) get(getPageBase() - .createComponentPath(ID_CONFIGURATION_PANEL, ID_PROPERTY_CONFIG_CONTAINER, ID_PROPERTY_CHOICE)); - return propertyChoicePanel.getModel().getObject(); + private DropDownChoicePanel getPropertyChoicePanel(){ + return (DropDownChoicePanel) get(createComponentPath(ID_CONFIGURATION_PANEL, ID_PROPERTY_CONFIG_CONTAINER, ID_PROPERTY_CHOICE)); + } + + private ValueSearchFilterItem createDefaultValueFilter(Property property) { + if (property == null){ + return null; + } + return new ValueSearchFilterItem(property, false); + } + + private Component getPropertyValueField(String id, IModel> rowModel) { + Component searchItemField = null; + ValueSearchFilterItem valueSearchFilter = rowModel.getObject().getValue(); + ItemDefinition propertyDef = valueSearchFilter.getPropertyDef(); + if (propertyDef != null) { + PrismObject lookupTable = WebComponentUtil.findLookupTable(propertyDef, getPageBase()); + + if (propertyDef instanceof PrismReferenceDefinition) { + ObjectReferenceType propertyValue = (ObjectReferenceType) valueSearchFilter.getValue(); + searchItemField = new ReferenceValueSearchPanel(id, Model.of(propertyValue), + (PrismReferenceDefinition) propertyDef); + } else if (propertyDef instanceof PrismPropertyDefinition) { + List allowedValues = new ArrayList<>(); + if (((PrismPropertyDefinition) propertyDef).getAllowedValues() != null) { + allowedValues.addAll(((PrismPropertyDefinition) propertyDef).getAllowedValues()); + } + if (lookupTable != null) { + searchItemField = new AutoCompleteTextPanel(id, + new PropertyModel<>(rowModel, "value." + ValueSearchFilterItem.F_VALUE), String.class, + true, lookupTable.asObjectable()) { + + private static final long serialVersionUID = 1L; + + @Override + public Iterator getIterator(String input) { + return WebComponentUtil.prepareAutoCompleteList(lookupTable.asObjectable(), input, + ((PageBase) getPage()).getLocalizationService()).iterator(); + } + }; + } else if (CollectionUtils.isNotEmpty(allowedValues)) { + searchItemField = new DropDownChoicePanel(id, + new PropertyModel<>(rowModel, "value." + ValueSearchFilterItem.F_VALUE), + Model.ofList(allowedValues), new IChoiceRenderer() { + private static final long serialVersionUID = 1L; + + @Override + public Object getDisplayValue(DisplayableValue val) { + return val.getLabel(); + } + + @Override + public String getIdValue(DisplayableValue val, int index) { + return Integer.toString(index); + } + + @Override + public DisplayableValue getObject(String id, IModel> choices) { + return StringUtils.isNotBlank(id) ? choices.getObject().get(Integer.parseInt(id)) : null; + } + }, true); + } else { + searchItemField = new TextPanel(id, new PropertyModel<>(rowModel, "value." + ValueSearchFilterItem.F_VALUE)); + + } + } + } + if (searchItemField != null && searchItemField instanceof InputPanel){ + ((InputPanel) searchItemField).getBaseFormComponent().add(new EmptyOnBlurAjaxFormUpdatingBehaviour()); + } + return searchItemField != null ? searchItemField : new WebMarkupContainer(id); + } + + @Override + protected void okButtonClicked(AjaxRequestTarget target){ + ObjectFilter configuredFilter = getModelObject().buildObjectFilter(); + filterConfiguredPerformed(configuredFilter, target); + } + + protected void filterConfiguredPerformed(ObjectFilter configuredFilter, AjaxRequestTarget target){ } public int getWidth() { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/filter/BasicSearchFilter.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/filter/BasicSearchFilter.java new file mode 100644 index 00000000000..7e28ec7ec4e --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/filter/BasicSearchFilter.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2020 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ +package com.evolveum.midpoint.web.component.search.filter; + +import java.util.Arrays; +import java.util.List; + +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.query.*; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; + +/** + * @author honchar + */ +public class BasicSearchFilter extends SearchFilter { + + private static final long serialVersionUID = 1L; + private static final Trace LOGGER = TraceManager.getTrace(BasicSearchFilter.class); + + private LogicalFilterValue logicalFilterValue = LogicalFilterValue.AND; + + public BasicSearchFilter(PrismContext prismContext, ObjectFilter baseFilter, Class type) { + super(prismContext, baseFilter, type); + } + + @Override + public void addSearchFilterItem(ValueSearchFilterItem valueSearchFilterItem) { + getValueSearchFilterItems().add(valueSearchFilterItem); + } + +// public ObjectFilter convertToObjectFilter() { +// if (CollectionUtils.isEmpty(getSearchFilterItems())) { +// return null; +// } +// List subFilterList = new ArrayList<>(); +// getSearchFilterItems().forEach(searchFilterItem -> { +// subFilterList.add(((ValueSearchFilterItem) searchFilterItem).buildObjectFilter()); +// }); +// if (logicalFilterItem == null && subFilterList.size() == 1) { +// return subFilterList.get(0); +// } +// if (logicalFilterItem == null) { +// logicalFilterItem = getPrismContext().queryFactory().createAnd(); +// } +// if (logicalFilterItem instanceof OrSearchFilterItem) { +// return getPrismContext().queryFactory().createOr(subFilterList); +// } else { +// return getPrismContext().queryFactory().createAnd(subFilterList); +// } +// } + + protected void initSearchFilterItems(ObjectFilter baseFilter) { + if (baseFilter == null) { + return; + } + if (baseFilter instanceof AndFilter) { + logicalFilterValue = LogicalFilterValue.AND; + + AndFilter andFilter = (AndFilter) baseFilter; + addValueFilters(andFilter.getConditions()); + } else if (baseFilter instanceof OrFilter) { + logicalFilterValue = LogicalFilterValue.OR; + + OrFilter orFilter = (OrFilter) baseFilter; + addValueFilters(orFilter.getConditions()); + } else if (baseFilter instanceof ValueFilter) { + addValueFilters(Arrays.asList(baseFilter)); + } + } + + @Override + public ObjectFilter buildObjectFilter(){ + if (logicalFilterValue.equals(LogicalFilterValue.OR)){ + return getPrismContext().queryFactory().createAnd(getObjectFilterList()); + } else { + return getPrismContext().queryFactory().createOr(getObjectFilterList()); + } + } + + public void addValueFilters(List objectFilters) { + objectFilters.forEach(filter -> { + boolean applyNegation = false; + if (filter instanceof NotFilter){ + applyNegation = true; + } + ObjectFilter realFilter = applyNegation ? ((NotFilter) filter).getFilter() : filter; + if (realFilter instanceof ValueFilter) { + ValueSearchFilterItem filterItem = new ValueSearchFilterItem((ValueFilter)realFilter, applyNegation); + addSearchFilterItem(filterItem); + } + }); + } + + public LogicalFilterValue getLogicalFilterValue() { + return logicalFilterValue; + } + + public void setLogicalFilterValue(LogicalFilterValue logicalFilterValue) { + this.logicalFilterValue = logicalFilterValue; + } +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/filter/SearchFilter.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/filter/SearchFilter.java new file mode 100644 index 00000000000..f221ee9f6bf --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/filter/SearchFilter.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ +package com.evolveum.midpoint.web.component.search.filter; + +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.query.ObjectFilter; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * @author honchar + */ +public abstract class SearchFilter implements Serializable { + + private static final long serialVersionUID = 1L; + private List valueSearchFilterItems = new ArrayList<>(); +// private LogicalSearchFilterItem logicalSearchFilterItem; + private PrismContext prismContext; + private ObjectFilter baseFilter; + Class type; + + public enum LogicalFilterValue{ + AND, + OR; + } + + public SearchFilter(PrismContext prismContext, ObjectFilter baseFilter, Class type){ + this.prismContext = prismContext; + this.baseFilter = baseFilter; + this.type = type; + + initSearchFilterItems(baseFilter); + } + + public List getValueSearchFilterItems() { + return valueSearchFilterItems; //todo return unmodifiable list + } + + public List getObjectFilterList() { + List objectFilters = new ArrayList<>(); + valueSearchFilterItems.forEach(filterItem -> objectFilters.add(filterItem.buildFilter(prismContext, type))); + return objectFilters; + } + + public abstract void addSearchFilterItem(ValueSearchFilterItem valueSearchFilterItem); + + protected abstract void initSearchFilterItems(ObjectFilter baseFilter); + + public abstract ObjectFilter buildObjectFilter(); + + public Class getType(){ + return type; + } + + public PrismContext getPrismContext() { + return prismContext; + } +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/filter/ValueSearchFilterItem.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/filter/ValueSearchFilterItem.java new file mode 100644 index 00000000000..dbb6ccd753e --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/filter/ValueSearchFilterItem.java @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2020 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ +package com.evolveum.midpoint.web.component.search.filter; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import javax.xml.namespace.QName; + +import org.apache.commons.collections.CollectionUtils; + +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.query.*; +import com.evolveum.midpoint.prism.query.builder.S_ConditionEntry; +import com.evolveum.midpoint.web.component.search.Property; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; + +/** + * @author honchar + */ +public class ValueSearchFilterItem implements Serializable { + + private static final long serialVersionUID = 1L; + public static final String F_VALUE = "value"; + public static final String F_FILTER_TYPE_NAME = "filterTypeName"; + public static final String F_APPLY_NEGATION = "applyNegation"; + public static final String F_FILTER = "filter"; + public static final String F_MATCHING_RULE = "matchingRule"; + public static final String F_PROPERTY_NAME = "propertyName"; + public static final String F_PROPERTY_PATH = "propertyPath"; + + public enum FilterName { + EQUAL(EqualFilter.class), + GREATER_OR_EQUAL(GreaterFilter.class), + GREATER(GreaterFilter.class), + LESS_OR_EQUAL(LessFilter.class), + LESS(LessFilter.class), + REF(RefFilter.class), + SUBSTRING(SubstringFilter.class), + SUBSTRING_ANCHOR_START(SubstringFilter.class), + SUBSTRING_ANCHOR_END(SubstringFilter.class); +// SUBSTRING_ANCHOR_START_AND_END("SUBSTRING_ANCHOR_START_AND_END"); //seems repeats usual substring + + private Class filterType; + + FilterName(Class filterType) { + this.filterType = filterType; + } + + public Class getFilterType() { + return filterType; + } + + public static FilterName findFilterName(F filter) { + if (filter instanceof LessFilter && ((LessFilter) filter).isEquals()) { + return FilterName.LESS_OR_EQUAL; + } else if (filter instanceof GreaterFilter && ((GreaterFilter) filter).isEquals()) { + return FilterName.GREATER_OR_EQUAL; + } else if (filter instanceof SubstringFilter && ((SubstringFilter) filter).isAnchorStart() && !((SubstringFilter) filter).isAnchorEnd()) { + return FilterName.SUBSTRING_ANCHOR_START; + } else if (filter instanceof SubstringFilter && ((SubstringFilter) filter).isAnchorEnd() && !((SubstringFilter) filter).isAnchorStart()) { + return FilterName.SUBSTRING_ANCHOR_END; + } else{ + return findFilterName(filter.getClass()); + } + } + + public static FilterName findFilterName(Class filterType){ + for (FilterName filterName : values()){ + if (filterName.getFilterType().equals(filterType.getInterfaces()[0])){ + return filterName; + } + } + return null; + } + } + + public enum MatchingRule { + STRING_IGNORE_CASE(PrismConstants.STRING_IGNORE_CASE_MATCHING_RULE_NAME), + POLY_STRING_STRICT(PrismConstants.POLY_STRING_STRICT_MATCHING_RULE_NAME), + POLY_STRING_ORIG(PrismConstants.POLY_STRING_ORIG_MATCHING_RULE_NAME), + POLY_STRING_NORM(PrismConstants.POLY_STRING_NORM_MATCHING_RULE_NAME), + EXCHANGE_EMAIL_ADDRESSES(PrismConstants.EXCHANGE_EMAIL_ADDRESSES_MATCHING_RULE_NAME), + DISTINGUISHED_NAME(PrismConstants.DISTINGUISHED_NAME_MATCHING_RULE_NAME), + XML(PrismConstants.XML_MATCHING_RULE_NAME), + UUID(PrismConstants.UUID_MATCHING_RULE_NAME), + DEFAULT(PrismConstants.DEFAULT_MATCHING_RULE_NAME); + + private QName matchingRuleName; + + MatchingRule(QName matchingRuleName) { + this.matchingRuleName = matchingRuleName; + } + + public QName getMatchingRuleName() { + return matchingRuleName; + } + } + + private boolean applyNegation; + private ValueFilter filter; + private FilterName filterTypeName = FilterName.EQUAL; + private MatchingRule matchingRule = null; + private String propertyName; + private QName propertyPath; + private Object value; + ItemDefinition propertyDef; + + public ValueSearchFilterItem(ValueFilter filter, boolean applyNegation) { + this.filter = filter; + this.applyNegation = applyNegation; + propertyName = filter.getElementName().toString(); + propertyPath = filter.getElementName(); + propertyDef = filter.getDefinition(); + value = CollectionUtils.isNotEmpty(filter.getValues()) ? filter.getValues().get(0) : null; + parseFilterName(); + } + + public ValueSearchFilterItem(Property property, boolean applyNegation) { + propertyName = property.getDefinition().getItemName().toString(); + propertyPath = property.getDefinition().getItemName(); + propertyDef = property.getDefinition(); + this.applyNegation = applyNegation; + if (propertyDef instanceof PrismReferenceDefinition){ + value = new ObjectReferenceType(); + } + parseFilterName(); + } + + public boolean isApplyNegation() { + return applyNegation; + } + + public void setApplyNegation(boolean applyNegation) { + this.applyNegation = applyNegation; + } + + public ValueFilter getFilter() { + return filter; + } + + public void setFilter(ValueFilter filter) { + this.filter = filter; + } + + //todo which filter types do we want to support here + public Object getValue() { + if (value instanceof PrismValue) { + return ((PrismValue) value).getRealValue(); + } + return null; + } + + public FilterName getFilterTypeName() { + return filterTypeName; + } + + public void setFilterTypeName(FilterName filterTypeName) { + this.filterTypeName = filterTypeName; + } + + public MatchingRule getMatchingRule() { + return matchingRule; + } + + public void setMatchingRule(MatchingRule matchingRule) { + this.matchingRule = matchingRule; + } + + public String getPropertyName() { + return propertyName; + } + + public void setPropertyName(String propertyName) { + this.propertyName = propertyName; + } + + public QName getPropertyPath() { + return propertyPath; + } + + public void setPropertyPath(QName propertyPath) { + this.propertyPath = propertyPath; + } + + public void setValue(Object value) { + this.value = value; + } + + public ItemDefinition getPropertyDef() { + return propertyDef; + } + + public void setPropertyDef(ItemDefinition propertyDef) { + this.propertyDef = propertyDef; + } + + public ObjectFilter buildFilter(PrismContext prismContext, Class type){ + S_ConditionEntry conditionEntry = prismContext.queryFor(type).item(propertyPath); + ObjectFilter builtFilter = null; + if (FilterName.EQUAL.equals(filterTypeName)) { + builtFilter = conditionEntry.eq(value).buildFilter(); + } else if (FilterName.GREATER.equals(filterTypeName)) { + builtFilter = conditionEntry.gt(value).buildFilter(); + } else if (FilterName.GREATER_OR_EQUAL.equals(filterTypeName)) { + builtFilter = conditionEntry.ge(value).buildFilter(); + } else if (FilterName.LESS.equals(filterTypeName)) { + builtFilter = conditionEntry.lt(value).buildFilter(); + } else if (FilterName.LESS_OR_EQUAL.equals(filterTypeName)) { + builtFilter = conditionEntry.le(value).buildFilter(); + } else if (FilterName.REF.equals(filterTypeName) && value != null) { + PrismReferenceValue refVal = (PrismReferenceValue) value; + //todo do we need to separately create refType and refRelation ? +// if (StringUtils.isNotEmpty(refVal.getOid())){ +// +// } + if (refVal.getParent() instanceof RefFilter){ + builtFilter = (RefFilter) refVal.getParent(); + } else { + builtFilter = conditionEntry.ref(refVal).buildFilter(); + } + } else if (FilterName.SUBSTRING.equals(filterTypeName)) { + builtFilter = conditionEntry.contains(value).buildFilter(); + } else if (FilterName.SUBSTRING_ANCHOR_START.equals(filterTypeName)) { + builtFilter = conditionEntry.startsWith(value).buildFilter(); + } else if (FilterName.SUBSTRING_ANCHOR_END.equals(filterTypeName)) { + builtFilter = conditionEntry.endsWith(value).buildFilter(); + } + if (builtFilter instanceof ValueFilter && matchingRule != null){ + ((ValueFilter) builtFilter).setMatchingRule(matchingRule.getMatchingRuleName()); + } + if (isApplyNegation()){ + builtFilter = prismContext.queryFactory().createNot(builtFilter); + } + return builtFilter != null ? builtFilter : prismContext.queryFor(type).buildFilter(); + } + + private void parseFilterName (){ + if (propertyDef instanceof PrismReferenceDefinition){ + filterTypeName = FilterName.REF; + } else if (filter != null) { + filterTypeName = FilterName.findFilterName(filter); + } + } + + public List getAvailableFilterNameList(){ + if (propertyDef == null){ + return Arrays.asList(FilterName.values()); + } + if (propertyDef instanceof PrismReferenceDefinition){ + return Collections.singletonList(FilterName.REF); + } else { + List filterNames = new ArrayList<>(); + for (FilterName val : FilterName.values()) { + if (!FilterName.REF.equals(val)){ + filterNames.add(val); + } + } + return filterNames; + } + } + + public List getAvailableMatchingRuleList(){ + List matchingRules = Arrays.asList(MatchingRule.values()); + if (propertyDef == null){ + return matchingRules; + } + //todo + return matchingRules; + } +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AceEditorPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AceEditorPanel.html index 281057c5fc7..cdcb7e4dfee 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AceEditorPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AceEditorPanel.html @@ -8,7 +8,9 @@ -

+
+

+

diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AceEditorPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AceEditorPanel.java index 3e77c96b71b..054a91b0ce6 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AceEditorPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AceEditorPanel.java @@ -9,8 +9,10 @@ import com.evolveum.midpoint.gui.api.component.BasePanel; import com.evolveum.midpoint.web.component.AceEditor; +import com.evolveum.midpoint.web.component.util.VisibleBehaviour; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; +import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.model.IModel; @@ -20,6 +22,7 @@ public class AceEditorPanel extends BasePanel { private static final String ID_TITLE = "title"; + private static final String ID_TITLE_CONTAINER = "titleContainer"; private static final String ID_EDITOR = "editor"; private IModel title; @@ -40,14 +43,14 @@ public AceEditorPanel(String id, IModel title, IModel data, int private void initLayout(int minSize) { + WebMarkupContainer titleContainer = new WebMarkupContainer(ID_TITLE_CONTAINER); + titleContainer.setOutputMarkupId(true); + titleContainer.add(new VisibleBehaviour(() -> title != null)); + add(titleContainer); + Label title = new Label(ID_TITLE, this.title); - title.add(new VisibleEnableBehaviour() { - @Override - public boolean isVisible() { - return title != null; - } - }); - add(title); + title.setOutputMarkupId(true); + titleContainer.add(title); AceEditor editor = new AceEditor(ID_EDITOR, getModel()); editor.setReadonly(false); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/SearchFilterConfigurationPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/SearchFilterConfigurationPanel.html new file mode 100644 index 00000000000..ea492496de9 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/SearchFilterConfigurationPanel.html @@ -0,0 +1,19 @@ + + + + +
+ + + diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/SearchFilterConfigurationPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/SearchFilterConfigurationPanel.java new file mode 100644 index 00000000000..6c7a714d250 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/SearchFilterConfigurationPanel.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2020 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ +package com.evolveum.midpoint.web.page.admin.reports.component; + +import com.evolveum.midpoint.gui.api.component.BasePanel; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.gui.impl.factory.panel.SearchFilterTypeModel; +import com.evolveum.midpoint.prism.query.ObjectFilter; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.logging.LoggingUtils; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.web.component.search.BasicSearchFilterModel; +import com.evolveum.midpoint.web.component.search.SearchPropertiesConfigPanel; +import com.evolveum.midpoint.web.component.search.filter.BasicSearchFilter; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType; + +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.AjaxLink; +import org.apache.wicket.model.IModel; +import org.jetbrains.annotations.NotNull; + +import javax.xml.namespace.QName; + +/** + * @author honchar + */ +public class SearchFilterConfigurationPanel extends BasePanel { + private static final long serialVersionUID = 1L; + + private static final Trace LOGGER = TraceManager.getTrace(SearchFilterConfigurationPanel.class); + + private static final String ID_ACE_EDITOR_FIELD = "aceEditorField"; + private static final String ID_CONFIGURE_BUTTON = "configureButton"; + + Class filterType; + + public SearchFilterConfigurationPanel(String id, IModel model, Class filterType){ + super(id, model); + this.filterType = filterType; + } + + @Override + protected void onInitialize(){ + super.onInitialize(); + initLayout(); + } + + private void initLayout(){ + AceEditorPanel aceEditorField = new AceEditorPanel(ID_ACE_EDITOR_FIELD, null, new SearchFilterTypeModel(getModel(), getPageBase()), 10); + aceEditorField.setOutputMarkupId(true); + add(aceEditorField); + + AjaxLink searchConfigurationButton = new AjaxLink(ID_CONFIGURE_BUTTON) { + private static final long serialVersionUID = 1L; + + @Override + public void onClick(AjaxRequestTarget target) { + searchConfigurationPerformed(target); + } + }; + searchConfigurationButton.setOutputMarkupId(true); + add(searchConfigurationButton); + + } + + private void searchConfigurationPerformed(AjaxRequestTarget target){ + SearchPropertiesConfigPanel configPanel = new SearchPropertiesConfigPanel(getPageBase().getMainPopupBodyId(), + new BasicSearchFilterModel(getModel(), filterType, getPageBase()), filterType){ + private static final long serialVersionUID = 1L; + + @Override + protected void filterConfiguredPerformed(ObjectFilter configuredFilter, AjaxRequestTarget target){ + getPageBase().hideMainPopup(target); + + try { + if (configuredFilter == null) { + return; + } + SearchFilterConfigurationPanel.this.getModel().setObject(getPageBase().getPrismContext().getQueryConverter().createSearchFilterType(configuredFilter)); + target.add(getAceEditorPanel()); + } catch (SchemaException e) { + LoggingUtils.logUnexpectedException(LOGGER, "Cannot serialize filter", e); + } + } + }; + getPageBase().showMainPopup(configPanel, target); + } + + private AceEditorPanel getAceEditorPanel(){ + return (AceEditorPanel) get(ID_ACE_EDITOR_FIELD); + } +}