diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/autocomplete/AutoCompleteReferenceRenderer.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/autocomplete/AutoCompleteReferenceRenderer.java new file mode 100644 index 00000000000..7d87ac9f839 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/autocomplete/AutoCompleteReferenceRenderer.java @@ -0,0 +1,33 @@ +/* + * 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.gui.api.component.autocomplete; + +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; + +import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AbstractAutoCompleteRenderer; +import org.apache.wicket.request.Response; + +/** + * @author honchar + */ +public class AutoCompleteReferenceRenderer extends AbstractAutoCompleteRenderer { + + private static final long serialVersionUID = 1L; + + @Override + protected String getTextValue(ObjectReferenceType object) { + return WebComponentUtil.getName(object); + } + + @Override + protected void renderChoice(ObjectReferenceType object, Response response, String criteria) { + String textValue = getTextValue(object); + response.write(textValue); + + } +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/autocomplete/AutoCompleteTextPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/autocomplete/AutoCompleteTextPanel.java index a715ecc0852..492dbf20d9e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/autocomplete/AutoCompleteTextPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/autocomplete/AutoCompleteTextPanel.java @@ -78,12 +78,7 @@ protected void updateAjaxAttributes(AjaxRequestAttributes attributes){ @Override public IConverter getConverter(Class type) { IConverter converter = super.getConverter(type); - if (lookupTable == null) { - return converter; - } - - return new LookupTableConverter<>(converter, lookupTable, getBaseFormComponent(), strict); - + return getAutoCompleteConverter(type, converter); } }; @@ -114,6 +109,14 @@ protected void updateAjaxAttributes(AjaxRequestAttributes attributes){ * */ public abstract Iterator getIterator(String input); + protected IConverter getAutoCompleteConverter(Class type, IConverter originConverter){ + if (lookupTable == null) { + return originConverter; + } + + return new LookupTableConverter<>(originConverter, lookupTable, getBaseFormComponent(), strict); + } + @Override public FormComponent getBaseFormComponent() { return (FormComponent) get(ID_INPUT); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/autocomplete/ReferenceConverter.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/autocomplete/ReferenceConverter.java new file mode 100644 index 00000000000..2af853ffdab --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/autocomplete/ReferenceConverter.java @@ -0,0 +1,68 @@ +/* + * 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.gui.api.component.autocomplete; + +import com.evolveum.midpoint.gui.api.page.PageBase; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.schema.util.ObjectTypeUtil; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType; + +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.wicket.markup.html.form.FormComponent; +import org.apache.wicket.util.convert.ConversionException; +import org.apache.wicket.util.convert.IConverter; + +import java.util.List; +import java.util.Locale; + +/** + * @author honchar + */ +public class ReferenceConverter implements IConverter { + + private static final long serialVersionUID = 1L; + private IConverter originConverter; + private List referenceList = null; + private FormComponent baseComponent; + + private PageBase pageBase; + + public ReferenceConverter(IConverter originConverter, List referenceList, FormComponent baseComponent, PageBase pageBase) { + this.originConverter = originConverter; + this.referenceList = referenceList; + this.baseComponent = baseComponent; + this.pageBase = pageBase; + } + + @Override + public ObjectReferenceType convertToObject(String value, Locale locale) throws ConversionException { + ObjectQuery query = pageBase.getPrismContext().queryFor(AbstractRoleType.class) + .item(ObjectType.F_NAME) + .eq(value) + .matchingOrig() + .build(); + List> objectsList = WebModelServiceUtils.searchObjects(AbstractRoleType.class, query, + new OperationResult("searchObjects"), pageBase); + if (CollectionUtils.isNotEmpty(objectsList)){ + return ObjectTypeUtil.createObjectRefWithFullObject(objectsList.get(0), pageBase.getPrismContext()); + } + return originConverter.convertToObject(value, locale); + + } + + @Override + public String convertToString(ObjectReferenceType ref, Locale arg1) { + return ref != null ? WebComponentUtil.getName(ref) : ""; + } +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/wrapper/ShadowWrapperFactoryImpl.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/wrapper/ShadowWrapperFactoryImpl.java index 332ed02748d..bfb6a2e6412 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/wrapper/ShadowWrapperFactoryImpl.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/wrapper/ShadowWrapperFactoryImpl.java @@ -6,6 +6,11 @@ */ package com.evolveum.midpoint.gui.impl.factory.wrapper; +import com.evolveum.midpoint.gui.api.prism.wrapper.ShadowWrapper; +import com.evolveum.midpoint.util.logging.Trace; + +import com.evolveum.midpoint.util.logging.TraceManager; + import org.springframework.stereotype.Component; import com.evolveum.midpoint.gui.api.prism.ItemStatus; @@ -23,9 +28,14 @@ @Component public class ShadowWrapperFactoryImpl extends PrismObjectWrapperFactoryImpl { + private static final transient Trace LOGGER = TraceManager.getTrace(ShadowWrapperFactoryImpl.class); + @Override public PrismObjectWrapper createObjectWrapper(PrismObject object, ItemStatus status) { - return new ShadowWrapperImpl(object, status); + LOGGER.trace("create shadow wrapper"); + ShadowWrapper shadowWrapper = new ShadowWrapperImpl(object, status); + LOGGER.trace("Shadow wrapper created: {}", shadowWrapper); + return shadowWrapper; } @Override diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/ShadowPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/ShadowPanel.java index 75c08c2513d..6ff9aff84b1 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/ShadowPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/panel/ShadowPanel.java @@ -59,36 +59,47 @@ private void initLayout() { try { + long attributesStart = System.currentTimeMillis(); ItemPanelSettingsBuilder attributesSettingsBuilder = new ItemPanelSettingsBuilder() .visibilityHandler(itemWrapper -> checkShadowContainerVisibility(itemWrapper, getModel())); Panel attributesPanel = getPageBase().initItemPanel(ID_ATTRIBUTES, ShadowAttributesType.COMPLEX_TYPE, PrismContainerWrapperModel.fromContainerWrapper(getModel(), ShadowType.F_ATTRIBUTES), attributesSettingsBuilder.build()); add(attributesPanel); + long attributesEnd = System.currentTimeMillis(); + LOGGER.trace("Attributes finished in {} ms", attributesEnd - attributesStart); + long associationStart = System.currentTimeMillis(); ItemPanelSettingsBuilder associationBuilder = new ItemPanelSettingsBuilder() .visibilityHandler(itemWrapper -> checkShadowContainerVisibility(itemWrapper, getModel())); Panel associationsPanel = getPageBase().initItemPanel(ID_ASSOCIATIONS, ShadowAssociationType.COMPLEX_TYPE, PrismContainerWrapperModel.fromContainerWrapper(getModel(), ShadowType.F_ASSOCIATION), associationBuilder.build()); associationsPanel.add(new VisibleBehaviour(() -> checkAssociationsVisibility())); add(associationsPanel); + long associationEnd = System.currentTimeMillis(); + LOGGER.trace("Association finished in {} ms", associationEnd - associationStart); - + long activationStart = System.currentTimeMillis(); ItemPanelSettingsBuilder activationBuilder = new ItemPanelSettingsBuilder() .visibilityHandler(itemWrapper -> checkShadowContainerVisibility(itemWrapper, getModel())); Panel activationPanel = getPageBase().initItemPanel(ID_ACTIVATION, ActivationType.COMPLEX_TYPE, PrismContainerWrapperModel.fromContainerWrapper(getModel(), ShadowType.F_ACTIVATION), activationBuilder.build()); activationPanel.add(new VisibleBehaviour(() -> isActivationSupported())); add(activationPanel); + long activationEnd = System.currentTimeMillis(); + LOGGER.trace("Activation finished in {} ms", activationEnd - activationStart); + long passwordStart = System.currentTimeMillis(); ItemPanelSettingsBuilder passwordSettingsBuilder = new ItemPanelSettingsBuilder() .visibilityHandler(itemWrapper -> checkShadowContainerVisibility(itemWrapper, getModel())); Panel passwordPanel = getPageBase().initItemPanel(ID_PASSWORD, PasswordType.COMPLEX_TYPE, PrismContainerWrapperModel.fromContainerWrapper(getModel(), ItemPath.create(ShadowType.F_CREDENTIALS, CredentialsType.F_PASSWORD)), passwordSettingsBuilder.build()); passwordPanel.add(new VisibleBehaviour(() -> isCredentialsSupported())); add(passwordPanel); + long passwordEnd = System.currentTimeMillis(); + LOGGER.trace("Password finished in {} ms", passwordEnd - passwordStart); } catch (SchemaException e) { getSession().error("Cannot create panels for shadow, reason: " + e.getMessage()); - LOGGER.error("Cannot create panels for shadow, reason: {}", e.getMessage(), e); + LOGGER.trace("Cannot create panels for shadow, reason: {}", e.getMessage(), e); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/DropDownChoicePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/DropDownChoicePanel.java index 972458b5ed0..3afc9f23eba 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/DropDownChoicePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/DropDownChoicePanel.java @@ -29,8 +29,6 @@ public class DropDownChoicePanel extends InputPanel { private static final long serialVersionUID = 1L; private static final String ID_INPUT = "input"; - private boolean sortChoices = true; - public DropDownChoicePanel(String id, IModel model, IModel> choices) { this(id, model, choices, false); } @@ -66,16 +64,6 @@ protected String getNullValidDisplayValue() { return DropDownChoicePanel.this.getNullValidDisplayValue(); } - @Override - public IModel> getChoicesModel() { - IModel> choices = super.getChoicesModel(); - if (sortChoices) { - return Model.ofList(WebComponentUtil.sortDropDownChoices(choices, renderer)); - } else { - return choices; - } - } - @Override public String getModelValue() { T object = this.getModelObject(); @@ -108,12 +96,4 @@ public IModel getModel() { protected String getNullValidDisplayValue() { return getString("DropDownChoicePanel.notDefined"); } - - public boolean isSortChoices() { - return sortChoices; - } - - public void setSortChoices(boolean sortChoices) { - this.sortChoices = sortChoices; - } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusProjectionsTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusProjectionsTabPanel.java index f9a654282a8..e36665c2fe7 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusProjectionsTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusProjectionsTabPanel.java @@ -475,27 +475,6 @@ private void addSelectedAccountPerformed(AjaxRequestTarget target, List> createEmptyShadowWrapperModel() { - ShadowType shadow = new ShadowType(); - ShadowWrapper wrapper = null; - Task task = getPageBase().createSimpleTask("create empty shadow wrapper"); - try { - getPageBase().getPrismContext().adopt(shadow); - wrapper = ((PageAdminFocus) getPage()).loadShadowWrapper(shadow.asPrismContainer(), task, task.getResult()); - } catch (SchemaException e) { - getPageBase().showResult(task.getResult(), "pageAdminFocus.message.couldntCreateShadowWrapper"); - LOGGER.error("Couldn't create shadow wrapper", e); - } - final ShadowWrapper ret = wrapper; - return new IModel>() { - - @Override - public PrismContainerWrapper getObject() { - return ret; - } - }; - } - private List createShadowMenu() { List items = new ArrayList<>(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceAutocomplete.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceAutocomplete.java new file mode 100644 index 00000000000..47ac3f894a8 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/ReferenceAutocomplete.java @@ -0,0 +1,71 @@ +/* + * 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; + +import com.evolveum.midpoint.gui.api.component.autocomplete.AutoCompleteTextPanel; + +import com.evolveum.midpoint.gui.api.component.autocomplete.ReferenceConverter; +import com.evolveum.midpoint.gui.api.page.PageBase; +import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; +import com.evolveum.midpoint.prism.PrismObject; + +import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.schema.util.ObjectTypeUtil; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; + +import org.apache.commons.lang.StringUtils; +import org.apache.wicket.extensions.ajax.markup.html.autocomplete.IAutoCompleteRenderer; +import org.apache.wicket.markup.html.form.FormComponent; +import org.apache.wicket.model.IModel; +import org.apache.wicket.util.convert.IConverter; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author honchar + */ +public abstract class ReferenceAutocomplete extends AutoCompleteTextPanel { + private static final long serialVersionUID = 1L; + + private PageBase pageBase; + + public ReferenceAutocomplete(String id, final IModel model, IAutoCompleteRenderer renderer, PageBase pageBase) { + super(id, model, ObjectReferenceType.class, renderer); + this.pageBase = pageBase; + } + + + @Override + public Iterator getIterator(String input) { + FormComponent inputField = getBaseFormComponent(); + if (inputField == null || StringUtils.isEmpty(inputField.getRawInput())){ + return null; + } + ObjectQuery query = pageBase.getPrismContext().queryFor(AbstractRoleType.class) + .item(ObjectType.F_NAME) + .containsPoly(inputField.getRawInput()) + .matchingNorm() + .build(); + List> objectsList = WebModelServiceUtils.searchObjects(AbstractRoleType.class, query, + new OperationResult("searchObjects"), pageBase); + return (Iterator) ObjectTypeUtil.objectListToReferences(objectsList); + } + + @Override + protected IConverter getAutoCompleteConverter(Class type, IConverter originConverter){ + IConverter converter = super.getAutoCompleteConverter(type, originConverter); + return (IConverter) new ReferenceConverter((IConverter)converter, new ArrayList<>(), getBaseFormComponent(), pageBase); + } + + protected abstract Class getReferenceTargetObjectType(); + +} 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/ReferencePopupPanel.html index 8948e32ea0b..56cd2ccb275 100644 --- 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/ReferencePopupPanel.html @@ -13,9 +13,15 @@
- +
+ + + + + +
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/ReferencePopupPanel.java index 9c4e2e70647..5be0ea2de87 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/ReferencePopupPanel.java @@ -8,31 +8,38 @@ import java.util.ArrayList; import java.util.List; - import javax.xml.namespace.QName; -import com.evolveum.midpoint.prism.PrismConstants; -import com.evolveum.midpoint.web.component.AjaxButton; -import com.evolveum.midpoint.web.page.admin.configuration.component.EmptyOnBlurAjaxFormUpdatingBehaviour; +import com.evolveum.midpoint.gui.api.component.autocomplete.AutoCompleteReferenceRenderer; + +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import org.apache.commons.collections.CollectionUtils; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; +import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AbstractAutoCompleteRenderer; +import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AbstractAutoCompleteTextRenderer; import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.prism.PrismConstants; import com.evolveum.midpoint.util.DisplayableValue; +import com.evolveum.midpoint.web.component.AjaxButton; import com.evolveum.midpoint.web.component.input.QNameObjectTypeChoiceRenderer; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; +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 SearchPopupPanel { +public class ReferencePopupPanel extends SearchPopupPanel { private static final long serialVersionUID = 1L; private static final String ID_OID = "oid"; + private static final String ID_NAME = "name"; private static final String ID_TYPE = "type"; private static final String ID_RELATION = "relation"; private static final String ID_CONFIRM_BUTTON = "confirmButton"; @@ -67,6 +74,36 @@ protected void onUpdate(AjaxRequestTarget target) { oidField.add(new EmptyOnBlurAjaxFormUpdatingBehaviour()); add(oidField); + ReferenceAutocomplete nameField = new ReferenceAutocomplete(ID_NAME, Model.of(getModelObject().getValue()), + new AutoCompleteReferenceRenderer(), + getPageBase()){ + + private static final long serialVersionUID = 1L; + + @Override + protected Class getReferenceTargetObjectType(){ + List supportedTypes = getSupportedTargetList(); + if (CollectionUtils.isNotEmpty(supportedTypes)){ + return (Class) WebComponentUtil.qnameToClass(getPageBase().getPrismContext(), supportedTypes.get(0)); + } + return (Class) ObjectType.class; + } + + }; + +// 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"), getSupportedTargetList(), new QNameObjectTypeChoiceRenderer()); type.setNullValid(true); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminFocus.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminFocus.java index eba74e97bc5..892a0c2b455 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminFocus.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminFocus.java @@ -136,6 +136,8 @@ public void continueEditing(AjaxRequestTarget target) { } private List loadShadowWrappers(boolean noFetch) { + LOGGER.trace("Loading shadow wrapper"); + long start = System.currentTimeMillis(); List list = new ArrayList<>(); PrismObjectWrapper focusWrapper = getObjectModel().getObject(); @@ -152,17 +154,22 @@ private List loadShadowWrappers(boolean noFetch) { LOGGER.trace("Skiping reference for shadow with null oid"); continue; // default value } + long shadowTimestampBefore = System.currentTimeMillis(); OperationResult subResult = task.getResult().createMinorSubresult(OPERATION_LOAD_SHADOW); PrismObject projection = getPrismObjectForWrapper(ShadowType.class, reference.getOid(), noFetch, task, subResult, createLoadOptionForShadowWrapper()); + long shadowTimestampAfter = System.currentTimeMillis(); + LOGGER.trace("Got shadow: {} in {}", projection, shadowTimestampAfter - shadowTimestampBefore); if(projection == null) { // showResult(subResult, "pageAdminFocus.message.couldntLoadShadowProjection"); LOGGER.error("Couldn't load shadow projection"); continue; } + long timestampWrapperStart = System.currentTimeMillis(); try { + ShadowWrapper wrapper = loadShadowWrapper(projection, task, subResult); wrapper.setLoadWithNoFetch(noFetch); @@ -178,7 +185,11 @@ private List loadShadowWrappers(boolean noFetch) { showResult(subResult, "pageAdminFocus.message.couldntCreateShadowWrapper"); LoggingUtils.logUnexpectedException(LOGGER, "Couldn't create shadow wrapper", e); } + long timestampWrapperEnd = System.currentTimeMillis(); + LOGGER.trace("Load wrapper in {}", timestampWrapperEnd - timestampWrapperStart); } + long end = System.currentTimeMillis(); + LOGGER.trace("Load projctions in {}", end - start); return list; } @@ -198,6 +209,8 @@ public ShadowWrapper loadShadowWrapper(PrismObject projection, Task } public void loadFullShadow(PrismObjectValueWrapper shadowWrapperValue, AjaxRequestTarget target) { + LOGGER.trace("Loading full shadow"); + long start = System.currentTimeMillis(); if(shadowWrapperValue.getRealValue() == null) { error(getString("pageAdminFocus.message.couldntCreateShadowWrapper")); LOGGER.error("Couldn't create shadow wrapper, because RealValue is null in " + shadowWrapperValue); @@ -206,9 +219,12 @@ public void loadFullShadow(PrismObjectValueWrapper shadowWrapperValu String oid = shadowWrapperValue.getRealValue().getOid(); Task task = createSimpleTask(OPERATION_LOAD_SHADOW); OperationResult result = task.getResult(); + long loadStart = System.currentTimeMillis(); PrismObject projection = getPrismObjectForWrapper(ShadowType.class, oid, false, task, result, createLoadOptionForShadowWrapper()); + long loadEnd = System.currentTimeMillis(); + LOGGER.trace("Load projection in {} ms", loadEnd - loadStart); if (projection == null) { result.recordFatalError(getString("PageAdminFocus.message.loadFullShadow.fatalError", shadowWrapperValue.getRealValue())); showResult(result); @@ -216,6 +232,7 @@ public void loadFullShadow(PrismObjectValueWrapper shadowWrapperValu return; } + long wrapperStart = System.currentTimeMillis(); ShadowWrapper shadowWrapperNew; try { shadowWrapperNew = loadShadowWrapper(projection, task, result); @@ -233,6 +250,10 @@ public void loadFullShadow(PrismObjectValueWrapper shadowWrapperValu error(getString("pageAdminFocus.message.couldntCreateShadowWrapper")); LOGGER.error("Couldn't create shadow wrapper", e); } + long wrapperEnd = System.currentTimeMillis(); + LOGGER.trace("Wrapper loaded in {} ms", wrapperEnd - wrapperStart); + long end = System.currentTimeMillis(); + LOGGER.trace("Got full shadow in {} ms", end - start); } // @Override diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageTraceView.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageTraceView.java index 8b50d28bddd..4341dcd26ec 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageTraceView.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageTraceView.java @@ -116,7 +116,6 @@ private void initLayout() { GenericTraceVisualizationType.class, ID_CLOCKWORK_EXECUTION, createClockworkLevels(), new PropertyModel<>(model, TraceViewDto.F_CLOCKWORK_EXECUTION), this, false); - clockworkExecutionChoice.setSortChoices(false); clockworkExecutionChoice.setOutputMarkupId(true); mainForm.add(clockworkExecutionChoice); @@ -124,7 +123,6 @@ GenericTraceVisualizationType.class, ID_CLOCKWORK_EXECUTION, createClockworkLeve GenericTraceVisualizationType.class, ID_CLOCKWORK_CLICK, createClockworkLevels(), new PropertyModel<>(model, TraceViewDto.F_CLOCKWORK_CLICK), this, false); - clockworkClickChoice.setSortChoices(false); clockworkClickChoice.setOutputMarkupId(true); mainForm.add(clockworkClickChoice); @@ -132,7 +130,6 @@ GenericTraceVisualizationType.class, ID_CLOCKWORK_CLICK, createClockworkLevels() GenericTraceVisualizationType.class, ID_MAPPING_EVALUATION, createMappingLevels(), new PropertyModel<>(model, TraceViewDto.F_MAPPING_EVALUATION), this, false); - mappingEvaluationChoice.setSortChoices(false); mappingEvaluationChoice.setOutputMarkupId(true); mainForm.add(mappingEvaluationChoice); @@ -140,7 +137,6 @@ GenericTraceVisualizationType.class, ID_MAPPING_EVALUATION, createMappingLevels( GenericTraceVisualizationType.class, ID_FOCUS_LOAD, createStandardLevels(), new PropertyModel<>(model, TraceViewDto.F_FOCUS_LOAD), this, false); - focusLoadChoice.setSortChoices(false); focusLoadChoice.setOutputMarkupId(true); mainForm.add(focusLoadChoice); @@ -148,7 +144,6 @@ GenericTraceVisualizationType.class, ID_FOCUS_LOAD, createStandardLevels(), GenericTraceVisualizationType.class, ID_PROJECTION_LOAD, createStandardLevels(), new PropertyModel<>(model, TraceViewDto.F_PROJECTION_LOAD), this, false); - projectionLoadChoice.setSortChoices(false); projectionLoadChoice.setOutputMarkupId(true); mainForm.add(projectionLoadChoice); @@ -156,7 +151,6 @@ GenericTraceVisualizationType.class, ID_PROJECTION_LOAD, createStandardLevels(), GenericTraceVisualizationType.class, ID_FOCUS_CHANGE, createStandardLevels(), new PropertyModel<>(model, TraceViewDto.F_FOCUS_CHANGE), this, false); - focusChangeChoice.setSortChoices(false); focusChangeChoice.setOutputMarkupId(true); mainForm.add(focusChangeChoice); @@ -164,7 +158,6 @@ GenericTraceVisualizationType.class, ID_FOCUS_CHANGE, createStandardLevels(), GenericTraceVisualizationType.class, ID_PROJECTION_CHANGE, createStandardLevels(), new PropertyModel<>(model, TraceViewDto.F_PROJECTION_CHANGE), this, false); - projectionChangeChoice.setSortChoices(false); projectionChangeChoice.setOutputMarkupId(true); mainForm.add(projectionChangeChoice); @@ -172,7 +165,6 @@ GenericTraceVisualizationType.class, ID_PROJECTION_CHANGE, createStandardLevels( GenericTraceVisualizationType.class, ID_OTHERS, createOthersLevels(), new PropertyModel<>(model, TraceViewDto.F_OTHERS), this, false); - otherChoice.setSortChoices(false); otherChoice.setOutputMarkupId(true); mainForm.add(otherChoice); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/AbstractShoppingCartTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/AbstractShoppingCartTabPanel.java index dd67484e21a..9135d3cba0a 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/AbstractShoppingCartTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/AbstractShoppingCartTabPanel.java @@ -11,13 +11,11 @@ import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.query.NoneFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.schema.util.ObjectQueryUtil; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; @@ -444,7 +442,7 @@ protected ObjectQuery createContentQuery() { .type(getQueryClass()) .build(); ObjectFilter assignableRolesFilter = getAssignableRolesFilter(); - if (assignableRolesFilter != null && !(assignableRolesFilter instanceof NoneFilter)){ + if (assignableRolesFilter != null) { memberQuery.addFilter(assignableRolesFilter); } // if (getQueryType() != null && !AbstractRoleType.COMPLEX_TYPE.equals(getQueryType())){ @@ -465,9 +463,7 @@ private SearchPanel getSearchPanel(){ } private ObjectFilter getAssignableRolesFilter() { - if (getRoleCatalogStorage().isMultiUserRequest()){ - return null; - } + // When multiple users are selected, filter the roles by targeting one of them Task task = getPageBase().createSimpleTask(OPERATION_LOAD_ASSIGNABLE_ROLES); OperationResult result = task.getResult(); UserType targetUser = targetUserModel.getObject(); diff --git a/infra/prism-api/src/main/java/com/evolveum/midpoint/prism/PrismPropertyValue.java b/infra/prism-api/src/main/java/com/evolveum/midpoint/prism/PrismPropertyValue.java index 22b8cdc741c..7d6e2554791 100644 --- a/infra/prism-api/src/main/java/com/evolveum/midpoint/prism/PrismPropertyValue.java +++ b/infra/prism-api/src/main/java/com/evolveum/midpoint/prism/PrismPropertyValue.java @@ -12,7 +12,8 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.util.DebugDumpable; -import com.evolveum.midpoint.util.exception.SchemaException; + +import org.apache.commons.lang.BooleanUtils; import org.jetbrains.annotations.Nullable; import javax.xml.bind.JAXBElement; @@ -69,4 +70,15 @@ public interface PrismPropertyValue extends DebugDumpable, Serializable, Pris @Override T getRealValue(); + static T getRealValue(PrismPropertyValue propertyValue) { + return propertyValue != null ? propertyValue.getRealValue() : null; + } + + static boolean isNotFalse(PrismPropertyValue booleanPropertyValue) { + return booleanPropertyValue == null || BooleanUtils.isNotFalse(booleanPropertyValue.getRealValue()); + } + + static boolean isTrue(PrismPropertyValue booleanPropertyValue) { + return booleanPropertyValue != null && BooleanUtils.isTrue(booleanPropertyValue.getRealValue()); + } } diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd index baec7735e0d..1e6140b320c 100755 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd @@ -13116,7 +13116,7 @@ (abstract) role.

- Use with care. MidPoint will will have to process all the roles that + Use with care. MidPoint will have to process all the roles that have this flag set to true. All the roles will be looked up, autoassign specification will be processed to see if the focus is matching. This will happen all the time for all modification operations. @@ -13181,6 +13181,15 @@ + + + +

+ Restrics autoassignment to concrete focus type. +

+ + + @@ -13621,7 +13630,7 @@ - + Selects some objects from all the objects in midPoint. diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/stringpolicy/ValuePolicyProcessor.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/stringpolicy/ValuePolicyProcessor.java index b4cd56b09fe..64abafd6f51 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/stringpolicy/ValuePolicyProcessor.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/stringpolicy/ValuePolicyProcessor.java @@ -781,8 +781,8 @@ private boolean checkExpression(String generatedValue, Ex } variables.addVariableDefinition(ExpressionConstants.VAR_OBJECT, object, objectDef); - PrismPropertyValue output = ExpressionUtil.evaluateCondition(variables, checkExpression, expressionProfile, expressionFactory, shortDesc, task, result); - return ExpressionUtil.getBooleanConditionOutput(output); + return ExpressionUtil.evaluateConditionDefaultFalse(variables, checkExpression, + expressionProfile, expressionFactory, shortDesc, task, result); } /** diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/DashboardServiceImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/DashboardServiceImpl.java index 0958f3ca2a3..497a1243912 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/DashboardServiceImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/DashboardServiceImpl.java @@ -10,11 +10,12 @@ import java.util.*; -import com.evolveum.midpoint.prism.query.AndFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; +import com.evolveum.midpoint.schema.util.MiscSchemaUtil; + import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.springframework.beans.factory.annotation.Autowired; @@ -32,7 +33,6 @@ import com.evolveum.midpoint.model.impl.ModelObjectResolver; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.repo.common.expression.ExpressionFactory; import com.evolveum.midpoint.repo.common.expression.ExpressionUtil; @@ -349,19 +349,14 @@ private String generateNumberMessage(DashboardWidgetType widget, ExpressionVaria } private void evaluateVariation(DashboardWidgetType widget, ExpressionVariables variables, DashboardWidget data) { - - if(widget.getPresentation() != null) { - if(widget.getPresentation().getVariation() != null) { - for(DashboardWidgetVariationType variation : widget.getPresentation().getVariation()) { + if (widget.getPresentation() != null) { + if (widget.getPresentation().getVariation() != null) { + for (DashboardWidgetVariationType variation : widget.getPresentation().getVariation()) { Task task = taskManager.createTaskInstance("Evaluate variation"); - PrismPropertyValue usingVariation; try { - usingVariation = ExpressionUtil.evaluateCondition(variables, variation.getCondition(), null, - expressionFactory, - "Variation", task, task.getResult()); - - if(usingVariation != null && usingVariation.getRealValue() != null - && usingVariation.getRealValue().equals(Boolean.TRUE)) { + boolean usingVariation = ExpressionUtil.evaluateConditionDefaultFalse(variables, variation.getCondition(), + MiscSchemaUtil.getExpressionProfile(), expressionFactory, "Variation", task, task.getResult()); + if (usingVariation) { data.setDisplay(combineDisplay(widget.getDisplay(), variation.getDisplay())); } else { data.setDisplay(widget.getDisplay()); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ObjectMerger.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ObjectMerger.java index 9fd95d9ab24..eaedfd30ee9 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ObjectMerger.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ObjectMerger.java @@ -15,6 +15,7 @@ import com.evolveum.midpoint.prism.delta.*; import com.evolveum.midpoint.prism.path.ItemPath; import org.apache.commons.lang.StringUtils; +import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -146,11 +147,13 @@ private void executeDelta(ObjectDelta objectDelta, Mod } } - public MergeDeltas computeMergeDeltas(Class type, String leftOid, String rightOid, + MergeDeltas computeMergeDeltas(Class type, String leftOid, String rightOid, final String mergeConfigurationName, final Task task, final OperationResult result) throws ObjectNotFoundException, SchemaException, ConfigurationException, ExpressionEvaluationException, CommunicationException, SecurityViolationException { + //noinspection unchecked final PrismObject objectLeft = (PrismObject) objectResolver.getObjectSimple(type, leftOid, null, task, result).asPrismObject(); + //noinspection unchecked final PrismObject objectRight = (PrismObject) objectResolver.getObjectSimple(type, rightOid, null, task, result).asPrismObject(); PrismObject systemConfiguration = systemObjectCache.getSystemConfiguration(result); @@ -242,7 +245,6 @@ public void visit(Visitable visitable) { } } - ItemDelta itemDelta; try { itemDelta = mergeItem(objectLeft, objectRight, mergeConfigurationName, defaultItemMergeConfig, itemPath, @@ -257,7 +259,9 @@ public void visit(Visitable visitable) { } }; + //noinspection unchecked objectLeft.accept(visitor); + //noinspection unchecked objectRight.accept(visitor); @@ -425,8 +429,6 @@ private void takeProjections(MergeStrategyType strategy, List merged LOGGER.trace("Discriminator does NOT match {}", candidateProjection); } } - - } private boolean projectionMatches(ShadowType candidateProjection, @@ -439,11 +441,10 @@ private boolean projectionMatches(ShadowType candidateProjection, ProjectionMergeSituationType situationPattern = projectionMergeConfig.getSituation(); if (situationPattern != null) { ProjectionMergeSituationType projectionSituation = determineSituation(candidateProjection, projectionsLeft, projectionsRight); - if (situationPattern != projectionSituation) { - return false; - } + return situationPattern == projectionSituation; + } else { + return true; } - return true; } private void takeUnmatchedProjections(MergeStrategyType strategy, List mergedProjections, @@ -509,12 +510,14 @@ private ShadowType getProjection(ObjectReferenceType linkRef, Task task, Operati private ItemDelta mergeItem(PrismObject objectLeft, PrismObject objectRight, String mergeConfigurationName, ItemMergeConfigurationType itemMergeConfig, ItemPath itemPath, Task task, OperationResult result) throws SchemaException, ConfigurationException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, SecurityViolationException { + //noinspection unchecked I itemLeft = (I) objectLeft.findItem(itemPath); + //noinspection unchecked I itemRight = (I) objectRight.findItem(itemPath); if (itemLeft == null && itemRight == null) { return null; } - ItemDefinition itemDefinition = null; + ItemDefinition itemDefinition; if (itemLeft != null) { itemDefinition = itemLeft.getDefinition(); } else { @@ -526,12 +529,14 @@ private ItemDelta mergeItem(PrismObject valueExpression = null; + Expression valueExpression; if (itemMergeConfig.getValueExpression() != null) { ExpressionType expressionType = itemMergeConfig.getValueExpression(); valueExpression = expressionFactory.makeExpression(expressionType, itemDefinition, MiscSchemaUtil.getExpressionProfile(), "value expression for item " + itemPath + " in merge configuration " + mergeConfigurationName, task, result); + } else { + valueExpression = null; } ItemDelta itemDelta = itemDefinition.createEmptyDelta(itemPath); @@ -553,6 +558,7 @@ private ItemDelta mergeItem(PrismObject valuesToTake = getValuesToTake(objectLeft, objectRight, SIDE_RIGHT, itemRight, rightStrategy, valueExpression, task, result); + //noinspection unchecked itemDelta.setValuesToReplace(valuesToTake); } return itemDelta; @@ -566,9 +572,11 @@ private ItemDelta mergeItem(PrismObject valuesToLeave = getValuesToTake(objectLeft, objectRight, SIDE_LEFT, itemLeft, leftStrategy, valueExpression, task, result); + //noinspection unchecked List currentLeftValues = itemLeft.getValues(); Collection leftValuesToRemove = diffValues(currentLeftValues, valuesToLeave); if (leftValuesToRemove != null && !leftValuesToRemove.isEmpty()) { + //noinspection unchecked itemDelta.addValuesToDelete(leftValuesToRemove); return itemDelta; } else { @@ -580,6 +588,7 @@ private ItemDelta mergeItem(PrismObject valuesToTake = getValuesToTake(objectLeft, objectRight, SIDE_RIGHT, itemRight, rightStrategy, valueExpression, task, result); + //noinspection unchecked itemDelta.addValuesToAdd(valuesToTake); return itemDelta; @@ -593,22 +602,22 @@ private ItemDelta mergeItem(PrismObject currentLeftValues = itemLeft.getValues(); Collection leftValuesToRemove = diffValues(currentLeftValues, leftValuesToLeave); if (leftValuesToRemove != null && !leftValuesToRemove.isEmpty()) { + //noinspection unchecked itemDelta.addValuesToDelete(leftValuesToRemove); } - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Merging item {} T/T case:\n leftValuesToLeave: {}\n rightValuesToTake: {}\n leftValuesToRemove: {}\n itemDelta:\n{}", - new Object[]{itemPath, leftValuesToLeave, rightValuesToTake, leftValuesToRemove, itemDelta.debugDump(2)}); - } - + LOGGER.trace("Merging item {} T/T case:\n leftValuesToLeave: {}\n rightValuesToTake: {}\n leftValuesToRemove: {}\n itemDelta:\n{}", + itemPath, leftValuesToLeave, rightValuesToTake, leftValuesToRemove, itemDelta.debugDumpLazily(2)); return itemDelta; } @@ -616,6 +625,7 @@ private ItemDelta mergeItem(PrismObject diffValues(List currentValues, Collection valuesToLeave) { if (valuesToLeave == null || valuesToLeave.isEmpty()) { return PrismValueCollectionsUtil.cloneCollection(currentValues); @@ -636,11 +646,13 @@ private Collection getValuesT return new ArrayList<>(0); } if (strategy == MergeStrategyType.TAKE) { + //noinspection unchecked return cleanContainerIds(origItem.getClonedValues()); } else if (strategy == MergeStrategyType.EXPRESSION) { if (valueExpression == null) { throw new ConfigurationException("Expression strategy specified but no expression present"); } + //noinspection unchecked List origValues = origItem.getValues(); Collection valuesToTake = new ArrayList<>(origValues.size()); for (PrismValue origValue: origValues) { @@ -668,13 +680,15 @@ private Collection cleanContainerIds(Collection pvals) { return pvals; } - - private Collection evaluateValueExpression(PrismObject objectLeft, PrismObject objectRight, String side, PrismValue origValue, Expression valueExpression, - Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { + private Collection evaluateValueExpression(PrismObject objectLeft, + PrismObject objectRight, String side, PrismValue origValue, + Expression valueExpression, Task task, OperationResult result) + throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, + ConfigurationException, SecurityViolationException { ExpressionVariables variables = new ExpressionVariables(); variables.put(ExpressionConstants.VAR_SIDE, side, String.class); - variables.put(ExpressionConstants.VAR_OBJECT_LEFT, side, String.class); - variables.put(ExpressionConstants.VAR_OBJECT_RIGHT, side, String.class); + variables.put(ExpressionConstants.VAR_OBJECT_LEFT, objectLeft, String.class); + variables.put(ExpressionConstants.VAR_OBJECT_RIGHT, objectRight, String.class); variables.put(ExpressionConstants.VAR_INPUT, origValue, origValue.getParent().getDefinition()); variables.put(ExpressionConstants.VAR_VALUE, origValue, origValue.getParent().getDefinition()); ExpressionEvaluationContext exprContext = new ExpressionEvaluationContext(null, variables, "for value "+origValue, task); @@ -697,5 +711,4 @@ private MergeConfigurationType selectConfiguration( } throw new ConfigurationException("Merge configuration with name '"+mergeConfigurationName+"' was not found"); } - } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/ExpressionHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/ExpressionHandler.java index 4ca4cc43fde..53efa4c9b86 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/ExpressionHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/ExpressionHandler.java @@ -1,179 +1,180 @@ -/* - * 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.model.impl.expr; - -import com.evolveum.midpoint.model.common.expression.ModelExpressionThreadLocalHolder; -import com.evolveum.midpoint.repo.common.expression.Expression; -import com.evolveum.midpoint.repo.common.expression.ExpressionEvaluationContext; -import com.evolveum.midpoint.repo.common.expression.ExpressionFactory; -import com.evolveum.midpoint.repo.common.expression.ExpressionVariables; -import com.evolveum.midpoint.model.impl.ModelObjectResolver; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismPropertyValue; -import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; -import com.evolveum.midpoint.repo.api.RepositoryService; -import com.evolveum.midpoint.schema.constants.ExpressionConstants; -import com.evolveum.midpoint.schema.constants.ObjectTypes; -import com.evolveum.midpoint.schema.expression.ExpressionProfile; -import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.schema.util.MiscSchemaUtil; -import com.evolveum.midpoint.task.api.Task; -import com.evolveum.midpoint.util.DOMUtil; -import com.evolveum.midpoint.util.exception.CommunicationException; -import com.evolveum.midpoint.util.exception.ConfigurationException; -import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; -import com.evolveum.midpoint.util.exception.ObjectNotFoundException; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.exception.SecurityViolationException; -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.*; -import org.apache.commons.lang.Validate; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Component; - -import java.util.Collection; - -/** - * - * @author lazyman - * - */ -@Component -public class ExpressionHandler { - - private static final Trace LOGGER = TraceManager.getTrace(ExpressionHandler.class); - - @Autowired @Qualifier("cacheRepositoryService") private RepositoryService repositoryService; - @Autowired private ExpressionFactory expressionFactory; - @Autowired private ModelObjectResolver modelObjectResolver; - @Autowired private PrismContext prismContext; - - public String evaluateExpression(ShadowType shadow, ExpressionType expressionType, - String shortDesc, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException { - Validate.notNull(shadow, "Resource object shadow must not be null."); - Validate.notNull(expressionType, "Expression must not be null."); - Validate.notNull(result, "Operation result must not be null."); - - ResourceType resource = resolveResource(shadow, result); - - ExpressionVariables variables = getDefaultXPathVariables(null, shadow, resource); - - PrismPropertyDefinition outputDefinition = prismContext.definitionFactory().createPropertyDefinition(ExpressionConstants.OUTPUT_ELEMENT_NAME, - DOMUtil.XSD_STRING); - Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(expressionType, - outputDefinition, MiscSchemaUtil.getExpressionProfile(), shortDesc, task, result); - - ExpressionEvaluationContext params = new ExpressionEvaluationContext(null, variables, shortDesc, task); - PrismValueDeltaSetTriple> outputTriple = ModelExpressionThreadLocalHolder.evaluateExpressionInContext(expression, params, task, result); - if (outputTriple == null) { - return null; - } - Collection> nonNegativeValues = outputTriple.getNonNegativeValues(); - if (nonNegativeValues == null || nonNegativeValues.isEmpty()) { - return null; - } - if (nonNegativeValues.size() > 1) { - throw new ExpressionEvaluationException("Expression returned more than one value ("+nonNegativeValues.size()+") in "+shortDesc); - } - return nonNegativeValues.iterator().next().getValue(); - } - - public boolean evaluateConfirmationExpression(UserType user, ShadowType shadow, - ExpressionType expressionType, Task task, OperationResult result) - throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException { - Validate.notNull(user, "User must not be null."); - Validate.notNull(shadow, "Resource object shadow must not be null."); - Validate.notNull(expressionType, "Expression must not be null."); - Validate.notNull(result, "Operation result must not be null."); - - ResourceType resource = resolveResource(shadow, result); - ExpressionVariables variables = getDefaultXPathVariables(user, shadow, resource); - String shortDesc = "confirmation expression for "+resource.asPrismObject(); - - PrismPropertyDefinition outputDefinition = prismContext.definitionFactory().createPropertyDefinition(ExpressionConstants.OUTPUT_ELEMENT_NAME, - DOMUtil.XSD_BOOLEAN); - ExpressionProfile expressionProfile = MiscSchemaUtil.getExpressionProfile(); - Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(expressionType, - outputDefinition, expressionProfile, shortDesc, task, result); - - ExpressionEvaluationContext params = new ExpressionEvaluationContext(null, variables, shortDesc, task); - PrismValueDeltaSetTriple> outputTriple = ModelExpressionThreadLocalHolder.evaluateExpressionInContext(expression, params, task, result); - Collection> nonNegativeValues = outputTriple.getNonNegativeValues(); - if (nonNegativeValues == null || nonNegativeValues.isEmpty()) { - throw new ExpressionEvaluationException("Expression returned no value ("+nonNegativeValues.size()+") in "+shortDesc); - } - if (nonNegativeValues.size() > 1) { - throw new ExpressionEvaluationException("Expression returned more than one value ("+nonNegativeValues.size()+") in "+shortDesc); - } - PrismPropertyValue resultpval = nonNegativeValues.iterator().next(); - if (resultpval == null) { - throw new ExpressionEvaluationException("Expression returned no value ("+nonNegativeValues.size()+") in "+shortDesc); - } - Boolean resultVal = resultpval.getValue(); - if (resultVal == null) { - throw new ExpressionEvaluationException("Expression returned no value ("+nonNegativeValues.size()+") in "+shortDesc); - } - return resultVal; - } - - // TODO: refactor - this method is also in SchemaHandlerImpl - private ResourceType resolveResource(ShadowType shadow, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { - ObjectReferenceType ref = shadow.getResourceRef(); - if (ref == null) { - throw new ExpressionEvaluationException("Resource shadow object " + shadow + " doesn't have defined resource."); - } - PrismObject resource = ref.getObject(); - if (resource != null) { - return resource.asObjectable(); - } - if (ref.getOid() == null) { - throw new ExpressionEvaluationException("Resource shadow object " + shadow + " defines null resource OID."); - } - - return modelObjectResolver.getObjectSimple(ResourceType.class, ref.getOid(), null, null, result); - } - - public static ExpressionVariables getDefaultXPathVariables(UserType user, - ShadowType shadow, ResourceType resource) { - - ExpressionVariables variables = new ExpressionVariables(); - if (user != null) { - variables.put(ExpressionConstants.VAR_FOCUS, user.asPrismObject(), user.asPrismObject().getDefinition()); - variables.put(ExpressionConstants.VAR_USER, user.asPrismObject(), user.asPrismObject().getDefinition()); - } - - if (shadow != null) { - variables.addVariableDefinition(ExpressionConstants.VAR_ACCOUNT, shadow.asPrismObject(), shadow.asPrismObject().getDefinition()); - variables.addVariableDefinition(ExpressionConstants.VAR_PROJECTION, shadow.asPrismObject(), shadow.asPrismObject().getDefinition()); - } - - if (resource != null) { - variables.addVariableDefinition(ExpressionConstants.VAR_RESOURCE, resource.asPrismObject(), resource.asPrismObject().getDefinition()); - } - - return variables; - } - - // Called from the ObjectResolver.resolve - public ObjectType resolveRef(ObjectReferenceType ref, String contextDescription, OperationResult result) - throws ObjectNotFoundException, SchemaException { - - Class type = ObjectType.class; - if (ref.getType() != null) { - ObjectTypes objectTypeType = ObjectTypes.getObjectTypeFromTypeQName(ref.getType()); - type = objectTypeType.getClassDefinition(); - } - - return repositoryService.getObject(type, ref.getOid(), null, result).asObjectable(); - - } - -} +/* + * 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.model.impl.expr; + +import com.evolveum.midpoint.model.common.expression.ModelExpressionThreadLocalHolder; +import com.evolveum.midpoint.repo.common.expression.Expression; +import com.evolveum.midpoint.repo.common.expression.ExpressionEvaluationContext; +import com.evolveum.midpoint.repo.common.expression.ExpressionFactory; +import com.evolveum.midpoint.repo.common.expression.ExpressionVariables; +import com.evolveum.midpoint.model.impl.ModelObjectResolver; +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismPropertyDefinition; +import com.evolveum.midpoint.prism.PrismPropertyValue; +import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; +import com.evolveum.midpoint.repo.api.RepositoryService; +import com.evolveum.midpoint.schema.constants.ExpressionConstants; +import com.evolveum.midpoint.schema.constants.ObjectTypes; +import com.evolveum.midpoint.schema.expression.ExpressionProfile; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.schema.util.MiscSchemaUtil; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.util.DOMUtil; +import com.evolveum.midpoint.util.exception.CommunicationException; +import com.evolveum.midpoint.util.exception.ConfigurationException; +import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; +import com.evolveum.midpoint.util.exception.ObjectNotFoundException; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.SecurityViolationException; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import org.apache.commons.lang.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import java.util.Collection; + +/** + * + * @author lazyman + * + * TODO is this class ever used? + */ +@Component +public class ExpressionHandler { + + private static final Trace LOGGER = TraceManager.getTrace(ExpressionHandler.class); + + @Autowired @Qualifier("cacheRepositoryService") private RepositoryService repositoryService; + @Autowired private ExpressionFactory expressionFactory; + @Autowired private ModelObjectResolver modelObjectResolver; + @Autowired private PrismContext prismContext; + + public String evaluateExpression(ShadowType shadow, ExpressionType expressionType, + String shortDesc, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException { + Validate.notNull(shadow, "Resource object shadow must not be null."); + Validate.notNull(expressionType, "Expression must not be null."); + Validate.notNull(result, "Operation result must not be null."); + + ResourceType resource = resolveResource(shadow, result); + + ExpressionVariables variables = getDefaultXPathVariables(null, shadow, resource); + + PrismPropertyDefinition outputDefinition = prismContext.definitionFactory().createPropertyDefinition(ExpressionConstants.OUTPUT_ELEMENT_NAME, + DOMUtil.XSD_STRING); + Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(expressionType, + outputDefinition, MiscSchemaUtil.getExpressionProfile(), shortDesc, task, result); + + ExpressionEvaluationContext params = new ExpressionEvaluationContext(null, variables, shortDesc, task); + PrismValueDeltaSetTriple> outputTriple = ModelExpressionThreadLocalHolder.evaluateExpressionInContext(expression, params, task, result); + if (outputTriple == null) { + return null; + } + Collection> nonNegativeValues = outputTriple.getNonNegativeValues(); + if (nonNegativeValues == null || nonNegativeValues.isEmpty()) { + return null; + } + if (nonNegativeValues.size() > 1) { + throw new ExpressionEvaluationException("Expression returned more than one value ("+nonNegativeValues.size()+") in "+shortDesc); + } + return nonNegativeValues.iterator().next().getValue(); + } + + public boolean evaluateConfirmationExpression(UserType user, ShadowType shadow, + ExpressionType expressionType, Task task, OperationResult result) + throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException { + Validate.notNull(user, "User must not be null."); + Validate.notNull(shadow, "Resource object shadow must not be null."); + Validate.notNull(expressionType, "Expression must not be null."); + Validate.notNull(result, "Operation result must not be null."); + + ResourceType resource = resolveResource(shadow, result); + ExpressionVariables variables = getDefaultXPathVariables(user, shadow, resource); + String shortDesc = "confirmation expression for "+resource.asPrismObject(); + + PrismPropertyDefinition outputDefinition = prismContext.definitionFactory().createPropertyDefinition(ExpressionConstants.OUTPUT_ELEMENT_NAME, + DOMUtil.XSD_BOOLEAN); + ExpressionProfile expressionProfile = MiscSchemaUtil.getExpressionProfile(); + Expression,PrismPropertyDefinition> expression = expressionFactory.makeExpression(expressionType, + outputDefinition, expressionProfile, shortDesc, task, result); + + ExpressionEvaluationContext params = new ExpressionEvaluationContext(null, variables, shortDesc, task); + PrismValueDeltaSetTriple> outputTriple = ModelExpressionThreadLocalHolder.evaluateExpressionInContext(expression, params, task, result); + Collection> nonNegativeValues = outputTriple.getNonNegativeValues(); + if (nonNegativeValues == null || nonNegativeValues.isEmpty()) { + throw new ExpressionEvaluationException("Expression returned no value ("+nonNegativeValues.size()+") in "+shortDesc); + } + if (nonNegativeValues.size() > 1) { + throw new ExpressionEvaluationException("Expression returned more than one value ("+nonNegativeValues.size()+") in "+shortDesc); + } + PrismPropertyValue resultpval = nonNegativeValues.iterator().next(); + if (resultpval == null) { + throw new ExpressionEvaluationException("Expression returned no value ("+nonNegativeValues.size()+") in "+shortDesc); + } + Boolean resultVal = resultpval.getValue(); + if (resultVal == null) { + throw new ExpressionEvaluationException("Expression returned no value ("+nonNegativeValues.size()+") in "+shortDesc); + } + return resultVal; + } + + // TODO: refactor - this method is also in SchemaHandlerImpl + private ResourceType resolveResource(ShadowType shadow, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { + ObjectReferenceType ref = shadow.getResourceRef(); + if (ref == null) { + throw new ExpressionEvaluationException("Resource shadow object " + shadow + " doesn't have defined resource."); + } + PrismObject resource = ref.getObject(); + if (resource != null) { + return resource.asObjectable(); + } + if (ref.getOid() == null) { + throw new ExpressionEvaluationException("Resource shadow object " + shadow + " defines null resource OID."); + } + + return modelObjectResolver.getObjectSimple(ResourceType.class, ref.getOid(), null, null, result); + } + + public static ExpressionVariables getDefaultXPathVariables(UserType user, + ShadowType shadow, ResourceType resource) { + + ExpressionVariables variables = new ExpressionVariables(); + if (user != null) { + variables.put(ExpressionConstants.VAR_FOCUS, user.asPrismObject(), user.asPrismObject().getDefinition()); + variables.put(ExpressionConstants.VAR_USER, user.asPrismObject(), user.asPrismObject().getDefinition()); + } + + if (shadow != null) { + variables.addVariableDefinition(ExpressionConstants.VAR_ACCOUNT, shadow.asPrismObject(), shadow.asPrismObject().getDefinition()); + variables.addVariableDefinition(ExpressionConstants.VAR_PROJECTION, shadow.asPrismObject(), shadow.asPrismObject().getDefinition()); + } + + if (resource != null) { + variables.addVariableDefinition(ExpressionConstants.VAR_RESOURCE, resource.asPrismObject(), resource.asPrismObject().getDefinition()); + } + + return variables; + } + + // Called from the ObjectResolver.resolve + public ObjectType resolveRef(ObjectReferenceType ref, String contextDescription, OperationResult result) + throws ObjectNotFoundException, SchemaException { + + Class type = ObjectType.class; + if (ref.getType() != null) { + ObjectTypes objectTypeType = ObjectTypes.getObjectTypeFromTypeQName(ref.getType()); + type = objectTypeType.getClassDefinition(); + } + + return repositoryService.getObject(type, ref.getOid(), null, result).asObjectable(); + + } + +} diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java index ee9c5eb3a70..e0de939f7f8 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java @@ -1744,21 +1744,11 @@ private OperationProvisioningScriptsType evaluateScript(OperationProvisioningScr } private boolean evaluateScriptCondition(OperationProvisioningScriptType script, - ExpressionVariables variables, ExpressionProfile expressionProfile, Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { - ExpressionType condition = script.getCondition(); - if (condition == null) { - return true; - } - - PrismPropertyValue conditionOutput = ExpressionUtil.evaluateCondition(variables, condition, expressionProfile, expressionFactory, " condition for provisioning script ", task, result); - if (conditionOutput == null) { - return true; - } - - Boolean conditionOutputValue = conditionOutput.getValue(); - - return BooleanUtils.isNotFalse(conditionOutputValue); - + ExpressionVariables variables, ExpressionProfile expressionProfile, Task task, OperationResult result) + throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, + ConfigurationException, SecurityViolationException { + return ExpressionUtil.evaluateConditionDefaultTrue(variables, script.getCondition(), expressionProfile, + expressionFactory, " condition for provisioning script ", task, result); } private void evaluateScriptArgument(ProvisioningScriptArgumentType argument, diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/focus/ObjectTemplateProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/focus/ObjectTemplateProcessor.java index 316ccc949c6..91bcaa88589 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/focus/ObjectTemplateProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/focus/ObjectTemplateProcessor.java @@ -24,6 +24,11 @@ import com.evolveum.midpoint.prism.delta.*; import com.evolveum.midpoint.prism.equivalence.EquivalenceStrategy; import com.evolveum.midpoint.prism.path.ItemPathCollectionsUtil; +import com.evolveum.midpoint.schema.ObjectSelector; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.util.exception.*; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; + import org.apache.commons.lang.BooleanUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -57,32 +62,8 @@ import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.DebugUtil; -import com.evolveum.midpoint.util.exception.CommunicationException; -import com.evolveum.midpoint.util.exception.ConfigurationException; -import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; -import com.evolveum.midpoint.util.exception.ObjectNotFoundException; -import com.evolveum.midpoint.util.exception.PolicyViolationException; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.exception.SecurityViolationException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentHolderType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AutoassignMappingType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AutoassignSpecificationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.FocalAutoassignSpecificationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.MappingStrengthType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateItemDefinitionType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateMappingEvaluationPhaseType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateMappingType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleManagementConfigurationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.VariableBindingDefinitionType; import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; import static com.evolveum.midpoint.model.impl.lens.projector.util.SkipWhenFocusDeleted.PRIMARY; @@ -459,6 +440,11 @@ private void collectAutoassignMappings(LensCon if (focalAutoassignSpec == null) { return true; } + + if (!isApplicableFor(focalAutoassignSpec.getSelector(), context.getFocusContext(), objectResult)) { + return true; + } + for (AutoassignMappingType autoMapping: focalAutoassignSpec.getMapping()) { AutoassignMappingType mapping = autoMapping.clone(); setMappingTarget(mapping, new ItemPathType(SchemaConstants.PATH_ASSIGNMENT)); @@ -470,6 +456,19 @@ private void collectAutoassignMappings(LensCon cacheRepositoryService.searchObjectsIterative(AbstractRoleType.class, query, handler, GetOperationOptions.createReadOnlyCollection(), true, result); } + private boolean isApplicableFor(ObjectSelectorType selector, LensFocusContext focusContext, OperationResult result) { + if (selector == null) { + return true; + } + try { + return cacheRepositoryService.selectorMatches(selector, focusContext.getObjectAny(), null, LOGGER, ""); + } catch (SchemaException | SecurityViolationException | ExpressionEvaluationException | CommunicationException | ObjectNotFoundException | ConfigurationException e) { + LOGGER.error("Failed to evaluate selector constraints, selector {}, focusContext {}\nReason: {}", selector, focusContext, e.getMessage(), e); + result.recordFatalError("Failed to evaluate selector constrains, selector: " + selector + ", focusContext: " + focusContext + "\nReason: " + e.getMessage(), e); + throw new SystemException(e); + } + } + private void setMappingTarget(MappingType mapping, ItemPathType path) { VariableBindingDefinitionType target = mapping.getTarget(); if (target == null) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationContext.java index 6d05c2a2cbb..f0df0918e48 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationContext.java @@ -236,9 +236,8 @@ private boolean conditionMatches(SynchronizationReactionType reaction, Operation variables.put(ExpressionConstants.VAR_RESOURCE_OBJECT_DELTA, resourceObjectDelta, ObjectDelta.class); try { ModelExpressionThreadLocalHolder.pushExpressionEnvironment(new ExpressionEnvironment<>(task, result)); - PrismPropertyValue evaluateCondition = ExpressionUtil.evaluateCondition(variables, expression, + boolean value = ExpressionUtil.evaluateConditionDefaultFalse(variables, expression, expressionProfile, expressionFactory, desc, task, result); - boolean value = Boolean.TRUE.equals(evaluateCondition.getValue()); if (!value) { LOGGER.trace("Skipping reaction {} because the condition was evaluated to false", reaction); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationExpressionsEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationExpressionsEvaluator.java index 72d3640c4ec..96f0dd380f4 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationExpressionsEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationExpressionsEvaluator.java @@ -60,6 +60,8 @@ import java.util.HashSet; import java.util.Set; +import static com.evolveum.midpoint.prism.PrismPropertyValue.getRealValue; + @Component public class SynchronizationExpressionsEvaluator { @@ -129,25 +131,17 @@ public List> findFocusesByCorrelationRule(C } private boolean satisfyCondition(ShadowType currentShadow, ConditionalSearchFilterType conditionalFilter, - ExpressionProfile expressionProfile, ResourceType resourceType, SystemConfigurationType configurationType, String shortDesc, Task task, - OperationResult parentResult) throws SchemaException, + ExpressionProfile expressionProfile, ResourceType resource, SystemConfigurationType configuration, + String shortDesc, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException { - - if (conditionalFilter.getCondition() == null){ + if (conditionalFilter.getCondition() == null) { return true; + } else { + ExpressionVariables variables = ModelImplUtils.getDefaultExpressionVariables(null, currentShadow, + resource, configuration, prismContext); + return ExpressionUtil.evaluateConditionDefaultFalse(variables, + conditionalFilter.getCondition(), expressionProfile, expressionFactory, shortDesc, task, result); } - - ExpressionType condition = conditionalFilter.getCondition(); - ExpressionVariables variables = ModelImplUtils.getDefaultExpressionVariables(null,currentShadow, resourceType, configurationType, prismContext); - ItemDefinition outputDefinition = prismContext.definitionFactory().createPropertyDefinition( - ExpressionConstants.OUTPUT_ELEMENT_NAME, PrimitiveType.BOOLEAN.getQname()); - PrismPropertyValue satisfy = (PrismPropertyValue) ExpressionUtil.evaluateExpression(variables, - outputDefinition, condition, expressionProfile, expressionFactory, shortDesc, task, parentResult); - if (satisfy.getValue() == null) { - return false; - } - - return satisfy.getValue(); } private boolean contains(List> users, PrismObject foundUser){ @@ -159,7 +153,6 @@ private boolean contains(List> users, Prism return false; } - private List> findFocusesByCorrelationRule(Class focusType, ShadowType currentShadow, ConditionalSearchFilterType conditionalFilter, ExpressionProfile expressionProfile, ResourceType resourceType, SystemConfigurationType configurationType, Task task, OperationResult result) @@ -357,7 +350,7 @@ private ObjectQuery evaluateQueryExpressions(ObjectQuery query, ExpressionProfil return ExpressionUtil.evaluateQueryExpressions(query, variables, expressionProfile, expressionFactory, prismContext, shortDesc, task, result); } - public boolean evaluateConfirmationExpression(Class focusType, F user, ShadowType shadow, ResourceType resource, + private boolean evaluateConfirmationExpression(Class focusType, F user, ShadowType shadow, ResourceType resource, SystemConfigurationType configuration, ExpressionType expressionType, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException { Validate.notNull(user, "User must not be null."); @@ -395,6 +388,7 @@ public boolean evaluateConfirmationExpression(Class foc } // For now only used in sync service. but later can be used in outbound/assignments + @SuppressWarnings("WeakerAccess") public String generateTag(ResourceObjectMultiplicityType multiplicity, PrismObject shadow, PrismObject resource, PrismObject configuration, String shortDesc, Task task, OperationResult parentResult) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { if (multiplicity == null) { return null; @@ -411,12 +405,8 @@ public String generateTag(ResourceObjectMultiplicityType multiplicity, PrismObje ExpressionVariables variables = ModelImplUtils.getDefaultExpressionVariables(null, shadow, null, resource, configuration, null, prismContext); ItemDefinition outputDefinition = prismContext.definitionFactory().createPropertyDefinition( ExpressionConstants.OUTPUT_ELEMENT_NAME, PrimitiveType.STRING.getQname()); - PrismPropertyValue tagProp = (PrismPropertyValue) ExpressionUtil.evaluateExpression(variables, + PrismPropertyValue tagProp = ExpressionUtil.evaluateExpression(variables, outputDefinition, expressionType, MiscSchemaUtil.getExpressionProfile(), expressionFactory, shortDesc, task, parentResult); - if (tagProp == null) { - return null; - } - return tagProp.getRealValue(); + return getRealValue(tagProp); } - } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationServiceImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationServiceImpl.java index c14fabd2c42..8fa9d80349b 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationServiceImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationServiceImpl.java @@ -59,6 +59,7 @@ import javax.xml.namespace.QName; import java.util.*; +import static com.evolveum.midpoint.prism.PrismPropertyValue.getRealValue; import static com.evolveum.midpoint.schema.internals.InternalsConfig.consistencyChecks; /** @@ -321,10 +322,7 @@ private ObjectSynchronizationDiscriminatorType evaluateSyn .findPropertyDefinitionByElementName(new QName(SchemaConstants.NS_C, "objectSynchronizationDiscriminator")); PrismPropertyValue evaluateDiscriminator = ExpressionUtil.evaluateExpression(variables, discriminatorDef, classificationExpression, syncCtx.getExpressionProfile(), expressionFactory, desc, task, result); - if (evaluateDiscriminator == null) { - return null; - } - return evaluateDiscriminator.getValue(); + return getRealValue(evaluateDiscriminator); } finally { ModelExpressionThreadLocalHolder.popExpressionEnvironment(); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationServiceUtils.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationServiceUtils.java index 467672755f9..4c86b48aeb1 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationServiceUtils.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationServiceUtils.java @@ -1,109 +1,104 @@ -/* - * 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.model.impl.sync; - -import javax.xml.namespace.QName; - -import com.evolveum.midpoint.schema.result.OperationResult; -import org.apache.commons.lang.Validate; - -import com.evolveum.midpoint.common.SynchronizationUtils; -import com.evolveum.midpoint.model.common.expression.ExpressionEnvironment; -import com.evolveum.midpoint.model.common.expression.ModelExpressionThreadLocalHolder; -import com.evolveum.midpoint.model.impl.util.ModelImplUtils; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismPropertyValue; -import com.evolveum.midpoint.repo.common.expression.ExpressionFactory; -import com.evolveum.midpoint.repo.common.expression.ExpressionUtil; -import com.evolveum.midpoint.repo.common.expression.ExpressionVariables; -import com.evolveum.midpoint.util.exception.CommunicationException; -import com.evolveum.midpoint.util.exception.ConfigurationException; -import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; -import com.evolveum.midpoint.util.exception.ObjectNotFoundException; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.exception.SecurityViolationException; -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectSynchronizationDiscriminatorType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectSynchronizationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; - -public class SynchronizationServiceUtils { - - private static final Trace LOGGER = TraceManager.getTrace(SynchronizationServiceUtils.class); - - public static boolean isPolicyApplicable(ObjectSynchronizationType synchronizationPolicy, - ObjectSynchronizationDiscriminatorType discriminator, ExpressionFactory expressionFactory, - SynchronizationContext syncCtx, OperationResult result) throws SchemaException, ExpressionEvaluationException, - ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { - - boolean isApplicablePolicy; - if (discriminator != null) { - isApplicablePolicy = isPolicyApplicable(discriminator, synchronizationPolicy, syncCtx.getResource()); - } else { - isApplicablePolicy = isPolicyApplicable(synchronizationPolicy, syncCtx); - } - - if (isApplicablePolicy) { - Boolean conditionResult = evaluateSynchronizationPolicyCondition(synchronizationPolicy, syncCtx, expressionFactory, result); - return conditionResult != null ? conditionResult : true; - } else { - return false; - } - } - - private static boolean isPolicyApplicable(ObjectSynchronizationType synchronizationPolicy, SynchronizationContext syncCtx) - throws SchemaException { - ShadowType currentShadowType = syncCtx.getApplicableShadow().asObjectable(); - - // objectClass - QName shadowObjectClass = currentShadowType.getObjectClass(); - Validate.notNull(shadowObjectClass, "No objectClass in currentShadow"); - - return SynchronizationUtils.isPolicyApplicable(shadowObjectClass, currentShadowType.getKind(), currentShadowType.getIntent(), synchronizationPolicy, syncCtx.getResource()); - - } - - private static boolean isPolicyApplicable(ObjectSynchronizationDiscriminatorType synchronizationDiscriminator, - ObjectSynchronizationType synchronizationPolicy, PrismObject resource) - throws SchemaException { - ShadowKindType kind = synchronizationDiscriminator.getKind(); - String intent = synchronizationDiscriminator.getIntent(); - if (kind == null && intent == null) { - throw new SchemaException( - "Illegal state, object synchronization discriminator type must have kind/intent specified. Current values are: kind=" - + kind + ", intent=" + intent); - } - return SynchronizationUtils.isPolicyApplicable(null, kind, intent, synchronizationPolicy, resource); - } - - private static Boolean evaluateSynchronizationPolicyCondition( - ObjectSynchronizationType synchronizationPolicy, SynchronizationContext syncCtx, - ExpressionFactory expressionFactory, OperationResult result) - throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, - ConfigurationException, SecurityViolationException { - if (synchronizationPolicy.getCondition() == null) { - return null; - } - ExpressionType conditionExpressionType = synchronizationPolicy.getCondition(); - String desc = "condition in object synchronization " + synchronizationPolicy.getName(); - ExpressionVariables variables = ModelImplUtils.getDefaultExpressionVariables(null, syncCtx.getApplicableShadow(), null, - syncCtx.getResource(), syncCtx.getSystemConfiguration(), null, syncCtx.getPrismContext()); - try { - ModelExpressionThreadLocalHolder.pushExpressionEnvironment(new ExpressionEnvironment<>(syncCtx.getTask(), result)); - PrismPropertyValue evaluateCondition = ExpressionUtil.evaluateCondition(variables, - conditionExpressionType, syncCtx.getExpressionProfile(), expressionFactory, desc, syncCtx.getTask(), result); - return evaluateCondition.getValue(); - } finally { - ModelExpressionThreadLocalHolder.popExpressionEnvironment(); - } - } -} +/* + * 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.model.impl.sync; + +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.schema.result.OperationResult; +import org.apache.commons.lang.Validate; + +import com.evolveum.midpoint.common.SynchronizationUtils; +import com.evolveum.midpoint.model.common.expression.ExpressionEnvironment; +import com.evolveum.midpoint.model.common.expression.ModelExpressionThreadLocalHolder; +import com.evolveum.midpoint.model.impl.util.ModelImplUtils; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismPropertyValue; +import com.evolveum.midpoint.repo.common.expression.ExpressionFactory; +import com.evolveum.midpoint.repo.common.expression.ExpressionUtil; +import com.evolveum.midpoint.repo.common.expression.ExpressionVariables; +import com.evolveum.midpoint.util.exception.CommunicationException; +import com.evolveum.midpoint.util.exception.ConfigurationException; +import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; +import com.evolveum.midpoint.util.exception.ObjectNotFoundException; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.SecurityViolationException; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectSynchronizationDiscriminatorType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectSynchronizationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; + +public class SynchronizationServiceUtils { + + private static final Trace LOGGER = TraceManager.getTrace(SynchronizationServiceUtils.class); + + public static boolean isPolicyApplicable(ObjectSynchronizationType synchronizationPolicy, + ObjectSynchronizationDiscriminatorType discriminator, ExpressionFactory expressionFactory, + SynchronizationContext syncCtx, OperationResult result) throws SchemaException, ExpressionEvaluationException, + ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { + + boolean isApplicablePolicy; + if (discriminator != null) { + isApplicablePolicy = isPolicyApplicable(discriminator, synchronizationPolicy, syncCtx.getResource()); + } else { + isApplicablePolicy = isPolicyApplicable(synchronizationPolicy, syncCtx); + } + + return isApplicablePolicy && + evaluateSynchronizationPolicyCondition(synchronizationPolicy, syncCtx, expressionFactory, result); + } + + private static boolean isPolicyApplicable(ObjectSynchronizationType synchronizationPolicy, SynchronizationContext syncCtx) + throws SchemaException { + ShadowType currentShadowType = syncCtx.getApplicableShadow().asObjectable(); + + // objectClass + QName shadowObjectClass = currentShadowType.getObjectClass(); + Validate.notNull(shadowObjectClass, "No objectClass in currentShadow"); + + return SynchronizationUtils.isPolicyApplicable(shadowObjectClass, currentShadowType.getKind(), currentShadowType.getIntent(), synchronizationPolicy, syncCtx.getResource()); + + } + + private static boolean isPolicyApplicable(ObjectSynchronizationDiscriminatorType synchronizationDiscriminator, + ObjectSynchronizationType synchronizationPolicy, PrismObject resource) + throws SchemaException { + ShadowKindType kind = synchronizationDiscriminator.getKind(); + String intent = synchronizationDiscriminator.getIntent(); + if (kind == null && intent == null) { + throw new SchemaException( + "Illegal state, object synchronization discriminator type must have kind/intent specified. Current values are: kind=" + + kind + ", intent=" + intent); + } + return SynchronizationUtils.isPolicyApplicable(null, kind, intent, synchronizationPolicy, resource); + } + + private static boolean evaluateSynchronizationPolicyCondition( + ObjectSynchronizationType synchronizationPolicy, SynchronizationContext syncCtx, + ExpressionFactory expressionFactory, OperationResult result) + throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, + ConfigurationException, SecurityViolationException { + if (synchronizationPolicy.getCondition() == null) { + return true; + } + ExpressionType conditionExpressionBean = synchronizationPolicy.getCondition(); + String desc = "condition in object synchronization " + synchronizationPolicy.getName(); + ExpressionVariables variables = ModelImplUtils.getDefaultExpressionVariables(null, syncCtx.getApplicableShadow(), null, + syncCtx.getResource(), syncCtx.getSystemConfiguration(), null, syncCtx.getPrismContext()); + try { + ModelExpressionThreadLocalHolder.pushExpressionEnvironment(new ExpressionEnvironment<>(syncCtx.getTask(), result)); + return ExpressionUtil.evaluateConditionDefaultTrue(variables, + conditionExpressionBean, syncCtx.getExpressionProfile(), expressionFactory, desc, syncCtx.getTask(), result); + } finally { + ModelExpressionThreadLocalHolder.popExpressionEnvironment(); + } + } +} diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestAutoassign.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestAutoassign.java index 08232a4986f..a772a2bfaae 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestAutoassign.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestAutoassign.java @@ -10,6 +10,10 @@ import javax.xml.datatype.XMLGregorianCalendar; +import com.evolveum.midpoint.prism.path.ItemPath; + +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; + import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; @@ -20,11 +24,6 @@ import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.test.DummyResourceContoller; -import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleManagementConfigurationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemObjectsType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; /** * @author semancik @@ -47,9 +46,14 @@ public class TestAutoassign extends AbstractRbacTest { protected static final String ROLE_UNIT_WALKER_OID = "a2bc45fc-bfec-11e7-bdfd-af4b3e689502"; protected static final String ROLE_UNIT_WALKER_TITLE = "Walker"; + protected static final File ROLE_UNIT_RIDER_FILE = new File(AUTOASSIGN_DIR, "role-unit-rider.xml"); + protected static final String ROLE_UNIT_RIDER_OID = "9a60cdc6-f2ad-4414-964b-5fd1dfaec157"; + protected static final String ROLE_UNIT_RIDER_TITLE = "Rider"; + protected static final String UNIT_WORKER = "worker"; protected static final String UNIT_SLEEPER = "sleeper"; protected static final String UNIT_WALKER = "walker"; + protected static final String UNIT_RIDER = "rider"; private static final XMLGregorianCalendar ROLE_SLEEPER_AUTOASSIGN_VALID_TO = XmlTypeConverter.createXMLGregorianCalendar(2222, 1, 2, 3, 4, 5); @@ -62,16 +66,13 @@ public void initSystem(Task initTask, OperationResult initResult) repoAddObjectFromFile(ROLE_UNIT_WORKER_FILE, RoleType.class, initResult); repoAddObjectFromFile(ROLE_UNIT_SLEEPER_FILE, RoleType.class, initResult); repoAddObjectFromFile(ROLE_UNIT_WALKER_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_UNIT_RIDER_FILE, RoleType.class, initResult); + + repoAddObjectFromFile(ARCHETYPE_EMPLOYEE_FILE, ArchetypeType.class, initResult); - // Temporarily using repository service because of MID-5497 - repositoryService.modifyObject(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(), - prismContext.deltaFor(SystemConfigurationType.class) - .item(SystemConfigurationType.F_ROLE_MANAGEMENT, RoleManagementConfigurationType.F_AUTOASSIGN_ENABLED) - .replace(true) - .asItemDeltas(), initResult); -// modifyObjectReplaceProperty(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(), -// ItemPath.create(SystemConfigurationType.F_ROLE_MANAGEMENT, RoleManagementConfigurationType.F_AUTOASSIGN_ENABLED), -// initTask, initResult, Boolean.TRUE); + modifyObjectReplaceProperty(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(), + ItemPath.create(SystemConfigurationType.F_ROLE_MANAGEMENT, RoleManagementConfigurationType.F_AUTOASSIGN_ENABLED), + initTask, initResult, Boolean.TRUE); } /** @@ -239,6 +240,126 @@ public void test114ModifyUnitAddSleeper() throws Exception { ROLE_UNIT_WORKER_TITLE, ROLE_UNIT_WALKER_TITLE, ROLE_UNIT_SLEEPER_TITLE); } + @Test + public void test115ModifyUnitAddRider() throws Exception { + // GIVEN + Task task = getTestTask(); + OperationResult result = task.getResult(); + + // WHEN + modifyUserAdd(USER_JACK_OID, UserType.F_ORGANIZATIONAL_UNIT, task, result, + createPolyString(UNIT_RIDER)); + + // THEN + assertSuccess(result); + + assertUserAfter(USER_JACK_OID) + .assertOrganizationalUnits(UNIT_WORKER, UNIT_WALKER, UNIT_SLEEPER, UNIT_RIDER) + .assignments() + .assertAssignments(3) + .assertRole(ROLE_UNIT_WORKER_OID) + .assertRole(ROLE_UNIT_WALKER_OID) + .assertRole(ROLE_UNIT_SLEEPER_OID) + .assertNoRole(ROLE_UNIT_RIDER_OID) + .end() + .links() + .single(); + + assertDummyAccountByUsername(null, USER_JACK_USERNAME) + .assertAttribute(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, + ROLE_UNIT_WORKER_TITLE, ROLE_UNIT_WALKER_TITLE, ROLE_UNIT_SLEEPER_TITLE); + } + + /** + * Prepare user guybrush for autoassignment + */ + @Test + public void test200assignArchetypeGuybrush() throws Exception { + // GIVEN + Task task = getTestTask(); + OperationResult result = task.getResult(); + + //WHEN + assignArchetype(USER_GUYBRUSH_OID, ARCHETYPE_EMPLOYEE_OID, task, result); + + //THEN + assertUserAfter(USER_GUYBRUSH_OID) + .assertArchetypeRef(ARCHETYPE_EMPLOYEE_OID) + .assignments() + .assertAssignments(1) + .assertArchetype(ARCHETYPE_EMPLOYEE_OID) + .end(); + + } + + @Test + public void test201addUnitRiderGuybrush() throws Exception { + //GIVEN + Task task = getTestTask(); + OperationResult result = task.getResult(); + + //WHEN + modifyUserAdd(USER_GUYBRUSH_OID, UserType.F_ORGANIZATIONAL_UNIT, task, result, createPolyString(UNIT_RIDER)); + + //THEN + assertUserAfter(USER_GUYBRUSH_OID) + .assertOrganizationalUnits(UNIT_RIDER) + .assertArchetypeRef(ARCHETYPE_EMPLOYEE_OID) + .assignments() + .assertAssignments(2) + .assertArchetype(ARCHETYPE_EMPLOYEE_OID) + .assertRole(ROLE_UNIT_RIDER_OID) + .end() + .links() + .single(); + } + + @Test + public void test202addUnitSleeperGuybrush() throws Exception { + //GIVEN + Task task = getTestTask(); + OperationResult result = task.getResult(); + + //WHEN + modifyUserAdd(USER_GUYBRUSH_OID, UserType.F_ORGANIZATIONAL_UNIT, task, result, createPolyString(UNIT_SLEEPER)); + + //THEN + assertUserAfter(USER_GUYBRUSH_OID) + .assertOrganizationalUnits(UNIT_RIDER, UNIT_SLEEPER) + .assertArchetypeRef(ARCHETYPE_EMPLOYEE_OID) + .assignments() + .assertAssignments(3) + .assertArchetype(ARCHETYPE_EMPLOYEE_OID) + .assertRole(ROLE_UNIT_RIDER_OID) + .assertRole(ROLE_UNIT_SLEEPER_OID) + .end() + .links() + .single(); + } + + @Test + public void test203removeUnitRiderGuybrush() throws Exception { + //GIVEN + Task task = getTestTask(); + OperationResult result = task.getResult(); + + //WHEN + modifyUserDelete(USER_GUYBRUSH_OID, UserType.F_ORGANIZATIONAL_UNIT, task, result, createPolyString(UNIT_RIDER)); + + //THEN + assertUserAfter(USER_GUYBRUSH_OID) + .assertArchetypeRef(ARCHETYPE_EMPLOYEE_OID) + .assignments() + .assertAssignments(2) + .assertArchetype(ARCHETYPE_EMPLOYEE_OID) + .assertNoRole(ROLE_UNIT_RIDER_OID) + .assertRole(ROLE_UNIT_SLEEPER_OID) + .end() + .links() + .single(); + } + + // TODO: org and relation // TODO: combine autoassign with object template role assign diff --git a/model/model-intest/src/test/resources/rbac/autoassign/role-unit-rider.xml b/model/model-intest/src/test/resources/rbac/autoassign/role-unit-rider.xml new file mode 100644 index 00000000000..a25c84fe6ee --- /dev/null +++ b/model/model-intest/src/test/resources/rbac/autoassign/role-unit-rider.xml @@ -0,0 +1,48 @@ + + + Unit Rider + + + + account + + ri:title + + + Rider + + + + + + + true + + + UserType + + + + autoassign-rider + true + + organizationalUnit + + + + + + + + diff --git a/model/model-intest/src/test/resources/rbac/autoassign/role-unit-sleeper.xml b/model/model-intest/src/test/resources/rbac/autoassign/role-unit-sleeper.xml index bb2f8d1b9f5..51784033504 100644 --- a/model/model-intest/src/test/resources/rbac/autoassign/role-unit-sleeper.xml +++ b/model/model-intest/src/test/resources/rbac/autoassign/role-unit-sleeper.xml @@ -27,6 +27,9 @@ true + + UserType + autoassign-sleeper true diff --git a/model/model-intest/src/test/resources/rbac/autoassign/role-unit-walker.xml b/model/model-intest/src/test/resources/rbac/autoassign/role-unit-walker.xml index fac2063254c..56d4bbb0878 100644 --- a/model/model-intest/src/test/resources/rbac/autoassign/role-unit-walker.xml +++ b/model/model-intest/src/test/resources/rbac/autoassign/role-unit-walker.xml @@ -27,6 +27,9 @@ true + + UserType + autoassign-walker true diff --git a/model/model-intest/src/test/resources/rbac/autoassign/role-unit-worker.xml b/model/model-intest/src/test/resources/rbac/autoassign/role-unit-worker.xml index c0befb16a17..9f079d52252 100644 --- a/model/model-intest/src/test/resources/rbac/autoassign/role-unit-worker.xml +++ b/model/model-intest/src/test/resources/rbac/autoassign/role-unit-worker.xml @@ -27,6 +27,9 @@ true + + UserType + autoassign-worker true diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/TransportUtil.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/TransportUtil.java index c26cafdb0cd..1a604a223ab 100644 --- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/TransportUtil.java +++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/api/transports/TransportUtil.java @@ -87,14 +87,14 @@ public static String formatToFileOld(Message message) { return "============================================ " + "\n" +new Date() + "\n" + message.toString() + "\n\n"; } - public static String formatToFileNew(Message message, String transport) { + static String formatToFileNew(Message message, String transport) { return "================ " + new Date() + " ======= [" + transport + "]\n" + message.debugDump() + "\n\n"; } - public static boolean isRecipientAllowed(String recipient, NotificationTransportConfigurationType transportConfigurationType, + private static boolean isRecipientAllowed(String recipient, NotificationTransportConfigurationType transportConfigurationType, Task task, OperationResult result, ExpressionFactory expressionFactory, ExpressionProfile expressionProfile, Trace logger) { if (optionsForFilteringRecipient(transportConfigurationType) > 1) { - throw new IllegalArgumentException("Couln't use more as one choise from 'blackList', 'whiteList' and 'recipientFilterExpression'"); + throw new IllegalArgumentException("Couldn't use more than one choice from 'blackList', 'whiteList' and 'recipientFilterExpression'"); } ExpressionType filter = transportConfigurationType.getRecipientFilterExpression(); if (filter != null) { @@ -103,7 +103,7 @@ public static boolean isRecipientAllowed(String recipient, NotificationTransport try { PrismPropertyValue allowedRecipient = ExpressionUtil.evaluateCondition(variables, filter, expressionProfile, expressionFactory, "Recipient filter", task, result); - if(allowedRecipient == null) { + if (allowedRecipient == null || allowedRecipient.getValue() == null) { throw new IllegalArgumentException("Return value from expresion for filtering recipient is null"); } return allowedRecipient.getValue(); @@ -134,19 +134,19 @@ public static boolean isRecipientAllowed(String recipient, NotificationTransport return true; } - public static int optionsForFilteringRecipient( + static int optionsForFilteringRecipient( NotificationTransportConfigurationType transportConfigurationType) { - int choises = 0; + int choices = 0; if (transportConfigurationType.getRecipientFilterExpression() != null) { - choises++; + choices++; } if (!transportConfigurationType.getBlackList().isEmpty()) { - choises++; + choices++; } if (!transportConfigurationType.getWhiteList().isEmpty()) { - choises++; + choices++; } - return choises; + return choices; } public static void validateRecipient(List allowedRecipient, List forbiddenRecipient, List recipients, diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/common/ExpressionEvaluationHelper.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/common/ExpressionEvaluationHelper.java index 36b60539dfb..a20cb9a067e 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/common/ExpressionEvaluationHelper.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/common/ExpressionEvaluationHelper.java @@ -1,122 +1,122 @@ -/* - * Copyright (c) 2010-2017 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.wf.impl.processes.common; - -import com.evolveum.midpoint.model.common.expression.ModelExpressionThreadLocalHolder; -import com.evolveum.midpoint.prism.*; -import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; -import com.evolveum.midpoint.prism.path.ItemName; -import com.evolveum.midpoint.repo.common.expression.*; -import com.evolveum.midpoint.schema.constants.SchemaConstants; -import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.schema.util.MiscSchemaUtil; -import com.evolveum.midpoint.task.api.Task; -import com.evolveum.midpoint.util.DOMUtil; -import com.evolveum.midpoint.util.MiscUtil; -import com.evolveum.midpoint.util.QNameUtil; -import com.evolveum.midpoint.util.exception.CommunicationException; -import com.evolveum.midpoint.util.exception.ConfigurationException; -import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; -import com.evolveum.midpoint.util.exception.ObjectNotFoundException; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.exception.SecurityViolationException; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; -import org.jetbrains.annotations.NotNull; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import javax.xml.namespace.QName; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.function.Function; - -/** - * @author mederly - */ -@Component -public class ExpressionEvaluationHelper { - - @Autowired private ExpressionFactory expressionFactory; - @Autowired private PrismContext prismContext; - - public List evaluateRefExpressions(List expressions, - ExpressionVariables variables, String contextDescription, - Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException { - List retval = new ArrayList<>(); - for (ExpressionType expression : expressions) { - retval.addAll(evaluateRefExpression(expression, variables, contextDescription, task, result)); - } - return retval; - } - - public List evaluateRefExpression(ExpressionType expressionType, ExpressionVariables variables, - String contextDescription, Task task, OperationResult result) - throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException { - return evaluateExpression(expressionType, variables, contextDescription, ObjectReferenceType.class, - ObjectReferenceType.COMPLEX_TYPE, false, ExpressionUtil.createRefConvertor(UserType.COMPLEX_TYPE), task, result); - } - - @SuppressWarnings("unchecked") - @NotNull - public List evaluateExpression(ExpressionType expressionType, ExpressionVariables variables, - String contextDescription, Class clazz, QName typeName, - boolean multiValued, Function additionalConvertor, Task task, - OperationResult result) - throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException { - MutableItemDefinition resultDef; - ItemName resultName = new ItemName(SchemaConstants.NS_C, "result"); - if (QNameUtil.match(typeName, ObjectReferenceType.COMPLEX_TYPE)) { - resultDef = prismContext.definitionFactory().createReferenceDefinition(resultName, typeName); - } else { - resultDef = prismContext.definitionFactory().createPropertyDefinition(resultName, typeName); - } - if (multiValued) { - resultDef.setMaxOccurs(-1); - } - Expression expression = expressionFactory.makeExpression(expressionType, resultDef, MiscSchemaUtil.getExpressionProfile(), contextDescription, task, result); - ExpressionEvaluationContext context = new ExpressionEvaluationContext(null, variables, contextDescription, task); - context.setAdditionalConvertor(additionalConvertor); - PrismValueDeltaSetTriple exprResultTriple = ModelExpressionThreadLocalHolder - .evaluateAnyExpressionInContext(expression, context, task, result); - List list = new ArrayList<>(); - for (PrismValue pv : exprResultTriple.getZeroSet()) { - T realValue; - if (pv instanceof PrismReferenceValue) { - // pv.getRealValue sometimes returns synthesized Referencable, not ObjectReferenceType - // If we would stay with that we would need to make many changes throughout workflow module. - // So it is safer to stay with ObjectReferenceType. - ObjectReferenceType ort = new ObjectReferenceType(); - ort.setupReferenceValue((PrismReferenceValue) pv); - realValue = (T) ort; - } else { - realValue = pv.getRealValue(); - } - list.add(realValue); - } - return list; - } - - public boolean evaluateBooleanExpression(ExpressionType expressionType, ExpressionVariables expressionVariables, - String contextDescription, Task task, OperationResult result) - throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException { - Collection values = evaluateExpression(expressionType, expressionVariables, contextDescription, - Boolean.class, DOMUtil.XSD_BOOLEAN, false, null, task, result); - return MiscUtil.getSingleValue(values, false, contextDescription); - } - - public String evaluateStringExpression(ExpressionType expressionType, ExpressionVariables expressionVariables, - String contextDescription, Task task, OperationResult result) - throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException { - Collection values = evaluateExpression(expressionType, expressionVariables, contextDescription, - String.class, DOMUtil.XSD_STRING, false, null, task, result); - return MiscUtil.getSingleValue(values, null, contextDescription); - } -} +/* + * Copyright (c) 2010-2017 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.wf.impl.processes.common; + +import com.evolveum.midpoint.model.common.expression.ModelExpressionThreadLocalHolder; +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; +import com.evolveum.midpoint.prism.path.ItemName; +import com.evolveum.midpoint.repo.common.expression.*; +import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.schema.util.MiscSchemaUtil; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.util.DOMUtil; +import com.evolveum.midpoint.util.MiscUtil; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.util.exception.CommunicationException; +import com.evolveum.midpoint.util.exception.ConfigurationException; +import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; +import com.evolveum.midpoint.util.exception.ObjectNotFoundException; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.SecurityViolationException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.xml.namespace.QName; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.function.Function; + +/** + * @author mederly + */ +@Component +public class ExpressionEvaluationHelper { + + @Autowired private ExpressionFactory expressionFactory; + @Autowired private PrismContext prismContext; + + List evaluateRefExpressions(List expressions, + ExpressionVariables variables, String contextDescription, + Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException { + List retval = new ArrayList<>(); + for (ExpressionType expression : expressions) { + retval.addAll(evaluateRefExpression(expression, variables, contextDescription, task, result)); + } + return retval; + } + + private List evaluateRefExpression(ExpressionType expressionType, ExpressionVariables variables, + String contextDescription, Task task, OperationResult result) + throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException { + return evaluateExpression(expressionType, variables, contextDescription, ObjectReferenceType.class, + ObjectReferenceType.COMPLEX_TYPE, false, ExpressionUtil.createRefConvertor(UserType.COMPLEX_TYPE), task, result); + } + + @SuppressWarnings("unchecked") + @NotNull + public List evaluateExpression(ExpressionType expressionType, ExpressionVariables variables, + String contextDescription, Class clazz, QName typeName, + boolean multiValued, Function additionalConvertor, Task task, + OperationResult result) + throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException { + MutableItemDefinition resultDef; + ItemName resultName = new ItemName(SchemaConstants.NS_C, "result"); + if (QNameUtil.match(typeName, ObjectReferenceType.COMPLEX_TYPE)) { + resultDef = prismContext.definitionFactory().createReferenceDefinition(resultName, typeName); + } else { + resultDef = prismContext.definitionFactory().createPropertyDefinition(resultName, typeName); + } + if (multiValued) { + resultDef.setMaxOccurs(-1); + } + Expression expression = expressionFactory.makeExpression(expressionType, resultDef, MiscSchemaUtil.getExpressionProfile(), contextDescription, task, result); + ExpressionEvaluationContext context = new ExpressionEvaluationContext(null, variables, contextDescription, task); + context.setAdditionalConvertor(additionalConvertor); + PrismValueDeltaSetTriple exprResultTriple = ModelExpressionThreadLocalHolder + .evaluateAnyExpressionInContext(expression, context, task, result); + List list = new ArrayList<>(); + for (PrismValue pv : exprResultTriple.getZeroSet()) { + T realValue; + if (pv instanceof PrismReferenceValue) { + // pv.getRealValue sometimes returns synthesized Referencable, not ObjectReferenceType + // If we would stay with that we would need to make many changes throughout workflow module. + // So it is safer to stay with ObjectReferenceType. + ObjectReferenceType ort = new ObjectReferenceType(); + ort.setupReferenceValue((PrismReferenceValue) pv); + realValue = (T) ort; + } else { + realValue = pv.getRealValue(); + } + list.add(realValue); + } + return list; + } + + public boolean evaluateBooleanExpression(ExpressionType expressionType, ExpressionVariables expressionVariables, + String contextDescription, Task task, OperationResult result) + throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException { + Collection values = evaluateExpression(expressionType, expressionVariables, contextDescription, + Boolean.class, DOMUtil.XSD_BOOLEAN, false, null, task, result); + return MiscUtil.getSingleValue(values, false, contextDescription); + } + + public String evaluateStringExpression(ExpressionType expressionType, ExpressionVariables expressionVariables, + String contextDescription, Task task, OperationResult result) + throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException { + Collection values = evaluateExpression(expressionType, expressionVariables, contextDescription, + String.class, DOMUtil.XSD_STRING, false, null, task, result); + return MiscUtil.getSingleValue(values, null, contextDescription); + } +} diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/util/PerformerCommentsFormatterImpl.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/util/PerformerCommentsFormatterImpl.java index a9675b20318..28105e56346 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/util/PerformerCommentsFormatterImpl.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/util/PerformerCommentsFormatterImpl.java @@ -26,9 +26,6 @@ import java.util.HashMap; import java.util.Map; -/** - * @author mederly - */ public class PerformerCommentsFormatterImpl implements PerformerCommentsFormatter { private static final Trace LOGGER = TraceManager.getTrace(PerformerCommentsFormatterImpl.class); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/UcfExpressionEvaluatorImpl.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/UcfExpressionEvaluatorImpl.java index 81bca28e091..4037f9f6aba 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/UcfExpressionEvaluatorImpl.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/UcfExpressionEvaluatorImpl.java @@ -19,7 +19,6 @@ import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.MiscSchemaUtil; import com.evolveum.midpoint.task.api.Task; -import com.evolveum.midpoint.task.api.TaskManager; import com.evolveum.midpoint.util.annotation.Experimental; import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionType; @@ -32,7 +31,7 @@ import java.util.List; /** - * + * Expression evaluator that is provided to lower-level components in UCF layer. */ @Component @Experimental @@ -41,7 +40,6 @@ public class UcfExpressionEvaluatorImpl implements UcfExpressionEvaluator { private static final String OP_EVALUATE = UcfExpressionEvaluatorImpl.class.getName() + ".evaluate"; @Autowired private ExpressionFactory expressionFactory; - @Autowired private TaskManager taskManager; @NotNull @Override diff --git a/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/UcfExpressionEvaluator.java b/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/UcfExpressionEvaluator.java index baf9c0908ed..833e43c153c 100644 --- a/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/UcfExpressionEvaluator.java +++ b/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/UcfExpressionEvaluator.java @@ -18,7 +18,7 @@ import java.util.List; /** - * + * Expression evaluator that is provided to lower-level components in UCF layer. */ @Experimental public interface UcfExpressionEvaluator { diff --git a/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/expression/ExpressionUtil.java b/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/expression/ExpressionUtil.java index df33a4b1059..c3239346135 100644 --- a/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/expression/ExpressionUtil.java +++ b/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/expression/ExpressionUtil.java @@ -711,12 +711,9 @@ private static V evaluateExpression(ExpressionVariables v DOMUtil.XSD_STRING); } + //noinspection unchecked return (V) evaluateExpression(variables, outputDefinition, expressionType, expressionProfile, expressionFactory, shortDesc, task, parentResult); - - // String expressionResult = - // expressionHandler.evaluateExpression(currentShadow, valueExpression, - // shortDesc, result); } public static V evaluateExpression(Collection> sources, @@ -795,10 +792,49 @@ public static PrismPropertyValue evaluateCondition(ExpressionVariables throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { ItemDefinition outputDefinition = expressionFactory.getPrismContext().definitionFactory().createPropertyDefinition( ExpressionConstants.OUTPUT_ELEMENT_NAME, DOMUtil.XSD_BOOLEAN); + //noinspection unchecked return (PrismPropertyValue) evaluateExpression(variables, outputDefinition, expressionType, expressionProfile, expressionFactory, shortDesc, task, parentResult); } + public static boolean evaluateConditionDefaultTrue(ExpressionVariables variables, + ExpressionType expressionBean, ExpressionProfile expressionProfile, ExpressionFactory expressionFactory, + String shortDesc, Task task, OperationResult parentResult) + throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, + ConfigurationException, SecurityViolationException { + return evaluateConditionWithDefault(variables, expressionBean, expressionProfile, expressionFactory, shortDesc, + true, task, parentResult); + } + + public static boolean evaluateConditionDefaultFalse(ExpressionVariables variables, + ExpressionType expressionBean, ExpressionProfile expressionProfile, ExpressionFactory expressionFactory, + String shortDesc, Task task, OperationResult parentResult) + throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, + ConfigurationException, SecurityViolationException { + return evaluateConditionWithDefault(variables, expressionBean, expressionProfile, expressionFactory, shortDesc, + false, task, parentResult); + } + + private static boolean evaluateConditionWithDefault(ExpressionVariables variables, + ExpressionType expressionBean, ExpressionProfile expressionProfile, ExpressionFactory expressionFactory, String shortDesc, + boolean defaultValue, Task task, OperationResult parentResult) + throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { + if (expressionBean == null) { + return defaultValue; + } + PrismPropertyValue booleanPropertyValue = evaluateCondition(variables, expressionBean, expressionProfile, + expressionFactory, shortDesc, task, parentResult); + if (booleanPropertyValue == null) { + return defaultValue; + } + Boolean realValue = booleanPropertyValue.getRealValue(); + if (realValue == null) { + return defaultValue; + } else { + return realValue; + } + } + public static boolean getBooleanConditionOutput(PrismPropertyValue conditionOutput) { if (conditionOutput == null) { return false; diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObject.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObject.java index 44e3defe81b..a893a3017c7 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObject.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObject.java @@ -7,13 +7,12 @@ package com.evolveum.midpoint.repo.sql.data.common; -import static org.hibernate.annotations.CascadeType.ALL; +import static javax.persistence.CascadeType.ALL; import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; +import java.util.Objects; +import java.util.*; +import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.Index; import javax.persistence.Table; @@ -22,7 +21,6 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; -import org.hibernate.annotations.ForeignKey; import org.hibernate.annotations.NamedQueries; import org.hibernate.annotations.NamedQuery; import org.hibernate.annotations.*; @@ -61,7 +59,6 @@ @NamedQuery(name = "searchShadowOwner.getShadow", query = "select s.oid from RShadow as s where s.oid = :oid"), @NamedQuery(name = "searchShadowOwner.getOwner", query = "select o.oid, o.fullObject, 0, 0, 0, 0, 0, 0 from RFocus as o left join o.linkRef as ref where ref.targetOid = :oid"), @NamedQuery(name = "listAccountShadowOwner.getUser", query = "select u.oid, u.fullObject, 0, 0, 0, 0, 0, 0 from RUser as u left join u.linkRef as ref where ref.targetOid = :oid"), -// @NamedQuery(name = "getExtCount", query = "select stringsCount, longsCount, datesCount, referencesCount, polysCount, booleansCount from RObject where oid = :oid"), @NamedQuery(name = "getVersion", query = "select o.version from RObject as o where o.oid = :oid"), @NamedQuery(name = "existOrgClosure", query = "select count(*) from ROrgClosure as o where o.ancestorOid = :ancestorOid and o.descendantOid = :descendantOid"), @NamedQuery(name = "sqlDeleteOrgClosure", query = "delete from ROrgClosure as o where o.descendantOid = :oid or o.ancestorOid = :oid"), @@ -164,8 +161,7 @@ public RPolyString getName() { return name; } - @OneToMany(mappedBy = RTrigger.F_OWNER, orphanRemoval = true) - @Cascade({ org.hibernate.annotations.CascadeType.ALL }) + @OneToMany(mappedBy = RTrigger.F_OWNER, orphanRemoval = true, cascade = ALL) public Set getTrigger() { if (trigger == null) { trigger = new HashSet<>(); @@ -174,8 +170,7 @@ public Set getTrigger() { } @Where(clause = RObjectReference.REFERENCE_TYPE + "= 0") - @OneToMany(mappedBy = RObjectReference.F_OWNER, orphanRemoval = true) - @Cascade({ org.hibernate.annotations.CascadeType.ALL }) + @OneToMany(mappedBy = RObjectReference.F_OWNER, orphanRemoval = true, cascade = ALL) public Set> getParentOrgRef() { if (parentOrgRef == null) { parentOrgRef = new HashSet<>(); @@ -184,15 +179,17 @@ public Set> getParentOrgRef() { } @NotQueryable - @OneToMany(fetch = FetchType.LAZY, targetEntity = ROrgClosure.class, mappedBy = "descendant") - @Cascade({ org.hibernate.annotations.CascadeType.DELETE }) + @OneToMany(fetch = FetchType.LAZY, targetEntity = ROrgClosure.class, mappedBy = "descendant", + cascade = CascadeType.REMOVE) +// @Cascade({ org.hibernate.annotations.CascadeType.DELETE }) public Set getDescendants() { return descendants; } @NotQueryable - @OneToMany(fetch = FetchType.LAZY, targetEntity = ROrgClosure.class, mappedBy = "ancestor")//, orphanRemoval = true) - @Cascade({ org.hibernate.annotations.CascadeType.DELETE }) + @OneToMany(fetch = FetchType.LAZY, targetEntity = ROrgClosure.class, mappedBy = "ancestor", + cascade = CascadeType.REMOVE)//, orphanRemoval = true) +// @Cascade({ org.hibernate.annotations.CascadeType.DELETE }) public Set getAncestors() { return ancestors; } @@ -214,8 +211,8 @@ public byte[] getFullObject() { } @Where(clause = RObjectReference.REFERENCE_TYPE + "= 5") - @OneToMany(mappedBy = RObjectReference.F_OWNER, orphanRemoval = true) - @Cascade({ org.hibernate.annotations.CascadeType.ALL }) + @OneToMany(mappedBy = RObjectReference.F_OWNER, orphanRemoval = true, cascade = ALL) +// @Cascade({ org.hibernate.annotations.CascadeType.ALL }) @JaxbPath(itemPath = { @JaxbName(localPart = "metadata"), @JaxbName(localPart = "createApproverRef") }) public Set> getCreateApproverRef() { if (createApproverRef == null) { @@ -225,9 +222,9 @@ public Set> getCreateApproverRef() { } @Where(clause = RObjectReference.REFERENCE_TYPE + "= 8") - @OneToMany(mappedBy = "owner", orphanRemoval = true) - @ForeignKey(name = "none") - @Cascade({ org.hibernate.annotations.CascadeType.ALL }) + @OneToMany(mappedBy = "owner", orphanRemoval = true, cascade = ALL) +// @ForeignKey(name = "none") +// @Cascade({ org.hibernate.annotations.CascadeType.ALL }) public Set> getRoleMembershipRef() { if (roleMembershipRef == null) { roleMembershipRef = new HashSet<>(); @@ -236,9 +233,9 @@ public Set> getRoleMembershipRef() { } @Where(clause = RObjectReference.REFERENCE_TYPE + "= 9") - @OneToMany(mappedBy = "owner", orphanRemoval = true) - @ForeignKey(name = "none") - @Cascade({ org.hibernate.annotations.CascadeType.ALL }) + @OneToMany(mappedBy = "owner", orphanRemoval = true, cascade = ALL) +// @ForeignKey(name = "none") +// @Cascade({ org.hibernate.annotations.CascadeType.ALL }) public Set> getDelegatedRef() { if (delegatedRef == null) { delegatedRef = new HashSet<>(); @@ -247,9 +244,9 @@ public Set> getDelegatedRef() { } @Where(clause = RObjectReference.REFERENCE_TYPE + "= 11") - @OneToMany(mappedBy = "owner", orphanRemoval = true) - @ForeignKey(name = "none") - @Cascade({ org.hibernate.annotations.CascadeType.ALL }) + @OneToMany(mappedBy = "owner", orphanRemoval = true, cascade = ALL) +// @ForeignKey(name = "none") +// @Cascade({ org.hibernate.annotations.CascadeType.ALL }) public Set> getArchetypeRef() { if (archetypeRef == null) { archetypeRef = new HashSet<>(); @@ -281,9 +278,9 @@ public Set getAssignment() { @JaxbPath(itemPath = @JaxbName(localPart = "assignment")) @JaxbPath(itemPath = @JaxbName(localPart = "inducement")) - @OneToMany(mappedBy = RAssignment.F_OWNER, orphanRemoval = true) - @ForeignKey(name = "none") - @Cascade({ org.hibernate.annotations.CascadeType.ALL }) + @OneToMany(mappedBy = RAssignment.F_OWNER, orphanRemoval = true, cascade = ALL) +// @ForeignKey(name = "none") +// @Cascade({ org.hibernate.annotations.CascadeType.ALL }) @NotQueryable // virtual definition is used instead public Set getAssignments() { if (assignments == null) { @@ -315,8 +312,8 @@ public REmbeddedReference getModifierRef() { } @Where(clause = RObjectReference.REFERENCE_TYPE + "= 6") - @OneToMany(mappedBy = RObjectReference.F_OWNER, orphanRemoval = true) - @Cascade({ org.hibernate.annotations.CascadeType.ALL }) + @OneToMany(mappedBy = RObjectReference.F_OWNER, orphanRemoval = true, cascade = ALL) +// @Cascade({ org.hibernate.annotations.CascadeType.ALL }) @JaxbPath(itemPath = { @JaxbName(localPart = "metadata"), @JaxbName(localPart = "modifyApproverRef") }) public Set> getModifyApproverRef() { if (modifyApproverRef == null) { @@ -336,49 +333,49 @@ public XMLGregorianCalendar getModifyTimestamp() { } @NotQueryable - @OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", orphanRemoval = true) + @OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", orphanRemoval = true, cascade = ALL) //@Cascade({ PERSIST, MERGE, REMOVE, REFRESH, DELETE, REPLICATE, LOCK, DETACH }) // not SAVE_UPDATE - @Cascade({ ALL }) +// @Cascade({ ALL }) public Collection getLongs() { return longs; } @NotQueryable - @OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", orphanRemoval = true) + @OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", orphanRemoval = true, cascade = ALL) //@Cascade({ PERSIST, MERGE, REMOVE, REFRESH, DELETE, REPLICATE, LOCK, DETACH }) // not SAVE_UPDATE - @Cascade({ ALL }) +// @Cascade({ ALL }) public Collection getBooleans() { return booleans; } @NotQueryable - @OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", orphanRemoval = true) + @OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", orphanRemoval = true, cascade = ALL) //@Cascade({ PERSIST, MERGE, REMOVE, REFRESH, DELETE, REPLICATE, LOCK, DETACH }) // not SAVE_UPDATE - @Cascade({ ALL }) +// @Cascade({ org.hibernate.annotations.CascadeType.ALL }) public Collection getStrings() { return strings; } @NotQueryable - @OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", orphanRemoval = true) + @OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", orphanRemoval = true, cascade = ALL) //@Cascade({ PERSIST, MERGE, REMOVE, REFRESH, DELETE, REPLICATE, LOCK, DETACH }) // not SAVE_UPDATE - @Cascade({ ALL }) +// @Cascade({ org.hibernate.annotations.CascadeType.ALL }) public Collection getDates() { return dates; } @NotQueryable - @OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", orphanRemoval = true) + @OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", orphanRemoval = true, cascade = ALL) //@Cascade({ PERSIST, MERGE, REMOVE, REFRESH, DELETE, REPLICATE, LOCK, DETACH }) // not SAVE_UPDATE - @Cascade({ ALL }) +// @Cascade({ org.hibernate.annotations.CascadeType.ALL }) public Collection getReferences() { return references; } @NotQueryable - @OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", orphanRemoval = true) + @OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", orphanRemoval = true, cascade = ALL) //@Cascade({ PERSIST, MERGE, REMOVE, REFRESH, DELETE, REPLICATE, LOCK, DETACH }) // not SAVE_UPDATE - @Cascade({ ALL }) +// @Cascade({ org.hibernate.annotations.CascadeType.ALL }) public Collection getPolys() { return polys; } @@ -391,9 +388,9 @@ public RObjectType getObjectTypeClass() { @ElementCollection @CollectionTable(name = "m_object_subtype", joinColumns = { - @JoinColumn(name = "object_oid", referencedColumnName = "oid", foreignKey = @javax.persistence.ForeignKey(name = "fk_object_subtype")) - }) - @Cascade({ org.hibernate.annotations.CascadeType.ALL }) + @JoinColumn(name = "object_oid", referencedColumnName = "oid", + foreignKey = @javax.persistence.ForeignKey(name = "fk_object_subtype")) }) +// @Cascade({ org.hibernate.annotations.CascadeType.ALL }) public Set getSubtype() { return subtype; } @@ -517,8 +514,8 @@ public void setBooleans(Collection booleans) { } @NotQueryable - @OneToMany(mappedBy = "owner", orphanRemoval = true) - @Cascade({ org.hibernate.annotations.CascadeType.ALL }) + @OneToMany(mappedBy = "owner", orphanRemoval = true, cascade = ALL) +// @Cascade({ org.hibernate.annotations.CascadeType.ALL }) public Set getTextInfoItems() { if (textInfoItems == null) { textInfoItems = new HashSet<>(); @@ -530,9 +527,9 @@ public void setTextInfoItems(Set textInfoItems) { this.textInfoItems = textInfoItems; } - @OneToMany(mappedBy = RAssignment.F_OWNER, orphanRemoval = true) - @ForeignKey(name = "none") - @Cascade({ org.hibernate.annotations.CascadeType.ALL }) + @OneToMany(mappedBy = RAssignment.F_OWNER, orphanRemoval = true, cascade = ALL) +// @ForeignKey(name = "none") +// @Cascade({ org.hibernate.annotations.CascadeType.ALL }) @JaxbName(localPart = "operationExecution") public Set getOperationExecutions() { if (operationExecutions == null) { @@ -562,6 +559,7 @@ public void setArchetypeRef(Set> archetypeRef) { this.archetypeRef = archetypeRef; } + /* TODO: remove in 2021, I believe id-based eq/hash is best for entities like this @Override public boolean equals(Object o) { if (this == o) { return true; } @@ -613,6 +611,25 @@ public int hashCode() { return result; } + */ + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + RObject rObject = (RObject) o; + return Objects.equals(oid, rObject.oid); + } + + @Override + public int hashCode() { + return Objects.hash(oid); + } static void copyAssignmentHolderInformationFromJAXB(AssignmentHolderType jaxb, RObject repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAccessCertificationCase.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAccessCertificationCase.java index 63bee1bdf45..256f8d21b6b 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAccessCertificationCase.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAccessCertificationCase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum and contributors + * 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. @@ -63,8 +63,6 @@ public class RAccessCertificationCase implements Container { +public class RAssignment implements Container, Metadata { public static final String F_OWNER = "owner"; - /** - * enum identifier of object class which owns this assignment. It's used because we have to - * distinguish between assignments and inducements (all of them are the same kind) in {@link com.evolveum.midpoint.repo.sql.data.common.RAbstractRole}. - */ - public static final String F_ASSIGNMENT_OWNER = "assignmentOwner"; - - private static final Trace LOGGER = TraceManager.getTrace(RAssignment.class); private Boolean trans; @@ -180,8 +151,8 @@ public REmbeddedReference getResourceRef() { } @com.evolveum.midpoint.repo.sql.query.definition.Any(jaxbNameLocalPart = "extension") - @OneToOne(optional = true, orphanRemoval = true) - @Cascade({org.hibernate.annotations.CascadeType.ALL}) + @OneToOne(orphanRemoval = true) + @Cascade({ org.hibernate.annotations.CascadeType.ALL }) @JoinColumns(value = { @JoinColumn(name = "extOid", referencedColumnName = "owner_owner_oid"), @JoinColumn(name = "extId", referencedColumnName = "owner_id") @@ -202,7 +173,7 @@ public Integer getOrder() { @Where(clause = RAssignmentReference.REFERENCE_TYPE + "= 0") @OneToMany(fetch = FetchType.LAZY, mappedBy = RAssignmentReference.F_OWNER, orphanRemoval = true) - @Cascade({org.hibernate.annotations.CascadeType.ALL}) + @Cascade({ org.hibernate.annotations.CascadeType.ALL }) @JaxbPath(itemPath = { @JaxbName(localPart = "metadata"), @JaxbName(localPart = "createApproverRef") }) public Set getCreateApproverRef() { if (createApproverRef == null) { @@ -235,7 +206,7 @@ public REmbeddedReference getModifierRef() { @Where(clause = RAssignmentReference.REFERENCE_TYPE + "= 1") @OneToMany(fetch = FetchType.LAZY, mappedBy = RAssignmentReference.F_OWNER, orphanRemoval = true) - @Cascade({org.hibernate.annotations.CascadeType.ALL}) + @Cascade({ org.hibernate.annotations.CascadeType.ALL }) @JaxbPath(itemPath = { @JaxbName(localPart = "metadata"), @JaxbName(localPart = "modifyApproverRef") }) public Set getModifyApproverRef() { if (modifyApproverRef == null) { @@ -268,10 +239,10 @@ public String getLifecycleState() { @CollectionTable(name = "m_assignment_policy_situation", foreignKey = @ForeignKey(name = "fk_assignment_policy_situation"), joinColumns = { - @JoinColumn(name = "assignment_oid", referencedColumnName = "owner_oid"), - @JoinColumn(name = "assignment_id", referencedColumnName = "id") - }) - @Cascade({org.hibernate.annotations.CascadeType.ALL}) + @JoinColumn(name = "assignment_oid", referencedColumnName = "owner_oid"), + @JoinColumn(name = "assignment_id", referencedColumnName = "id") + }) + @Cascade({ org.hibernate.annotations.CascadeType.ALL }) public Set getPolicySituation() { return policySituation; } @@ -280,7 +251,6 @@ public void setPolicySituation(Set policySituation) { this.policySituation = policySituation; } - public void setLifecycleState(String lifecycleState) { this.lifecycleState = lifecycleState; } @@ -382,27 +352,30 @@ public void setResourceRef(REmbeddedReference resourceRef) { this.resourceRef = resourceRef; } + /* @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { return true; } + if (o == null || getClass() != o.getClass()) { return false; } RAssignment that = (RAssignment) o; - if (activation != null ? !activation.equals(that.activation) : that.activation != null) return false; - if (extension != null ? !extension.equals(that.extension) : that.extension != null) return false; - if (targetRef != null ? !targetRef.equals(that.targetRef) : that.targetRef != null) return false; - if (assignmentOwner != null ? !assignmentOwner.equals(that.assignmentOwner) : that.assignmentOwner != null) + if (activation != null ? !activation.equals(that.activation) : that.activation != null) { return false; } + if (extension != null ? !extension.equals(that.extension) : that.extension != null) { return false; } + if (targetRef != null ? !targetRef.equals(that.targetRef) : that.targetRef != null) { return false; } + if (assignmentOwner != null ? !assignmentOwner.equals(that.assignmentOwner) : that.assignmentOwner != null) { return false; - if (order != null ? !order.equals(that.order) : that.order != null) + } + if (order != null ? !order.equals(that.order) : that.order != null) { return false; } + if (tenantRef != null ? !tenantRef.equals(that.tenantRef) : that.tenantRef != null) { return false; } + if (orgRef != null ? !orgRef.equals(that.orgRef) : that.orgRef != null) { return false; } + if (resourceRef != null ? !resourceRef.equals(that.resourceRef) : that.resourceRef != null) { return false; } + if (lifecycleState != null ? !lifecycleState.equals(that.lifecycleState) : that.lifecycleState != null) { return false; } + if (policySituation != null ? !policySituation.equals(that.policySituation) : that.policySituation != null) { return false; - if (tenantRef != null ? !tenantRef.equals(that.tenantRef) : that.tenantRef != null) return false; - if (orgRef != null ? !orgRef.equals(that.orgRef) : that.orgRef != null) return false; - if (resourceRef != null ? !resourceRef.equals(that.resourceRef) : that.resourceRef != null) return false; - if (lifecycleState != null ? !lifecycleState.equals(that.lifecycleState) : that.lifecycleState != null) return false; - if (policySituation != null ? !policySituation.equals(that.policySituation) : that.policySituation != null) return false; + } - if (!MetadataFactory.equals(this, that)) return false; + if (!MetadataFactory.equals(this, that)) { return false; } return true; } @@ -423,9 +396,29 @@ public int hashCode() { return result; } + */ + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof RAssignment)) { + return false; + } + + RAssignment that = (RAssignment) o; + return Objects.equals(ownerOid, that.ownerOid) + && Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return Objects.hash(ownerOid, id); + } public static void fromJaxb(AssignmentType jaxb, RAssignment repo, RObject parent, - RepositoryContext repositoryContext) throws DtoTranslationException{ + RepositoryContext repositoryContext) throws DtoTranslationException { fromJaxb(jaxb, repo, repositoryContext, null); repo.setOwner(parent); } @@ -437,7 +430,7 @@ public static void fromJaxb(AssignmentType jaxb, RAssignment repo, ObjectType pa } private static void fromJaxb(AssignmentType jaxb, RAssignment repo, RepositoryContext repositoryContext, - IdGeneratorResult generatorResult) throws DtoTranslationException { + IdGeneratorResult generatorResult) throws DtoTranslationException { Validate.notNull(repo, "Repo object must not be null."); Validate.notNull(jaxb, "JAXB object must not be null."); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/ROperationExecution.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/ROperationExecution.java index 82ed27f932f..56aa274b702 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/ROperationExecution.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/ROperationExecution.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum and contributors + * 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. @@ -7,6 +7,14 @@ package com.evolveum.midpoint.repo.sql.data.common.container; +import java.util.Objects; +import javax.persistence.*; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Persister; +import org.jetbrains.annotations.NotNull; + import com.evolveum.midpoint.repo.sql.data.RepositoryContext; import com.evolveum.midpoint.repo.sql.data.common.RObject; import com.evolveum.midpoint.repo.sql.data.common.embedded.REmbeddedReference; @@ -21,21 +29,9 @@ import com.evolveum.midpoint.repo.sql.util.IdGeneratorResult; import com.evolveum.midpoint.repo.sql.util.MidPointSingleTablePersister; import com.evolveum.midpoint.repo.sql.util.RUtil; -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; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationExecutionType; -import org.hibernate.annotations.GenericGenerator; -import org.hibernate.annotations.Persister; -import org.jetbrains.annotations.NotNull; -import javax.persistence.*; -import javax.xml.datatype.XMLGregorianCalendar; -import java.util.Objects; - -/** - * @author mederly - */ @JaxbType(type = OperationExecutionType.class) @Entity @QueryEntity @@ -45,14 +41,10 @@ @Index(name = "iOpExecInitiatorOid", columnList = "initiatorRef_targetOid"), @Index(name = "iOpExecStatus", columnList = "status"), @Index(name = "iOpExecStatus", columnList = "status"), - @Index(name = "iOpExecOwnerOid", columnList = "owner_oid")}) + @Index(name = "iOpExecOwnerOid", columnList = "owner_oid") }) @Persister(impl = MidPointSingleTablePersister.class) public class ROperationExecution implements Container { - public static final String F_OWNER = "owner"; - - private static final Trace LOGGER = TraceManager.getTrace(ROperationExecution.class); - private Boolean trans; private RObject owner; @@ -160,42 +152,21 @@ public void setTransient(Boolean trans) { this.trans = trans; } - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (!(o instanceof ROperationExecution)) - return false; - ROperationExecution that = (ROperationExecution) o; - return Objects.equals(trans, that.trans) && - Objects.equals(getOwnerOid(), that.getOwnerOid()) && - Objects.equals(id, that.id) && - Objects.equals(initiatorRef, that.initiatorRef) && - Objects.equals(taskRef, that.taskRef) && - Objects.equals(timestamp, that.timestamp) && - status == that.status; - } - - @Override - public int hashCode() { - return Objects.hash(trans, getOwnerOid(), id, initiatorRef, taskRef, status); - } - public static void fromJaxb(@NotNull OperationExecutionType jaxb, @NotNull ROperationExecution repo, - RObject parent, RepositoryContext repositoryContext) throws DtoTranslationException { + RObject parent, RepositoryContext repositoryContext) throws DtoTranslationException { repo.setOwner(parent); fromJaxb(jaxb, repo, repositoryContext, null); } public static void fromJaxb(@NotNull OperationExecutionType jaxb, @NotNull ROperationExecution repo, ObjectType parent, RepositoryContext repositoryContext, - IdGeneratorResult generatorResult) throws DtoTranslationException { + IdGeneratorResult generatorResult) { repo.setOwnerOid(parent.getOid()); fromJaxb(jaxb, repo, repositoryContext, generatorResult); } private static void fromJaxb(@NotNull OperationExecutionType jaxb, @NotNull ROperationExecution repo, - RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { + RepositoryContext repositoryContext, IdGeneratorResult generatorResult) { if (generatorResult != null) { repo.setTransient(generatorResult.isTransient(jaxb.asPrismContainerValue())); } @@ -206,6 +177,25 @@ private static void fromJaxb(@NotNull OperationExecutionType jaxb, @NotNull ROpe repo.setTimestamp(jaxb.getTimestamp()); } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof ROperationExecution)) { + return false; + } + + ROperationExecution that = (ROperationExecution) o; + return Objects.equals(ownerOid, that.ownerOid) + && Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return Objects.hash(ownerOid, id); + } + @Override public String toString() { return "ROperationExecution{" + diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RTrigger.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RTrigger.java index 2592ce3a48d..65489903765 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RTrigger.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RTrigger.java @@ -1,11 +1,18 @@ /* - * Copyright (c) 2010-2019 Evolveum and contributors + * 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.repo.sql.data.common.container; +import java.util.Objects; +import javax.persistence.*; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.apache.commons.lang.Validate; +import org.hibernate.annotations.GenericGenerator; + import com.evolveum.midpoint.repo.sql.data.RepositoryContext; import com.evolveum.midpoint.repo.sql.data.common.RObject; import com.evolveum.midpoint.repo.sql.data.common.id.RContainerId; @@ -18,16 +25,11 @@ import com.evolveum.midpoint.repo.sql.util.RUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.TriggerType; -import org.apache.commons.lang.Validate; -import org.hibernate.annotations.GenericGenerator; - -import javax.persistence.*; -import javax.xml.datatype.XMLGregorianCalendar; @JaxbType(type = TriggerType.class) @Entity @IdClass(RContainerId.class) -@Table(indexes = {@Index(name = "iTriggerTimestamp", columnList = RTrigger.C_TIMESTAMP)}) +@Table(indexes = { @Index(name = "iTriggerTimestamp", columnList = RTrigger.C_TIMESTAMP) }) public class RTrigger implements Container { public static final String F_OWNER = "owner"; @@ -120,28 +122,24 @@ public void setHandlerUri(String handlerUri) { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (!(o instanceof RTrigger)) { + return false; + } RTrigger that = (RTrigger) o; - - if (handlerUri != null ? !handlerUri.equals(that.handlerUri) : - that.handlerUri != null) return false; - if (timestamp != null ? !timestamp.equals(that.timestamp) : - that.timestamp != null) return false; - - return true; + return Objects.equals(ownerOid, that.ownerOid) + && Objects.equals(id, that.id); } @Override public int hashCode() { - int result = handlerUri != null ? handlerUri.hashCode() : 0; - result = 31 * result + (timestamp != null ? timestamp.hashCode() : 0); - return result; + return Objects.hash(ownerOid, id); } - public static void copyToJAXB(RTrigger repo, TriggerType jaxb) throws - DtoTranslationException { + public static void copyToJAXB(RTrigger repo, TriggerType jaxb) { Validate.notNull(repo, "Repo object must not be null."); Validate.notNull(jaxb, "JAXB object must not be null."); @@ -158,14 +156,13 @@ public static void fromJaxb(TriggerType jaxb, RTrigger repo, RObject parent, } public static void fromJaxb(TriggerType jaxb, RTrigger repo, ObjectType parent, - RepositoryContext repositoryContext, IdGeneratorResult generatorResult) - throws DtoTranslationException { + RepositoryContext repositoryContext, IdGeneratorResult generatorResult) { repo.setOwnerOid(parent.getOid()); fromJaxb(jaxb, repo, repositoryContext, generatorResult); } private static void fromJaxb(TriggerType jaxb, RTrigger repo, RepositoryContext repositoryContext, - IdGeneratorResult generatorResult) throws DtoTranslationException { + IdGeneratorResult generatorResult) { Validate.notNull(repo, "Repo object must not be null."); Validate.notNull(jaxb, "JAXB object must not be null."); @@ -179,7 +176,7 @@ private static void fromJaxb(TriggerType jaxb, RTrigger repo, RepositoryContext repo.setTimestamp(jaxb.getTimestamp()); } - public TriggerType toJAXB() throws DtoTranslationException { + public TriggerType toJAXB() { TriggerType object = new TriggerType(); RTrigger.copyToJAXB(this, object); return object; diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/id/RContainerId.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/id/RContainerId.java index 00e2531f6a4..04c5bc2c49c 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/id/RContainerId.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/id/RContainerId.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum and contributors + * 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. @@ -8,22 +8,17 @@ package com.evolveum.midpoint.repo.sql.data.common.id; import java.io.Serializable; +import java.util.Objects; -/** - * @author lazyman - */ public class RContainerId implements Serializable { private String ownerOid; private Integer id; + @SuppressWarnings("unused") public RContainerId() { } - public RContainerId(String oid) { - this(0, oid); - } - public RContainerId(Integer id, String oid) { this.id = id; this.ownerOid = oid; @@ -47,22 +42,21 @@ public void setOwnerOid(String oid) { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (!(o instanceof RContainerId)) { + return false; + } RContainerId that = (RContainerId) o; - - if (id != null ? !id.equals(that.id) : that.id != null) return false; - if (ownerOid != null ? !ownerOid.equals(that.ownerOid) : that.ownerOid != null) return false; - - return true; + return Objects.equals(ownerOid, that.ownerOid) + && Objects.equals(id, that.id); } @Override public int hashCode() { - int result = ownerOid != null ? ownerOid.hashCode() : 0; - result = 31 * result + (id != null ? id.hashCode() : 0); - return result; + return Objects.hash(ownerOid, id); } @Override diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/other/RLookupTableRow.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/other/RLookupTableRow.java index 7c2ad24236e..6ac32806b43 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/other/RLookupTableRow.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/other/RLookupTableRow.java @@ -1,11 +1,18 @@ /* - * Copyright (c) 2010-2019 Evolveum and contributors + * 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.repo.sql.data.common.other; +import java.util.Date; +import java.util.Objects; +import javax.persistence.*; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.hibernate.annotations.GenericGenerator; + import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.repo.sql.data.common.RLookupTable; import com.evolveum.midpoint.repo.sql.data.common.container.Container; @@ -19,25 +26,11 @@ import com.evolveum.midpoint.repo.sql.util.RUtil; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableRowType; -import org.hibernate.annotations.GenericGenerator; - -import javax.persistence.*; -import javax.xml.datatype.XMLGregorianCalendar; -import java.util.Date; -/** - * @author Viliam Repan (lazyman) - */ @Ignore @Entity -@Table(indexes = { -//todo create indexes after lookup api is created (when we know how we will search through lookup table [lazyman] -// @Index(name = "iRowKey", columnList = "key"), -// @Index(name = "iRowLabelOrig", columnList = "label.orig"), -// @Index(name = "iRowLabelNorm", columnList = "label.norm") -}, -uniqueConstraints = { - @UniqueConstraint(name = "uc_row_key", columnNames = {"owner_oid", "row_key"}) +@Table(uniqueConstraints = { + @UniqueConstraint(name = "uc_row_key", columnNames = { "owner_oid", "row_key" }) }) @IdClass(RContainerId.class) public class RLookupTableRow implements Container { @@ -75,6 +68,7 @@ public String getOwnerOid() { } public static final String ID_COLUMN_NAME = "id"; + @Id @GeneratedValue(generator = "ContainerIdGenerator") @GenericGenerator(name = "ContainerIdGenerator", strategy = "com.evolveum.midpoint.repo.sql.util.ContainerIdGenerator") @@ -145,31 +139,6 @@ public void setTransient(Boolean trans) { this.trans = trans; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - RLookupTableRow that = (RLookupTableRow) o; - - if (key != null ? !key.equals(that.key) : that.key != null) return false; - if (label != null ? !label.equals(that.label) : that.label != null) return false; - if (lastChangeTimestamp != null ? !lastChangeTimestamp.equals(that.lastChangeTimestamp) : that.lastChangeTimestamp != null) - return false; - if (value != null ? !value.equals(that.value) : that.value != null) return false; - - return true; - } - - @Override - public int hashCode() { - int result = key != null ? key.hashCode() : 0; - result = 31 * result + (value != null ? value.hashCode() : 0); - result = 31 * result + (label != null ? label.hashCode() : 0); - result = 31 * result + (lastChangeTimestamp != null ? lastChangeTimestamp.hashCode() : 0); - return result; - } - public LookupTableRowType toJAXB(PrismContext prismContext) { LookupTableRowType row = new LookupTableRowType(); row.setId(Long.valueOf(id)); @@ -212,6 +181,25 @@ private static RLookupTableRow toRepo(LookupTableRowType row) throws SchemaExcep return rRow; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof RLookupTableRow)) { + return false; + } + + RLookupTableRow that = (RLookupTableRow) o; + return Objects.equals(ownerOid, that.ownerOid) + && Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return Objects.hash(ownerOid, id); + } + @Override public String toString() { return "RLookupTableRow{" +