From 18fa2adc0ba74ba1eb922a33f9ffae4bb2cb0bfd Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Thu, 14 Sep 2017 09:40:05 +0200 Subject: [PATCH 01/97] supprt for multivalue containers --- .../gui/api/util/WebComponentUtil.java | 92 +- .../PolicyRuleConstraintsExpandablePanel.java | 2 +- .../FocusProjectionsTabPanel.java | 4 +- .../component/prism/AssociationWrapper.java | 2 +- .../component/prism/ContainerValuePanel.html | 27 + .../component/prism/ContainerValuePanel.java | 173 ++++ .../prism/ContainerValueWrapper.java | 744 +++++++++++++++ .../web/component/prism/ContainerWrapper.java | 421 +++++---- .../prism/ContainerWrapperFactory.java | 858 ++++++++++-------- .../web/component/prism/ItemWrapper.java | 8 +- .../prism/ItemWrapperComparator.java | 20 +- .../web/component/prism/ObjectWrapper.java | 153 ++-- .../component/prism/ObjectWrapperFactory.java | 81 +- .../component/prism/PrismContainerPanel.html | 11 +- .../component/prism/PrismContainerPanel.java | 87 +- .../web/component/prism/PrismHeaderPanel.java | 58 +- .../web/component/prism/PrismObjectPanel.html | 4 +- .../web/component/prism/PrismObjectPanel.java | 6 +- .../component/prism/PrismPropertyPanel.java | 27 +- .../web/component/prism/PrismValuePanel.java | 103 +-- .../web/component/prism/PrismWrapper.java | 43 + .../prism/PropertyOrReferenceWrapper.java | 54 +- .../web/component/prism/PropertyWrapper.java | 43 +- .../web/component/prism/ReferenceWrapper.java | 2 +- .../web/page/admin/PageAdminFocus.java | 2 +- .../web/page/admin/users/PageUserHistory.java | 34 +- 26 files changed, 2206 insertions(+), 853 deletions(-) create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValuePanel.html create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValuePanel.java create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismWrapper.java diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java index 38ab6974401..5b7c7a863e9 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java @@ -25,7 +25,16 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.text.SimpleDateFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; import java.util.stream.Collectors; import javax.xml.datatype.DatatypeConfigurationException; @@ -33,14 +42,6 @@ import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; -import com.evolveum.midpoint.gui.api.SubscriptionType; -import com.evolveum.midpoint.model.api.ModelExecuteOptions; -import com.evolveum.midpoint.schema.GetOperationOptions; -import com.evolveum.midpoint.schema.SelectorOptions; -import com.evolveum.midpoint.web.component.prism.InputPanel; -import com.evolveum.midpoint.web.util.ObjectTypeGuiDescriptor; -import com.evolveum.midpoint.xml.ns._public.common.common_3.*; - import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; @@ -65,7 +66,11 @@ import org.apache.wicket.feedback.IFeedback; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; -import org.apache.wicket.markup.html.form.*; +import org.apache.wicket.markup.html.form.CheckBox; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.form.FormComponent; +import org.apache.wicket.markup.html.form.IChoiceRenderer; +import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.model.AbstractReadOnlyModel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.StringResourceModel; @@ -78,10 +83,13 @@ import org.joda.time.format.DateTimeFormat; import com.evolveum.midpoint.gui.api.GuiStyleConstants; +import com.evolveum.midpoint.gui.api.SubscriptionType; import com.evolveum.midpoint.gui.api.component.MainObjectListPanel; import com.evolveum.midpoint.gui.api.model.LoadableModel; import com.evolveum.midpoint.gui.api.model.NonEmptyModel; import com.evolveum.midpoint.gui.api.page.PageBase; +import com.evolveum.midpoint.model.api.ModelExecuteOptions; +import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.Objectable; import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismContainerValue; @@ -113,7 +121,9 @@ import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.schema.DeltaConvertor; +import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SchemaConstantsGenerated; +import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; @@ -139,6 +149,7 @@ import com.evolveum.midpoint.web.component.data.column.ColumnMenuAction; import com.evolveum.midpoint.web.component.input.DisplayableValueChoiceRenderer; import com.evolveum.midpoint.web.component.input.DropDownChoicePanel; +import com.evolveum.midpoint.web.component.prism.InputPanel; import com.evolveum.midpoint.web.component.util.Selectable; import com.evolveum.midpoint.web.component.util.SelectableBean; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; @@ -164,7 +175,46 @@ import com.evolveum.midpoint.web.session.UserProfileStorage.TableId; import com.evolveum.midpoint.web.util.DateValidator; import com.evolveum.midpoint.web.util.InfoTooltipBehavior; +import com.evolveum.midpoint.web.util.ObjectTypeGuiDescriptor; import com.evolveum.midpoint.web.util.OnePageParameterEncoder; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationDefinitionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AvailabilityStatusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ConstructionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ExclusionPolicyConstraintType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.MisfireActionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultStatusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationalStateType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PersonaConstructionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyRuleType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ScheduleType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ServiceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemObjectsType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskBindingType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskExecutionStatusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskRecurrenceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ThreadStopActionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserInterfaceElementVisibilityType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemType; import com.evolveum.prism.xml.ns._public.query_3.QueryType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType; @@ -808,6 +858,28 @@ public static String getName(PrismObject object) { return name != null ? name.getOrig() : null; } + + public static String getDisplayName(PrismContainerValue prismContainerValue) { + if (prismContainerValue == null || prismContainerValue.isEmpty()) { + return "prismContainerValue.new"; + } + + C containerable = prismContainerValue.asContainerable(); + + if (containerable instanceof AssignmentType && ((AssignmentType) containerable).getTargetRef() != null) { + ObjectReferenceType assignemntTargetRef = ((AssignmentType) containerable).getTargetRef(); + return getName(assignemntTargetRef) + " - " + assignemntTargetRef.getRelation(); + } + + if (containerable instanceof ExclusionPolicyConstraintType){ + ExclusionPolicyConstraintType exclusionContraint = (ExclusionPolicyConstraintType) containerable; + String displayName = exclusionContraint.getName() + "-" + getName(exclusionContraint.getTargetRef()); + return StringUtils.isNotEmpty(displayName) ? displayName : "Not defined exclusion name"; + } + + return "Impelement in WebComponentUtil.getName(PrismContainerValue prismContainerValue"; + + } public static String getDisplayNameOrName(PrismObject object) { if (object == null) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleConstraintsExpandablePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleConstraintsExpandablePanel.java index 5887e723818..793e4d4cf01 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleConstraintsExpandablePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleConstraintsExpandablePanel.java @@ -43,7 +43,7 @@ private void initContainerWrapper(){ PolicyConstraintsType.F_EXCLUSION); // if (exclusionContainer != null) { - policyRuleConstraintsContainerWrapper = cwf.createCustomContainerWrapper(getModelObject(), ContainerStatus.MODIFYING, exclusionContainerPath, false, true); + policyRuleConstraintsContainerWrapper = cwf.createContainerWrapper(getModelObject().asPrismContainerValue().getContainer(), ContainerStatus.MODIFYING, exclusionContainerPath, true); // } else { // exclusionContainer = containerDef.instantiate(); // containerWrapper = cwf.createContainerWrapper(exclusionContainer, ContainerStatus.ADDING, exclusionContainerPath, false); 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 ae75705e1f3..cc52bed14fb 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 @@ -433,7 +433,7 @@ private void updateShadowActivation(AjaxRequestTarget target, } PropertyWrapper enabledProperty = (PropertyWrapper) activation - .findPropertyWrapper(ActivationType.F_ADMINISTRATIVE_STATUS); + .findPropertyWrapper(new ItemPath(ActivationType.F_ADMINISTRATIVE_STATUS)); if (enabledProperty == null || enabledProperty.getValues().size() != 1) { warn(getString("pageAdminFocus.message.noEnabledPropertyFound", wrapper.getDisplayName())); continue; @@ -469,7 +469,7 @@ private void unlockShadowPerformed(AjaxRequestTarget target, continue; } - PropertyWrapper lockedProperty = activation.findPropertyWrapper(ActivationType.F_LOCKOUT_STATUS); + PropertyWrapper lockedProperty = activation.findPropertyWrapper(new ItemPath(ActivationType.F_LOCKOUT_STATUS)); if (lockedProperty == null || lockedProperty.getValues().size() != 1) { warn(getString("pageAdminFocus.message.noLockoutStatusPropertyFound", wrapper.getDisplayName())); continue; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/AssociationWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/AssociationWrapper.java index 6888f9e70b5..544bdfa3aa8 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/AssociationWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/AssociationWrapper.java @@ -34,7 +34,7 @@ public class AssociationWrapper extends PropertyWrapper container, PrismContainer property, + public AssociationWrapper(ContainerValueWrapper container, PrismContainer property, boolean readonly, ValueStatus status, RefinedAssociationDefinition assocRDef) { super(container, property, readonly, status); this.assocRDef = assocRDef; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValuePanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValuePanel.html new file mode 100644 index 00000000000..df7935a8a82 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValuePanel.html @@ -0,0 +1,27 @@ + + + + + +
+
+
+
+
+
+ + diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValuePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValuePanel.java new file mode 100644 index 00000000000..2c4b21f6aaa --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValuePanel.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.web.component.prism; + +import java.util.List; + +import org.apache.wicket.AttributeModifier; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.list.ListItem; +import org.apache.wicket.markup.html.list.ListView; +import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.model.AbstractReadOnlyModel; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.PropertyModel; + +import com.evolveum.midpoint.gui.api.page.PageBase; +import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.prism.PrismContainer; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; + +/** + * @author lazyman + * @author semancik + */ +public class ContainerValuePanel extends Panel { + private static final long serialVersionUID = 1L; + + private static final Trace LOGGER = TraceManager.getTrace(ContainerValuePanel.class); + private static final String ID_HEADER = "header"; + private static final String STRIPED_CLASS = "striped"; + + private PageBase pageBase; + + public ContainerValuePanel(String id, final IModel model, boolean showHeader, Form form, PageBase pageBase) { + super(id, model); + setOutputMarkupId(true); + this.pageBase = pageBase; + + LOGGER.trace("Creating container panel for {}", model.getObject()); + + add(new VisibleEnableBehaviour() { + private static final long serialVersionUID = 1L; + + @Override + public boolean isVisible() { + ContainerValueWrapper containerValueWrapper = model.getObject(); + return containerValueWrapper.isItemVisible(); +// PrismContainer prismContainer = containerWrapper.getItem(); +// if (containerWrapper.getItemDefinition().isOperational()) { +// return false; +// } +// +// // HACK HACK HACK +// if (ShadowType.F_ASSOCIATION.equals(prismContainer.getElementName())) { +// return true; +// } + +// containerValueWrapper.is +// boolean isVisible = false; +// for (ItemWrapper item : containerValueWrapper.getItems()) { +// if (containerValueWrapper.isItemVisible(item)) { +// isVisible = true; +// break; +// } +// } + +// return !containerValueWrapper.getItems().isEmpty() && isVisible; +// return true; + } + }); + + initLayout(model, form, showHeader); + } + + private void initLayout(final IModel model, final Form form, boolean showHeader) { + PrismHeaderPanel header = new PrismHeaderPanel(ID_HEADER, model) { + private static final long serialVersionUID = 1L; + + @Override + protected void onButtonClick(AjaxRequestTarget target) { + addOrReplaceProperties(model, form, true); + target.add(ContainerValuePanel.this.findParent(PrismObjectPanel.class)); + } + + @Override + public boolean isButtonsVisible() { + return true; + } + + }; + header.add(new VisibleEnableBehaviour() { + private static final long serialVersionUID = 1L; + + @Override + public boolean isVisible() { + return showHeader;// && !model.getObject().isMain(); + } + }); + add(header); + + addOrReplaceProperties(model, form, false); + } + + public PageBase getPageBase(){ + return pageBase; + } + + private IModel createStyleClassModel(final IModel wrapper) { + return new AbstractReadOnlyModel() { + private static final long serialVersionUID = 1L; + + @Override + public String getObject() { + ItemWrapper property = wrapper.getObject(); + return property.isStripe() ? "stripe" : null; + } + }; + } + + private void addOrReplaceProperties(IModel model, final Form form, boolean isToBeReplaced){ + ListView properties = new ListView("properties", + new PropertyModel>(model, "properties")) { + private static final long serialVersionUID = 1L; + + @Override + protected void populateItem(final ListItem item) { + if (item.getModel().getObject() instanceof ContainerWrapper) { + PrismContainerPanel containerPanel = new PrismContainerPanel("property", (IModel) item.getModel(), true, form, pageBase); + containerPanel.setOutputMarkupId(true); + item.add(containerPanel); + return; + } + + PrismPropertyPanel propertyPanel = new PrismPropertyPanel("property", item.getModel(), form, pageBase); + propertyPanel.setOutputMarkupId(true); + item.add(propertyPanel); + item.add(new VisibleEnableBehaviour() { + private static final long serialVersionUID = 1L; + + @Override + public boolean isVisible() { + return item.getModel().getObject().isVisible(model.getObject().isShowEmpty()); + } + }); + item.add(AttributeModifier.append("class", createStyleClassModel((IModel) item.getModel()))); + } + }; + properties.setReuseItems(true); + if (isToBeReplaced) { + replace(properties); + } else { + add(properties); + } + } +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java new file mode 100644 index 00000000000..bfa9424eb8e --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java @@ -0,0 +1,744 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.web.component.prism; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import javax.xml.namespace.QName; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; +import org.apache.commons.lang.math.NumberUtils; +import org.jetbrains.annotations.Nullable; + +import com.evolveum.midpoint.gui.api.page.PageBase; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.prism.Item; +import com.evolveum.midpoint.prism.ItemDefinition; +import com.evolveum.midpoint.prism.PrismContainerDefinition; +import com.evolveum.midpoint.prism.PrismContainerValue; +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.PrismPropertyDefinition; +import com.evolveum.midpoint.prism.PrismReferenceDefinition; +import com.evolveum.midpoint.prism.PrismValue; +import com.evolveum.midpoint.prism.delta.ItemDelta; +import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.prism.delta.ReferenceDelta; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.util.DebugDumpable; +import com.evolveum.midpoint.util.DebugUtil; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; + +/** + * @author lazyman + */ +public class ContainerValueWrapper extends PrismWrapper implements Serializable, DebugDumpable { + + private static final Trace LOGGER = TraceManager.getTrace(ContainerValueWrapper.class); + +// private String displayName; + private ContainerWrapper containerWrapper; + private PrismContainerValue containerValue; + private ValueStatus status; + + private boolean main; + private ItemPath path; + private List properties; + + private boolean readonly; + private boolean showInheritedObjectAttributes; + +// private PrismContainerDefinition containerDefinition; + + + ContainerValueWrapper(ContainerWrapper containerWrapper, PrismContainerValue containerValue, ValueStatus status, ItemPath path) { +// Validate.notNull(containerValue, "container must not be null."); +// super(containerWrapper, containerValue, status); + Validate.notNull(status, "Container status must not be null."); + + this.containerWrapper = containerWrapper; + this.containerValue = containerValue; + this.status = status; + this.path = path; + this.main = path == null; + this.readonly = containerWrapper.isReadonly(); // [pm] this is quite questionable + this.showInheritedObjectAttributes = containerWrapper.isShowInheritedObjectAttributes(); + // have to be after setting "main" property +// this.containerDefinition = getItemDefinition(); + } + + ContainerValueWrapper(PrismContainerValue container, ValueStatus status, ItemPath path, boolean readOnly, boolean showInheritedObjectAttributes) { +// super(null, container); + Validate.notNull(container, "container must not be null."); + Validate.notNull(container.getParent().getDefinition(), "container definition must not be null."); + Validate.notNull(status, "Container status must not be null."); + + this.containerValue = container; +// this.containerDefinition = container.getParent().getDefinition(); + this.status = status; + this.path = path; + this.main = path == null; + this.readonly = readOnly; + this.showInheritedObjectAttributes = showInheritedObjectAttributes; + } + + public PrismContainerDefinition getDefinition() { + return containerValue.getParent().getDefinition(); + } + + public void revive(PrismContext prismContext) throws SchemaException { + if (containerValue != null) { + containerValue.revive(prismContext); + } + if (getDefinition() != null) { + getDefinition().revive(prismContext); + } + if (properties != null) { + for (ItemWrapper itemWrapper : properties) { + itemWrapper.revive(prismContext); + } + } + } + +// @Override +// public PrismContainerDefinition getItemDefinition() { +// if (containerDefinition != null) { +// return containerDefinition; +// } +// if (main) { +// return containerWrapper.getItemDefinition(); +// } else { +// return containerWrapper.getItemDefinition().findContainerDefinition(path); +// } +// } + + @Nullable + ContainerWrapper getContainer() { + return containerWrapper; + } + + public ValueStatus getStatus() { + return status; + } + + public ItemPath getPath() { + return path; + } + + public PrismContainerValue getContainerValue() { + return containerValue; + } + + public List getItems() { + if (properties == null) { + properties = new ArrayList<>(); + } + return properties; + } + + public void setProperties(List properties) { + this.properties = properties; + } + + + + // TODO: refactor this. Why it is not in the itemWrapper? + boolean isItemVisible(ItemWrapper item) { + ItemDefinition def = item.getItemDefinition(); + if (def.isIgnored() || def.isOperational()) { + return false; + } + + if (def instanceof PrismPropertyDefinition && skipProperty((PrismPropertyDefinition) def)) { + return false; + } + + // we decide not according to status of this container, but according to + // the status of the whole object + if (containerWrapper != null && containerWrapper.getStatus() == ContainerStatus.ADDING) { + + return (def.canAdd() && def.isEmphasized()) + || (def.canAdd() && showEmpty(item)); + } + + // otherwise, object.getStatus() is MODIFYING + + if (def.canModify()) { + return showEmpty(item); + } else { + if (def.canRead()) { + return showEmpty(item); + } + return false; + } + } + + boolean isItemVisible() { +// ItemDefinition def = item.getItemDefinition(); +// PrismContainerDefinition def = get +// if (def.isIgnored() || def.isOperational()) { +// return false; +// } + +// if (def instanceof PrismPropertyDefinition && skipProperty((PrismPropertyDefinition) def)) { +// return false; +// } + + // we decide not according to status of this container, but according to + // the status of the whole object +// if (containerWrapper != null && containerWrapper.getStatus() == ContainerStatus.ADDING) { +// +// return (def.canAdd() && def.isEmphasized()) +// || (def.canAdd() && showEmpty(item)); +// } + + switch (status) { + case ADDED: + return (getDefinition().isEmphasized() || isShowEmpty()) && getDefinition().canAdd(); + case NOT_CHANGED: +// getItems().forEach(i -> ); + return ((getDefinition().canModify()) || getDefinition().canRead()); + default: + break; + } + + for (ItemWrapper item : getItems()) { + if (item.isVisible(isShowEmpty())) { + return true; + } + } + + // otherwise, object.getStatus() is MODIFYING + +// if (def.canModify()) { +// return showEmpty(item); +// } else { +// if (def.canRead()) { +// return showEmpty(item); +// } +// return false; +// } + return false; + } + + public void computeStripes() { + int visibleProperties = 0; + for (ItemWrapper item: properties) { + if (item.isVisible(isShowEmpty())) { + visibleProperties++; + } + if (visibleProperties % 2 == 0) { + item.setStripe(true); + } else { + item.setStripe(false); + } + } + } + + public boolean isShowInheritedObjectAttributes() { + return showInheritedObjectAttributes; + } + + private boolean showEmpty(ItemWrapper item) { + // make sure that emphasized state is evaluated after the normal definitions are considered + // we do not want to display emphasized property if the user does not have an access to it. + // MID-3206 + if (item.getItemDefinition().isEmphasized()) { + return true; + } +// ContainerWrapper objectWrapper = getContainer(); + List valueWrappers = item.getValues(); + boolean isEmpty; + if (valueWrappers == null) { + isEmpty = true; + } else { + isEmpty = valueWrappers.isEmpty(); + } +// if (!isEmpty && valueWrappers.size() == 1) { +// ValueWrapper value = valueWrappers.get(0); +// if (ValueStatus.ADDED.equals(value.getStatus())) { +// isEmpty = true; +// } +// } + return (containerWrapper.isShowEmpty()) || !isEmpty; + } + +// @Override +// public String getDisplayName() { +// if (StringUtils.isNotEmpty(displayName)) { +// return displayName; +// } +// return getDisplayNameFromItem(containerValue.getParent()); +// } +// +// @Override +// public void setDisplayName(String name) { +// this.displayName = name; +// } +// +// @Override +// public QName getName() { +// return getItem().getElementName(); +// } + + public boolean isMain() { + return path==null || path.isEmpty(); + } + + public void setMain(boolean main) { + this.main = main; + } + + static String getDisplayNameFromItem(Item item) { + Validate.notNull(item, "Item must not be null."); + + String displayName = item.getDisplayName(); + if (StringUtils.isEmpty(displayName)) { + QName name = item.getElementName(); + if (name != null) { + displayName = name.getLocalPart(); + } else { + displayName = item.getDefinition().getTypeName().getLocalPart(); + } + } + + return displayName; + } + + public boolean hasChanged() { + for (ItemWrapper item : getItems()) { + if (item.hasChanged()) { + return true; + } + } + + return false; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("ContainerWrapper("); +// builder.append(getDisplayNameFromItem(containerValue)); + builder.append(" ("); + builder.append(status); + builder.append(") "); + builder.append(getItems() == null ? null : getItems().size()); + builder.append(" items)"); + return builder.toString(); + } + + /** + * This methods check if we want to show property in form (e.g. + * failedLogins, fetchResult, lastFailedLoginTimestamp must be invisible) + * + * @return + * @deprecated will be implemented through annotations in schema + */ + @Deprecated + private boolean skipProperty(PrismPropertyDefinition def) { + final List names = new ArrayList(); + names.add(PasswordType.F_FAILED_LOGINS); + names.add(PasswordType.F_LAST_FAILED_LOGIN); + names.add(PasswordType.F_LAST_SUCCESSFUL_LOGIN); + names.add(PasswordType.F_PREVIOUS_SUCCESSFUL_LOGIN); + names.add(ObjectType.F_FETCH_RESULT); + // activation + names.add(ActivationType.F_EFFECTIVE_STATUS); + names.add(ActivationType.F_VALIDITY_STATUS); + // user + names.add(UserType.F_RESULT); + // org and roles + names.add(OrgType.F_APPROVAL_PROCESS); + names.add(OrgType.F_APPROVER_EXPRESSION); + names.add(OrgType.F_AUTOMATICALLY_APPROVED); + names.add(OrgType.F_CONDITION); + + + for (QName name : names) { + if (name.equals(def.getName())) { + return true; + } + } + + return false; + } + + public boolean isReadonly() { + // readonly flag in container is an override. Do not get the value from definition + // otherwise it will be propagated to items and overrides the item definition. + return readonly; + } + + public void setReadonly(boolean readonly) { + this.readonly = readonly; + } + +// @Override +// public List getValues() { +// // TODO Auto-generated method stub +// return null; +// } + +// @Override +// public boolean isVisible() { +// // TODO Auto-generated method stub +// return false; +// } + +// @Override +// public boolean isEmpty() { +// return getItem().isEmpty(); +// } + + //TODO add new PrismContainerValue to association container +// public void addValue() { +// getItems().add(createItem()); +// } +// +// public ItemWrapper createItem() { +// Property +// ValueWrapper wrapper = new ValueWrapper(this, new PrismPropertyValue(null), ValueStatus.ADDED); +// return wrapper.getItem(); +// } + + + public void sort(final PageBase pageBase) { + if (containerWrapper.isSorted()){ + Collections.sort(properties, new Comparator(){ + @Override + public int compare(ItemWrapper pw1, ItemWrapper pw2) { + ItemDefinition id1 = pw1.getItemDefinition(); + ItemDefinition id2 = pw2.getItemDefinition(); + String str1 =(id1 != null ? (id1.getDisplayName() != null ? + (pageBase.createStringResource(id1.getDisplayName()) != null && + StringUtils.isNotEmpty(pageBase.createStringResource(id1.getDisplayName()).getString()) ? + pageBase.createStringResource(id1.getDisplayName()).getString() : id1.getDisplayName()): + (id1.getName() != null && id1.getName().getLocalPart() != null ? id1.getName().getLocalPart() : "")) : ""); + String str2 =(id2 != null ? (id2.getDisplayName() != null ? + (pageBase.createStringResource(id2.getDisplayName()) != null && + StringUtils.isNotEmpty(pageBase.createStringResource(id2.getDisplayName()).getString()) ? + pageBase.createStringResource(id2.getDisplayName()).getString() : id2.getDisplayName()): + (id2.getName() != null && id2.getName().getLocalPart() != null ? id2.getName().getLocalPart() : "")) : ""); + return str1.compareToIgnoreCase(str2); + } + }); + } + else { + final int[] maxOrderArray = new int[3]; + Collections.sort(properties, new Comparator(){ + @Override + public int compare(ItemWrapper pw1, ItemWrapper pw2) { + ItemDefinition id1 = pw1.getItemDefinition(); + ItemDefinition id2 = pw2.getItemDefinition(); + + //we need to find out the value of the biggest displayOrder to put + //properties with null display order to the end of the list + int displayOrder1 = (id1 != null && id1.getDisplayOrder() != null) ? id1.getDisplayOrder() : 0; + int displayOrder2 = (id2 != null && id2.getDisplayOrder() != null) ? id2.getDisplayOrder() : 0; + if (maxOrderArray[0] == 0){ + maxOrderArray[0] = displayOrder1 > displayOrder2 ? displayOrder1 + 1 : displayOrder2 + 1; + } + maxOrderArray[1] = displayOrder1; + maxOrderArray[2] = displayOrder2; + + int maxDisplayOrder = NumberUtils.max(maxOrderArray); + maxOrderArray[0] = maxDisplayOrder + 1; + + return Integer.compare(id1 != null && id1.getDisplayOrder() != null ? id1.getDisplayOrder() : maxDisplayOrder, + id2 != null && id2.getDisplayOrder() != null ? id2.getDisplayOrder() : maxDisplayOrder); + } + }); + } + } + + @Override + public String debugDump() { + return debugDump(0); + } + + @Override + public String debugDump(int indent) { + StringBuilder sb = new StringBuilder(); + DebugUtil.indentDebugDump(sb, indent); + sb.append("ContainervalueWrapper: ");//.append(PrettyPrinter.prettyPrint(getName())).append("\n"); + DebugUtil.debugDumpWithLabel(sb, "displayName", getDisplayName(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "status", status == null ? null : status.toString(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "main", main, indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "readonly", readonly, indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "showInheritedObjectAttributes", showInheritedObjectAttributes, indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "path", path == null ? null : path.toString(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "containerDefinition", getDefinition() == null ? null : getDefinition().toString(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "container", containerValue == null ? null : containerValue.toString(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpLabel(sb, "properties", indent + 1); + sb.append("\n"); + DebugUtil.debugDump(sb, properties, indent + 2, false); + return sb.toString(); + } + +// @Override +// public boolean isStripe() { +// // Does not make much sense, but it is given by the interface +// return false; +// } +// +// @Override +// public void setStripe(boolean isStripe) { +// // Does not make much sense, but it is given by the interface +// } + + public void collectModifications(ObjectDelta delta) throws SchemaException { +// if (getItemDefinition().getName().equals(ShadowType.F_ASSOCIATION)) { +// //create ContainerDelta for association container +// //HACK HACK HACK create correct procession for association container data +// //according to its structure +// ContainerDelta associationDelta = +// ContainerDelta.createDelta(ShadowType.F_ASSOCIATION, +// (PrismContainerDefinition) getItemDefinition()); +// for (ItemWrapper itemWrapper : getItems()) { +// AssociationWrapper associationItemWrapper = (AssociationWrapper) itemWrapper; +// List assocValueWrappers = associationItemWrapper.getValues(); +// for (ValueWrapper assocValueWrapper : assocValueWrappers) { +// PrismContainerValue assocValue = (PrismContainerValue) assocValueWrapper.getValue(); +// if (!assocValue.isEmpty()) { +// if (assocValueWrapper.getStatus() == ValueStatus.DELETED) { +// associationDelta.addValueToDelete(assocValue.clone()); +// } else if (assocValueWrapper.getStatus().equals(ValueStatus.ADDED)) { +// associationDelta.addValueToAdd(assocValue.clone()); +// } +// } +// } +// } +// if (!associationDelta.isEmpty()) { +// delta.addModification(associationDelta); +// } +// } else { + if (!hasChanged()) { + return; + } + + for (ItemWrapper itemWrapper : getItems()) { + if (!itemWrapper.hasChanged()) { + continue; + } + ItemPath containerPath = getPath() != null ? getPath() : ItemPath.EMPTY_PATH; + if (itemWrapper instanceof PropertyWrapper) { + ItemDelta pDelta = computePropertyDeltas((PropertyWrapper) itemWrapper, containerPath); + if (!pDelta.isEmpty()) { + //HACK to remove a password replace delta is to be created + if (getContainer().getName().equals(CredentialsType.F_PASSWORD)) { + if (pDelta.getValuesToDelete() != null){ + pDelta.resetValuesToDelete(); + pDelta.setValuesToReplace(new ArrayList()); + } + } + delta.addModification(pDelta); + } + } else if (itemWrapper instanceof ReferenceWrapper) { + ReferenceDelta pDelta = computeReferenceDeltas((ReferenceWrapper) itemWrapper, containerPath); + if (!pDelta.isEmpty()) { + delta.addModification(pDelta); + } + } else { + LOGGER.trace("Delta from wrapper: ignoring {}", itemWrapper); + } + } +// } + } + + private ItemDelta computePropertyDeltas(PropertyWrapper propertyWrapper, ItemPath containerPath) { + ItemDefinition itemDef = propertyWrapper.getItemDefinition(); + ItemDelta pDelta = itemDef.createEmptyDelta(containerPath.subPath(itemDef.getName())); + addItemDelta(propertyWrapper, pDelta, itemDef, containerPath); + return pDelta; + } + + private ReferenceDelta computeReferenceDeltas(ReferenceWrapper referenceWrapper, ItemPath containerPath) { + PrismReferenceDefinition propertyDef = referenceWrapper.getItemDefinition(); + ReferenceDelta pDelta = new ReferenceDelta(containerPath, propertyDef.getName(), propertyDef, + propertyDef.getPrismContext()); + addItemDelta(referenceWrapper, pDelta, propertyDef, containerPath.subPath(propertyDef.getName())); + return pDelta; + } + + private void addItemDelta(ItemWrapper itemWrapper, ItemDelta pDelta, ItemDefinition propertyDef, + ItemPath containerPath) { + for (ValueWrapper valueWrapper : itemWrapper.getValues()) { + valueWrapper.normalize(propertyDef.getPrismContext()); + ValueStatus valueStatus = valueWrapper.getStatus(); + if (!valueWrapper.hasValueChanged() + && (ValueStatus.NOT_CHANGED.equals(valueStatus) || ValueStatus.ADDED.equals(valueStatus))) { + continue; + } + + // TODO: need to check if the resource has defined + // capabilities + // todo this is bad hack because now we have not tri-state + // checkbox +// if (SchemaConstants.PATH_ACTIVATION.equivalent(containerPath) && getContainer().getObject() != null) { +// +// PrismObject object = getContainer().getObject().getObject(); +// if (object.asObjectable() instanceof ShadowType +// && (((ShadowType) object.asObjectable()).getActivation() == null || ((ShadowType) object +// .asObjectable()).getActivation().getAdministrativeStatus() == null)) { +// +// if (!getContainer().getObject().hasResourceCapability(((ShadowType) object.asObjectable()).getResource(), +// ActivationCapabilityType.class)) { +// continue; +// } +// } +// } + + PrismValue newValCloned = ObjectWrapper.clone(valueWrapper.getValue()); + PrismValue oldValCloned = ObjectWrapper.clone(valueWrapper.getOldValue()); + switch (valueWrapper.getStatus()) { + case ADDED: + if (newValCloned != null) { + if (SchemaConstants.PATH_PASSWORD.equivalent(containerPath)) { + // password change will always look like add, + // therefore we push replace + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Delta from wrapper: {} (password) ADD -> replace {}", pDelta.getPath(), newValCloned); + } + pDelta.setValuesToReplace(Arrays.asList(newValCloned)); + } else if (propertyDef.isSingleValue()) { + // values for single-valued properties + // should be pushed via replace + // in order to prevent problems e.g. with + // summarizing deltas for + // unreachable resources + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Delta from wrapper: {} (single,new) ADD -> replace {}", pDelta.getPath(), newValCloned); + } + pDelta.setValueToReplace(newValCloned); + } else { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Delta from wrapper: {} (multi,new) ADD -> add {}", pDelta.getPath(), newValCloned); + } + pDelta.addValueToAdd(newValCloned); + } + } + break; + case DELETED: + if (newValCloned != null) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Delta from wrapper: {} (new) DELETE -> delete {}", pDelta.getPath(), newValCloned); + } + pDelta.addValueToDelete(newValCloned); + } + if (oldValCloned != null) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Delta from wrapper: {} (old) DELETE -> delete {}", pDelta.getPath(), oldValCloned); + } + pDelta.addValueToDelete(oldValCloned); + } + break; + case NOT_CHANGED: + // this is modify... + if (propertyDef.isSingleValue()) { + // newValCloned.isEmpty() + if (newValCloned != null && !newValCloned.isEmpty()) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Delta from wrapper: {} (single,new) NOT_CHANGED -> replace {}", pDelta.getPath(), newValCloned); + } + pDelta.setValuesToReplace(Arrays.asList(newValCloned)); + } else { + if (oldValCloned != null) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Delta from wrapper: {} (single,old) NOT_CHANGED -> delete {}", pDelta.getPath(), oldValCloned); + } + pDelta.addValueToDelete(oldValCloned); + } + } + } else { + if (newValCloned != null && !newValCloned.isEmpty()) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Delta from wrapper: {} (multi,new) NOT_CHANGED -> add {}", pDelta.getPath(), newValCloned); + } + pDelta.addValueToAdd(newValCloned); + } + if (oldValCloned != null) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Delta from wrapper: {} (multi,old) NOT_CHANGED -> delete {}", pDelta.getPath(), oldValCloned); + } + pDelta.addValueToDelete(oldValCloned); + } + } + break; + } + } + } + +// @Override + public boolean checkRequired(PageBase pageBase) { + boolean rv = true; + for (ItemWrapper itemWrapper : getItems()) { + if (!itemWrapper.checkRequired(pageBase)) { + rv = false; + } + } + return rv; + } + + public String getDisplayName() { + if (getContainer().isMain()){ + return "prismContainer.mainPanelDisplayName"; + } + + if (getDefinition() == null) { + return WebComponentUtil.getDisplayName(containerValue); + } + + if (getDefinition().isSingleValue()) { + + return ContainerWrapper.getDisplayNameFromItem(getContainerValue().getContainer()); + } + return WebComponentUtil.getDisplayName(containerValue); + +// return containerValue.toHumanReadableString(); + } +// +// @Override +// public boolean isEnforceRequiredFields() { +// return containerWrapper != null && containerWrapper.isEnforceRequiredFields(); +// } + + +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java index 97c615d1773..b100cdb604f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java @@ -23,6 +23,7 @@ import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.ReferenceDelta; import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.util.ItemPathUtil; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.DebugUtil; @@ -47,35 +48,33 @@ /** * @author lazyman */ -public class ContainerWrapper implements ItemWrapper, Serializable, DebugDumpable { +public class ContainerWrapper extends PrismWrapper implements ItemWrapper, Serializable, DebugDumpable { private static final Trace LOGGER = TraceManager.getTrace(ContainerWrapper.class); private String displayName; - private ObjectWrapper objectWrapper; +// private ObjectWrapper objectWrapper; private PrismContainer container; private ContainerStatus status; - private boolean main; private ItemPath path; - private List properties; + private List> values; private boolean readonly; private boolean showInheritedObjectAttributes; private PrismContainerDefinition containerDefinition; - ContainerWrapper(ObjectWrapper objectWrapper, PrismContainer container, ContainerStatus status, ItemPath path) { + ContainerWrapper(PrismContainer container, ContainerStatus status, ItemPath path) { Validate.notNull(container, "container must not be null."); Validate.notNull(status, "Container status must not be null."); - this.objectWrapper = objectWrapper; +// this.objectWrapper = objectWrapper; this.container = container; this.status = status; this.path = path; - this.main = path == null; - this.readonly = objectWrapper.isReadonly(); // [pm] this is quite questionable - this.showInheritedObjectAttributes = objectWrapper.isShowInheritedObjectAttributes(); +// this.readonly = objectWrapper.isReadonly(); // [pm] this is quite questionable +// this.showInheritedObjectAttributes = objectWrapper.isShowInheritedObjectAttributes(); // have to be after setting "main" property this.containerDefinition = getItemDefinition(); } @@ -89,7 +88,6 @@ public class ContainerWrapper implements ItemWrapper, S this.containerDefinition = container.getDefinition(); this.status = status; this.path = path; - this.main = path == null; this.readonly = readOnly; this.showInheritedObjectAttributes = showInheritedObjectAttributes; } @@ -101,8 +99,8 @@ public void revive(PrismContext prismContext) throws SchemaException { if (containerDefinition != null) { containerDefinition.revive(prismContext); } - if (properties != null) { - for (ItemWrapper itemWrapper : properties) { + if (values != null) { + for (ContainerValueWrapper itemWrapper : values) { itemWrapper.revive(prismContext); } } @@ -113,17 +111,17 @@ public PrismContainerDefinition getItemDefinition() { if (containerDefinition != null) { return containerDefinition; } - if (main) { - return objectWrapper.getDefinition(); - } else { - return objectWrapper.getDefinition().findContainerDefinition(path); - } +// if (isMain()) { + return container.getDefinition(); +// } else { +// return objectWrapper.getDefinition().findContainerDefinition(path); +// } } - @Nullable - ObjectWrapper getObject() { - return objectWrapper; - } +// @Nullable +// ObjectWrapper getObject() { +// return objectWrapper; +// } public ContainerStatus getStatus() { return status; @@ -133,25 +131,26 @@ public ItemPath getPath() { return path; } + @Override public PrismContainer getItem() { return container; } - public List getItems() { - if (properties == null) { - properties = new ArrayList<>(); + public List> getValues() { + if (values == null) { + values = new ArrayList<>(); } - return properties; + return values; } - public void setProperties(List properties) { - this.properties = properties; + public void setProperties(List> properties) { + this.values = properties; } - public IW findPropertyWrapper(QName name) { + public IW findPropertyWrapper(ItemPath name) { Validate.notNull(name, "QName must not be null."); - for (ItemWrapper wrapper : getItems()) { - if (QNameUtil.match(name, wrapper.getItem().getElementName())) { + for (ContainerValueWrapper wrapper : getValues()) { + if (name.equals(wrapper.getContainerValue().getPath())) { return (IW) wrapper; } } @@ -171,11 +170,12 @@ boolean isItemVisible(ItemWrapper item) { // we decide not according to status of this container, but according to // the status of the whole object - if (objectWrapper != null && objectWrapper.getStatus() == ContainerStatus.ADDING) { - - return (def.canAdd() && def.isEmphasized()) - || (def.canAdd() && showEmpty(item)); - } + +// if (objectWrapper != null && objectWrapper.getStatus() == ContainerStatus.ADDING) { +// +// return (def.canAdd() && def.isEmphasized()) +// || (def.canAdd() && showEmpty(item)); +// } // otherwise, object.getStatus() is MODIFYING @@ -188,18 +188,38 @@ boolean isItemVisible(ItemWrapper item) { return false; } } + + boolean isItemVisible() { + + //TODO: [katka] should we consider child items? e.g. we can dee assignemnt/description but noothing else.. + PrismContainerDefinition containerDefinition = getItemDefinition(); + if (containerDefinition.isIgnored() || containerDefinition.isOperational()) { + return false; + } + + switch (status) { + case ADDING : + return containerDefinition.canAdd(); + case MODIFYING : + return (containerDefinition.canRead() && containerDefinition.canModify()); + } + + return false; + + } public void computeStripes() { int visibleProperties = 0; - for (ItemWrapper item: properties) { - if (item.isVisible()) { - visibleProperties++; - } - if (visibleProperties % 2 == 0) { - item.setStripe(true); - } else { - item.setStripe(false); - } + for (ContainerValueWrapper item: values) { + item.computeStripes(); +// if (item.isVisible()) { +// visibleProperties++; +// } +// if (visibleProperties % 2 == 0) { +// item.setStripe(true); +// } else { +// item.setStripe(false); +// } } } @@ -214,7 +234,7 @@ private boolean showEmpty(ItemWrapper item) { if (item.getItemDefinition().isEmphasized()) { return true; } - ObjectWrapper objectWrapper = getObject(); +// ObjectWrapper objectWrapper = getObject(); List valueWrappers = item.getValues(); boolean isEmpty; if (valueWrappers == null) { @@ -228,7 +248,8 @@ private boolean showEmpty(ItemWrapper item) { isEmpty = true; } } - return (objectWrapper == null || objectWrapper.isShowEmpty()) || !isEmpty; +// /(objectWrapper == null || objectWrapper.isShowEmpty()) || + return !isEmpty; } @Override @@ -250,13 +271,10 @@ public QName getName() { } public boolean isMain() { - return main; - } - - public void setMain(boolean main) { - this.main = main; + return path == null || path.isEmpty(); } + static String getDisplayNameFromItem(Item item) { Validate.notNull(item, "Item must not be null."); @@ -274,7 +292,7 @@ static String getDisplayNameFromItem(Item item) { } public boolean hasChanged() { - for (ItemWrapper item : getItems()) { + for (ContainerValueWrapper item : getValues()) { if (item.hasChanged()) { return true; } @@ -291,7 +309,7 @@ public String toString() { builder.append(" ("); builder.append(status); builder.append(") "); - builder.append(getItems() == null ? null : getItems().size()); + builder.append(getValues() == null ? null : getValues().size()); builder.append(" items)"); return builder.toString(); } @@ -342,16 +360,24 @@ public void setReadonly(boolean readonly) { this.readonly = readonly; } - @Override - public List getValues() { - // TODO Auto-generated method stub - return null; - } - - @Override +// @Override +// public List getValues() { +// // TODO Auto-generated method stub +// return null; +// } +// +// @Override public boolean isVisible() { - // TODO Auto-generated method stub - return false; + switch (status) { + case ADDING : + return getItemDefinition().canAdd(); + case MODIFYING : + if (getItemDefinition().canModify()) { + return !isEmpty(); + } + } + + return false; } @Override @@ -359,71 +385,76 @@ public boolean isEmpty() { return getItem().isEmpty(); } - @Override - public ContainerWrapper getContainer() { - // TODO Auto-generated method stub - return null; - } +// PrismContainer getContainer() { +// // TODO Auto-generated method stub +// return container +// } //TODO add new PrismContainerValue to association container public void addValue() { - getItems().add(createItem()); + getValues().add(createItem()); } - public ItemWrapper createItem() { - ValueWrapper wrapper = new ValueWrapper(this, new PrismPropertyValue(null), ValueStatus.ADDED); - return wrapper.getItem(); + public ContainerValueWrapper createItem() { + PrismContainerValue pcv = container.createNewValue(); + ContainerValueWrapper wrapper = new ContainerValueWrapper(this, pcv, ValueStatus.ADDED, pcv.getPath()); + return wrapper; } + public void sort(final PageBase pageBase) { + for (ContainerValueWrapper valueWrapper : getValues()) { + valueWrapper.sort(pageBase); + } + } - public void sort(final PageBase pageBase) { - if (objectWrapper.isSorted()){ - Collections.sort(properties, new Comparator(){ - @Override - public int compare(ItemWrapper pw1, ItemWrapper pw2) { - ItemDefinition id1 = pw1.getItemDefinition(); - ItemDefinition id2 = pw2.getItemDefinition(); - String str1 =(id1 != null ? (id1.getDisplayName() != null ? - (pageBase.createStringResource(id1.getDisplayName()) != null && - StringUtils.isNotEmpty(pageBase.createStringResource(id1.getDisplayName()).getString()) ? - pageBase.createStringResource(id1.getDisplayName()).getString() : id1.getDisplayName()): - (id1.getName() != null && id1.getName().getLocalPart() != null ? id1.getName().getLocalPart() : "")) : ""); - String str2 =(id2 != null ? (id2.getDisplayName() != null ? - (pageBase.createStringResource(id2.getDisplayName()) != null && - StringUtils.isNotEmpty(pageBase.createStringResource(id2.getDisplayName()).getString()) ? - pageBase.createStringResource(id2.getDisplayName()).getString() : id2.getDisplayName()): - (id2.getName() != null && id2.getName().getLocalPart() != null ? id2.getName().getLocalPart() : "")) : ""); - return str1.compareToIgnoreCase(str2); - } - }); - } - else { - final int[] maxOrderArray = new int[3]; - Collections.sort(properties, new Comparator(){ - @Override - public int compare(ItemWrapper pw1, ItemWrapper pw2) { - ItemDefinition id1 = pw1.getItemDefinition(); - ItemDefinition id2 = pw2.getItemDefinition(); - - //we need to find out the value of the biggest displayOrder to put - //properties with null display order to the end of the list - int displayOrder1 = (id1 != null && id1.getDisplayOrder() != null) ? id1.getDisplayOrder() : 0; - int displayOrder2 = (id2 != null && id2.getDisplayOrder() != null) ? id2.getDisplayOrder() : 0; - if (maxOrderArray[0] == 0){ - maxOrderArray[0] = displayOrder1 > displayOrder2 ? displayOrder1 + 1 : displayOrder2 + 1; - } - maxOrderArray[1] = displayOrder1; - maxOrderArray[2] = displayOrder2; - - int maxDisplayOrder = NumberUtils.max(maxOrderArray); - maxOrderArray[0] = maxDisplayOrder + 1; - - return Integer.compare(id1 != null && id1.getDisplayOrder() != null ? id1.getDisplayOrder() : maxDisplayOrder, - id2 != null && id2.getDisplayOrder() != null ? id2.getDisplayOrder() : maxDisplayOrder); - } - }); - } - } +// public void sort(final PageBase pageBase) { +// if (objectWrapper.isSorted()){ +// Collections.sort(values, new Comparator(){ +// @Override +// public int compare(ItemWrapper pw1, ItemWrapper pw2) { +// ItemDefinition id1 = pw1.getItemDefinition(); +// ItemDefinition id2 = pw2.getItemDefinition(); +// String str1 =(id1 != null ? (id1.getDisplayName() != null ? +// (pageBase.createStringResource(id1.getDisplayName()) != null && +// StringUtils.isNotEmpty(pageBase.createStringResource(id1.getDisplayName()).getString()) ? +// pageBase.createStringResource(id1.getDisplayName()).getString() : id1.getDisplayName()): +// (id1.getName() != null && id1.getName().getLocalPart() != null ? id1.getName().getLocalPart() : "")) : ""); +// String str2 =(id2 != null ? (id2.getDisplayName() != null ? +// (pageBase.createStringResource(id2.getDisplayName()) != null && +// StringUtils.isNotEmpty(pageBase.createStringResource(id2.getDisplayName()).getString()) ? +// pageBase.createStringResource(id2.getDisplayName()).getString() : id2.getDisplayName()): +// (id2.getName() != null && id2.getName().getLocalPart() != null ? id2.getName().getLocalPart() : "")) : ""); +// return str1.compareToIgnoreCase(str2); +// } +// }); +// } +// else { +// final int[] maxOrderArray = new int[3]; +// Collections.sort(values, new Comparator(){ +// @Override +// public int compare(ItemWrapper pw1, ItemWrapper pw2) { +// ItemDefinition id1 = pw1.getItemDefinition(); +// ItemDefinition id2 = pw2.getItemDefinition(); +// +// //we need to find out the value of the biggest displayOrder to put +// //properties with null display order to the end of the list +// int displayOrder1 = (id1 != null && id1.getDisplayOrder() != null) ? id1.getDisplayOrder() : 0; +// int displayOrder2 = (id2 != null && id2.getDisplayOrder() != null) ? id2.getDisplayOrder() : 0; +// if (maxOrderArray[0] == 0){ +// maxOrderArray[0] = displayOrder1 > displayOrder2 ? displayOrder1 + 1 : displayOrder2 + 1; +// } +// maxOrderArray[1] = displayOrder1; +// maxOrderArray[2] = displayOrder2; +// +// int maxDisplayOrder = NumberUtils.max(maxOrderArray); +// maxOrderArray[0] = maxDisplayOrder + 1; +// +// return Integer.compare(id1 != null && id1.getDisplayOrder() != null ? id1.getDisplayOrder() : maxDisplayOrder, +// id2 != null && id2.getDisplayOrder() != null ? id2.getDisplayOrder() : maxDisplayOrder); +// } +// }); +// } +// } @Override public String debugDump() { @@ -439,7 +470,7 @@ public String debugDump(int indent) { sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "status", status == null ? null : status.toString(), indent + 1); sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "main", main, indent + 1); + DebugUtil.debugDumpWithLabel(sb, "main", isMain(), indent + 1); sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "readonly", readonly, indent + 1); sb.append("\n"); @@ -453,7 +484,7 @@ public String debugDump(int indent) { sb.append("\n"); DebugUtil.debugDumpLabel(sb, "properties", indent + 1); sb.append("\n"); - DebugUtil.debugDump(sb, properties, indent + 2, false); + DebugUtil.debugDump(sb, values, indent + 2, false); return sb.toString(); } @@ -469,62 +500,65 @@ public void setStripe(boolean isStripe) { } public void collectModifications(ObjectDelta delta) throws SchemaException { - if (getItemDefinition().getName().equals(ShadowType.F_ASSOCIATION)) { - //create ContainerDelta for association container - //HACK HACK HACK create correct procession for association container data - //according to its structure - ContainerDelta associationDelta = - ContainerDelta.createDelta(ShadowType.F_ASSOCIATION, - (PrismContainerDefinition) getItemDefinition()); - for (ItemWrapper itemWrapper : getItems()) { - AssociationWrapper associationItemWrapper = (AssociationWrapper) itemWrapper; - List assocValueWrappers = associationItemWrapper.getValues(); - for (ValueWrapper assocValueWrapper : assocValueWrappers) { - PrismContainerValue assocValue = (PrismContainerValue) assocValueWrapper.getValue(); - if (!assocValue.isEmpty()) { - if (assocValueWrapper.getStatus() == ValueStatus.DELETED) { - associationDelta.addValueToDelete(assocValue.clone()); - } else if (assocValueWrapper.getStatus().equals(ValueStatus.ADDED)) { - associationDelta.addValueToAdd(assocValue.clone()); - } - } - } - } - if (!associationDelta.isEmpty()) { - delta.addModification(associationDelta); - } - } else { +// if (getItemDefinition().getName().equals(ShadowType.F_ASSOCIATION)) { +// //create ContainerDelta for association container +// //HACK HACK HACK create correct procession for association container data +// //according to its structure +// ContainerDelta associationDelta = +// ContainerDelta.createDelta(ShadowType.F_ASSOCIATION, +// (PrismContainerDefinition) getItemDefinition()); +// for (ItemWrapper itemWrapper : getValues()) { +// AssociationWrapper associationItemWrapper = (AssociationWrapper) itemWrapper; +// List assocValueWrappers = associationItemWrapper.getValues(); +// for (ValueWrapper assocValueWrapper : assocValueWrappers) { +// PrismContainerValue assocValue = (PrismContainerValue) assocValueWrapper.getValue(); +// if (!assocValue.isEmpty()) { +// if (assocValueWrapper.getStatus() == ValueStatus.DELETED) { +// associationDelta.addValueToDelete(assocValue.clone()); +// } else if (assocValueWrapper.getStatus().equals(ValueStatus.ADDED)) { +// associationDelta.addValueToAdd(assocValue.clone()); +// } +// } +// } +// } +// if (!associationDelta.isEmpty()) { +// delta.addModification(associationDelta); +// } +// } else { if (!hasChanged()) { return; } - for (ItemWrapper itemWrapper : getItems()) { + for (ContainerValueWrapper itemWrapper : getValues()) { if (!itemWrapper.hasChanged()) { continue; } - ItemPath containerPath = getPath() != null ? getPath() : ItemPath.EMPTY_PATH; - if (itemWrapper instanceof PropertyWrapper) { - ItemDelta pDelta = computePropertyDeltas((PropertyWrapper) itemWrapper, containerPath); - if (!pDelta.isEmpty()) { - //HACK to remove a password replace delta is to be created - if (getName().equals(CredentialsType.F_PASSWORD)) { - if (pDelta.getValuesToDelete() != null){ - pDelta.resetValuesToDelete(); - pDelta.setValuesToReplace(new ArrayList()); - } - } - delta.addModification(pDelta); - } - } else if (itemWrapper instanceof ReferenceWrapper) { - ReferenceDelta pDelta = computeReferenceDeltas((ReferenceWrapper) itemWrapper, containerPath); - if (!pDelta.isEmpty()) { - delta.addModification(pDelta); - } - } else { - LOGGER.trace("Delta from wrapper: ignoring {}", itemWrapper); - } + + itemWrapper.collectModifications(delta); +// ItemPath containerPath = getPath() != null ? getPath() : ItemPath.EMPTY_PATH; +// +// if (itemWrapper instanceof PropertyWrapper) { +// ItemDelta pDelta = computePropertyDeltas((PropertyWrapper) itemWrapper, containerPath); +// if (!pDelta.isEmpty()) { +// //HACK to remove a password replace delta is to be created +// if (getName().equals(CredentialsType.F_PASSWORD)) { +// if (pDelta.getValuesToDelete() != null){ +// pDelta.resetValuesToDelete(); +// pDelta.setValuesToReplace(new ArrayList()); +// } +// } +// delta.addModification(pDelta); +// } +// } else if (itemWrapper instanceof ReferenceWrapper) { +// ReferenceDelta pDelta = computeReferenceDeltas((ReferenceWrapper) itemWrapper, containerPath); +// if (!pDelta.isEmpty()) { +// delta.addModification(pDelta); +// } +// } else { +// LOGGER.trace("Delta from wrapper: ignoring {}", itemWrapper); +// } } - } +// } } private ItemDelta computePropertyDeltas(PropertyWrapper propertyWrapper, ItemPath containerPath) { @@ -556,19 +590,19 @@ private void addItemDelta(ItemWrapper // capabilities // todo this is bad hack because now we have not tri-state // checkbox - if (SchemaConstants.PATH_ACTIVATION.equivalent(containerPath) && getObject() != null) { - - PrismObject object = getObject().getObject(); - if (object.asObjectable() instanceof ShadowType - && (((ShadowType) object.asObjectable()).getActivation() == null || ((ShadowType) object - .asObjectable()).getActivation().getAdministrativeStatus() == null)) { - - if (!getObject().hasResourceCapability(((ShadowType) object.asObjectable()).getResource(), - ActivationCapabilityType.class)) { - continue; - } - } - } +// if (SchemaConstants.PATH_ACTIVATION.equivalent(containerPath) && getObject() != null) { +// +// PrismObject object = getObject().getObject(); +// if (object.asObjectable() instanceof ShadowType +// && (((ShadowType) object.asObjectable()).getActivation() == null || ((ShadowType) object +// .asObjectable()).getActivation().getAdministrativeStatus() == null)) { +// +// if (!getObject().hasResourceCapability(((ShadowType) object.asObjectable()).getResource(), +// ActivationCapabilityType.class)) { +// continue; +// } +// } +// } PrismValue newValCloned = ObjectWrapper.clone(valueWrapper.getValue()); PrismValue oldValCloned = ObjectWrapper.clone(valueWrapper.getOldValue()); @@ -653,7 +687,7 @@ private void addItemDelta(ItemWrapper @Override public boolean checkRequired(PageBase pageBase) { boolean rv = true; - for (ItemWrapper itemWrapper : getItems()) { + for (ContainerValueWrapper itemWrapper : getValues()) { if (!itemWrapper.checkRequired(pageBase)) { rv = false; } @@ -663,6 +697,25 @@ public boolean checkRequired(PageBase pageBase) { @Override public boolean isEnforceRequiredFields() { - return objectWrapper != null && objectWrapper.isEnforceRequiredFields(); + return true;//objectWrapper != null && objectWrapper.isEnforceRequiredFields(); + } + + @Override + public ContainerWrapper getParent() { + // TODO Auto-generated method stub + return null; } + + @Override + public boolean isVisible(boolean showEmpty) { + // TODO Auto-generated method stub + return false; + } + + +// @Override +// public ContainerValueWrapper getContainerValue() { +// // TODO Auto-generated method stub +// return null; +// } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java index 0f0716afffc..5f51382e014 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java @@ -78,97 +78,112 @@ public OperationResult getResult() { return result; } - public ContainerWrapper createContainerWrapper(ObjectWrapper objectWrapper, - T container, + public ContainerWrapper createContainerWrapper( + PrismContainer container, ContainerStatus status, ItemPath path) { result = new OperationResult(CREATE_PROPERTIES); - ContainerWrapper cWrapper = new ContainerWrapper(objectWrapper, container, status, path); - - List properties = createProperties(cWrapper, result); - cWrapper.setProperties(properties); - + ContainerWrapper cWrapper = new ContainerWrapper(container, status, path); + + List> containerValues = createContainerValues(cWrapper, path); + cWrapper.setProperties(containerValues); cWrapper.computeStripes(); return cWrapper; } - - public ContainerWrapper createContainerWrapper(T container, ContainerStatus status, ItemPath path, boolean readonly) { + + + public ContainerWrapper createContainerWrapper(PrismContainer container, ContainerStatus status, ItemPath path, boolean readonly) { result = new OperationResult(CREATE_PROPERTIES); - ContainerWrapper cWrapper = new ContainerWrapper(container, status, path, readonly, false); + ContainerWrapper cWrapper = new ContainerWrapper(container, status, path, readonly, false); - List properties = createProperties(cWrapper, result); - cWrapper.setProperties(properties); + List> containerValues = createContainerValues(cWrapper, path); + cWrapper.setProperties(containerValues); + cWrapper.computeStripes(); - cWrapper.computeStripes(); + +// List properties = createProperties(cWrapper, result); +// cWrapper.setProperties(properties); +// +// cWrapper.computeStripes(); return cWrapper; } - private List createProperties(ContainerWrapper cWrapper, OperationResult result) { - ObjectWrapper objectWrapper = cWrapper.getObject(); - PrismContainer container = cWrapper.getItem(); - PrismContainerDefinition containerDefinition = cWrapper.getItemDefinition(); + private List> createContainerValues(ContainerWrapper cWrapper, ItemPath path) { + List> containerValueWrappers = new ArrayList<>(); + PrismContainer container = cWrapper.getItem(); + + if (container.isEmpty()) { + PrismContainerValue newValue = container.createNewValue(); + ContainerValueWrapper containerValueWrapper = new ContainerValueWrapper<>(cWrapper, newValue, ValueStatus.ADDED, path); + + List properties = createProperties(containerValueWrapper, result); + containerValueWrapper.setProperties(properties); + containerValueWrappers.add(containerValueWrapper); + return containerValueWrappers; + } + + for (PrismContainerValue containerValue : container.getValues()){ + ContainerValueWrapper containerValueWrapper = new ContainerValueWrapper<>(cWrapper, containerValue, ValueStatus.NOT_CHANGED, containerValue.getPath()); + + List properties = createProperties(containerValueWrapper, result); + containerValueWrapper.setProperties(properties); + containerValueWrappers.add(containerValueWrapper); + } + + return containerValueWrappers; + } + + private List createProperties(ContainerValueWrapper cWrapper, OperationResult result) { + ContainerWrapper containerWrapper = cWrapper.getContainer(); +// PrismContainerValue containerValue = cWrapper.getContainerValue(); + PrismContainerDefinition definition = containerWrapper.getItemDefinition(); List properties = new ArrayList<>(); - PrismContainerDefinition definition; - if (objectWrapper == null) { - definition = containerDefinition; - } else { - PrismObject parent = objectWrapper.getObject(); - Class clazz = parent.getCompileTimeClass(); - if (ShadowType.class.isAssignableFrom(clazz)) { - QName name = containerDefinition.getName(); - - if (ShadowType.F_ATTRIBUTES.equals(name)) { - try { - definition = objectWrapper.getRefinedAttributeDefinition(); - - if (definition == null) { - PrismReference resourceRef = parent.findReference(ShadowType.F_RESOURCE_REF); - PrismObject resource = resourceRef.getValue().getObject(); - - definition = modelServiceLocator - .getModelInteractionService() - .getEditObjectClassDefinition((PrismObject) objectWrapper.getObject(), resource, - AuthorizationPhaseType.REQUEST) - .toResourceAttributeContainerDefinition(); - - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Refined account def:\n{}", definition.debugDump()); - } - } - } catch (Exception ex) { - LoggingUtils.logUnexpectedException(LOGGER, - "Couldn't load definitions from refined schema for shadow", ex); - result.recordFatalError( - "Couldn't load definitions from refined schema for shadow, reason: " - + ex.getMessage(), ex); - - return properties; - } - } else { - definition = containerDefinition; - } - } else if (ResourceType.class.isAssignableFrom(clazz)) { - if (containerDefinition != null) { - definition = containerDefinition; - } else { - definition = container.getDefinition(); - } - } else { - definition = containerDefinition; - } - } +// PrismContainerDefinition definition = null; +// if (containerWrapper == null) { +// definition = containerDefinition; +// } else { +//// PrismObject parent = containerWrapper.getObject().getObject(); +// if (containerWrapper.isMain()) { +// +// +// Class clazz = ((PrismObject) containerWrapper.getItem()).getCompileTimeClass(); +// if (ShadowType.class.isAssignableFrom(clazz)) { +// try { +// createShadowContainer(containerDefinition, containerWrapper, definition); +// } catch (Exception ex) { +// LoggingUtils.logUnexpectedException(LOGGER, +// "Couldn't load definitions from refined schema for shadow", ex); +// result.recordFatalError( +// "Couldn't load definitions from refined schema for shadow, reason: " +// + ex.getMessage(), ex); +// +// return properties; +// } +// } else if (ResourceType.class.isAssignableFrom(clazz)) { +// if (containerDefinition != null) { +// definition = containerDefinition; +// } else { +// definition = containerWrapper.getItemDefinition(); +// } +// } else { +// definition = containerDefinition; +// } +// } else { +// definition = containerDefinition; +// } +// } if (definition == null) { LOGGER.error("Couldn't get property list from null definition {}", - new Object[]{container.getElementName()}); + new Object[]{containerWrapper.getItem().getElementName()}); return properties; } @@ -176,306 +191,428 @@ private List createProperties(ContainerWrapper cWrapper, OperationR // org.units and roles // (but only if ObjectWrapper.isShowAssignments() is true; otherwise // they are filtered out by ObjectWrapper) - if (container.getCompileTimeClass() != null - && AssignmentType.class.isAssignableFrom(container.getCompileTimeClass())) { - - for (Object o : container.getValues()) { - PrismContainerValue pcv = (PrismContainerValue) o; - - AssignmentType assignmentType = pcv.asContainerable(); - - if (assignmentType.getTargetRef() == null) { - continue; - } - - // hack... we want to create a definition for Name - // PrismPropertyDefinition def = ((PrismContainerValue) - // pcv.getContainer().getParent()).getContainer().findProperty(ObjectType.F_NAME).getDefinition(); - PrismPropertyDefinitionImpl def = new PrismPropertyDefinitionImpl(ObjectType.F_NAME, - DOMUtil.XSD_STRING, pcv.getPrismContext()); - - if (OrgType.COMPLEX_TYPE.equals(assignmentType.getTargetRef().getType())) { - def.setDisplayName("Org.Unit"); - def.setDisplayOrder(100); - } else if (RoleType.COMPLEX_TYPE.equals(assignmentType.getTargetRef().getType())) { - def.setDisplayName("Role"); - def.setDisplayOrder(200); - } else { - continue; - } - - PrismProperty temp = def.instantiate(); - - String value = formatAssignmentBrief(assignmentType); - - temp.setValue(new PrismPropertyValue(value)); - // TODO: do this.isReadOnly() - is that OK? (originally it was the default behavior for all cases) - properties.add(new PropertyWrapper(cWrapper, temp, cWrapper.isReadonly(), ValueStatus.NOT_CHANGED)); - } - - } else if (isShadowAssociation(cWrapper)) { - - // HACK: this should not be here. Find a better place. - cWrapper.setDisplayName("prismContainer.shadow.associations"); - - PrismContext prismContext = objectWrapper.getObject().getPrismContext(); - Map> assocMap = new HashMap<>(); - PrismContainer associationContainer = cWrapper.getItem(); - if (associationContainer != null && associationContainer.getValues() != null) { - // Do NOT load shadows here. This will be huge overhead if there are many associations. - // Load them on-demand (if necessary at all). - List> associations = associationContainer.getValues(); - if (associations != null) { - for (PrismContainerValue cval : associations) { - ShadowAssociationType associationType = cval.asContainerable(); - QName assocName = associationType.getName(); - PrismContainer fractionalContainer = assocMap.get(assocName); - if (fractionalContainer == null) { - fractionalContainer = new PrismContainer<>(ShadowType.F_ASSOCIATION, ShadowAssociationType.class, cval.getPrismContext()); - fractionalContainer.setDefinition(cval.getParent().getDefinition()); - // HACK: set the name of the association as the element name so wrapper.getName() will return correct data. - fractionalContainer.setElementName(assocName); - assocMap.put(assocName, fractionalContainer); - } - try { - fractionalContainer.add(cval.clone()); - } catch (SchemaException e) { - // Should not happen - throw new SystemException("Unexpected error: " + e.getMessage(), e); - } - } - } - } - - PrismReference resourceRef = objectWrapper.getObject().findReference(ShadowType.F_RESOURCE_REF); - PrismObject resource = resourceRef.getValue().getObject(); - - // HACK. The revive should not be here. Revive is no good. The next use of the resource will - // cause parsing of resource schema. We need some centralized place to maintain live cached copies - // of resources. - try { - resource.revive(prismContext); - } catch (SchemaException e) { - throw new SystemException(e.getMessage(), e); - } - RefinedResourceSchema refinedSchema; - CompositeRefinedObjectClassDefinition rOcDef; - try { - refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); - rOcDef = refinedSchema.determineCompositeObjectClassDefinition(objectWrapper.getObject()); - } catch (SchemaException e) { - throw new SystemException(e.getMessage(), e); - } - // Make sure even empty associations have their wrappers so they can be displayed and edited - for (RefinedAssociationDefinition assocDef : rOcDef.getAssociationDefinitions()) { - QName name = assocDef.getName(); - if (!assocMap.containsKey(name)) { - PrismContainer fractionalContainer = new PrismContainer<>(ShadowType.F_ASSOCIATION, ShadowAssociationType.class, prismContext); - fractionalContainer.setDefinition(cWrapper.getItemDefinition()); - // HACK: set the name of the association as the element name so wrapper.getName() will return correct data. - fractionalContainer.setElementName(name); - assocMap.put(name, fractionalContainer); - } - } - - for (Map.Entry> assocEntry : assocMap.entrySet()) { - RefinedAssociationDefinition assocRDef = rOcDef.findAssociationDefinition(assocEntry.getKey()); - AssociationWrapper assocWrapper = new AssociationWrapper(cWrapper, assocEntry.getValue(), - cWrapper.isReadonly(), ValueStatus.NOT_CHANGED, assocRDef); - properties.add(assocWrapper); - } - - } else { // if not an assignment - - if ((container.getValues().size() == 1 || container.getValues().isEmpty()) - && (containerDefinition == null || containerDefinition.isSingleValue())) { - - // there's no point in showing properties for non-single-valued +// if (containerWrapper.getItem().getCompileTimeClass() != null +// && AssignmentType.class.isAssignableFrom(containerWrapper.getItem().getCompileTimeClass())) { +// +// for (Object o : container.getValues()) { +// PrismContainerValue pcv = (PrismContainerValue) o; +// +// AssignmentType assignmentType = pcv.asContainerable(); +// +// if (assignmentType.getTargetRef() == null) { +// continue; +// } +// +// // hack... we want to create a definition for Name +// // PrismPropertyDefinition def = ((PrismContainerValue) +// // pcv.getContainer().getParent()).getContainer().findProperty(ObjectType.F_NAME).getDefinition(); +// PrismPropertyDefinitionImpl def = new PrismPropertyDefinitionImpl(ObjectType.F_NAME, +// DOMUtil.XSD_STRING, pcv.getPrismContext()); +// +// if (OrgType.COMPLEX_TYPE.equals(assignmentType.getTargetRef().getType())) { +// def.setDisplayName("Org.Unit"); +// def.setDisplayOrder(100); +// } else if (RoleType.COMPLEX_TYPE.equals(assignmentType.getTargetRef().getType())) { +// def.setDisplayName("Role"); +// def.setDisplayOrder(200); +// } else { +// continue; +// } +// +// PrismProperty temp = def.instantiate(); +// +// String value = formatAssignmentBrief(assignmentType); +// +// temp.setValue(new PrismPropertyValue(value)); +// // TODO: do this.isReadOnly() - is that OK? (originally it was the default behavior for all cases) +// properties.add(new PropertyWrapper(cWrapper, temp, cWrapper.isReadonly(), ValueStatus.NOT_CHANGED)); +// } +// +// } else if (isShadowAssociation(cWrapper)) { +// +// // HACK: this should not be here. Find a better place. +// cWrapper.setDisplayName("prismContainer.shadow.associations"); +// +// PrismContext prismContext = containerWrapper.getObject().getPrismContext(); +// Map> assocMap = new HashMap<>(); +// PrismContainer associationContainer = cWrapper.getItem(); +// if (associationContainer != null && associationContainer.getValues() != null) { +// // Do NOT load shadows here. This will be huge overhead if there are many associations. +// // Load them on-demand (if necessary at all). +// List> associations = associationContainer.getValues(); +// if (associations != null) { +// for (PrismContainerValue cval : associations) { +// ShadowAssociationType associationType = cval.asContainerable(); +// QName assocName = associationType.getName(); +// PrismContainer fractionalContainer = assocMap.get(assocName); +// if (fractionalContainer == null) { +// fractionalContainer = new PrismContainer<>(ShadowType.F_ASSOCIATION, ShadowAssociationType.class, cval.getPrismContext()); +// fractionalContainer.setDefinition(cval.getParent().getDefinition()); +// // HACK: set the name of the association as the element name so wrapper.getName() will return correct data. +// fractionalContainer.setElementName(assocName); +// assocMap.put(assocName, fractionalContainer); +// } +// try { +// fractionalContainer.add(cval.clone()); +// } catch (SchemaException e) { +// // Should not happen +// throw new SystemException("Unexpected error: " + e.getMessage(), e); +// } +// } +// } +// } +// +// PrismReference resourceRef = containerWrapper.getObject().findReference(ShadowType.F_RESOURCE_REF); +// PrismObject resource = resourceRef.getValue().getObject(); +// +// // HACK. The revive should not be here. Revive is no good. The next use of the resource will +// // cause parsing of resource schema. We need some centralized place to maintain live cached copies +// // of resources. +// try { +// resource.revive(prismContext); +// } catch (SchemaException e) { +// throw new SystemException(e.getMessage(), e); +// } +// RefinedResourceSchema refinedSchema; +// CompositeRefinedObjectClassDefinition rOcDef; +// try { +// refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); +// rOcDef = refinedSchema.determineCompositeObjectClassDefinition(containerWrapper.getObject()); +// } catch (SchemaException e) { +// throw new SystemException(e.getMessage(), e); +// } +// // Make sure even empty associations have their wrappers so they can be displayed and edited +// for (RefinedAssociationDefinition assocDef : rOcDef.getAssociationDefinitions()) { +// QName name = assocDef.getName(); +// if (!assocMap.containsKey(name)) { +// PrismContainer fractionalContainer = new PrismContainer<>(ShadowType.F_ASSOCIATION, ShadowAssociationType.class, prismContext); +// fractionalContainer.setDefinition(cWrapper.getItemDefinition()); +// // HACK: set the name of the association as the element name so wrapper.getName() will return correct data. +// fractionalContainer.setElementName(name); +// assocMap.put(name, fractionalContainer); +// } +// } +// +// for (Map.Entry> assocEntry : assocMap.entrySet()) { +// RefinedAssociationDefinition assocRDef = rOcDef.findAssociationDefinition(assocEntry.getKey()); +// AssociationWrapper assocWrapper = new AssociationWrapper(cWrapper, assocEntry.getValue(), +// cWrapper.isReadonly(), ValueStatus.NOT_CHANGED, assocRDef); +// properties.add(assocWrapper); +// } +// +// } else { // if not an assignment + + // there's no point in showing properties for non-single-valued // parent containers, // so we continue only if the parent is single-valued - Collection propertyDefinitions = definition.getDefinitions(); - for (ItemDefinition itemDef : propertyDefinitions) { - //TODO temporary decision to hide adminGuiConfiguration attribute (MID-3305) - if (itemDef != null && itemDef.getName() != null && itemDef.getName().getLocalPart() != null && - itemDef.getName().getLocalPart().equals("adminGuiConfiguration")){ - continue; - } - if (itemDef instanceof PrismPropertyDefinition) { - - PrismPropertyDefinition def = (PrismPropertyDefinition) itemDef; - if (def.isIgnored() || skipProperty(def)) { - continue; - } - if (!cWrapper.isShowInheritedObjectAttributes() - && INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) { - continue; - } - - // capability handling for activation properties - if (isShadowActivation(cWrapper) && !hasActivationCapability(cWrapper, def)) { - continue; - } - - if (isShadowAssociation(cWrapper)) { - continue; - } - - PrismProperty property = container.findProperty(def.getName()); - boolean propertyIsReadOnly; - // decision is based on parent object status, not this - // container's one (because container can be added also - // to an existing object) - if (objectWrapper == null || objectWrapper.getStatus() == ContainerStatus.MODIFYING) { - - propertyIsReadOnly = cWrapper.isReadonly() || !def.canModify(); - } else { - propertyIsReadOnly = cWrapper.isReadonly() || !def.canAdd(); - } - if (property == null) { - properties.add(new PropertyWrapper(cWrapper, def.instantiate(), propertyIsReadOnly, - ValueStatus.ADDED)); - } else { - properties.add(new PropertyWrapper(cWrapper, property, propertyIsReadOnly, - ValueStatus.NOT_CHANGED)); - } - } else if (itemDef instanceof PrismReferenceDefinition) { - PrismReferenceDefinition def = (PrismReferenceDefinition) itemDef; - - if (INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) { - continue; - } - - PrismReference reference = container.findReference(def.getName()); - boolean propertyIsReadOnly; - // decision is based on parent object status, not this - // container's one (because container can be added also - // to an existing object) - if (objectWrapper == null || objectWrapper.getStatus() == ContainerStatus.MODIFYING) { - - propertyIsReadOnly = !def.canModify(); - } else { - propertyIsReadOnly = !def.canAdd(); - } - if (reference == null) { - properties.add(new ReferenceWrapper(cWrapper, def.instantiate(), propertyIsReadOnly, - ValueStatus.ADDED)); - } else { - properties.add(new ReferenceWrapper(cWrapper, reference, propertyIsReadOnly, - ValueStatus.NOT_CHANGED)); - } - - } - } - } - } - - Collections.sort(properties, new ItemWrapperComparator()); + Collection propertyDefinitions = definition.getDefinitions(); + List propertyOrReferenceWrappers = new ArrayList<>(); + List> containerWrappers = new ArrayList<>(); + propertyDefinitions.forEach( itemDef -> { + + if (itemDef.isIgnored() || skipProperty(itemDef)) { + return; + } + if (!cWrapper.isShowInheritedObjectAttributes() && INHERITED_OBJECT_ATTRIBUTES.contains(itemDef.getName())) { + return; + } + + createPropertyOrReferenceWrapper(itemDef, cWrapper, propertyOrReferenceWrappers); + createContainerWrapper(itemDef, cWrapper, containerWrappers); + + }); + + +// } + + Collections.sort(propertyOrReferenceWrappers, new ItemWrapperComparator()); + Collections.sort(containerWrappers, new ItemWrapperComparator()); + + properties.addAll(propertyOrReferenceWrappers); + properties.addAll(containerWrappers); result.recomputeStatus(); return properties; } + + + private void createPropertyOrReferenceWrapper(ItemDefinition itemDef, ContainerValueWrapper cWrapper, List properties) { + +// if (itemDef.isIgnored() || skipProperty(itemDef)) { +// return; +// } +// if (!cWrapper.isShowInheritedObjectAttributes() && INHERITED_OBJECT_ATTRIBUTES.contains(itemDef.getName())) { +// return; +// } + + PrismContainerValue containerValue = cWrapper.getContainerValue(); + + //TODO temporary decision to hide adminGuiConfiguration attribute (MID-3305) +// if (itemDef != null && itemDef.getName() != null && itemDef.getName().getLocalPart() != null && +// itemDef.getName().getLocalPart().equals("adminGuiConfiguration")){ +// continue; +// } + if (itemDef instanceof PrismPropertyDefinition) { + + properties.add(createPropertyWrapper((PrismPropertyDefinition) itemDef, cWrapper)); + } else if (itemDef instanceof PrismReferenceDefinition) { + properties.add(createReferenceWrapper((PrismReferenceDefinition) itemDef, cWrapper)); - public ContainerWrapper createCustomContainerWrapper(C container, ContainerStatus status, ItemPath path, - boolean readonly, boolean showInheritedAttributes) { - - result = new OperationResult(CREATE_PROPERTIES); + } + } - PrismContainer containerValue = container.asPrismContainerValue().getContainer(); + + private void createContainerWrapper(ItemDefinition itemDef, ContainerValueWrapper cWrapper, List> properties) { + + if (itemDef.isIgnored() || skipProperty(itemDef)) { + return; + } + if (!cWrapper.isShowInheritedObjectAttributes() && INHERITED_OBJECT_ATTRIBUTES.contains(itemDef.getName())) { + return; + } + + PrismContainerValue containerValue = cWrapper.getContainerValue(); + + //TODO temporary decision to hide adminGuiConfiguration attribute (MID-3305) +// if (itemDef != null && itemDef.getName() != null && itemDef.getName().getLocalPart() != null && +// itemDef.getName().getLocalPart().equals("adminGuiConfiguration")){ +// continue; +// } + + if (itemDef instanceof PrismContainerDefinition) { + + if (cWrapper.isMain() && !ObjectType.F_EXTENSION.equals(itemDef.getName())) { + return; + } + + ContainerWrapper subContainerWrapper = createContainerWrapper((PrismContainerDefinition) itemDef, cWrapper); + + if (ObjectType.F_EXTENSION.equals(itemDef.getName())) { + properties.addAll(((ContainerValueWrapper)subContainerWrapper.getValues().iterator().next()).getItems()); + } else { + properties.add(subContainerWrapper); + } + } + } + + private PropertyWrapper, PrismPropertyDefinition> createPropertyWrapper( + PrismPropertyDefinition def, ContainerValueWrapper cWrapper) { + PrismContainerValue containerValue = cWrapper.getContainerValue(); +// if (def.isIgnored() || skipProperty(def)) { +// return null; +// } +// if (!cWrapper.isShowInheritedObjectAttributes() && INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) { +// return null; +// } + + // capability handling for activation properties + // if (isShadowActivation(cWrapper) && + // !hasActivationCapability(cWrapper, def)) { + // continue; + // } + // + // if (isShadowAssociation(cWrapper)) { + // continue; + // } + + PrismProperty property = containerValue.findProperty(def.getName()); + boolean propertyIsReadOnly = isItemReadOnly(def, cWrapper); + // decision is based on parent object status, not this + // container's one (because container can be added also + // to an existing object) + + if (property == null) { + return new PropertyWrapper(cWrapper, def.instantiate(), propertyIsReadOnly, ValueStatus.ADDED); + } + return new PropertyWrapper(cWrapper, property, propertyIsReadOnly, ValueStatus.NOT_CHANGED); + } - ContainerWrapper cWrapper = new ContainerWrapper(containerValue, status, path, readonly, showInheritedAttributes); + private ReferenceWrapper createReferenceWrapper(PrismReferenceDefinition def, ContainerValueWrapper cWrapper) { + + PrismContainerValue containerValue = cWrapper.getContainerValue(); +// +// if (INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) { +// return null; +// } + + PrismReference reference = containerValue.findReference(def.getName()); + boolean propertyIsReadOnly = isItemReadOnly(def, cWrapper); + // decision is based on parent object status, not this + // container's one (because container can be added also + // to an existing object) + + if (reference == null) { + return new ReferenceWrapper(cWrapper, def.instantiate(), propertyIsReadOnly, + ValueStatus.ADDED); + } + + return new ReferenceWrapper(cWrapper, reference, propertyIsReadOnly, + ValueStatus.NOT_CHANGED); + + } + + private ContainerWrapper createContainerWrapper(PrismContainerDefinition def, ContainerValueWrapper cWrapper) { + + PrismContainerValue containerValue = cWrapper.getContainerValue(); +// PrismContainer container = containerValue.findContainer(def.getName()); + + PrismContainer container = containerValue.findContainer(def.getName()); + + ContainerWrapper subContainerWrapper = null; + if (container == null) { + PrismContainer newContainer; + try { + newContainer = (PrismContainer) def.instantiate(); + } catch (SchemaException e) { + LoggingUtils.logException(LOGGER, "Cannot create container " + def.getName(), e); + return null; + } + return createContainerWrapper(newContainer, ContainerStatus.ADDING, cWrapper.getPath().append(newContainer.getPath())); + } + return createContainerWrapper(container, ContainerStatus.MODIFYING, container.getPath()); +// List subContainerValues = createContainerValues(subContainerWrapper); +// subContainerWrapper.setProperties(subContainerValues); +// subContainerWrapper.computeStripes(); + } + + private boolean isItemReadOnly(ItemDefinition def, ContainerValueWrapper cWrapper) { + if (cWrapper == null || cWrapper.getStatus() == ValueStatus.NOT_CHANGED) { - List properties = createProperties(container, containerValue.getDefinition(), cWrapper); - cWrapper.setProperties(properties); + return cWrapper.isReadonly() || !def.canModify(); + } + + return cWrapper.isReadonly() || !def.canAdd(); + + } - cWrapper.computeStripes(); +private void createShadowContainer(PrismContainerDefinition containerDefinition, ContainerWrapper containerWrapper, PrismContainerDefinition definition) throws SchemaException { + QName name = containerDefinition.getName(); - return cWrapper; - } + if (ShadowType.F_ATTRIBUTES.equals(name)) { + definition = null;//containerWrapper.getObject().getRefinedAttributeDefinition(); -private List createProperties(C container, PrismContainerDefinition definition, ContainerWrapper cWrapper) { - Collection propertyDefinitions = definition.getDefinitions(); - - List properties = new ArrayList<>(); - for (ItemDefinition itemDef : propertyDefinitions) { - //TODO temporary decision to hide adminGuiConfiguration attribute (MID-3305) - if (itemDef != null && itemDef.getName() != null && itemDef.getName().getLocalPart() != null && - itemDef.getName().getLocalPart().equals("adminGuiConfiguration")){ - continue; - } - if (itemDef instanceof PrismPropertyDefinition) { - - PrismPropertyDefinition def = (PrismPropertyDefinition) itemDef; - if (def.isIgnored() || skipProperty(def)) { - continue; - } - if (!cWrapper.isShowInheritedObjectAttributes() - && INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) { - continue; - } - - PrismProperty property = container.asPrismContainerValue().findProperty(def.getName()); - boolean propertyIsReadOnly; - // decision is based on parent object status, not this - // container's one (because container can be added also - // to an existing object) - if (cWrapper.getStatus() == ContainerStatus.MODIFYING) { - - propertyIsReadOnly = cWrapper.isReadonly() || !def.canModify(); - } else { - propertyIsReadOnly = cWrapper.isReadonly() || !def.canAdd(); - } - if (property == null) { - properties.add(new PropertyWrapper(cWrapper, def.instantiate(), propertyIsReadOnly, - ValueStatus.ADDED)); - } else { - properties.add(new PropertyWrapper(cWrapper, property, propertyIsReadOnly, - ValueStatus.NOT_CHANGED)); - } - } else if (itemDef instanceof PrismReferenceDefinition) { - PrismReferenceDefinition def = (PrismReferenceDefinition) itemDef; - - if (INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) { - continue; - } - - PrismReference reference = container.asPrismContainerValue().findReference(def.getName()); - boolean propertyIsReadOnly; - // decision is based on parent object status, not this - // container's one (because container can be added also - // to an existing object) - if (cWrapper.getStatus() == ContainerStatus.MODIFYING) { - - propertyIsReadOnly = !def.canModify(); - } else { - propertyIsReadOnly = !def.canAdd(); - } - if (reference == null) { - properties.add(new ReferenceWrapper(cWrapper, def.instantiate(), propertyIsReadOnly, - ValueStatus.ADDED)); - } else { - properties.add(new ReferenceWrapper(cWrapper, reference, propertyIsReadOnly, - ValueStatus.NOT_CHANGED)); - } - - } - } - - Collections.sort(properties, new ItemWrapperComparator()); + if (definition == null) { + PrismReference resourceRef = containerWrapper.getItem().findReference(ShadowType.F_RESOURCE_REF); + PrismObject resource = resourceRef.getValue().getObject(); - return properties; +// definition = modelServiceLocator +// .getModelInteractionService() +// .getEditObjectClassDefinition((PrismObject) containerWrapper.getObject().getObject(), resource, +// AuthorizationPhaseType.REQUEST) +// .toResourceAttributeContainerDefinition(); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Refined account def:\n{}", definition.debugDump()); + } + } + + + } else { + definition = containerDefinition; + } } +// public ContainerWrapper createCustomContainerWrapper(C container, ContainerStatus status, ItemPath path, +// boolean readonly, boolean showInheritedAttributes) { +// +// result = new OperationResult(CREATE_PROPERTIES); +// +// PrismContainer containerValue = container.asPrismContainerValue().getContainer(); +// +// ContainerWrapper cWrapper = new ContainerWrapper(containerValue, status, path, readonly, showInheritedAttributes); +// +// List properties = createProperties(container, containerValue.getDefinition(), cWrapper); +// cWrapper.setProperties(properties); +// +// cWrapper.computeStripes(); +// +// return cWrapper; +// } + +//private List createProperties(C container, PrismContainerDefinition definition, ContainerWrapper cWrapper) { +// Collection propertyDefinitions = definition.getDefinitions(); +// +// List properties = new ArrayList<>(); +// for (ItemDefinition itemDef : propertyDefinitions) { +// //TODO temporary decision to hide adminGuiConfiguration attribute (MID-3305) +// if (itemDef != null && itemDef.getName() != null && itemDef.getName().getLocalPart() != null && +// itemDef.getName().getLocalPart().equals("adminGuiConfiguration")){ +// continue; +// } +// if (itemDef instanceof PrismPropertyDefinition) { +// +// PrismPropertyDefinition def = (PrismPropertyDefinition) itemDef; +// if (def.isIgnored() || skipProperty(def)) { +// continue; +// } +// if (!cWrapper.isShowInheritedObjectAttributes() +// && INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) { +// continue; +// } +// +// PrismProperty property = container.asPrismContainerValue().findProperty(def.getName()); +// boolean propertyIsReadOnly; +// // decision is based on parent object status, not this +// // container's one (because container can be added also +// // to an existing object) +// if (cWrapper.getStatus() == ContainerStatus.MODIFYING) { +// +// propertyIsReadOnly = cWrapper.isReadonly() || !def.canModify(); +// } else { +// propertyIsReadOnly = cWrapper.isReadonly() || !def.canAdd(); +// } +// if (property == null) { +// properties.add(new PropertyWrapper(cWrapper, def.instantiate(), propertyIsReadOnly, +// ValueStatus.ADDED)); +// } else { +// properties.add(new PropertyWrapper(cWrapper, property, propertyIsReadOnly, +// ValueStatus.NOT_CHANGED)); +// } +// } else if (itemDef instanceof PrismReferenceDefinition) { +// PrismReferenceDefinition def = (PrismReferenceDefinition) itemDef; +// +// if (INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) { +// continue; +// } +// +// PrismReference reference = container.asPrismContainerValue().findReference(def.getName()); +// boolean propertyIsReadOnly; +// // decision is based on parent object status, not this +// // container's one (because container can be added also +// // to an existing object) +// if (cWrapper.getStatus() == ContainerStatus.MODIFYING) { +// +// propertyIsReadOnly = !def.canModify(); +// } else { +// propertyIsReadOnly = !def.canAdd(); +// } +// if (reference == null) { +// properties.add(new ReferenceWrapper(cWrapper, def.instantiate(), propertyIsReadOnly, +// ValueStatus.ADDED)); +// } else { +// properties.add(new ReferenceWrapper(cWrapper, reference, propertyIsReadOnly, +// ValueStatus.NOT_CHANGED)); +// } +// +// } +// } +// +// Collections.sort(properties, new ItemWrapperComparator()); +// +// return properties; +// +//} + private boolean isShadowAssociation(ContainerWrapper cWrapper) { - ObjectWrapper oWrapper = cWrapper.getObject(); - if (oWrapper == null) { - return false; - } +// ObjectWrapper oWrapper = cWrapper.getObject(); +// if (oWrapper == null) { +// return false; +// } PrismContainer container = cWrapper.getItem(); - - if (!ShadowType.class.isAssignableFrom(oWrapper.getObject().getCompileTimeClass())) { +// + if (!ShadowType.class.isAssignableFrom(container.getCompileTimeClass())) { return false; } @@ -487,17 +624,17 @@ private boolean isShadowAssociation(ContainerWrapper cWrapper) { } private boolean isShadowActivation(ContainerWrapper cWrapper) { - ObjectWrapper oWrapper = cWrapper.getObject(); - if (oWrapper == null) { - return false; - } - PrismContainer container = cWrapper.getItem(); - - if (!ShadowType.class.isAssignableFrom(oWrapper.getObject().getCompileTimeClass())) { +// ObjectWrapper oWrapper = cWrapper.getObject(); +// if (oWrapper == null) { +// return false; +// } + PrismContainer oWrapper = cWrapper.getItem(); + + if (!ShadowType.class.isAssignableFrom(oWrapper.getCompileTimeClass())) { return false; } - if (!ShadowType.F_ACTIVATION.equals(container.getElementName())) { + if (!ShadowType.F_ACTIVATION.equals(oWrapper.getElementName())) { return false; } @@ -505,9 +642,16 @@ private boolean isShadowActivation(ContainerWrapper cWrapper) { } private boolean hasActivationCapability(ContainerWrapper cWrapper, PrismPropertyDefinition def) { - ObjectWrapper oWrapper = cWrapper.getObject(); - ShadowType shadow = (ShadowType) oWrapper.getObject().asObjectable(); + PrismContainer oWrapper = cWrapper.getItem(); + if (!(oWrapper instanceof PrismObject)) { + return false; + } + ObjectType objectType = (ObjectType) ((PrismObject)oWrapper).asObjectable(); + if (!(objectType instanceof ShadowType)) { + return false; + } + ShadowType shadow = (ShadowType) objectType; ActivationCapabilityType cap = ResourceTypeUtil.getEffectiveCapability(shadow.getResource(), ActivationCapabilityType.class); @@ -595,7 +739,7 @@ private static String formatTime(XMLGregorianCalendar time) { * @deprecated will be implemented through annotations in schema */ @Deprecated - private boolean skipProperty(PrismPropertyDefinition def) { + private boolean skipProperty(ItemDefinition def) { final List names = new ArrayList<>(); names.add(PasswordType.F_FAILED_LOGINS); names.add(PasswordType.F_LAST_FAILED_LOGIN); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapper.java index 27525ac2ac3..c03c3d787c1 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapper.java @@ -63,7 +63,7 @@ public interface ItemWrapper extends * Visibility flag. This is NOT an override, it defines whether the item * should be displayed or not. */ - boolean isVisible(); + boolean isVisible(boolean showEmpty); /** * Used to display the form elements with stripe in every other line. @@ -72,7 +72,7 @@ public interface ItemWrapper extends void setStripe(boolean isStripe); - ContainerWrapper getContainer(); +// ContainerValueWrapper getContainerValue(); void addValue(); @@ -80,7 +80,9 @@ public interface ItemWrapper extends // are required fields enforced by wicket? default boolean isEnforceRequiredFields() { - ContainerWrapper cw = getContainer(); + ContainerWrapper cw = getParent(); return cw == null || cw.isEnforceRequiredFields(); } + + ContainerWrapper getParent(); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapperComparator.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapperComparator.java index 288c5799465..5e2b9305278 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapperComparator.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapperComparator.java @@ -17,6 +17,8 @@ package com.evolveum.midpoint.web.component.prism; import com.evolveum.midpoint.prism.ItemDefinition; +import com.evolveum.midpoint.prism.PrismContainerDefinition; + import org.apache.commons.lang.StringUtils; import java.io.Serializable; @@ -38,8 +40,20 @@ public int compare(ItemWrapper p1, ItemWrapper p2) { if (isMainContainer(p2)) { return 1; } - - Integer index1 = def1.getDisplayOrder(); + + if (def1 instanceof PrismContainerDefinition) { + return 1; + } + + if (def1 instanceof PrismContainerDefinition) { + return 1; + } + + Integer index1 = null; + if (def1 != null) { + index1 = def1.getDisplayOrder(); + } + Integer index2 = def2.getDisplayOrder(); if (index1 != null && index2 != null) { return index1 - index2; @@ -47,6 +61,8 @@ public int compare(ItemWrapper p1, ItemWrapper p2) { return -1; } else if (index1 == null && index2 != null) { return 1; + } else if (index1 == index2) { + return 0; } return String.CASE_INSENSITIVE_ORDER.compare(getDisplayName(def1), getDisplayName(def2)); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java index 55beaf592ec..db42d95feb3 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java @@ -46,7 +46,7 @@ /** * @author lazyman */ -public class ObjectWrapper implements Serializable, Revivable, DebugDumpable { +public class ObjectWrapper extends PrismWrapper implements Serializable, Revivable, DebugDumpable { private static final long serialVersionUID = 1L; public static final String F_DISPLAY_NAME = "displayName"; @@ -65,10 +65,10 @@ public class ObjectWrapper implements Serializable, Reviva private String description; private List> containers; - private boolean showEmpty; - private boolean minimalized; - private boolean sorted; - private boolean showMetadata = false; +// private boolean showEmpty; +// private boolean minimalized; +// private boolean sorted; +// private boolean showMetadata = false; private boolean selectable; private boolean selected; @@ -89,17 +89,15 @@ public class ObjectWrapper implements Serializable, Reviva private OperationResult fetchResult; // a "static" (non-refined) definition that reflects editability of the object in terms of midPoint schema limitations and security - private PrismContainerDefinition objectDefinitionForEditing; +// private PrismContainerDefinition objectDefinitionForEditing; // a refined definition of an resource object class that reflects its editability; applicable for shadows only private RefinedObjectClassDefinition objectClassDefinitionForEditing; - public ObjectWrapper(String displayName, String description, PrismObject object, - PrismContainerDefinition objectDefinitionForEditing, ContainerStatus status) { - this(displayName, description, object, objectDefinitionForEditing, null, status); + public ObjectWrapper(String displayName, String description, PrismObject object, ContainerStatus status) { + this(displayName, description, object, null, status); } public ObjectWrapper(String displayName, String description, PrismObject object, - PrismContainerDefinition objectDefinitionForEditing, RefinedObjectClassDefinition objectClassDefinitionForEditing, ContainerStatus status) { Validate.notNull(object, "Object must not be null."); Validate.notNull(status, "Container status must not be null."); @@ -109,13 +107,12 @@ public ObjectWrapper(String displayName, String description, PrismObject object, this.object = object; this.objectOld = object.clone(); this.status = status; - this.objectDefinitionForEditing = objectDefinitionForEditing; this.objectClassDefinitionForEditing = objectClassDefinitionForEditing; } - public void initializeContainers(PageBase pageBase) { - //todo remove - } +// public void initializeContainers(PageBase pageBase) { +// //todo remove +// } public void revive(PrismContext prismContext) throws SchemaException { if (object != null) { @@ -205,38 +202,46 @@ public String getDescription() { return description; } - public boolean isMinimalized() { - return minimalized; - } - - public void setMinimalized(boolean minimalized) { - this.minimalized = minimalized; - } - - public boolean isSorted() { - return sorted; - } - - public void setSorted(boolean sorted) { - this.sorted = sorted; - } - - public boolean isShowMetadata() { - return showMetadata; - } - - public void setShowMetadata(boolean showMetadata) { - this.showMetadata = showMetadata; - } - - public boolean isShowEmpty() { - return showEmpty; - } - - public void setShowEmpty(boolean showEmpty) { - this.showEmpty = showEmpty; - computeStripes(); - } +// @Override +// public boolean isMinimalized() { +// return minimalized; +// } +// +// @Override +// public void setMinimalized(boolean minimalized) { +// this.minimalized = minimalized; +// } +// +// @Override +// public boolean isSorted() { +// return sorted; +// } +// +// @Override +// public void setSorted(boolean sorted) { +// this.sorted = sorted; +// } +// +// @Override +// public boolean isShowMetadata() { +// return showMetadata; +// } +// +// @Override +// public void setShowMetadata(boolean showMetadata) { +// this.showMetadata = showMetadata; +// } +// +// @Override +// public boolean isShowEmpty() { +// return showEmpty; +// } +// +// @Override +// public void setShowEmpty(boolean showEmpty) { +// this.showEmpty = showEmpty; +// computeStripes(); +// } public boolean isSelectable() { return selectable; @@ -303,7 +308,7 @@ public IW findPropertyWrapper(ItemPath path) { if (containerWrapper == null) { return null; } - return (IW) containerWrapper.findPropertyWrapper(ItemPath.getFirstName(propertyPath)); + return (IW) containerWrapper.findPropertyWrapper(propertyPath); } public void normalize() throws SchemaException { @@ -412,18 +417,18 @@ private ObjectDelta createAddingObjectDelta() throws SchemaException { for (ContainerWrapper containerWrapper : getContainers()) { - if (containerWrapper.getItemDefinition().getName().equals(ShadowType.F_ASSOCIATION)) { - PrismContainer associationContainer = object.findOrCreateContainer(ShadowType.F_ASSOCIATION); - List associationItemWrappers = (List) containerWrapper.getItems(); - for (AssociationWrapper associationItemWrapper : associationItemWrappers) { - List assocValueWrappers = associationItemWrapper.getValues(); - for (ValueWrapper assocValueWrapper : assocValueWrappers) { - PrismContainerValue assocValue = (PrismContainerValue) assocValueWrapper.getValue(); - associationContainer.add(assocValue.clone()); - } - } - continue; - } +// if (containerWrapper.getItemDefinition().getName().equals(ShadowType.F_ASSOCIATION)) { +// PrismContainer associationContainer = object.findOrCreateContainer(ShadowType.F_ASSOCIATION); +// List associationItemWrappers = (List) containerWrapper.getItems(); +// for (AssociationWrapper associationItemWrapper : associationItemWrappers) { +// List assocValueWrappers = associationItemWrapper.getValues(); +// for (ValueWrapper assocValueWrapper : assocValueWrappers) { +// PrismContainerValue assocValue = (PrismContainerValue) assocValueWrapper.getValue(); +// associationContainer.add(assocValue.clone()); +// } +// } +// continue; +// } if (!containerWrapper.hasChanged()) { continue; @@ -449,18 +454,18 @@ private ObjectDelta createAddingObjectDelta() throws SchemaException { container = object; } - for (ItemWrapper itemWrapper : (List) containerWrapper.getItems()) { - if (!itemWrapper.hasChanged()) { - continue; - } - if (container.findItem(itemWrapper.getName()) != null) { - continue; - } - Item updatedItem = ((PropertyOrReferenceWrapper) itemWrapper).getUpdatedItem(object.getPrismContext()); - if (!updatedItem.isEmpty()) { - container.add(updatedItem); - } - } +// for (ContainerValueWrapper itemWrapper : (List) containerWrapper.getValues()) { +// if (!itemWrapper.hasChanged()) { +// continue; +// } +// if (container.findItem(itemWrapper.getName()) != null) { +// continue; +// } +// Item updatedItem = ((PropertyOrReferenceWrapper) itemWrapper).getUpdatedItem(object.getPrismContext()); +// if (!updatedItem.isEmpty()) { +// container.add(updatedItem); +// } +// } } // cleanup empty containers @@ -587,9 +592,9 @@ public void setEnforceRequiredFields(boolean enforceRequiredFields) { } public PrismContainerDefinition getDefinition() { - if (objectDefinitionForEditing != null) { - return objectDefinitionForEditing; - } +// if (objectDefinitionForEditing != null) { +// return objectDefinitionForEditing; +// } return object.getDefinition(); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java index 443a1324fcf..ed871410db5 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java @@ -58,12 +58,14 @@ public class ObjectWrapperFactory { private static final String CREATE_OBJECT_WRAPPER = DOT_CLASS + "createObjectWrapper"; private static final List INHERITED_OBJECT_SUBCONTAINERS = Arrays.asList( - ObjectType.F_METADATA, - ObjectType.F_EXTENSION); +// ObjectType.F_METADATA, +// ObjectType.F_EXTENSION + ); private static final List CONTAINERS_TO_IGNORE = Arrays.asList( SubjectedObjectSelectorType.COMPLEX_TYPE, TriggerType.COMPLEX_TYPE, + OperationExecutionType.COMPLEX_TYPE, ApprovalSchemaType.COMPLEX_TYPE, PasswordHistoryEntryType.COMPLEX_TYPE, NonceType.COMPLEX_TYPE); @@ -101,6 +103,8 @@ public ObjectWrapper createObjectWrapper(String displa if (LOGGER.isTraceEnabled()) { LOGGER.trace("Edit definition for {}:\n{}", object, objectDefinitionForEditing.debugDump(1)); } + + RefinedObjectClassDefinition objectClassDefinitionForEditing = null; if (isShadow(object)) { PrismReference resourceRef = object.findReference(ShadowType.F_RESOURCE_REF); @@ -134,8 +138,13 @@ private ObjectWrapper createObjectWrapper(String displ } else { this.result = result; } - - ObjectWrapper objectWrapper = new ObjectWrapper<>(displayName, description, object, objectDefinitionForEditing, + + //replace default definition with the updated definition - limitation + security included + if (objectDefinitionForEditing != null) { + object.setDefinition(objectDefinitionForEditing); + } + + ObjectWrapper objectWrapper = new ObjectWrapper<>(displayName, description, object, objectClassDefinitionForEditing, status); List> containerWrappers = createContainerWrappers(objectWrapper, object, @@ -169,7 +178,7 @@ private List> c } else if (ReportType.class.isAssignableFrom(clazz)) { addReportContainers(containerWrappers, oWrapper, object, result); } else { - ContainerWrapper mainContainerWrapper = cwf.createContainerWrapper(oWrapper, object, cStatus, null); + ContainerWrapper mainContainerWrapper = cwf.createContainerWrapper(object, cStatus, null); mainContainerWrapper.setDisplayName("prismContainer.mainPanelDisplayName"); result.addSubresult(cwf.getResult()); containerWrappers.add(mainContainerWrapper); @@ -211,7 +220,7 @@ private List> c } ContainerWrapperFactory cwf = new ContainerWrapperFactory(modelServiceLocator); - ContainerWrapper wrapper = cwf.createContainerWrapper(oWrapper, container, status, new ItemPath(name)); + ContainerWrapper wrapper = cwf.createContainerWrapper(container, status, new ItemPath(name)); result.addSubresult(cwf.getResult()); list.add(wrapper); if (!ShadowType.F_ASSOCIATION.equals(name)) { @@ -245,17 +254,17 @@ private void addContainerWrapper PrismContainerDefinition containerDef = (PrismContainerDefinition) def; //todo this oWrapper.isShowAssignments() value is not set when initialization occurs (only default is there) [lazyman] - if (!oWrapper.isShowAssignments() && AssignmentType.COMPLEX_TYPE.equals(containerDef.getTypeName())) { - continue; - } +// if (!oWrapper.isShowAssignments() && AssignmentType.COMPLEX_TYPE.equals(containerDef.getTypeName())) { +// continue; +// } //todo this oWrapper.isShowInheritedObjectAttributes() value is not set when initialization occurs (only default is there) [lazyman] - if (!oWrapper.isShowInheritedObjectAttributes()) { - boolean res = INHERITED_OBJECT_SUBCONTAINERS.contains(containerDef.getName()); - LOGGER.info("checking " + containerDef.getName() + ", result = " + res); - if (res) { - continue; - } - } +// if (!oWrapper.isShowInheritedObjectAttributes()) { +// boolean res = INHERITED_OBJECT_SUBCONTAINERS.contains(containerDef.getName()); +// LOGGER.info("checking " + containerDef.getName() + ", result = " + res); +// if (res) { +// continue; +// } +// } ItemPath newPath = createPropertyPath(parentPath, containerDef.getName()); @@ -264,34 +273,40 @@ private void addContainerWrapper // potentially multivalued. // Therefore (as a brutal hack), for multivalued parents we simply // skip it. - if (parentContainer.size() <= 1) { +// if (parentContainer.size() <= 1) { // the same check as in getValue() implementation - boolean isMultiValued = parentContainer.getDefinition() != null && !parentContainer.getDefinition().isDynamic() - && !parentContainer.getDefinition().isSingleValue(); - if (!isMultiValued) { +// boolean isMultiValued = parentContainer.getDefinition() != null && !parentContainer.getDefinition().isDynamic(); +// && !parentContainer.getDefinition().isSingleValue(); +// if (!isMultiValued) { ContainerWrapperFactory cwf = new ContainerWrapperFactory(modelServiceLocator); + if (AssignmentType.COMPLEX_TYPE.equals(parentContainer.getDefinition().getName())) { + System.out.println("something"); + } + PrismContainer prismContainer = parentContainer.findContainer(def.getName()); ContainerWrapper container; if (prismContainer != null) { - container = cwf.createContainerWrapper(oWrapper, prismContainer, ContainerStatus.MODIFYING, newPath); + container = cwf.createContainerWrapper(prismContainer, ContainerStatus.MODIFYING, newPath); } else { prismContainer = containerDef.instantiate(); - container = cwf.createContainerWrapper(oWrapper, prismContainer, ContainerStatus.ADDING, newPath); + container = cwf.createContainerWrapper(prismContainer, ContainerStatus.ADDING, newPath); } result.addSubresult(cwf.getResult()); containerWrappers.add(container); - if (!AssignmentType.COMPLEX_TYPE.equals(containerDef.getTypeName()) - || !ShadowType.F_ASSOCIATION.equals(parentContainer.getElementName())) { +// if (!AssignmentType.COMPLEX_TYPE.equals(containerDef.getTypeName()) +// || !ShadowType.F_ASSOCIATION.equals(parentContainer.getElementName())) { // do not show internals of Assignments (e.g. activation) - addContainerWrappers(containerWrappers, oWrapper, prismContainer, newPath, result); - } +// if (newPath.size() <= 1) { +// addContainerWrappers(containerWrappers, oWrapper, prismContainer, newPath, result); +// } +// } } - } - } +// } +// } } @@ -355,12 +370,14 @@ private void addShadowContainers( ShadowType.F_ATTRIBUTES); attributesContainer = definition.instantiate(); } + + - ContainerWrapper attributesContainerWrapper = cwf.createContainerWrapper(oWrapper, attributesContainer, status, + ContainerWrapper attributesContainerWrapper = cwf.createContainerWrapper(attributesContainer, status, new ItemPath(ShadowType.F_ATTRIBUTES)); result.addSubresult(cwf.getResult()); - attributesContainerWrapper.setMain(true); +// attributesContainerWrapper.setMain(true); attributesContainerWrapper.setDisplayName("prismContainer.shadow.mainPanelDisplayName"); containers.add(attributesContainerWrapper); @@ -376,7 +393,7 @@ private void addShadowContainers( } PrismContainer associationContainer = object.findOrCreateContainer(ShadowType.F_ASSOCIATION); - attributesContainerWrapper = cwf.createContainerWrapper(oWrapper, associationContainer, ContainerStatus.MODIFYING, + attributesContainerWrapper = cwf.createContainerWrapper(associationContainer, ContainerStatus.MODIFYING, new ItemPath(ShadowType.F_ASSOCIATION)); result.addSubresult(cwf.getResult()); containers.add(attributesContainerWrapper); @@ -409,7 +426,7 @@ private void addReportContainers( container = definition.instantiate(); } ContainerWrapperFactory cwf = new ContainerWrapperFactory(modelServiceLocator); - ContainerWrapper wrapper = cwf.createContainerWrapper(oWrapper, container, status, new ItemPath(ReportType.F_CONFIGURATION)); + ContainerWrapper wrapper = cwf.createContainerWrapper(container, status, new ItemPath(ReportType.F_CONFIGURATION)); result.addSubresult(cwf.getResult()); containers.add(wrapper); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.html index df7935a8a82..e13cc49f4d9 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.html @@ -17,11 +17,12 @@ -
-
-
-
+ + +
+ +
-
+ diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.java index 2fa5e6cab0f..6968ed3e15f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.java @@ -16,6 +16,8 @@ package com.evolveum.midpoint.web.component.prism; +import java.util.List; + import org.apache.wicket.AttributeModifier; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.html.form.Form; @@ -48,6 +50,7 @@ public class PrismContainerPanel extends Panel { public PrismContainerPanel(String id, final IModel model, boolean showHeader, Form form, PageBase pageBase) { super(id); + setOutputMarkupId(true); this.pageBase = pageBase; LOGGER.trace("Creating container panel for {}", model.getObject()); @@ -58,29 +61,34 @@ public PrismContainerPanel(String id, final IModel model, bool @Override public boolean isVisible() { ContainerWrapper containerWrapper = model.getObject(); - PrismContainer prismContainer = containerWrapper.getItem(); - if (containerWrapper.getItemDefinition().isOperational()) { - return false; - } - - // HACK HACK HACK - if (ShadowType.F_ASSOCIATION.equals(prismContainer.getElementName())) { - return true; - } - - boolean isVisible = false; - for (ItemWrapper item : containerWrapper.getItems()) { - if (containerWrapper.isItemVisible(item)) { - isVisible = true; - break; - } - } - - return !containerWrapper.getItems().isEmpty() && isVisible; +// PrismContainer prismContainer = containerWrapper.getItem(); +// if (containerWrapper.getItemDefinition().isOperational()) { +// return false; +// } + return containerWrapper.isVisible(); +// return containerWrapper.isItemVisible(); + +// // HACK HACK HACK +// if (ShadowType.F_ASSOCIATION.equals(prismContainer.getElementName())) { +// return true; +// } + +// return !containerWrapper.getValues().isEmpty() && containerWrapper.isVisible(); +// return true; +// boolean isVisible = false; +// for (ContainerValueWrapper values : containerWrapper.getValues()) { +// if (item.isItemVisible(item)) { +// isVisible = true; +// break; +// } +// } +// +// return !containerWrapper.getValues().isEmpty() && isVisible; } }); initLayout(model, form, showHeader); + } private void initLayout(final IModel model, final Form form, boolean showHeader) { @@ -91,10 +99,11 @@ private void initLayout(final IModel model, final Form form, b protected void onButtonClick(AjaxRequestTarget target) { target.add(PrismContainerPanel.this.findParent(PrismObjectPanel.class)); } + @Override public boolean isButtonsVisible() { - return false; + return true; } }; @@ -103,10 +112,10 @@ public boolean isButtonsVisible() { @Override public boolean isVisible() { - return showHeader && !model.getObject().isMain(); + return showHeader;// && !model.getObject().isMain(); } }); - add(header); +// add(header); addOrReplaceProperties(model, form, false); } @@ -128,29 +137,23 @@ public String getObject() { } private void addOrReplaceProperties(IModel model, final Form form, boolean isToBeReplaced){ - ListView properties = new ListView("properties", - new PropertyModel(model, "properties")) { - private static final long serialVersionUID = 1L; - + + ListView values = new ListView("values", new PropertyModel>(model, "values")) { + @Override - protected void populateItem(final ListItem item) { - item.add(new PrismPropertyPanel("property", item.getModel(), form, pageBase)); - item.add(new VisibleEnableBehaviour() { - private static final long serialVersionUID = 1L; - - @Override - public boolean isVisible() { - return item.getModel().getObject().isVisible(); - } - }); - item.add(AttributeModifier.append("class", createStyleClassModel(item.getModel()))); - } - }; - properties.setReuseItems(true); + protected void populateItem(ListItem item) { + item.add(new ContainerValuePanel("value", item.getModel(), true, form, pageBase)); + + + } + + }; + + values.setReuseItems(true); if (isToBeReplaced) { - replace(properties); + replace(values); } else { - add(properties); + add(values); } } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismHeaderPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismHeaderPanel.java index fe90371ee02..3cc38ae5399 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismHeaderPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismHeaderPanel.java @@ -35,7 +35,7 @@ * * WARNING: super ugly code ahead */ -public class PrismHeaderPanel extends BasePanel { +public abstract class PrismHeaderPanel extends BasePanel { private static final long serialVersionUID = 1L; private static final String ID_SHOW_EMPTY_FIELDS = "showEmptyFields"; @@ -49,11 +49,12 @@ public class PrismHeaderPanel extends BasePanel { public PrismHeaderPanel(String id, IModel model) { super(id, model); - initLayout(model); + initLayout(); } - private void initLayout(final IModel model) { + private void initLayout() { + setOutputMarkupId(true); VisibleEnableBehaviour buttonsVisibleBehaviour = new VisibleEnableBehaviour() { private static final long serialVersionUID = 1L; @@ -69,21 +70,23 @@ public boolean isVisible() { @Override public void onClick(AjaxRequestTarget target) { - ObjectWrapper objectWrapper = getObjectWrapper(model); - objectWrapper.setShowMetadata(!objectWrapper.isShowMetadata()); +// ObjectWrapper objectWrapper = getObjectWrapper(model); +// PrismWrapper wrapper = PrismHeaderPanel.this.getModelObject(); +// wrapper.setShowMetadata(wrapper.isShowMetadata()); +// objectWrapper.setShowMetadata(!objectWrapper.isShowMetadata()); onButtonClick(target); } @Override public boolean isOn() { - return getObjectWrapper(model).isShowMetadata(); + return getObjectWrapper().isShowMetadata(); } }; showMetadataButton.add(new AttributeModifier("title", new AbstractReadOnlyModel() { @Override public Object getObject() { - return getObjectWrapper(model) == null ? "" : (getObjectWrapper(model).isShowMetadata() ? + return getObjectWrapper() == null ? "" : (getObjectWrapper().isShowMetadata() ? createStringResource("PrismObjectPanel.hideMetadata").getString() : createStringResource("PrismObjectPanel.showMetadata").getString()); } @@ -97,7 +100,7 @@ public Object getObject() { @Override public void onClick(AjaxRequestTarget target) { - ObjectWrapper objectWrapper = getObjectWrapper(model); + PrismWrapper objectWrapper = getObjectWrapper(); objectWrapper.setShowEmpty(!objectWrapper.isShowEmpty()); onButtonClick(target); @@ -105,10 +108,10 @@ public void onClick(AjaxRequestTarget target) { @Override public boolean isOn() { - return getObjectWrapper(model).isShowEmpty(); + return getObjectWrapper().isShowEmpty(); } }; - showEmptyFieldsButton.setMarkupId(ID_SHOW_EMPTY_FIELDS); + showEmptyFieldsButton.setOutputMarkupId(true); showEmptyFieldsButton.add(buttonsVisibleBehaviour); add(showEmptyFieldsButton); @@ -119,16 +122,16 @@ public boolean isOn() { @Override public void onClick(AjaxRequestTarget target) { - ObjectWrapper objectWrapper = getObjectWrapper(model); + PrismWrapper objectWrapper = getObjectWrapper(); objectWrapper.setSorted(!objectWrapper.isSorted()); - objectWrapper.sort((PageBase)getPage()); +// objectWrapper.sort((PageBase)getPage()); onButtonClick(target); } @Override public boolean isOn() { - return getObjectWrapper(model).isSorted(); + return getObjectWrapper().isSorted(); } }; sortPropertiesButton.add(buttonsVisibleBehaviour); @@ -140,9 +143,11 @@ public boolean isOn() { @Override public String getObject() { - Object wrapper = model.getObject(); - String displayName = null; - if (wrapper instanceof ContainerWrapper) { + PrismWrapper wrapper = getObjectWrapper(); + String displayName = "displayName.not.set"; + if (wrapper instanceof ContainerValueWrapper) { + displayName = ((ContainerValueWrapper) wrapper).getDisplayName(); + } else if (wrapper instanceof ContainerWrapper) { displayName = ((ContainerWrapper)wrapper).getDisplayName(); } else if (wrapper instanceof ObjectWrapper) { // HACK HACK HACK @@ -162,15 +167,18 @@ public String getObject() { add(new Label(ID_LABEL, headerLabelModel)); } - private ObjectWrapper getObjectWrapper(IModel model) { - Object wrapper = model.getObject(); - ObjectWrapper objectWrapper = null; - if (wrapper instanceof ContainerWrapper) { - return ((ContainerWrapper)wrapper).getObject(); - } else if (wrapper instanceof ObjectWrapper) { - return (ObjectWrapper)wrapper; - } - return null; + private PrismWrapper getObjectWrapper() { + return getModelObject(); +// Object wrapper = model.getObject(); +// ObjectWrapper objectWrapper = null; +// if (wrapper instanceof ContainerWrapper) { +// return ((ContainerWrapper)wrapper).getObject(); +// } else if (wrapper instanceof ObjectWrapper) { +// return (ObjectWrapper)wrapper; +// } else if (wrapper instanceof ContainerValueWrapper) { +// return ((ContainerValueWrapper) wrapper).getContainer().getObject(); +// } +// return null; } protected void onButtonClick(AjaxRequestTarget target) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismObjectPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismObjectPanel.html index d558fa45cc7..5f11a1d2161 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismObjectPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismObjectPanel.html @@ -18,10 +18,10 @@
-
+
-
+
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismObjectPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismObjectPanel.java index 2c867ecd9ba..59b395d1a02 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismObjectPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismObjectPanel.java @@ -70,7 +70,7 @@ public PrismObjectPanel(String id, IModel> model, ResourceRefer private void initLayout(final IModel> model, ResourceReference image, final Form> form) { Component headerComponent = createHeader(ID_HEADER, model, form); - add(headerComponent); +// add(headerComponent); addOrReplaceContainers(model, form, false); @@ -104,7 +104,7 @@ protected IModel> createContainerModel(IModel item, Form form){ - PrismContainerPanel panel = new PrismContainerPanel(ID_CONTAINER, item.getModel(), true, form, pageBase); + PrismContainerPanel panel = new PrismContainerPanel(ID_CONTAINER, item.getModel(), false, form, pageBase); panel.setOutputMarkupPlaceholderTag(true); item.add(panel); return panel; @@ -155,7 +155,7 @@ private void addOrReplaceContainers(IModel> model, final Form f @Override protected void populateItem(ListItem item) { PrismContainerPanel containerPanel = createContainerPanel(item, form); - createMetadataPanel(model, item, containerPanel); +// createMetadataPanel(model, item, containerPanel); } }; containers.setReuseItems(true); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismPropertyPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismPropertyPanel.java index 9a4fed41b49..4faf0c4bf16 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismPropertyPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismPropertyPanel.java @@ -74,13 +74,13 @@ public PrismPropertyPanel(String id, final IModel model, Form form, PageBase add(new VisibleEnableBehaviour() { private static final long serialVersionUID = 1L; - @Override - public boolean isVisible() { - IW propertyWrapper = model.getObject(); - boolean visible = propertyWrapper.isVisible(); - LOGGER.trace("isVisible: {}: {}", propertyWrapper, visible); - return visible; - } +// @Override +// public boolean isVisible() { +// IW propertyWrapper = model.getObject(); +// boolean visible = propertyWrapper.isVisible(propertyWrapper.getParent().isShowEmpty()); +// LOGGER.trace("isVisible: {}: {}", propertyWrapper, visible); +// return visible; +// } @Override public boolean isEnabled() { @@ -258,16 +258,15 @@ private boolean hasOutbound(IModel model) { private boolean hasPendingModification(IModel model) { ItemWrapper propertyWrapper = model.getObject(); - ContainerWrapper containerWrapper = propertyWrapper.getContainer(); + ContainerWrapper containerWrapper = propertyWrapper.getParent(); if (containerWrapper == null) { return false; // TODO - ok? } - ObjectWrapper objectWrapper = containerWrapper.getObject(); - - if (objectWrapper == null) { - return false; - } - PrismObject prismObject = objectWrapper.getObject(); + if (!containerWrapper.isMain()) { + return false; + } + + PrismObject prismObject = (PrismObject) containerWrapper.getItem(); if (!ShadowType.class.isAssignableFrom(prismObject.getCompileTimeClass())) { return false; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java index 3e0c3889da7..94abe7eb92b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java @@ -218,13 +218,13 @@ private void initAccessBehaviour(InputPanel panel) { public boolean isEnabled() { ValueWrapper wrapper = valueWrapperModel.getObject(); ItemWrapper itemWrapper = wrapper.getItem(); - if (valueWrapperModel.getObject().isReadonly()) { + if (wrapper.isReadonly()) { return false; } - if (itemWrapper.getContainer() == null) { - return true; // TODO - } - ObjectWrapper object = itemWrapper.getContainer().getObject(); +// if (itemWrapper.getParent() == null) { +// return true; // TODO +// } + ContainerWrapper object = itemWrapper.getParent(); ItemDefinition def = itemWrapper.getItem().getDefinition(); return object == null || isAccessible(def, object.getStatus()); @@ -307,7 +307,7 @@ private boolean isRemoveButtonVisible() { return false; } - if (propertyWrapper.getContainer() == null) { + if (propertyWrapper.getParent() == null) { return true; // TODO } @@ -315,7 +315,7 @@ private boolean isRemoveButtonVisible() { } private ContainerStatus getContainerStatus(ItemWrapper propertyWrapper) { - final ObjectWrapper objectWrapper = propertyWrapper.getContainer().getObject(); + final ContainerWrapper objectWrapper = propertyWrapper.getParent(); return objectWrapper != null ? objectWrapper.getStatus() : ContainerStatus.MODIFYING; } @@ -345,7 +345,7 @@ private boolean isAddButtonVisible() { return false; } - if (propertyWrapper.getContainer() == null) { + if (propertyWrapper.getParent() == null) { return true; // TODO } return isAccessible(definition, getContainerStatus(propertyWrapper)); @@ -353,9 +353,9 @@ private boolean isAddButtonVisible() { private Panel createInputComponent(String id, IModel labelModel, Form form) { ValueWrapper valueWrapper = valueWrapperModel.getObject(); - ObjectWrapper objectWrapper = null; - if (valueWrapper.getItem().getContainer() != null) { - objectWrapper = valueWrapper.getItem().getContainer().getObject(); + ContainerWrapper objectWrapper = null; + if (valueWrapper.getItem().getParent() != null) { + objectWrapper = valueWrapper.getItem().getParent(); } Item property = valueWrapper.getItem().getItem(); ItemDefinition definition = valueWrapper.getItem().getItemDefinition(); @@ -663,46 +663,47 @@ protected void updateFeedbackPanel(AutoCompleteTextField input, boolean isError, new PropertyModel<>(valueWrapperModel, "value"), item.getValues(), false, typeClasses); } else if (item instanceof PrismContainer) { - AssociationWrapper itemWrapper = (AssociationWrapper) valueWrapperModel.getObject().getItem(); - final PrismContainer container = (PrismContainer) item; - PrismContainerDefinition definition = container.getDefinition(); - QName valueType = definition.getTypeName(); - - if (ShadowAssociationType.COMPLEX_TYPE.equals(valueType)) { - - PrismContext prismContext = item.getPrismContext(); - if (prismContext == null) { - prismContext = pageBase.getPrismContext(); - } - - ShadowType shadowType = ((ShadowType)itemWrapper.getContainer().getObject().getObject().asObjectable()); - PrismObject resource = shadowType.getResource().asPrismObject(); - // HACK. The revive should not be here. Revive is no good. The next use of the resource will - // cause parsing of resource schema. We need some centralized place to maintain live cached copies - // of resources. - try { - resource.revive(prismContext); - } catch (SchemaException e) { - throw new SystemException(e.getMessage(), e); - } - RefinedResourceSchema refinedSchema; - CompositeRefinedObjectClassDefinition rOcDef; - try { - refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); - rOcDef = refinedSchema.determineCompositeObjectClassDefinition(shadowType.asPrismObject()); - } catch (SchemaException e) { - throw new SystemException(e.getMessage(),e); - } - RefinedAssociationDefinition assocDef = itemWrapper.getRefinedAssociationDefinition(); - RefinedObjectClassDefinition assocTargetDef = assocDef.getAssociationTarget(); - - ObjectQuery query = getAssociationsSearchQuery(prismContext, resource, - assocTargetDef.getTypeName(), assocTargetDef.getKind()); - - List values = item.getValues(); - return new AssociationValueChoicePanel(id, valueWrapperModel, values, false, ShadowType.class, - query, assocTargetDef); - } +// AssociationWrapper itemWrapper = (AssociationWrapper) valueWrapperModel.getObject().getItem(); +// final PrismContainer container = (PrismContainer) item; +// PrismContainerDefinition definition = container.getDefinition(); +// QName valueType = definition.getTypeName(); +// +// if (ShadowAssociationType.COMPLEX_TYPE.equals(valueType)) { +// +// PrismContext prismContext = item.getPrismContext(); +// if (prismContext == null) { +// prismContext = pageBase.getPrismContext(); +// } +// +// ContainerWrapperitemWrapper.getParent(); +// ShadowType shadowType = ((ShadowType)itemWrapper.getParent().asObjectable()); +// PrismObject resource = shadowType.getResource().asPrismObject(); +// // HACK. The revive should not be here. Revive is no good. The next use of the resource will +// // cause parsing of resource schema. We need some centralized place to maintain live cached copies +// // of resources. +// try { +// resource.revive(prismContext); +// } catch (SchemaException e) { +// throw new SystemException(e.getMessage(), e); +// } +// RefinedResourceSchema refinedSchema; +// CompositeRefinedObjectClassDefinition rOcDef; +// try { +// refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); +// rOcDef = refinedSchema.determineCompositeObjectClassDefinition(shadowType.asPrismObject()); +// } catch (SchemaException e) { +// throw new SystemException(e.getMessage(),e); +// } +// RefinedAssociationDefinition assocDef = itemWrapper.getRefinedAssociationDefinition(); +// RefinedObjectClassDefinition assocTargetDef = assocDef.getAssociationTarget(); +// +// ObjectQuery query = getAssociationsSearchQuery(prismContext, resource, +// assocTargetDef.getTypeName(), assocTargetDef.getKind()); +// +// List values = item.getValues(); +// return new AssociationValueChoicePanel(id, valueWrapperModel, values, false, ShadowType.class, +// query, assocTargetDef); +// } } return panel; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismWrapper.java new file mode 100644 index 00000000000..8a9035191ec --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismWrapper.java @@ -0,0 +1,43 @@ +package com.evolveum.midpoint.web.component.prism; + +public class PrismWrapper { + + + private boolean showEmpty; + private boolean minimalized; + private boolean sorted; + private boolean showMetadata; + + public boolean isMinimalized() { + return minimalized; + } + + public void setMinimalized(boolean minimalized) { + this.minimalized = minimalized; + } + + public boolean isSorted() { + return sorted; + } + + public void setSorted(boolean sorted) { + this.sorted = sorted; + } + + public boolean isShowMetadata() { + return showMetadata; + } + + public void setShowMetadata(boolean showMetadata) { + this.showMetadata = showMetadata; + } + + public boolean isShowEmpty() { + return showEmpty; + } + + public void setShowEmpty(boolean showEmpty) { + this.showEmpty = showEmpty; +// computeStripes(); + } +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyOrReferenceWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyOrReferenceWrapper.java index b2e333ac466..1bdc3de82be 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyOrReferenceWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyOrReferenceWrapper.java @@ -38,7 +38,7 @@ public abstract class PropertyOrReferenceWrapper, ID extend private static final long serialVersionUID = -6347026284758253783L; - public PropertyWrapper(@Nullable ContainerWrapper container, I property, boolean readonly, ValueStatus status) { + public PropertyWrapper(@Nullable ContainerValueWrapper container, I property, boolean readonly, ValueStatus status) { super(container, property, readonly, status); if (container != null && SchemaConstants.PATH_PASSWORD.equivalent(container.getPath()) @@ -78,9 +78,9 @@ public ValueWrapper createAddedValue() { if (SchemaConstants.T_POLY_STRING_TYPE.equals(definition.getTypeName())) { wrapper = new ValueWrapper(this, new PrismPropertyValue(new PolyString("")), new PrismPropertyValue(new PolyString("")), ValueStatus.ADDED); - } else if (isUser() && isThisPropertyActivationEnabled()) { - wrapper = new ValueWrapper(this, new PrismPropertyValue(null), - new PrismPropertyValue(null), ValueStatus.ADDED); +// } else if (isUser() && isThisPropertyActivationEnabled()) { +// wrapper = new ValueWrapper(this, new PrismPropertyValue(null), +// new PrismPropertyValue(null), ValueStatus.ADDED); } else { wrapper = new ValueWrapper(this, new PrismPropertyValue(null), ValueStatus.ADDED); } @@ -88,18 +88,18 @@ public ValueWrapper createAddedValue() { return wrapper; } - private boolean isUser() { - if (getContainer() == null) { - return false; - } - ObjectWrapper wrapper = getContainer().getObject(); - if (wrapper == null) { - return false; - } - PrismObject object = wrapper.getObject(); - - return UserType.class.isAssignableFrom(object.getCompileTimeClass()); - } +// private boolean isUser() { +// if (getContainerValue() == null) { +// return false; +// } +// ObjectWrapper wrapper = getContainerValue().getContainer().getObject(); +// if (wrapper == null) { +// return false; +// } +// PrismObject object = wrapper.getObject(); +// +// return UserType.class.isAssignableFrom(object.getCompileTimeClass()); +// } private boolean isThisPropertyActivationEnabled() { if (!new ItemPath(UserType.F_ACTIVATION).equivalent(container.getPath())) { @@ -110,10 +110,10 @@ private boolean isThisPropertyActivationEnabled() { return false; } - if (container.getObject() == null || ContainerStatus.MODIFYING.equals(container.getObject().getStatus())) { - //when modifying then we don't want to create "true" value for c:activation/c:enabled, only during add - return false; - } +// if (container.getContainer().getObject() == null || ContainerStatus.MODIFYING.equals(container.getContainer().getObject().getStatus())) { +// //when modifying then we don't want to create "true" value for c:activation/c:enabled, only during add +// return false; +// } return true; } @@ -162,5 +162,6 @@ public String debugDump(int indent) { protected String getDebugName() { return "PropertyWrapper"; } - } + + \ No newline at end of file diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ReferenceWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ReferenceWrapper.java index e846c6e0acc..e2ef5447d1e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ReferenceWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ReferenceWrapper.java @@ -29,7 +29,7 @@ public class ReferenceWrapper extends PropertyOrReferenceWrapper FocusSubwrapperDto loadSubWrapperDto(Class wrapper.setSelectable(true); wrapper.setMinimalized(true); - wrapper.initializeContainers(this); +// wrapper.initializeContainers(this); subResult.computeStatus(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUserHistory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUserHistory.java index 02ce56eb471..b50d2c72e04 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUserHistory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUserHistory.java @@ -22,6 +22,7 @@ import com.evolveum.midpoint.gui.api.util.FocusTabVisibleBehavior; import com.evolveum.midpoint.gui.api.util.ModelServiceLocator; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.security.api.AuthorizationConstants; import com.evolveum.midpoint.util.logging.Trace; @@ -78,16 +79,29 @@ protected ObjectWrapper loadObjectWrapper(PrismObject user) objectWrapper.setShowEmpty(false); for (ContainerWrapper container : objectWrapper.getContainers()) { - container.setReadonly(true); - - List itemWrappers = container.getItems(); - for (ItemWrapper item : itemWrappers){ - if (item instanceof PropertyWrapper){ - ((PropertyWrapper) item).setReadonly(true); - } else if (item instanceof ReferenceWrapper){ - ((ReferenceWrapper) item).setReadonly(true); - } - } + container.setReadonly(true); + + container.getValues().forEach(v -> { + ((ContainerValueWrapper ) v).getItems().forEach(item -> ((PropertyOrReferenceWrapper) item).setReadonly(true)); + ((ContainerValueWrapper ) v).setReadonly(true); + + }); + +// container.setReadonly(true); +// +// List> containervalues = container.getValues(); +// container.getValues().stream().forEach(v -> { +// (v.setReadonly(true); +// v.getItems().forEach(i -> ((PropertyOrReferenceWrapper) i).setReadonly(true)); +// }); +// List itemWrappers = container.getItems(); +// for (ItemWrapper item : itemWrappers){ +// if (item instanceof PropertyWrapper){ +// ((PropertyWrapper) item).setReadonly(true); +// } else if (item instanceof ReferenceWrapper){ +// ((ReferenceWrapper) item).setReadonly(true); +// } +// } } return objectWrapper; From d41bda6d915e2535bb9c26cfcd462e4cf176ea42 Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Fri, 15 Sep 2017 14:59:54 +0200 Subject: [PATCH 02/97] mutlivalue containers improvements - work in progress --- .../objectdetails/FocusDetailsTabPanel.html | 2 + .../objectdetails/FocusDetailsTabPanel.java | 29 +- .../FocusProjectionsTabPanel.java | 8 +- .../component/prism/AssociationWrapper.java | 91 ++-- .../component/prism/ContainerValuePanel.java | 68 +-- .../prism/ContainerValueWrapper.java | 273 ++++------ .../web/component/prism/ContainerWrapper.java | 475 ++++++++---------- .../prism/ContainerWrapperFactory.java | 20 +- .../web/component/prism/DynamicFormPanel.java | 2 +- .../web/component/prism/ItemWrapper.java | 12 +- .../web/component/prism/ObjectWrapper.java | 50 +- .../prism/PrismContainerHeaderPanel.html | 24 + .../prism/PrismContainerHeaderPanel.java | 61 +++ .../component/prism/PrismContainerPanel.html | 2 +- .../component/prism/PrismContainerPanel.java | 80 +-- .../prism/PrismContainerValueHeaderPanel.html | 24 + .../prism/PrismContainerValueHeaderPanel.java | 113 +++++ .../web/component/prism/PrismHeaderPanel.html | 4 +- .../web/component/prism/PrismHeaderPanel.java | 106 +--- .../web/component/prism/PrismObjectPanel.java | 36 +- .../prism/PrismOptionButtonPanel.java | 16 +- .../component/prism/PrismPropertyPanel.java | 14 +- .../web/component/prism/PrismValuePanel.java | 16 +- .../web/component/prism/PrismWrapper.java | 6 +- .../prism/PropertyOrReferenceWrapper.java | 44 +- .../web/component/prism/PropertyWrapper.java | 10 +- .../web/component/prism/ReferenceWrapper.java | 4 +- .../web/component/prism/ValueWrapper.java | 10 +- ...ontainerWrapperFromObjectWrapperModel.java | 2 +- ...PropertyWrapperFromObjectWrapperModel.java | 8 +- .../page/admin/PageAdminObjectDetails.java | 2 +- .../admin/resources/content/PageAccount.java | 2 +- .../handlers/dto/GenericHandlerDto.java | 2 +- .../web/page/admin/users/PageUserHistory.java | 2 +- .../AssociationValueChoicePanel.java | 22 +- .../TestIntegrationObjectWrapperFactory.java | 153 +++--- .../web/TestUnitObjectWrapperFactory.java | 15 +- .../midpoint/web/WrapperTestUtil.java | 3 +- 38 files changed, 902 insertions(+), 909 deletions(-) create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerHeaderPanel.html create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerHeaderPanel.java create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.html create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.html index b1f839ecf3f..b5c862f5caf 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.html @@ -22,6 +22,8 @@
+
+
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.java index a835a5f5b6f..e14c0f2e296 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.java @@ -21,13 +21,17 @@ import com.evolveum.midpoint.gui.api.model.LoadableModel; import com.evolveum.midpoint.gui.api.page.PageBase; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.web.component.assignment.AssignmentDto; import com.evolveum.midpoint.web.component.assignment.AssignmentEditorDto; import com.evolveum.midpoint.web.component.form.Form; import com.evolveum.midpoint.web.component.prism.ObjectWrapper; +import com.evolveum.midpoint.web.component.prism.PrismContainerPanel; import com.evolveum.midpoint.web.component.prism.PrismObjectPanel; +import com.evolveum.midpoint.web.model.ContainerWrapperFromObjectWrapperModel; import com.evolveum.midpoint.web.page.admin.users.dto.FocusSubwrapperDto; import com.evolveum.midpoint.web.resource.img.ImgResources; import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; @@ -39,7 +43,11 @@ public class FocusDetailsTabPanel extends AbstractFocusTabPanel { private static final long serialVersionUID = 1L; - protected static final String ID_FOCUS_FORM = "focusDetails"; +// protected static final String ID_FOCUS_FORM = "focusDetails"; + protected static final String ID_FOCUS_MAIN_PANEL = "focusDetails"; + protected static final String ID_FOCUS_ACTIVATION_PANEL = "activation"; + protected static final String ID_FOCUS_PASSWORD_PANEL = "password"; + private static final Trace LOGGER = TraceManager.getTrace(FocusDetailsTabPanel.class); @@ -53,10 +61,23 @@ public FocusDetailsTabPanel(String id, Form mainForm, } private void initLayout() { + + ContainerWrapperFromObjectWrapperModel basicContainerModel = new ContainerWrapperFromObjectWrapperModel<>(getObjectWrapperModel(), ItemPath.EMPTY_PATH); + PrismContainerPanel mainContainer = new PrismContainerPanel<>(ID_FOCUS_MAIN_PANEL, basicContainerModel, false, getMainForm(), getPageBase()); + add(mainContainer); - PrismObjectPanel panel = new PrismObjectPanel(ID_FOCUS_FORM, getObjectWrapperModel(), - new PackageResourceReference(ImgResources.class, ImgResources.USER_PRISM), getMainForm(), getPageBase()); - add(panel); + ContainerWrapperFromObjectWrapperModel activationContainerModel = new ContainerWrapperFromObjectWrapperModel<>(getObjectWrapperModel(), SchemaConstants.PATH_ACTIVATION); + PrismContainerPanel activationContainerPanel = new PrismContainerPanel<>(ID_FOCUS_ACTIVATION_PANEL, activationContainerModel, false, getMainForm(), getPageBase()); + add(activationContainerPanel); + + ContainerWrapperFromObjectWrapperModel passwordContainerModel = new ContainerWrapperFromObjectWrapperModel<>(getObjectWrapperModel(), SchemaConstants.PATH_PASSWORD); + PrismContainerPanel passwordContainerPanel = new PrismContainerPanel<>(ID_FOCUS_PASSWORD_PANEL, passwordContainerModel, false, getMainForm(), getPageBase()); + add(passwordContainerPanel); + + +// PrismObjectPanel panel = new PrismObjectPanel(ID_FOCUS_FORM, getObjectWrapperModel(), +// new PackageResourceReference(ImgResources.class, ImgResources.USER_PRISM), getMainForm(), getPageBase()); +// add(panel); } } 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 cc52bed14fb..eafa9bab1f1 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 @@ -256,7 +256,7 @@ private void addSelectedAccountPerformed(AjaxRequestTarget target, List, PrismContainerDefinition> { - private static final long serialVersionUID = 1L; - - private static final Trace LOGGER = TraceManager.getTrace(AssociationWrapper.class); - - private RefinedAssociationDefinition assocRDef; - - public AssociationWrapper(ContainerValueWrapper container, PrismContainer property, - boolean readonly, ValueStatus status, RefinedAssociationDefinition assocRDef) { - super(container, property, readonly, status); - this.assocRDef = assocRDef; - } - - @Override - public ValueWrapper createAddedValue() { - PrismContainer container = (PrismContainer)getItem(); - PrismContainerValue cval = container.createNewValue(); - ValueWrapper wrapper = new ValueWrapper<>(this, cval, ValueStatus.ADDED); - - return wrapper; - } - - @Override - public String getDisplayName() { - if (assocRDef != null) { - String displayName = assocRDef.getDisplayName(); - if (displayName != null) { - return displayName; - } - } - return super.getDisplayName(); - } - - public RefinedAssociationDefinition getRefinedAssociationDefinition() { - return assocRDef; - } - - @Override - protected String getDebugName() { - return "AssociationWrapper"; - } - +public class AssociationWrapper { +// extends PropertyWrapper, PrismContainerDefinition> { } +// private static final long serialVersionUID = 1L; +// +// private static final Trace LOGGER = TraceManager.getTrace(AssociationWrapper.class); +// +// private RefinedAssociationDefinition assocRDef; +// +// public AssociationWrapper(ContainerValueWrapper container, PrismContainer property, +// boolean readonly, ValueStatus status, RefinedAssociationDefinition assocRDef) { +// super(container, property, readonly, status); +// this.assocRDef = assocRDef; +// } +// +// @Override +// public ValueWrapper createAddedValue() { +// // TODO Auto-generated method stub +// return super.createAddedValue(); +// } +// @Override +// public ValueWrapper createAddedValue() { +// PrismContainer container = (PrismContainer)getItem(); +// PrismContainerValue cval = container.createNewValue(); +// ValueWrapper wrapper = new ValueWrapper<>(this, cval, ValueStatus.ADDED); +// +// return wrapper; +// } +// +// @Override +// public String getDisplayName() { +// if (assocRDef != null) { +// String displayName = assocRDef.getDisplayName(); +// if (displayName != null) { +// return displayName; +// } +// } +// return super.getDisplayName(); +// } +// +// public RefinedAssociationDefinition getRefinedAssociationDefinition() { +// return assocRDef; +// } +// +// @Override +// protected String getDebugName() { +// return "AssociationWrapper"; +// } +// +//} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValuePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValuePanel.java index 2c4b21f6aaa..15f459d7e38 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValuePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValuePanel.java @@ -40,7 +40,7 @@ * @author lazyman * @author semancik */ -public class ContainerValuePanel extends Panel { +public class ContainerValuePanel extends Panel { private static final long serialVersionUID = 1L; private static final Trace LOGGER = TraceManager.getTrace(ContainerValuePanel.class); @@ -49,60 +49,32 @@ public class ContainerValuePanel extends Panel { private PageBase pageBase; - public ContainerValuePanel(String id, final IModel model, boolean showHeader, Form form, PageBase pageBase) { + public ContainerValuePanel(String id, final IModel> model, boolean showHeader, Form form, PageBase pageBase) { super(id, model); setOutputMarkupId(true); this.pageBase = pageBase; - - LOGGER.trace("Creating container panel for {}", model.getObject()); - - add(new VisibleEnableBehaviour() { - private static final long serialVersionUID = 1L; + + add(new VisibleEnableBehaviour() { @Override - public boolean isVisible() { - ContainerValueWrapper containerValueWrapper = model.getObject(); - return containerValueWrapper.isItemVisible(); -// PrismContainer prismContainer = containerWrapper.getItem(); -// if (containerWrapper.getItemDefinition().isOperational()) { -// return false; -// } -// -// // HACK HACK HACK -// if (ShadowType.F_ASSOCIATION.equals(prismContainer.getElementName())) { -// return true; -// } - -// containerValueWrapper.is -// boolean isVisible = false; -// for (ItemWrapper item : containerValueWrapper.getItems()) { -// if (containerValueWrapper.isItemVisible(item)) { -// isVisible = true; -// break; -// } -// } - -// return !containerValueWrapper.getItems().isEmpty() && isVisible; -// return true; - } - }); + public boolean isVisible() { + return model.getObject().isVisible(); + } + }); + + LOGGER.trace("Creating container panel for {}", model.getObject()); initLayout(model, form, showHeader); } - private void initLayout(final IModel model, final Form form, boolean showHeader) { - PrismHeaderPanel header = new PrismHeaderPanel(ID_HEADER, model) { + private void initLayout(final IModel> model, final Form form, boolean showHeader) { + PrismContainerValueHeaderPanel header = new PrismContainerValueHeaderPanel(ID_HEADER, model) { private static final long serialVersionUID = 1L; @Override protected void onButtonClick(AjaxRequestTarget target) { addOrReplaceProperties(model, form, true); - target.add(ContainerValuePanel.this.findParent(PrismObjectPanel.class)); - } - - @Override - public boolean isButtonsVisible() { - return true; + target.add(ContainerValuePanel.this); } }; @@ -115,6 +87,7 @@ public boolean isVisible() { } }); add(header); + header.setOutputMarkupId(true); addOrReplaceProperties(model, form, false); } @@ -135,7 +108,7 @@ public String getObject() { }; } - private void addOrReplaceProperties(IModel model, final Form form, boolean isToBeReplaced){ + private void addOrReplaceProperties(IModel> model, final Form form, boolean isToBeReplaced){ ListView properties = new ListView("properties", new PropertyModel>(model, "properties")) { private static final long serialVersionUID = 1L; @@ -143,7 +116,7 @@ private void addOrReplaceProperties(IModel item) { if (item.getModel().getObject() instanceof ContainerWrapper) { - PrismContainerPanel containerPanel = new PrismContainerPanel("property", (IModel) item.getModel(), true, form, pageBase); + PrismContainerPanel containerPanel = new PrismContainerPanel("property", (IModel>) item.getModel(), true, form, pageBase); containerPanel.setOutputMarkupId(true); item.add(containerPanel); return; @@ -152,15 +125,8 @@ protected void populateItem(final ListItem item) { PrismPropertyPanel propertyPanel = new PrismPropertyPanel("property", item.getModel(), form, pageBase); propertyPanel.setOutputMarkupId(true); item.add(propertyPanel); - item.add(new VisibleEnableBehaviour() { - private static final long serialVersionUID = 1L; - - @Override - public boolean isVisible() { - return item.getModel().getObject().isVisible(model.getObject().isShowEmpty()); - } - }); item.add(AttributeModifier.append("class", createStyleClassModel((IModel) item.getModel()))); + } }; properties.setReuseItems(true); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java index bfa9424eb8e..41b99651af8 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java @@ -48,11 +48,13 @@ import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.DebugUtil; +import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordType; @@ -63,6 +65,8 @@ */ public class ContainerValueWrapper extends PrismWrapper implements Serializable, DebugDumpable { + private static final long serialVersionUID = 1L; + private static final Trace LOGGER = TraceManager.getTrace(ContainerValueWrapper.class); // private String displayName; @@ -70,7 +74,6 @@ public class ContainerValueWrapper extends PrismWrapper private PrismContainerValue containerValue; private ValueStatus status; - private boolean main; private ItemPath path; private List properties; @@ -81,19 +84,15 @@ public class ContainerValueWrapper extends PrismWrapper ContainerValueWrapper(ContainerWrapper containerWrapper, PrismContainerValue containerValue, ValueStatus status, ItemPath path) { -// Validate.notNull(containerValue, "container must not be null."); -// super(containerWrapper, containerValue, status); Validate.notNull(status, "Container status must not be null."); this.containerWrapper = containerWrapper; this.containerValue = containerValue; this.status = status; this.path = path; - this.main = path == null; this.readonly = containerWrapper.isReadonly(); // [pm] this is quite questionable this.showInheritedObjectAttributes = containerWrapper.isShowInheritedObjectAttributes(); - // have to be after setting "main" property -// this.containerDefinition = getItemDefinition(); + } ContainerValueWrapper(PrismContainerValue container, ValueStatus status, ItemPath path, boolean readOnly, boolean showInheritedObjectAttributes) { @@ -106,7 +105,6 @@ public class ContainerValueWrapper extends PrismWrapper // this.containerDefinition = container.getParent().getDefinition(); this.status = status; this.path = path; - this.main = path == null; this.readonly = readOnly; this.showInheritedObjectAttributes = showInheritedObjectAttributes; } @@ -168,94 +166,17 @@ public List getItems() { public void setProperties(List properties) { this.properties = properties; } - - - - // TODO: refactor this. Why it is not in the itemWrapper? - boolean isItemVisible(ItemWrapper item) { - ItemDefinition def = item.getItemDefinition(); - if (def.isIgnored() || def.isOperational()) { - return false; - } - - if (def instanceof PrismPropertyDefinition && skipProperty((PrismPropertyDefinition) def)) { - return false; - } - - // we decide not according to status of this container, but according to - // the status of the whole object - if (containerWrapper != null && containerWrapper.getStatus() == ContainerStatus.ADDING) { - - return (def.canAdd() && def.isEmphasized()) - || (def.canAdd() && showEmpty(item)); - } - - // otherwise, object.getStatus() is MODIFYING - - if (def.canModify()) { - return showEmpty(item); - } else { - if (def.canRead()) { - return showEmpty(item); - } - return false; - } - } - - boolean isItemVisible() { -// ItemDefinition def = item.getItemDefinition(); -// PrismContainerDefinition def = get -// if (def.isIgnored() || def.isOperational()) { -// return false; -// } - -// if (def instanceof PrismPropertyDefinition && skipProperty((PrismPropertyDefinition) def)) { -// return false; -// } - - // we decide not according to status of this container, but according to - // the status of the whole object -// if (containerWrapper != null && containerWrapper.getStatus() == ContainerStatus.ADDING) { -// -// return (def.canAdd() && def.isEmphasized()) -// || (def.canAdd() && showEmpty(item)); -// } - - switch (status) { - case ADDED: - return (getDefinition().isEmphasized() || isShowEmpty()) && getDefinition().canAdd(); - case NOT_CHANGED: -// getItems().forEach(i -> ); - return ((getDefinition().canModify()) || getDefinition().canRead()); - default: - break; - } - - for (ItemWrapper item : getItems()) { - if (item.isVisible(isShowEmpty())) { - return true; - } - } - - // otherwise, object.getStatus() is MODIFYING - -// if (def.canModify()) { -// return showEmpty(item); -// } else { -// if (def.canRead()) { -// return showEmpty(item); -// } -// return false; -// } - return false; - } - + public void computeStripes() { + if (properties == null) { + return; + } int visibleProperties = 0; + for (ItemWrapper item: properties) { - if (item.isVisible(isShowEmpty())) { +// if (item.isVisible(isShowEmpty())) { visibleProperties++; - } +// } if (visibleProperties % 2 == 0) { item.setStripe(true); } else { @@ -268,56 +189,10 @@ public boolean isShowInheritedObjectAttributes() { return showInheritedObjectAttributes; } - private boolean showEmpty(ItemWrapper item) { - // make sure that emphasized state is evaluated after the normal definitions are considered - // we do not want to display emphasized property if the user does not have an access to it. - // MID-3206 - if (item.getItemDefinition().isEmphasized()) { - return true; - } -// ContainerWrapper objectWrapper = getContainer(); - List valueWrappers = item.getValues(); - boolean isEmpty; - if (valueWrappers == null) { - isEmpty = true; - } else { - isEmpty = valueWrappers.isEmpty(); - } -// if (!isEmpty && valueWrappers.size() == 1) { -// ValueWrapper value = valueWrappers.get(0); -// if (ValueStatus.ADDED.equals(value.getStatus())) { -// isEmpty = true; -// } -// } - return (containerWrapper.isShowEmpty()) || !isEmpty; - } - -// @Override -// public String getDisplayName() { -// if (StringUtils.isNotEmpty(displayName)) { -// return displayName; -// } -// return getDisplayNameFromItem(containerValue.getParent()); -// } -// -// @Override -// public void setDisplayName(String name) { -// this.displayName = name; -// } -// -// @Override -// public QName getName() { -// return getItem().getElementName(); -// } - public boolean isMain() { return path==null || path.isEmpty(); } - public void setMain(boolean main) { - this.main = main; - } - static String getDisplayNameFromItem(Item item) { Validate.notNull(item, "Item must not be null."); @@ -403,34 +278,6 @@ public void setReadonly(boolean readonly) { this.readonly = readonly; } -// @Override -// public List getValues() { -// // TODO Auto-generated method stub -// return null; -// } - -// @Override -// public boolean isVisible() { -// // TODO Auto-generated method stub -// return false; -// } - -// @Override -// public boolean isEmpty() { -// return getItem().isEmpty(); -// } - - //TODO add new PrismContainerValue to association container -// public void addValue() { -// getItems().add(createItem()); -// } -// -// public ItemWrapper createItem() { -// Property -// ValueWrapper wrapper = new ValueWrapper(this, new PrismPropertyValue(null), ValueStatus.ADDED); -// return wrapper.getItem(); -// } - public void sort(final PageBase pageBase) { if (containerWrapper.isSorted()){ @@ -495,7 +342,7 @@ public String debugDump(int indent) { sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "status", status == null ? null : status.toString(), indent + 1); sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "main", main, indent + 1); + DebugUtil.debugDumpWithLabel(sb, "main", isMain(), indent + 1); sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "readonly", readonly, indent + 1); sb.append("\n"); @@ -513,17 +360,6 @@ public String debugDump(int indent) { return sb.toString(); } -// @Override -// public boolean isStripe() { -// // Does not make much sense, but it is given by the interface -// return false; -// } -// -// @Override -// public void setStripe(boolean isStripe) { -// // Does not make much sense, but it is given by the interface -// } - public void collectModifications(ObjectDelta delta) throws SchemaException { // if (getItemDefinition().getName().equals(ShadowType.F_ASSOCIATION)) { // //create ContainerDelta for association container @@ -598,9 +434,15 @@ private ReferenceDelta computeReferenceDeltas(ReferenceWrapper referenceWrapper, return pDelta; } - private void addItemDelta(ItemWrapper itemWrapper, ItemDelta pDelta, ItemDefinition propertyDef, + private void addItemDelta(PropertyOrReferenceWrapper itemWrapper, ItemDelta pDelta, ItemDefinition propertyDef, ItemPath containerPath) { - for (ValueWrapper valueWrapper : itemWrapper.getValues()) { + for (Object vWrapper : itemWrapper.getValues()) { + if (!(vWrapper instanceof ValueWrapper)) { + continue; + } + + ValueWrapper valueWrapper = (ValueWrapper) vWrapper; + valueWrapper.normalize(propertyDef.getPrismContext()); ValueStatus valueStatus = valueWrapper.getStatus(); if (!valueWrapper.hasValueChanged() @@ -705,7 +547,50 @@ private void addItemDelta(ItemWrapper } } } + + //TODO: unify with other isVisibleMethods + public boolean isVisible() { + PrismContainerDefinition def = getDefinition(); + + if (def.isIgnored() || (def.isOperational() && !def.getTypeName().equals(MetadataType.COMPLEX_TYPE))) { + return false; + } + + //TODO: emphasized + switch (status) { + case NOT_CHANGED : + return isNotEmptyAndCanReadAndModify(def) || showEmptyCanReadAndModify(def); + case ADDED : + return emphasizedAndCanAdd(def) || showEmptyAndCanAdd(def); + } + + return false; + } + + private boolean isNotEmptyAndCanReadAndModify(PrismContainerDefinition def) { + return def.canRead() && def.canModify() && !getContainerValue().isEmpty(); + } + + private boolean showEmptyCanReadAndModify(PrismContainerDefinition def) { + return def.canRead() && def.canModify() && isShowEmpty(); + } + private boolean showEmptyAndCanAdd(PrismContainerDefinition def) { + return def.canAdd() && isShowEmpty(); + } + + private boolean emphasizedAndCanAdd(PrismContainerDefinition def) { + return def.canAdd() && def.isEmphasized(); + } + + @Override + public void setShowEmpty(boolean showEmpty) { + super.setShowEmpty(showEmpty); + getItems().forEach(item -> { + item.setShowEmpty(showEmpty); + }); + } + // @Override public boolean checkRequired(PageBase pageBase) { boolean rv = true; @@ -717,6 +602,36 @@ public boolean checkRequired(PageBase pageBase) { return rv; } + public PropertyOrReferenceWrapper findPropertyWrapper(QName name) { + Validate.notNull(name, "QName must not be null."); + for (ItemWrapper wrapper : getItems()) { + if (wrapper instanceof ContainerWrapper) { + continue; + } + if (QNameUtil.match(name, wrapper.getItem().getElementName())) { + return (PropertyOrReferenceWrapper) wrapper; + } + } + return null; + } + + public ContainerWrapper findContainerWrapper(ItemPath path) { + Validate.notNull(path, "QName must not be null."); + for (ItemWrapper wrapper : getItems()) { + if (!(wrapper instanceof ContainerWrapper)) { + continue; + } + ContainerWrapper containerWrapper = (ContainerWrapper) wrapper; + if (containerWrapper.getPath().equivalent(path)) { + return containerWrapper; + } + + return ((ContainerWrapper)wrapper).findContainerWrapper(path); + + } + return null; + } + public String getDisplayName() { if (getContainer().isMain()){ return "prismContainer.mainPanelDisplayName"; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java index b100cdb604f..c4178abe2a2 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java @@ -16,44 +16,56 @@ package com.evolveum.midpoint.web.component.prism; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.xml.namespace.QName; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; + import com.evolveum.midpoint.gui.api.page.PageBase; -import com.evolveum.midpoint.prism.*; -import com.evolveum.midpoint.prism.delta.ContainerDelta; +import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.prism.Item; +import com.evolveum.midpoint.prism.ItemDefinition; +import com.evolveum.midpoint.prism.PrismContainer; +import com.evolveum.midpoint.prism.PrismContainerDefinition; +import com.evolveum.midpoint.prism.PrismContainerValue; +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.PrismPropertyDefinition; +import com.evolveum.midpoint.prism.PrismReferenceDefinition; +import com.evolveum.midpoint.prism.PrismValue; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.ReferenceDelta; import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.util.ItemPathUtil; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.PrettyPrinter; -import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.*; - -import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ActivationCapabilityType; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.Validate; -import org.apache.commons.lang.math.NumberUtils; -import org.jetbrains.annotations.Nullable; - -import javax.xml.namespace.QName; - -import java.io.Serializable; -import java.util.*; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; /** * @author lazyman + * @author katkav */ -public class ContainerWrapper extends PrismWrapper implements ItemWrapper, Serializable, DebugDumpable { +public class ContainerWrapper extends PrismWrapper implements ItemWrapper, PrismContainerDefinition, ContainerValueWrapper>, Serializable, DebugDumpable { + + private static final long serialVersionUID = 1L; private static final Trace LOGGER = TraceManager.getTrace(ContainerWrapper.class); private String displayName; -// private ObjectWrapper objectWrapper; private PrismContainer container; private ContainerStatus status; @@ -63,20 +75,14 @@ public class ContainerWrapper extends PrismWrapper impl private boolean readonly; private boolean showInheritedObjectAttributes; - private PrismContainerDefinition containerDefinition; ContainerWrapper(PrismContainer container, ContainerStatus status, ItemPath path) { Validate.notNull(container, "container must not be null."); Validate.notNull(status, "Container status must not be null."); -// this.objectWrapper = objectWrapper; this.container = container; this.status = status; this.path = path; -// this.readonly = objectWrapper.isReadonly(); // [pm] this is quite questionable -// this.showInheritedObjectAttributes = objectWrapper.isShowInheritedObjectAttributes(); - // have to be after setting "main" property - this.containerDefinition = getItemDefinition(); } ContainerWrapper(PrismContainer container, ContainerStatus status, ItemPath path, boolean readOnly, boolean showInheritedObjectAttributes) { @@ -85,7 +91,6 @@ public class ContainerWrapper extends PrismWrapper impl Validate.notNull(status, "Container status must not be null."); this.container = container; - this.containerDefinition = container.getDefinition(); this.status = status; this.path = path; this.readonly = readOnly; @@ -96,8 +101,8 @@ public void revive(PrismContext prismContext) throws SchemaException { if (container != null) { container.revive(prismContext); } - if (containerDefinition != null) { - containerDefinition.revive(prismContext); + if (getItemDefinition() != null) { + getItemDefinition().revive(prismContext); } if (values != null) { for (ContainerValueWrapper itemWrapper : values) { @@ -108,21 +113,9 @@ public void revive(PrismContext prismContext) throws SchemaException { @Override public PrismContainerDefinition getItemDefinition() { - if (containerDefinition != null) { - return containerDefinition; - } -// if (isMain()) { return container.getDefinition(); -// } else { -// return objectWrapper.getDefinition().findContainerDefinition(path); -// } } -// @Nullable -// ObjectWrapper getObject() { -// return objectWrapper; -// } - public ContainerStatus getStatus() { return status; } @@ -136,76 +129,40 @@ public PrismContainer getItem() { return container; } + + @Override public List> getValues() { - if (values == null) { - values = new ArrayList<>(); - } - return values; + if (values == null) { + values = new ArrayList<>(); + } + return values; + } public void setProperties(List> properties) { this.values = properties; } - public IW findPropertyWrapper(ItemPath name) { + public PropertyOrReferenceWrapper findPropertyWrapper(QName name) { Validate.notNull(name, "QName must not be null."); for (ContainerValueWrapper wrapper : getValues()) { - if (name.equals(wrapper.getContainerValue().getPath())) { - return (IW) wrapper; - } + PropertyOrReferenceWrapper propertyWrapper = wrapper.findPropertyWrapper(name); + if (propertyWrapper != null) { + return propertyWrapper; + } } return null; } - - // TODO: refactor this. Why it is not in the itemWrapper? - boolean isItemVisible(ItemWrapper item) { - ItemDefinition def = item.getItemDefinition(); - if (def.isIgnored() || def.isOperational()) { - return false; - } - - if (def instanceof PrismPropertyDefinition && skipProperty((PrismPropertyDefinition) def)) { - return false; - } - - // we decide not according to status of this container, but according to - // the status of the whole object - -// if (objectWrapper != null && objectWrapper.getStatus() == ContainerStatus.ADDING) { -// -// return (def.canAdd() && def.isEmphasized()) -// || (def.canAdd() && showEmpty(item)); -// } - - // otherwise, object.getStatus() is MODIFYING - - if (def.canModify()) { - return showEmpty(item); - } else { - if (def.canRead()) { - return showEmpty(item); + + public ContainerWrapper findContainerWrapper(ItemPath path) { + Validate.notNull(path, "QName must not be null."); + for (ContainerValueWrapper wrapper : getValues()) { + ContainerWrapper containerWrapper = wrapper.findContainerWrapper(path); + if (containerWrapper != null) { + return containerWrapper; } - return false; } - } - - boolean isItemVisible() { - - //TODO: [katka] should we consider child items? e.g. we can dee assignemnt/description but noothing else.. - PrismContainerDefinition containerDefinition = getItemDefinition(); - if (containerDefinition.isIgnored() || containerDefinition.isOperational()) { - return false; - } - - switch (status) { - case ADDING : - return containerDefinition.canAdd(); - case MODIFYING : - return (containerDefinition.canRead() && containerDefinition.canModify()); - } - - return false; - + return null; } public void computeStripes() { @@ -227,31 +184,6 @@ public boolean isShowInheritedObjectAttributes() { return showInheritedObjectAttributes; } - private boolean showEmpty(ItemWrapper item) { - // make sure that emphasized state is evaluated after the normal definitions are considered - // we do not want to display emphasized property if the user does not have an access to it. - // MID-3206 - if (item.getItemDefinition().isEmphasized()) { - return true; - } -// ObjectWrapper objectWrapper = getObject(); - List valueWrappers = item.getValues(); - boolean isEmpty; - if (valueWrappers == null) { - isEmpty = true; - } else { - isEmpty = valueWrappers.isEmpty(); - } - if (!isEmpty && valueWrappers.size() == 1) { - ValueWrapper value = valueWrappers.get(0); - if (ValueStatus.ADDED.equals(value.getStatus())) { - isEmpty = true; - } - } -// /(objectWrapper == null || objectWrapper.isShowEmpty()) || - return !isEmpty; - } - @Override public String getDisplayName() { if (StringUtils.isNotEmpty(displayName)) { @@ -366,19 +298,7 @@ public void setReadonly(boolean readonly) { // return null; // } // -// @Override - public boolean isVisible() { - switch (status) { - case ADDING : - return getItemDefinition().canAdd(); - case MODIFYING : - if (getItemDefinition().canModify()) { - return !isEmpty(); - } - } - - return false; - } + @Override public boolean isEmpty() { @@ -390,14 +310,16 @@ public boolean isEmpty() { // return container // } + //TODO add new PrismContainerValue to association container - public void addValue() { - getValues().add(createItem()); + public void addValue(boolean showEmpty) { + getValues().add(createItem(showEmpty)); } - public ContainerValueWrapper createItem() { + public ContainerValueWrapper createItem(boolean showEmpty) { PrismContainerValue pcv = container.createNewValue(); ContainerValueWrapper wrapper = new ContainerValueWrapper(this, pcv, ValueStatus.ADDED, pcv.getPath()); + wrapper.setShowEmpty(showEmpty); return wrapper; } @@ -478,7 +400,7 @@ public String debugDump(int indent) { sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "path", path == null ? null : path.toString(), indent + 1); sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "containerDefinition", containerDefinition == null ? null : containerDefinition.toString(), indent + 1); + DebugUtil.debugDumpWithLabel(sb, "containerDefinition", getItemDefinition() == null ? null : getItemDefinition().toString(), indent + 1); sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "container", container == null ? null : container.toString(), indent + 1); sb.append("\n"); @@ -561,128 +483,128 @@ public void collectModifications(ObjectDelta delta) th // } } - private ItemDelta computePropertyDeltas(PropertyWrapper propertyWrapper, ItemPath containerPath) { - ItemDefinition itemDef = propertyWrapper.getItemDefinition(); - ItemDelta pDelta = itemDef.createEmptyDelta(containerPath.subPath(itemDef.getName())); - addItemDelta(propertyWrapper, pDelta, itemDef, containerPath); - return pDelta; - } - - private ReferenceDelta computeReferenceDeltas(ReferenceWrapper referenceWrapper, ItemPath containerPath) { - PrismReferenceDefinition propertyDef = referenceWrapper.getItemDefinition(); - ReferenceDelta pDelta = new ReferenceDelta(containerPath, propertyDef.getName(), propertyDef, - propertyDef.getPrismContext()); - addItemDelta(referenceWrapper, pDelta, propertyDef, containerPath.subPath(propertyDef.getName())); - return pDelta; - } - - private void addItemDelta(ItemWrapper itemWrapper, ItemDelta pDelta, ItemDefinition propertyDef, - ItemPath containerPath) { - for (ValueWrapper valueWrapper : itemWrapper.getValues()) { - valueWrapper.normalize(propertyDef.getPrismContext()); - ValueStatus valueStatus = valueWrapper.getStatus(); - if (!valueWrapper.hasValueChanged() - && (ValueStatus.NOT_CHANGED.equals(valueStatus) || ValueStatus.ADDED.equals(valueStatus))) { - continue; - } - - // TODO: need to check if the resource has defined - // capabilities - // todo this is bad hack because now we have not tri-state - // checkbox -// if (SchemaConstants.PATH_ACTIVATION.equivalent(containerPath) && getObject() != null) { +// private ItemDelta computePropertyDeltas(PropertyWrapper propertyWrapper, ItemPath containerPath) { +// ItemDefinition itemDef = propertyWrapper.getItemDefinition(); +// ItemDelta pDelta = itemDef.createEmptyDelta(containerPath.subPath(itemDef.getName())); +// addItemDelta(propertyWrapper, pDelta, itemDef, containerPath); +// return pDelta; +// } +// +// private ReferenceDelta computeReferenceDeltas(ReferenceWrapper referenceWrapper, ItemPath containerPath) { +// PrismReferenceDefinition propertyDef = referenceWrapper.getItemDefinition(); +// ReferenceDelta pDelta = new ReferenceDelta(containerPath, propertyDef.getName(), propertyDef, +// propertyDef.getPrismContext()); +// addItemDelta(referenceWrapper, pDelta, propertyDef, containerPath.subPath(propertyDef.getName())); +// return pDelta; +// } // -// PrismObject object = getObject().getObject(); -// if (object.asObjectable() instanceof ShadowType -// && (((ShadowType) object.asObjectable()).getActivation() == null || ((ShadowType) object -// .asObjectable()).getActivation().getAdministrativeStatus() == null)) { +// private void addItemDelta(ItemWrapper itemWrapper, ItemDelta pDelta, ItemDefinition propertyDef, +// ItemPath containerPath) { +// for (ValueWrapper valueWrapper : itemWrapper.getValues()) { +// valueWrapper.normalize(propertyDef.getPrismContext()); +// ValueStatus valueStatus = valueWrapper.getStatus(); +// if (!valueWrapper.hasValueChanged() +// && (ValueStatus.NOT_CHANGED.equals(valueStatus) || ValueStatus.ADDED.equals(valueStatus))) { +// continue; +// } +// +// // TODO: need to check if the resource has defined +// // capabilities +// // todo this is bad hack because now we have not tri-state +// // checkbox +//// if (SchemaConstants.PATH_ACTIVATION.equivalent(containerPath) && getObject() != null) { +//// +//// PrismObject object = getObject().getObject(); +//// if (object.asObjectable() instanceof ShadowType +//// && (((ShadowType) object.asObjectable()).getActivation() == null || ((ShadowType) object +//// .asObjectable()).getActivation().getAdministrativeStatus() == null)) { +//// +//// if (!getObject().hasResourceCapability(((ShadowType) object.asObjectable()).getResource(), +//// ActivationCapabilityType.class)) { +//// continue; +//// } +//// } +//// } // -// if (!getObject().hasResourceCapability(((ShadowType) object.asObjectable()).getResource(), -// ActivationCapabilityType.class)) { -// continue; +// PrismValue newValCloned = ObjectWrapper.clone(valueWrapper.getValue()); +// PrismValue oldValCloned = ObjectWrapper.clone(valueWrapper.getOldValue()); +// switch (valueWrapper.getStatus()) { +// case ADDED: +// if (newValCloned != null) { +// if (SchemaConstants.PATH_PASSWORD.equivalent(containerPath)) { +// // password change will always look like add, +// // therefore we push replace +// if (LOGGER.isTraceEnabled()) { +// LOGGER.trace("Delta from wrapper: {} (password) ADD -> replace {}", pDelta.getPath(), newValCloned); +// } +// pDelta.setValuesToReplace(Arrays.asList(newValCloned)); +// } else if (propertyDef.isSingleValue()) { +// // values for single-valued properties +// // should be pushed via replace +// // in order to prevent problems e.g. with +// // summarizing deltas for +// // unreachable resources +// if (LOGGER.isTraceEnabled()) { +// LOGGER.trace("Delta from wrapper: {} (single,new) ADD -> replace {}", pDelta.getPath(), newValCloned); +// } +// pDelta.setValueToReplace(newValCloned); +// } else { +// if (LOGGER.isTraceEnabled()) { +// LOGGER.trace("Delta from wrapper: {} (multi,new) ADD -> add {}", pDelta.getPath(), newValCloned); +// } +// pDelta.addValueToAdd(newValCloned); +// } // } -// } +// break; +// case DELETED: +// if (newValCloned != null) { +// if (LOGGER.isTraceEnabled()) { +// LOGGER.trace("Delta from wrapper: {} (new) DELETE -> delete {}", pDelta.getPath(), newValCloned); +// } +// pDelta.addValueToDelete(newValCloned); +// } +// if (oldValCloned != null) { +// if (LOGGER.isTraceEnabled()) { +// LOGGER.trace("Delta from wrapper: {} (old) DELETE -> delete {}", pDelta.getPath(), oldValCloned); +// } +// pDelta.addValueToDelete(oldValCloned); +// } +// break; +// case NOT_CHANGED: +// // this is modify... +// if (propertyDef.isSingleValue()) { +// // newValCloned.isEmpty() +// if (newValCloned != null && !newValCloned.isEmpty()) { +// if (LOGGER.isTraceEnabled()) { +// LOGGER.trace("Delta from wrapper: {} (single,new) NOT_CHANGED -> replace {}", pDelta.getPath(), newValCloned); +// } +// pDelta.setValuesToReplace(Arrays.asList(newValCloned)); +// } else { +// if (oldValCloned != null) { +// if (LOGGER.isTraceEnabled()) { +// LOGGER.trace("Delta from wrapper: {} (single,old) NOT_CHANGED -> delete {}", pDelta.getPath(), oldValCloned); +// } +// pDelta.addValueToDelete(oldValCloned); +// } +// } +// } else { +// if (newValCloned != null && !newValCloned.isEmpty()) { +// if (LOGGER.isTraceEnabled()) { +// LOGGER.trace("Delta from wrapper: {} (multi,new) NOT_CHANGED -> add {}", pDelta.getPath(), newValCloned); +// } +// pDelta.addValueToAdd(newValCloned); +// } +// if (oldValCloned != null) { +// if (LOGGER.isTraceEnabled()) { +// LOGGER.trace("Delta from wrapper: {} (multi,old) NOT_CHANGED -> delete {}", pDelta.getPath(), oldValCloned); +// } +// pDelta.addValueToDelete(oldValCloned); +// } +// } +// break; // } - - PrismValue newValCloned = ObjectWrapper.clone(valueWrapper.getValue()); - PrismValue oldValCloned = ObjectWrapper.clone(valueWrapper.getOldValue()); - switch (valueWrapper.getStatus()) { - case ADDED: - if (newValCloned != null) { - if (SchemaConstants.PATH_PASSWORD.equivalent(containerPath)) { - // password change will always look like add, - // therefore we push replace - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Delta from wrapper: {} (password) ADD -> replace {}", pDelta.getPath(), newValCloned); - } - pDelta.setValuesToReplace(Arrays.asList(newValCloned)); - } else if (propertyDef.isSingleValue()) { - // values for single-valued properties - // should be pushed via replace - // in order to prevent problems e.g. with - // summarizing deltas for - // unreachable resources - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Delta from wrapper: {} (single,new) ADD -> replace {}", pDelta.getPath(), newValCloned); - } - pDelta.setValueToReplace(newValCloned); - } else { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Delta from wrapper: {} (multi,new) ADD -> add {}", pDelta.getPath(), newValCloned); - } - pDelta.addValueToAdd(newValCloned); - } - } - break; - case DELETED: - if (newValCloned != null) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Delta from wrapper: {} (new) DELETE -> delete {}", pDelta.getPath(), newValCloned); - } - pDelta.addValueToDelete(newValCloned); - } - if (oldValCloned != null) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Delta from wrapper: {} (old) DELETE -> delete {}", pDelta.getPath(), oldValCloned); - } - pDelta.addValueToDelete(oldValCloned); - } - break; - case NOT_CHANGED: - // this is modify... - if (propertyDef.isSingleValue()) { - // newValCloned.isEmpty() - if (newValCloned != null && !newValCloned.isEmpty()) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Delta from wrapper: {} (single,new) NOT_CHANGED -> replace {}", pDelta.getPath(), newValCloned); - } - pDelta.setValuesToReplace(Arrays.asList(newValCloned)); - } else { - if (oldValCloned != null) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Delta from wrapper: {} (single,old) NOT_CHANGED -> delete {}", pDelta.getPath(), oldValCloned); - } - pDelta.addValueToDelete(oldValCloned); - } - } - } else { - if (newValCloned != null && !newValCloned.isEmpty()) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Delta from wrapper: {} (multi,new) NOT_CHANGED -> add {}", pDelta.getPath(), newValCloned); - } - pDelta.addValueToAdd(newValCloned); - } - if (oldValCloned != null) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Delta from wrapper: {} (multi,old) NOT_CHANGED -> delete {}", pDelta.getPath(), oldValCloned); - } - pDelta.addValueToDelete(oldValCloned); - } - } - break; - } - } - } +// } +// } @Override public boolean checkRequired(PageBase pageBase) { @@ -694,6 +616,12 @@ public boolean checkRequired(PageBase pageBase) { } return rv; } + + @Override + public void setShowEmpty(boolean showEmpty) { + super.setShowEmpty(showEmpty); + getValues().forEach(value -> value.setShowEmpty(showEmpty)); + } @Override public boolean isEnforceRequiredFields() { @@ -707,15 +635,38 @@ public ContainerWrapper getParent() { } @Override - public boolean isVisible(boolean showEmpty) { - // TODO Auto-generated method stub + public boolean isVisible() { + PrismContainerDefinition def = getItemDefinition(); + + if (def.isIgnored() || (def.isOperational() && !def.getTypeName().equals(MetadataType.COMPLEX_TYPE))) { + return false; + } + + //TODO: emphasized + switch (status) { + case MODIFYING : + return isNotEmptyAndCanReadAndModify(def) || showEmptyCanReadAndModify(def); + case ADDING : + return emphasizedAndCanAdd(def) || showEmptyAndCanAdd(def); + } + return false; } + + private boolean isNotEmptyAndCanReadAndModify(PrismContainerDefinition def) { + return def.canRead() && def.canModify() && !getItem().isEmpty(); + } + + private boolean showEmptyCanReadAndModify(PrismContainerDefinition def) { + return def.canRead() && def.canModify() && isShowEmpty(); + } + private boolean showEmptyAndCanAdd(PrismContainerDefinition def) { + return def.canAdd() && isShowEmpty(); + } + + private boolean emphasizedAndCanAdd(PrismContainerDefinition def) { + return def.canAdd() && def.isEmphasized(); + } -// @Override -// public ContainerValueWrapper getContainerValue() { -// // TODO Auto-generated method stub -// return null; -// } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java index 5f51382e014..2c123751704 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java @@ -397,26 +397,10 @@ private void createContainerWrapper(ItemDefinition ite } } - private PropertyWrapper, PrismPropertyDefinition> createPropertyWrapper( + private PropertyWrapper createPropertyWrapper( PrismPropertyDefinition def, ContainerValueWrapper cWrapper) { PrismContainerValue containerValue = cWrapper.getContainerValue(); -// if (def.isIgnored() || skipProperty(def)) { -// return null; -// } -// if (!cWrapper.isShowInheritedObjectAttributes() && INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) { -// return null; -// } - - // capability handling for activation properties - // if (isShadowActivation(cWrapper) && - // !hasActivationCapability(cWrapper, def)) { - // continue; - // } - // - // if (isShadowAssociation(cWrapper)) { - // continue; - // } - + PrismProperty property = containerValue.findProperty(def.getName()); boolean propertyIsReadOnly = isItemReadOnly(def, cWrapper); // decision is based on parent object status, not this diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/DynamicFormPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/DynamicFormPanel.java index 9cbdc1f2c58..515e04e694e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/DynamicFormPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/DynamicFormPanel.java @@ -121,7 +121,7 @@ private ObjectWrapper createObjectWrapper(ObjectWrapperFactory owf, Task task ObjectWrapper objectWrapper = owf.createObjectWrapper("DisplayName", "description", prismObject, prismObject.getOid() == null ? ContainerStatus.ADDING : ContainerStatus.MODIFYING, authorizationPhase, task); - objectWrapper.setShowEmpty(true); +// objectWrapper.setShowEmpty(true); objectWrapper.setEnforceRequiredFields(enforceRequiredFields); return objectWrapper; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapper.java index c03c3d787c1..b1bfc25851f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapper.java @@ -30,7 +30,7 @@ /** * @author lazyman */ -public interface ItemWrapper extends Revivable, DebugDumpable, Serializable { +public interface ItemWrapper extends Revivable, DebugDumpable, Serializable { QName getName(); @@ -57,13 +57,13 @@ public interface ItemWrapper extends boolean hasChanged(); - List getValues(); + List getValues(); /** * Visibility flag. This is NOT an override, it defines whether the item * should be displayed or not. */ - boolean isVisible(boolean showEmpty); + boolean isVisible(); /** * Used to display the form elements with stripe in every other line. @@ -74,7 +74,7 @@ public interface ItemWrapper extends // ContainerValueWrapper getContainerValue(); - void addValue(); + void addValue(boolean showEmpty); boolean checkRequired(PageBase pageBase); @@ -85,4 +85,8 @@ default boolean isEnforceRequiredFields() { } ContainerWrapper getParent(); + + boolean isShowEmpty(); + + void setShowEmpty(boolean isShowEmpty); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java index db42d95feb3..0f453018f7f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java @@ -271,19 +271,22 @@ public void setContainers(List> contai } public ContainerWrapper findContainerWrapper(ItemPath path) { - for (ContainerWrapper wrapper : getContainers()) { - if (path != null) { - if (path.equivalent(wrapper.getPath())) { - return wrapper; - } - } else { - if (wrapper.getPath() == null) { - return wrapper; - } - } - } + if (path == null || path.isEmpty()) { + return (ContainerWrapper) findMainContainerWrapper(); + } + + if (path.size() == 1) { + return (ContainerWrapper) getContainers().stream().filter(wrapper -> path.equivalent(wrapper.getPath())).findFirst().orElse(null); + } + + + ContainerWrapper containerWrapper = findContainerWrapper(path.head()); + if (containerWrapper == null) { + return null; + } + + return containerWrapper.findContainerWrapper(path); - return null; } public ContainerWrapper findMainContainerWrapper() { @@ -308,7 +311,7 @@ public IW findPropertyWrapper(ItemPath path) { if (containerWrapper == null) { return null; } - return (IW) containerWrapper.findPropertyWrapper(propertyPath); + return (IW) containerWrapper.findPropertyWrapper(ItemPath.getFirstName(propertyPath)); } public void normalize() throws SchemaException { @@ -328,10 +331,15 @@ public void sort(PageBase pageBase) { computeStripes(); } - private void computeStripes() { - for (ContainerWrapper container: containers) { - container.computeStripes(); - } +// @Override +// public void setShowEmpty(boolean showEmpty) { +// super.setShowEmpty(showEmpty); +// getContainers().forEach(c -> c.setShowEmpty(showEmpty)); +// } + + @Override + public void computeStripes() { + getContainers().forEach(c -> c.computeStripes()); } public ObjectDelta getObjectDelta() throws SchemaException { @@ -564,6 +572,12 @@ public void setShowAssignments(boolean showAssignments) { this.showAssignments = showAssignments; } + @Override + public void setShowEmpty(boolean showEmpty) { + super.setShowEmpty(showEmpty); + getContainers().forEach(container -> container.setShowEmpty(true)); + } + public boolean isReadonly() { if (isProtectedAccount()) { return true; @@ -607,7 +621,7 @@ public PrismContainerDefinition getRefinedAttributeDefinition() { public void copyRuntimeStateTo(ObjectWrapper newWrapper) { newWrapper.setMinimalized(this.isMinimalized()); - newWrapper.setShowEmpty(this.isShowEmpty()); +// newWrapper.setShowEmpty(this.isShowEmpty()); newWrapper.setSorted(this.isSorted()); newWrapper.setSelectable(this.isSelectable()); newWrapper.setSelected(this.isSelected()); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerHeaderPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerHeaderPanel.html new file mode 100644 index 00000000000..ba20aa94a54 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerHeaderPanel.html @@ -0,0 +1,24 @@ + + + + + + + + + + diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerHeaderPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerHeaderPanel.java new file mode 100644 index 00000000000..e701cbbc681 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerHeaderPanel.java @@ -0,0 +1,61 @@ +package com.evolveum.midpoint.web.component.prism; + +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.AjaxLink; +import org.apache.wicket.model.IModel; + +import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; + +public class PrismContainerHeaderPanel extends PrismHeaderPanel>{ + + private static final long serialVersionUID = 1L; + + private static final String ID_ADD_BUTTON = "addButton"; + + public PrismContainerHeaderPanel(String id, IModel> model) { + super(id, model); + + } + + @Override + protected void initButtons() { + + add(new VisibleEnableBehaviour() { + + private static final long serialVersionUID = 1L; + + @Override + public boolean isVisible() { + return isContainerMultivalue(); + } + }); + + AjaxLink addButton = new AjaxLink(ID_ADD_BUTTON) { + private static final long serialVersionUID = 1L; + + @Override + public void onClick(AjaxRequestTarget target) { + addValue(target); + } + }; + + add(addButton); + + } + + private void addValue(AjaxRequestTarget target) { + getModelObject().addValue(true); + onButtonClick(target); + } + + private boolean isContainerMultivalue(){ + return getModelObject().isVisible() && getModelObject().getItemDefinition().isMultiValue(); + } + + + + + + +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.html index e13cc49f4d9..992504b10dc 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.html @@ -17,7 +17,7 @@ - +
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.java index 6968ed3e15f..291c9060eec 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.java @@ -29,6 +29,7 @@ import org.apache.wicket.model.PropertyModel; import com.evolveum.midpoint.gui.api.page.PageBase; +import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; @@ -39,7 +40,7 @@ * @author lazyman * @author semancik */ -public class PrismContainerPanel extends Panel { +public class PrismContainerPanel extends Panel { private static final long serialVersionUID = 1L; private static final Trace LOGGER = TraceManager.getTrace(PrismContainerPanel.class); @@ -48,74 +49,40 @@ public class PrismContainerPanel extends Panel { private PageBase pageBase; - public PrismContainerPanel(String id, final IModel model, boolean showHeader, Form form, PageBase pageBase) { + public PrismContainerPanel(String id, final IModel> model, boolean showHeader, Form form, PageBase pageBase) { super(id); setOutputMarkupId(true); this.pageBase = pageBase; LOGGER.trace("Creating container panel for {}", model.getObject()); - add(new VisibleEnableBehaviour() { - private static final long serialVersionUID = 1L; - - @Override - public boolean isVisible() { - ContainerWrapper containerWrapper = model.getObject(); -// PrismContainer prismContainer = containerWrapper.getItem(); -// if (containerWrapper.getItemDefinition().isOperational()) { -// return false; -// } - return containerWrapper.isVisible(); -// return containerWrapper.isItemVisible(); - -// // HACK HACK HACK -// if (ShadowType.F_ASSOCIATION.equals(prismContainer.getElementName())) { -// return true; -// } - -// return !containerWrapper.getValues().isEmpty() && containerWrapper.isVisible(); -// return true; -// boolean isVisible = false; -// for (ContainerValueWrapper values : containerWrapper.getValues()) { -// if (item.isItemVisible(item)) { -// isVisible = true; -// break; -// } -// } -// -// return !containerWrapper.getValues().isEmpty() && isVisible; - } + //TODO: visible behaviour?? + add( new VisibleEnableBehaviour() { + + @Override + public boolean isVisible() { + return model.getObject() !=null && model.getObject().isVisible(); + } }); - + initLayout(model, form, showHeader); } - private void initLayout(final IModel model, final Form form, boolean showHeader) { - PrismHeaderPanel header = new PrismHeaderPanel(ID_HEADER, model) { + private void initLayout(final IModel> model, final Form form, boolean showHeader) { + PrismContainerHeaderPanel header = new PrismContainerHeaderPanel(ID_HEADER, model) { private static final long serialVersionUID = 1L; - + @Override protected void onButtonClick(AjaxRequestTarget target) { + addOrReplaceProperties(model, form, true); target.add(PrismContainerPanel.this.findParent(PrismObjectPanel.class)); } - @Override - public boolean isButtonsVisible() { - return true; - } - }; - header.add(new VisibleEnableBehaviour() { - private static final long serialVersionUID = 1L; - - @Override - public boolean isVisible() { - return showHeader;// && !model.getObject().isMain(); - } - }); -// add(header); + header.setOutputMarkupId(true); + add(header); addOrReplaceProperties(model, form, false); } @@ -136,13 +103,18 @@ public String getObject() { }; } - private void addOrReplaceProperties(IModel model, final Form form, boolean isToBeReplaced){ + private void addOrReplaceProperties(IModel> model, final Form form, boolean isToBeReplaced){ + - ListView values = new ListView("values", new PropertyModel>(model, "values")) { + ListView> values = new ListView>("values", new PropertyModel>>(model, "values")) { + private static final long serialVersionUID = 1L; + @Override - protected void populateItem(ListItem item) { - item.add(new ContainerValuePanel("value", item.getModel(), true, form, pageBase)); + protected void populateItem(ListItem> item) { + ContainerValuePanel containerPanel = new ContainerValuePanel("value", item.getModel(), true, form, pageBase); + containerPanel.setOutputMarkupId(true); + item.add(containerPanel); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.html new file mode 100644 index 00000000000..15956c9f475 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.html @@ -0,0 +1,24 @@ + + + + + + + + + + diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java new file mode 100644 index 00000000000..4217ac7099f --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java @@ -0,0 +1,113 @@ +package com.evolveum.midpoint.web.component.prism; + +import org.apache.wicket.AttributeModifier; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.model.AbstractReadOnlyModel; +import org.apache.wicket.model.IModel; + +import com.evolveum.midpoint.gui.api.GuiStyleConstants; +import com.evolveum.midpoint.gui.api.component.togglebutton.ToggleIconButton; +import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; + +public class PrismContainerValueHeaderPanel extends PrismHeaderPanel> { + + private static final long serialVersionUID = 1L; + + + private static final String ID_SHOW_EMPTY_FIELDS = "showEmptyFields"; + private static final String ID_SORT_PROPERTIES = "sortProperties"; + private static final String ID_SHOW_METADATA = "showMetadata"; + + + public PrismContainerValueHeaderPanel(String id, IModel> model) { + super(id, model); + } + + @Override + protected void initButtons() { + VisibleEnableBehaviour buttonsVisibleBehaviour = new VisibleEnableBehaviour() { + private static final long serialVersionUID = 1L; + + @Override + public boolean isVisible() { + return PrismContainerValueHeaderPanel.this.isButtonsVisible(); + } + }; + + ToggleIconButton showMetadataButton = new ToggleIconButton(ID_SHOW_METADATA, + GuiStyleConstants.CLASS_ICON_SHOW_METADATA, GuiStyleConstants.CLASS_ICON_SHOW_METADATA) { + private static final long serialVersionUID = 1L; + + @Override + public void onClick(AjaxRequestTarget target) { +// ObjectWrapper objectWrapper = getObjectWrapper(model); +// PrismWrapper wrapper = PrismHeaderPanel.this.getModelObject(); +// wrapper.setShowMetadata(wrapper.isShowMetadata()); +// objectWrapper.setShowMetadata(!objectWrapper.isShowMetadata()); + onButtonClick(target); + } + + @Override + public boolean isOn() { + return PrismContainerValueHeaderPanel.this.getModelObject().isShowMetadata(); + } + }; + showMetadataButton.add(new AttributeModifier("title", new AbstractReadOnlyModel() { + + @Override + public Object getObject() { + return PrismContainerValueHeaderPanel.this.getModelObject() == null ? "" : (PrismContainerValueHeaderPanel.this.getModelObject().isShowMetadata() ? + createStringResource("PrismObjectPanel.hideMetadata").getString() : + createStringResource("PrismObjectPanel.showMetadata").getString()); + } + })); + showMetadataButton.add(buttonsVisibleBehaviour); + add(showMetadataButton); + + ToggleIconButton showEmptyFieldsButton = new ToggleIconButton(ID_SHOW_EMPTY_FIELDS, + GuiStyleConstants.CLASS_ICON_SHOW_EMPTY_FIELDS, GuiStyleConstants.CLASS_ICON_NOT_SHOW_EMPTY_FIELDS) { + private static final long serialVersionUID = 1L; + + @Override + public void onClick(AjaxRequestTarget target) { + ContainerValueWrapper wrapper = PrismContainerValueHeaderPanel.this.getModelObject(); + wrapper.setShowEmpty(!wrapper.isShowEmpty()); + + onButtonClick(target); + } + + @Override + public boolean isOn() { + return PrismContainerValueHeaderPanel.this.getModelObject().isShowEmpty(); + } + }; + showEmptyFieldsButton.setOutputMarkupId(true); + + showEmptyFieldsButton.add(buttonsVisibleBehaviour); + add(showEmptyFieldsButton); + + ToggleIconButton sortPropertiesButton = new ToggleIconButton(ID_SORT_PROPERTIES, + GuiStyleConstants.CLASS_ICON_SORT_ALPHA_ASC, GuiStyleConstants.CLASS_ICON_SORT_AMOUNT_ASC) { + private static final long serialVersionUID = 1L; + + @Override + public void onClick(AjaxRequestTarget target) { + PrismWrapper objectWrapper = PrismContainerValueHeaderPanel.this.getModelObject(); + objectWrapper.setSorted(!objectWrapper.isSorted()); +// objectWrapper.sort((PageBase)getPage()); + + onButtonClick(target); + } + + @Override + public boolean isOn() { + return PrismContainerValueHeaderPanel.this.getModelObject().isSorted(); + } + }; + sortPropertiesButton.add(buttonsVisibleBehaviour); + add(sortPropertiesButton); + + } + +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismHeaderPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismHeaderPanel.html index 33709726079..8e3a147cd2e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismHeaderPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismHeaderPanel.html @@ -19,9 +19,7 @@
- - - +
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismHeaderPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismHeaderPanel.java index 3cc38ae5399..50076009406 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismHeaderPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismHeaderPanel.java @@ -38,15 +38,13 @@ public abstract class PrismHeaderPanel extends BasePanel { private static final long serialVersionUID = 1L; - private static final String ID_SHOW_EMPTY_FIELDS = "showEmptyFields"; - private static final String ID_SORT_PROPERTIES = "sortProperties"; - private static final String ID_SHOW_METADATA = "showMetadata"; + private static final String ID_LABEL = "label"; private static final Trace LOGGER = TraceManager.getTrace(PrismHeaderPanel.class); - public PrismHeaderPanel(String id, IModel model) { + public PrismHeaderPanel(String id, IModel model) { super(id, model); initLayout(); @@ -55,87 +53,8 @@ public PrismHeaderPanel(String id, IModel model) { private void initLayout() { setOutputMarkupId(true); - VisibleEnableBehaviour buttonsVisibleBehaviour = new VisibleEnableBehaviour() { - private static final long serialVersionUID = 1L; - - @Override - public boolean isVisible() { - return PrismHeaderPanel.this.isButtonsVisible(); - } - }; - - ToggleIconButton showMetadataButton = new ToggleIconButton(ID_SHOW_METADATA, - GuiStyleConstants.CLASS_ICON_SHOW_METADATA, GuiStyleConstants.CLASS_ICON_SHOW_METADATA) { - private static final long serialVersionUID = 1L; - - @Override - public void onClick(AjaxRequestTarget target) { -// ObjectWrapper objectWrapper = getObjectWrapper(model); -// PrismWrapper wrapper = PrismHeaderPanel.this.getModelObject(); -// wrapper.setShowMetadata(wrapper.isShowMetadata()); -// objectWrapper.setShowMetadata(!objectWrapper.isShowMetadata()); - onButtonClick(target); - } - - @Override - public boolean isOn() { - return getObjectWrapper().isShowMetadata(); - } - }; - showMetadataButton.add(new AttributeModifier("title", new AbstractReadOnlyModel() { - - @Override - public Object getObject() { - return getObjectWrapper() == null ? "" : (getObjectWrapper().isShowMetadata() ? - createStringResource("PrismObjectPanel.hideMetadata").getString() : - createStringResource("PrismObjectPanel.showMetadata").getString()); - } - })); - showMetadataButton.add(buttonsVisibleBehaviour); - add(showMetadataButton); - - ToggleIconButton showEmptyFieldsButton = new ToggleIconButton(ID_SHOW_EMPTY_FIELDS, - GuiStyleConstants.CLASS_ICON_SHOW_EMPTY_FIELDS, GuiStyleConstants.CLASS_ICON_NOT_SHOW_EMPTY_FIELDS) { - private static final long serialVersionUID = 1L; - - @Override - public void onClick(AjaxRequestTarget target) { - PrismWrapper objectWrapper = getObjectWrapper(); - objectWrapper.setShowEmpty(!objectWrapper.isShowEmpty()); - - onButtonClick(target); - } - - @Override - public boolean isOn() { - return getObjectWrapper().isShowEmpty(); - } - }; - showEmptyFieldsButton.setOutputMarkupId(true); - - showEmptyFieldsButton.add(buttonsVisibleBehaviour); - add(showEmptyFieldsButton); - - ToggleIconButton sortPropertiesButton = new ToggleIconButton(ID_SORT_PROPERTIES, - GuiStyleConstants.CLASS_ICON_SORT_ALPHA_ASC, GuiStyleConstants.CLASS_ICON_SORT_AMOUNT_ASC) { - private static final long serialVersionUID = 1L; - - @Override - public void onClick(AjaxRequestTarget target) { - PrismWrapper objectWrapper = getObjectWrapper(); - objectWrapper.setSorted(!objectWrapper.isSorted()); -// objectWrapper.sort((PageBase)getPage()); - - onButtonClick(target); - } - - @Override - public boolean isOn() { - return getObjectWrapper().isSorted(); - } - }; - sortPropertiesButton.add(buttonsVisibleBehaviour); - add(sortPropertiesButton); + + initButtons(); IModel headerLabelModel = new AbstractReadOnlyModel() { private static final long serialVersionUID = 1L; @@ -143,7 +62,7 @@ public boolean isOn() { @Override public String getObject() { - PrismWrapper wrapper = getObjectWrapper(); + PrismWrapper wrapper = getModelObject(); String displayName = "displayName.not.set"; if (wrapper instanceof ContainerValueWrapper) { displayName = ((ContainerValueWrapper) wrapper).getDisplayName(); @@ -167,20 +86,9 @@ public String getObject() { add(new Label(ID_LABEL, headerLabelModel)); } - private PrismWrapper getObjectWrapper() { - return getModelObject(); -// Object wrapper = model.getObject(); -// ObjectWrapper objectWrapper = null; -// if (wrapper instanceof ContainerWrapper) { -// return ((ContainerWrapper)wrapper).getObject(); -// } else if (wrapper instanceof ObjectWrapper) { -// return (ObjectWrapper)wrapper; -// } else if (wrapper instanceof ContainerValueWrapper) { -// return ((ContainerValueWrapper) wrapper).getContainer().getObject(); -// } -// return null; - } + protected abstract void initButtons(); + protected void onButtonClick(AjaxRequestTarget target) { } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismObjectPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismObjectPanel.java index 59b395d1a02..8708137f8e4 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismObjectPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismObjectPanel.java @@ -69,7 +69,7 @@ public PrismObjectPanel(String id, IModel> model, ResourceRefer } private void initLayout(final IModel> model, ResourceReference image, final Form> form) { - Component headerComponent = createHeader(ID_HEADER, model, form); +// Component headerComponent = createHeader(ID_HEADER, model, form); // add(headerComponent); addOrReplaceContainers(model, form, false); @@ -80,23 +80,23 @@ public void removeAllContainerWrappers() { ((ListView) get(ID_CONTAINERS)).removeAll(); } - protected Component createHeader(String id, final IModel> model, final Form> form) { - PrismHeaderPanel header = new PrismHeaderPanel(ID_HEADER, model) { - private static final long serialVersionUID = 1L; - - @Override - protected void onButtonClick(AjaxRequestTarget target) { - addOrReplaceContainers(model, form, true); - target.add(PrismObjectPanel.this); - } - - @Override - public boolean isButtonsVisible() { - return true; - } - }; - return header; - } +// protected Component createHeader(String id, final IModel> model, final Form> form) { +// PrismHeaderPanel header = new PrismHeaderPanel(ID_HEADER, model) { +// private static final long serialVersionUID = 1L; +// +// @Override +// protected void onButtonClick(AjaxRequestTarget target) { +// addOrReplaceContainers(model, form, true); +// target.add(PrismObjectPanel.this); +// } +// +// @Override +// public boolean isButtonsVisible() { +// return true; +// } +// }; +// return header; +// } protected IModel> createContainerModel(IModel> model){ diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismOptionButtonPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismOptionButtonPanel.java index 67cd72ddf29..18b6a78de6b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismOptionButtonPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismOptionButtonPanel.java @@ -85,10 +85,10 @@ public boolean isVisible() { @Override public Object getObject() { ObjectWrapper wrapper = model.getObject(); - if (wrapper.isShowEmpty()) { - return new PackageResourceReference(PrismObjectPanel.class, - "ShowEmptyFalse.png"); - } +// if (wrapper.isShowEmpty()) { +// return new PackageResourceReference(PrismObjectPanel.class, +// "ShowEmptyFalse.png"); +// } return new PackageResourceReference(PrismObjectPanel.class, "ShowEmptyTrue.png"); } @@ -98,10 +98,10 @@ public Object getObject() { @Override public Object getObject() { - ObjectWrapper wrapper = model.getObject(); - if (wrapper.isShowEmpty()) { - return getString("prismOptionButtonPanel.hideEmpty"); - } +// ObjectWrapper wrapper = model.getObject(); +// if (wrapper.isShowEmpty()) { +// return getString("prismOptionButtonPanel.hideEmpty"); +// } return getString("prismOptionButtonPanel.showEmpty"); } }, "")); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismPropertyPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismPropertyPanel.java index 4faf0c4bf16..76807891cf4 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismPropertyPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismPropertyPanel.java @@ -74,13 +74,13 @@ public PrismPropertyPanel(String id, final IModel model, Form form, PageBase add(new VisibleEnableBehaviour() { private static final long serialVersionUID = 1L; -// @Override -// public boolean isVisible() { -// IW propertyWrapper = model.getObject(); -// boolean visible = propertyWrapper.isVisible(propertyWrapper.getParent().isShowEmpty()); -// LOGGER.trace("isVisible: {}: {}", propertyWrapper, visible); -// return visible; -// } + @Override + public boolean isVisible() { + IW propertyWrapper = model.getObject(); + boolean visible = propertyWrapper.isVisible(); + LOGGER.trace("isVisible: {}: {}", propertyWrapper, visible); + return visible; + } @Override public boolean isEnabled() { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java index 94abe7eb92b..0d156a7f41e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java @@ -233,7 +233,7 @@ public boolean isEnabled() { } } - private int countUsableValues(ItemWrapper property) { + private int countUsableValues(PropertyOrReferenceWrapper property) { int count = 0; for (ValueWrapper value : property.getValues()) { value.normalize(property.getItemDefinition().getPrismContext()); @@ -251,7 +251,7 @@ private int countUsableValues(ItemWrapper getUsableValues(ItemWrapper property) { + private List getUsableValues(PropertyOrReferenceWrapper property) { List values = new ArrayList<>(); for (ValueWrapper value : property.getValues()) { value.normalize(property.getItemDefinition().getPrismContext()); @@ -264,7 +264,7 @@ private List getUsableValues(ItemWrapper property) { + private int countNonDeletedValues(PropertyOrReferenceWrapper property) { int count = 0; for (ValueWrapper value : property.getValues()) { value.normalize(property.getItemDefinition().getPrismContext()); @@ -276,7 +276,7 @@ private int countNonDeletedValues(ItemWrapper property) { + private boolean hasEmptyPlaceholder(PropertyOrReferenceWrapper property) { for (ValueWrapper value : property.getValues()) { value.normalize(property.getItemDefinition().getPrismContext()); if (ValueStatus.ADDED.equals(value.getStatus()) && !value.hasValueChanged()) { @@ -298,7 +298,7 @@ private boolean isRemoveButtonVisible() { return true; } - ItemWrapper propertyWrapper = valueWrapper.getItem(); + PropertyOrReferenceWrapper propertyWrapper = (PropertyOrReferenceWrapper) valueWrapper.getItem(); ItemDefinition definition = propertyWrapper.getItem().getDefinition(); int min = definition.getMinOccurs(); @@ -327,7 +327,7 @@ private boolean isAddButtonVisible() { return false; } - ItemWrapper propertyWrapper = valueWrapper.getItem(); + PropertyOrReferenceWrapper propertyWrapper = (PropertyOrReferenceWrapper) valueWrapper.getItem(); Item property = propertyWrapper.getItem(); ItemDefinition definition = property.getDefinition(); @@ -807,14 +807,14 @@ private void addValue(AjaxRequestTarget target) { ValueWrapper wrapper = valueWrapperModel.getObject(); ItemWrapper propertyWrapper = wrapper.getItem(); LOGGER.debug("Adding value of {}", propertyWrapper); - propertyWrapper.addValue(); + propertyWrapper.addValue(true); ListView parent = findParent(ListView.class); target.add(parent.getParent()); } private void removeValue(AjaxRequestTarget target) { ValueWrapper wrapper = valueWrapperModel.getObject(); - ItemWrapper propertyWrapper = wrapper.getItem(); + PropertyOrReferenceWrapper propertyWrapper = (PropertyOrReferenceWrapper) wrapper.getItem(); LOGGER.debug("Removing value of {}", propertyWrapper); List values = propertyWrapper.getValues(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismWrapper.java index 8a9035191ec..534e99dabfd 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismWrapper.java @@ -1,6 +1,6 @@ package com.evolveum.midpoint.web.component.prism; -public class PrismWrapper { +public abstract class PrismWrapper { private boolean showEmpty; @@ -38,6 +38,8 @@ public boolean isShowEmpty() { public void setShowEmpty(boolean showEmpty) { this.showEmpty = showEmpty; -// computeStripes(); + computeStripes(); } + + public abstract void computeStripes(); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyOrReferenceWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyOrReferenceWrapper.java index 1bdc3de82be..3aa2254b920 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyOrReferenceWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyOrReferenceWrapper.java @@ -34,18 +34,18 @@ * * @author mederly */ -public abstract class PropertyOrReferenceWrapper, ID extends ItemDefinition> implements ItemWrapper, Serializable { +public abstract class PropertyOrReferenceWrapper, ID extends ItemDefinition> implements ItemWrapper, Serializable { private static final long serialVersionUID = -179218652752175177L; protected ContainerValueWrapper container; protected I item; - protected ID itemDefinition; protected ValueStatus status; protected List values; protected String displayName; protected boolean readonly; private boolean isStripe; + private boolean showEmpty; public PropertyOrReferenceWrapper(@Nullable ContainerValueWrapper containerValue, I item, boolean readonly, ValueStatus status) { Validate.notNull(item, "Item must not be null."); @@ -53,7 +53,6 @@ public PropertyOrReferenceWrapper(@Nullable ContainerValueWrapper containerValue this.container = containerValue; this.item = item; - this.itemDefinition = getItemDefinition(); this.status = status; this.readonly = readonly; } @@ -68,20 +67,14 @@ public void revive(PrismContext prismContext) throws SchemaException { getItem().revive(prismContext); } if (getItemDefinition() != null) { - itemDefinition.revive(prismContext); + getItemDefinition().revive(prismContext); } } @Override public ID getItemDefinition() { - ID definition = null; - if (getParent() != null && getParent().getItemDefinition() != null) { - definition = (ID) getParent().getItemDefinition().findItemDefinition(item.getDefinition().getName()); - } - if (definition == null) { - definition = item.getDefinition(); - } - return definition; + return item.getDefinition(); + } @Override @@ -89,16 +82,16 @@ public ContainerWrapper getParent() { return container.getContainer(); } - public boolean isVisible(boolean showEmpty) { + public boolean isVisible() { if (getItemDefinition().isOperational()) { // TODO ...or use itemDefinition instead? return false; } switch (status) { case ADDED : - return canAddDefault() || canAddAndShowEmpty(showEmpty); + return canAddDefault() || canAddAndShowEmpty(); case NOT_CHANGED : - return canReadOrModifyAndNonEmpty() || canReadOrModifyAndShowEmpty(showEmpty); + return canReadOrModifyAndNonEmpty() || canReadOrModifyAndShowEmpty(); } // if (getItem().isEmpty() && isS) // else if (container != null) { @@ -108,8 +101,8 @@ public boolean isVisible(boolean showEmpty) { // } } - private boolean canAddAndShowEmpty(boolean showEmpty) { - return getItemDefinition().canAdd() && showEmpty; + private boolean canAddAndShowEmpty() { + return getItemDefinition().canAdd() && isShowEmpty(); } private boolean canAddDefault() { @@ -120,8 +113,8 @@ private boolean canReadOrModifyAndNonEmpty() { return (getItemDefinition().canModify() || getItemDefinition().canRead()) && !getItem().isEmpty(); } - private boolean canReadOrModifyAndShowEmpty(boolean showEmpty) { - return (getItemDefinition().canModify() || getItemDefinition().canRead()) && getItem().isEmpty() && showEmpty; + private boolean canReadOrModifyAndShowEmpty() { + return (getItemDefinition().canModify() || getItemDefinition().canRead()) && isShowEmpty(); } public boolean isStripe() { @@ -160,8 +153,17 @@ public void setStatus(ValueStatus status) { public List getValues() { return values; } + + public boolean isShowEmpty() { + return showEmpty; + } + + public void setShowEmpty(boolean showEmpty) { + this.showEmpty = showEmpty; + } - public void addValue() { + public void addValue(boolean showEmpty) { + this.showEmpty = showEmpty; getValues().add(createAddedValue()); } @@ -225,7 +227,7 @@ public I getUpdatedItem(PrismContext prismContext) throws SchemaException { @Override public boolean checkRequired(PageBase pageBase) { - if (itemDefinition == null || !itemDefinition.isMandatory()) { + if (getItemDefinition() == null || !getItemDefinition().isMandatory()) { return true; } for (ValueWrapper valueWrapper : CollectionUtils.emptyIfNull(getValues())) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyWrapper.java index 930bc6786a8..8cd653a3075 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyWrapper.java @@ -35,11 +35,11 @@ /** * @author lazyman */ -public class PropertyWrapper, ID extends ItemDefinition> extends PropertyOrReferenceWrapper implements Serializable, DebugDumpable { +public class PropertyWrapper extends PropertyOrReferenceWrapper, PrismPropertyDefinition> implements Serializable, DebugDumpable { private static final long serialVersionUID = -6347026284758253783L; - public PropertyWrapper(@Nullable ContainerValueWrapper container, I property, boolean readonly, ValueStatus status) { + public PropertyWrapper(@Nullable ContainerValueWrapper container, PrismProperty property, boolean readonly, ValueStatus status) { super(container, property, readonly, status); if (container != null && SchemaConstants.PATH_PASSWORD.equivalent(container.getPath()) @@ -55,7 +55,7 @@ private List createValues() { List values = new ArrayList<>(); for (PrismValue prismValue : item.getValues()) { - values.add(new ValueWrapper(this, prismValue, ValueStatus.NOT_CHANGED)); + values.add(new ValueWrapper(this, prismValue, ValueStatus.NOT_CHANGED)); } int minOccurs = getItemDefinition().getMinOccurs(); @@ -71,7 +71,7 @@ private List createValues() { } @Override - public ValueWrapper createAddedValue() { + public ValueWrapper createAddedValue() { ItemDefinition definition = item.getDefinition(); ValueWrapper wrapper; @@ -149,7 +149,7 @@ public String debugDump(int indent) { sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "readonly", readonly, indent+1); sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "itemDefinition", itemDefinition == null?null:itemDefinition.toString(), indent+1); + DebugUtil.debugDumpWithLabel(sb, "itemDefinition", getItemDefinition() == null?null:getItemDefinition().toString(), indent+1); sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "property", item == null?null:item.toString(), indent+1); sb.append("\n"); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ReferenceWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ReferenceWrapper.java index e2ef5447d1e..ce26cab0a05 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ReferenceWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ReferenceWrapper.java @@ -51,7 +51,7 @@ private List createValues() { while (values.size() < minOccurs) { values.add(createAddedValue()); } - + if (values.isEmpty()) { values.add(createAddedValue()); } @@ -97,7 +97,7 @@ public String debugDump(int indent) { sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "readonly", readonly, indent+1); sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "itemDefinition", itemDefinition == null?null:itemDefinition.toString(), indent+1); + DebugUtil.debugDumpWithLabel(sb, "itemDefinition", getItemDefinition() == null?null:getItemDefinition().toString(), indent+1); sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "reference", item, indent+1); sb.append("\n"); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ValueWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ValueWrapper.java index ebc07dd6799..e3d46de70c4 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ValueWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ValueWrapper.java @@ -16,6 +16,10 @@ package com.evolveum.midpoint.web.component.prism; +import java.io.Serializable; + +import org.apache.commons.lang.Validate; + import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.PrismValue; @@ -29,10 +33,6 @@ import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType; -import org.apache.commons.lang.Validate; - -import java.io.Serializable; - /** * @author lazyman */ @@ -69,7 +69,7 @@ public ValueWrapper(ItemWrapper property, PrismValue value, PrismValue oldValue, T val = ((PrismPropertyValue) value).getValue(); if (val instanceof PolyString) { PolyString poly = (PolyString) val; - this.value = new PrismPropertyValue(new PolyString(poly.getOrig(), poly.getNorm()), + this.value = new PrismPropertyValue(new PolyString(poly.getOrig(), poly.getNorm()), value.getOriginType(), value.getOriginObject()); } else if (val instanceof ProtectedStringType) { this.value = value.clone(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/model/ContainerWrapperFromObjectWrapperModel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/model/ContainerWrapperFromObjectWrapperModel.java index 62d617abc2f..5bf129d766e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/model/ContainerWrapperFromObjectWrapperModel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/model/ContainerWrapperFromObjectWrapperModel.java @@ -63,7 +63,7 @@ public void detach() { @Override public ContainerWrapper getObject() { - ContainerWrapper containerWrapper = getWrapper().findPropertyWrapper(path); + ContainerWrapper containerWrapper = getWrapper().findContainerWrapper(path); return containerWrapper; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/model/PropertyWrapperFromObjectWrapperModel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/model/PropertyWrapperFromObjectWrapperModel.java index 8c66cf3e508..a3d0534604f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/model/PropertyWrapperFromObjectWrapperModel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/model/PropertyWrapperFromObjectWrapperModel.java @@ -37,7 +37,7 @@ * @author lazyman * @author semancik */ -public class PropertyWrapperFromObjectWrapperModel extends AbstractWrapperModel,PrismPropertyDefinition>,O> { +public class PropertyWrapperFromObjectWrapperModel extends AbstractWrapperModel,O> { private static final Trace LOGGER = TraceManager.getTrace(PropertyWrapperFromObjectWrapperModel.class); @@ -54,12 +54,12 @@ public PropertyWrapperFromObjectWrapperModel(IModel> model, Ite } @Override - public PropertyWrapper, PrismPropertyDefinition> getObject() { - PropertyWrapper, PrismPropertyDefinition> propertyWrapper = getWrapper().findPropertyWrapper(path); + public PropertyWrapper getObject() { + PropertyWrapper propertyWrapper = getWrapper().findPropertyWrapper(path); return propertyWrapper; } - @Override public void setObject(PropertyWrapper, PrismPropertyDefinition> prismPropertyPropertyWrapper) { + @Override public void setObject(PropertyWrapper prismPropertyPropertyWrapper) { throw new UnsupportedOperationException("PropertyWrapperFromObjectWrapperModel.setObject called"); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminObjectDetails.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminObjectDetails.java index e2a19e751d1..70a2e726a4c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminObjectDetails.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminObjectDetails.java @@ -339,7 +339,7 @@ protected ObjectWrapper loadObjectWrapper(PrismObject objectToEdit) { loadParentOrgs(wrapper, task, result); - wrapper.setShowEmpty(!isEditingFocus()); +// wrapper.setShowEmpty(!isEditingFocus()); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Loaded focus wrapper:\n{}", wrapper.debugDump()); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/content/PageAccount.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/content/PageAccount.java index 5a1d82feece..0637b67fa98 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/content/PageAccount.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/content/PageAccount.java @@ -116,7 +116,7 @@ private ObjectWrapper loadAccount(PageParameters parameters) { } catch (SchemaException e) { throw new SystemException(e.getMessage(), e); } - wrapper.setShowEmpty(false); +// wrapper.setShowEmpty(false); return wrapper; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/GenericHandlerDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/GenericHandlerDto.java index 02d6740a355..d199ab5824f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/GenericHandlerDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/dto/GenericHandlerDto.java @@ -62,7 +62,7 @@ public GenericHandlerDto(TaskDto taskDto, @NotNull List items, PageBase pa for (Item item : items) { PrismProperty property = taskDto.getExtensionProperty(item.name); if (property != null) { - PropertyWrapper propertyWrapper = new PropertyWrapper<>(null, property, true, ValueStatus.NOT_CHANGED); + PropertyWrapper propertyWrapper = new PropertyWrapper<>(null, property, true, ValueStatus.NOT_CHANGED); propertyWrappers.add(propertyWrapper); } else { // TODO create empty property? diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUserHistory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUserHistory.java index b50d2c72e04..1cd25ff242b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUserHistory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUserHistory.java @@ -76,7 +76,7 @@ public PageUserHistory(final PrismObject user, String date) { protected ObjectWrapper loadObjectWrapper(PrismObject user) { ObjectWrapper objectWrapper = super.loadObjectWrapper(user); objectWrapper.setReadonly(true); - objectWrapper.setShowEmpty(false); +// objectWrapper.setShowEmpty(false); for (ContainerWrapper container : objectWrapper.getContainers()) { container.setReadonly(true); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/AssociationValueChoicePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/AssociationValueChoicePanel.java index 0f996c95d6d..0ae61cbbf35 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/AssociationValueChoicePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/AssociationValueChoicePanel.java @@ -141,17 +141,17 @@ protected void replace(Object object) { ShadowType shadowType = (ShadowType) object; ValueWrapper> oldCValueWrapper = model.getObject(); AssociationWrapper associationWrapper = (AssociationWrapper) oldCValueWrapper.getItem(); - PrismContainer container = (PrismContainer) associationWrapper.getItem(); - container.remove((PrismContainerValue)oldCValueWrapper.getValue()); - PrismContainerValue newValue = container.createNewValue(); - ShadowAssociationType assocType = newValue.asContainerable(); - ObjectReferenceType shadowRef = new ObjectReferenceType(); - shadowRef.setOid(shadowType.getOid()); - shadowRef.asReferenceValue().setObject(shadowType.asPrismObject()); - assocType.setShadowRef(shadowRef); - assocType.setName(model.getObject().getItem().getName()); - getModel().setObject(newValue); - LOGGER.trace("Replaced value of {} with {} ({})", this, newValue, assocType); +// PrismContainer container = (PrismContainer) associationWrapper.getItem(); +// container.remove((PrismContainerValue)oldCValueWrapper.getValue()); +// PrismContainerValue newValue = container.createNewValue(); +// ShadowAssociationType assocType = newValue.asContainerable(); +// ObjectReferenceType shadowRef = new ObjectReferenceType(); +// shadowRef.setOid(shadowType.getOid()); +// shadowRef.asReferenceValue().setObject(shadowType.asPrismObject()); +// assocType.setShadowRef(shadowRef); +// assocType.setName(model.getObject().getItem().getName()); +// getModel().setObject(newValue); +// LOGGER.trace("Replaced value of {} with {} ({})", this, newValue, assocType); } protected void initDialog(final Class type, List values) { diff --git a/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/TestIntegrationObjectWrapperFactory.java b/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/TestIntegrationObjectWrapperFactory.java index f029baaeb56..1f92fc230af 100644 --- a/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/TestIntegrationObjectWrapperFactory.java +++ b/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/TestIntegrationObjectWrapperFactory.java @@ -63,6 +63,7 @@ import com.evolveum.midpoint.util.exception.SecurityViolationException; import com.evolveum.midpoint.web.component.prism.AssociationWrapper; import com.evolveum.midpoint.web.component.prism.ContainerStatus; +import com.evolveum.midpoint.web.component.prism.ContainerValueWrapper; import com.evolveum.midpoint.web.component.prism.ContainerWrapper; import com.evolveum.midpoint.web.component.prism.ItemWrapper; import com.evolveum.midpoint.web.component.prism.ObjectWrapper; @@ -135,31 +136,35 @@ public void test100CreateWrapperUserJack() throws Exception { ContainerWrapper mainContainerWrapper = objectWrapper.findContainerWrapper(null); WrapperTestUtil.assertWrapper(mainContainerWrapper, "prismContainer.mainPanelDisplayName", (ItemPath)null, user, ContainerStatus.MODIFYING); - WrapperTestUtil.assertPropertyWrapper(mainContainerWrapper, UserType.F_NAME, PrismTestUtil.createPolyString(USER_JACK_USERNAME)); - WrapperTestUtil.assertPropertyWrapper(mainContainerWrapper, UserType.F_TIMEZONE, null); + assertEquals("wrong number of containers in "+mainContainerWrapper, 1, mainContainerWrapper.getValues().size()); + ContainerValueWrapper mainContainerValueWrapper = mainContainerWrapper.getValues().iterator().next(); + WrapperTestUtil.assertPropertyWrapper(mainContainerValueWrapper, UserType.F_NAME, PrismTestUtil.createPolyString(USER_JACK_USERNAME)); + WrapperTestUtil.assertPropertyWrapper(mainContainerValueWrapper, UserType.F_TIMEZONE, null); ContainerWrapper activationContainerWrapper = objectWrapper.findContainerWrapper(new ItemPath(UserType.F_ACTIVATION)); WrapperTestUtil.assertWrapper(activationContainerWrapper, "ActivationType.activation", UserType.F_ACTIVATION, user, ContainerStatus.MODIFYING); - WrapperTestUtil.assertPropertyWrapper(activationContainerWrapper, ActivationType.F_ADMINISTRATIVE_STATUS, ActivationStatusType.ENABLED); - WrapperTestUtil.assertPropertyWrapper(activationContainerWrapper, ActivationType.F_LOCKOUT_STATUS, null); + assertEquals("wrong number of containers in "+activationContainerWrapper, 1, activationContainerWrapper.getValues().size()); + ContainerValueWrapper activationContainerValueWrapper = activationContainerWrapper.getValues().iterator().next(); + WrapperTestUtil.assertPropertyWrapper(activationContainerValueWrapper, ActivationType.F_ADMINISTRATIVE_STATUS, ActivationStatusType.ENABLED); + WrapperTestUtil.assertPropertyWrapper(activationContainerValueWrapper, ActivationType.F_LOCKOUT_STATUS, null); assertEquals("Wrong main container wrapper readOnly", Boolean.FALSE, (Boolean)mainContainerWrapper.isReadonly()); - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_NAME, true); - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_GIVEN_NAME, true); - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_FULL_NAME, true); - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_ADDITIONAL_NAME, false); // not visible, because it is empty - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_LOCALITY, true); + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_NAME, true); + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_GIVEN_NAME, true); + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_FULL_NAME, true); + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_ADDITIONAL_NAME, false); // not visible, because it is empty + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_LOCALITY, true); // WHEN objectWrapper.setShowEmpty(true); // THEN - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_NAME, true); - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_GIVEN_NAME, true); // emphasized - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_FULL_NAME, true); // emphasized - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_ADDITIONAL_NAME, true); // empty - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_LOCALITY, true); // empty + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_NAME, true); + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_GIVEN_NAME, true); // emphasized + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_FULL_NAME, true); // emphasized + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_ADDITIONAL_NAME, true); // empty + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_LOCALITY, true); // empty } @Test @@ -188,8 +193,10 @@ public void test102CreateWrapperUserEmpty() throws Exception { ContainerWrapper mainContainerWrapper = objectWrapper.findContainerWrapper(null); WrapperTestUtil.assertWrapper(mainContainerWrapper, "prismContainer.mainPanelDisplayName", (ItemPath)null, user, ContainerStatus.MODIFYING); - WrapperTestUtil.assertPropertyWrapper(mainContainerWrapper, UserType.F_NAME, PrismTestUtil.createPolyString(USER_EMPTY_USERNAME)); - WrapperTestUtil.assertPropertyWrapper(mainContainerWrapper, UserType.F_TIMEZONE, null); + assertEquals("wrong number of containers in "+mainContainerWrapper, 1, mainContainerWrapper.getValues().size()); + ContainerValueWrapper mainContainerValueWrapper = mainContainerWrapper.getValues().iterator().next(); + WrapperTestUtil.assertPropertyWrapper(mainContainerValueWrapper, UserType.F_NAME, PrismTestUtil.createPolyString(USER_EMPTY_USERNAME)); + WrapperTestUtil.assertPropertyWrapper(mainContainerValueWrapper, UserType.F_TIMEZONE, null); // Not sure about this // ContainerWrapper activationContainerWrapper = objectWrapper.findContainerWrapper(new ItemPath(UserType.F_ACTIVATION)); @@ -197,21 +204,21 @@ public void test102CreateWrapperUserEmpty() throws Exception { assertEquals("Wrong main container wrapper readOnly", Boolean.FALSE, (Boolean)mainContainerWrapper.isReadonly()); - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_NAME, true); - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_GIVEN_NAME, true); // emphasized - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_FULL_NAME, true); // emphasized - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_ADDITIONAL_NAME, false); // empty - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_LOCALITY, false); // empty + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_NAME, true); + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_GIVEN_NAME, true); // emphasized + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_FULL_NAME, true); // emphasized + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_ADDITIONAL_NAME, false); // empty + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_LOCALITY, false); // empty // WHEN objectWrapper.setShowEmpty(true); // THEN - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_NAME, true); - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_GIVEN_NAME, true); // emphasized - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_FULL_NAME, true); // emphasized - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_ADDITIONAL_NAME, true); // empty - assertItemWrapperFullConrol(mainContainerWrapper, UserType.F_LOCALITY, true); // empty + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_NAME, true); + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_GIVEN_NAME, true); // emphasized + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_FULL_NAME, true); // emphasized + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_ADDITIONAL_NAME, true); // empty + assertItemWrapperFullConrol(mainContainerValueWrapper, UserType.F_LOCALITY, true); // empty } @@ -240,21 +247,25 @@ public void test150CreateWrapperShadow() throws Exception { assertEquals("wrong number of containers in "+objectWrapper, 9, objectWrapper.getContainers().size()); ContainerWrapper attributesContainerWrapper = objectWrapper.findContainerWrapper(new ItemPath(ShadowType.F_ATTRIBUTES)); + assertEquals("wrong number of values in "+attributesContainerWrapper, 1, attributesContainerWrapper.getValues().size()); PrismContainer attributesContainer = shadow.findContainer(ShadowType.F_ATTRIBUTES); WrapperTestUtil.assertWrapper(attributesContainerWrapper, "prismContainer.shadow.mainPanelDisplayName", new ItemPath(ShadowType.F_ATTRIBUTES), attributesContainer, true, ContainerStatus.MODIFYING); - WrapperTestUtil.assertPropertyWrapper(attributesContainerWrapper, dummyResourceCtl.getAttributeFullnameQName(), USER_JACK_FULL_NAME); - WrapperTestUtil.assertPropertyWrapper(attributesContainerWrapper, SchemaConstants.ICFS_NAME, USER_JACK_USERNAME); - assertEquals("wrong number of items in "+attributesContainerWrapper, 16, attributesContainerWrapper.getItems().size()); + ContainerValueWrapper attributesContainerValueWrapper = attributesContainerWrapper.getValues().iterator().next(); + WrapperTestUtil.assertPropertyWrapper(attributesContainerValueWrapper, dummyResourceCtl.getAttributeFullnameQName(), USER_JACK_FULL_NAME); + WrapperTestUtil.assertPropertyWrapper(attributesContainerValueWrapper, SchemaConstants.ICFS_NAME, USER_JACK_USERNAME); + assertEquals("wrong number of items in "+attributesContainerWrapper, 16, attributesContainerValueWrapper.getItems().size()); ContainerWrapper activationContainerWrapper = objectWrapper.findContainerWrapper(new ItemPath(UserType.F_ACTIVATION)); + assertEquals("wrong number of values in "+activationContainerWrapper, 1, activationContainerWrapper.getValues().size()); + ContainerValueWrapper activationContainerValueWrapper = activationContainerWrapper.getValues().iterator().next(); WrapperTestUtil.assertWrapper(activationContainerWrapper, "ShadowType.activation", UserType.F_ACTIVATION, shadow, ContainerStatus.MODIFYING); - WrapperTestUtil.assertPropertyWrapper(activationContainerWrapper, ActivationType.F_ADMINISTRATIVE_STATUS, ActivationStatusType.ENABLED); - WrapperTestUtil.assertPropertyWrapper(activationContainerWrapper, ActivationType.F_LOCKOUT_STATUS, null); + WrapperTestUtil.assertPropertyWrapper(activationContainerValueWrapper, ActivationType.F_ADMINISTRATIVE_STATUS, ActivationStatusType.ENABLED); + WrapperTestUtil.assertPropertyWrapper(activationContainerValueWrapper, ActivationType.F_LOCKOUT_STATUS, null); assertEquals("Wrong attributes container wrapper readOnly", Boolean.FALSE, (Boolean)attributesContainerWrapper.isReadonly()); - ItemWrapper fullnameWrapper = attributesContainerWrapper.findPropertyWrapper(dummyResourceCtl.getAttributeFullnameQName()); + ItemWrapper fullnameWrapper = attributesContainerValueWrapper.findPropertyWrapper(dummyResourceCtl.getAttributeFullnameQName()); assertEquals("Wrong attribute fullname readOnly", Boolean.FALSE, (Boolean)fullnameWrapper.isReadonly()); // Is this OK? assertEquals("Wrong attribute fullname visible", Boolean.TRUE, (Boolean)fullnameWrapper.isVisible()); ItemDefinition fullNameDefinition = fullnameWrapper.getItemDefinition(); @@ -317,34 +328,39 @@ public void test220AssignRoleLandluberToWally() throws Exception { WrapperTestUtil.assertWrapper(objectWrapper, "shadow display name", "shadow description", shadow, ContainerStatus.MODIFYING); assertEquals("wrong number of containers in "+objectWrapper, 9, objectWrapper.getContainers().size()); - ContainerWrapper attributesContainerWrapper = objectWrapper.findContainerWrapper(new ItemPath(ShadowType.F_ATTRIBUTES)); + ContainerWrapper attributesContainerWrapper = objectWrapper.findContainerWrapper(new ItemPath(ShadowType.F_ATTRIBUTES)); WrapperTestUtil.assertWrapper(attributesContainerWrapper, "prismContainer.shadow.mainPanelDisplayName", new ItemPath(ShadowType.F_ATTRIBUTES), shadow.findContainer(ShadowType.F_ATTRIBUTES), true, ContainerStatus.MODIFYING); - WrapperTestUtil.assertPropertyWrapper(attributesContainerWrapper, dummyResourceCtl.getAttributeFullnameQName(), USER_WALLY_FULLNAME); - WrapperTestUtil.assertPropertyWrapper(attributesContainerWrapper, SchemaConstants.ICFS_NAME, USER_WALLY_NAME); - assertEquals("wrong number of items in "+attributesContainerWrapper, 16, attributesContainerWrapper.getItems().size()); + assertEquals("wrong number of containers in "+attributesContainerWrapper, 1, attributesContainerWrapper.getValues().size()); + ContainerValueWrapper attributesContainerValueWrapper = attributesContainerWrapper.getValues().iterator().next(); + WrapperTestUtil.assertPropertyWrapper(attributesContainerValueWrapper, dummyResourceCtl.getAttributeFullnameQName(), USER_WALLY_FULLNAME); + WrapperTestUtil.assertPropertyWrapper(attributesContainerValueWrapper, SchemaConstants.ICFS_NAME, USER_WALLY_NAME); + assertEquals("wrong number of items in "+attributesContainerWrapper, 16, attributesContainerValueWrapper.getItems().size()); ContainerWrapper activationContainerWrapper = objectWrapper.findContainerWrapper(new ItemPath(UserType.F_ACTIVATION)); WrapperTestUtil.assertWrapper(activationContainerWrapper, "ShadowType.activation", UserType.F_ACTIVATION, shadow, ContainerStatus.MODIFYING); - WrapperTestUtil.assertPropertyWrapper(activationContainerWrapper, ActivationType.F_ADMINISTRATIVE_STATUS, ActivationStatusType.ENABLED); - WrapperTestUtil.assertPropertyWrapper(activationContainerWrapper, ActivationType.F_LOCKOUT_STATUS, null); - - ContainerWrapper associationContainerWrapper = objectWrapper.findContainerWrapper(new ItemPath(ShadowType.F_ASSOCIATION)); - assertNotNull("No association container wrapper", associationContainerWrapper); - assertEquals("wrong number of items in "+associationContainerWrapper, 2, associationContainerWrapper.getItems().size()); - ItemWrapper groupAssociationWrapper = associationContainerWrapper.findPropertyWrapper(RESOURCE_DUMMY_ASSOCIATION_GROUP_QNAME); - assertNotNull("No group association property wrapper", groupAssociationWrapper); - assertTrue("Wrong type of group association property wrapper: "+groupAssociationWrapper.getClass(), groupAssociationWrapper instanceof AssociationWrapper); - List groupAssociationValues = groupAssociationWrapper.getValues(); - assertEquals("wrong number of values in "+groupAssociationWrapper, 1, groupAssociationValues.size()); - ValueWrapper groupAssociationValue = groupAssociationValues.get(0); - PrismContainerValue groupAssociationValuePVal = (PrismContainerValue) groupAssociationValue.getValue(); - display("groupAssociationValuePVal", groupAssociationValuePVal); - assertEquals("wrong number of values in "+groupAssociationValue, ValueStatus.NOT_CHANGED, groupAssociationValue.getStatus()); - assertEquals("Wrong group association name", RESOURCE_DUMMY_ASSOCIATION_GROUP_QNAME, groupAssociationValuePVal.findProperty(ShadowAssociationType.F_NAME).getRealValue()); - PrismContainer groupAssociationValueIdentifiers = groupAssociationValuePVal.findContainer(ShadowAssociationType.F_IDENTIFIERS); - PrismProperty groupAssociationUidProp = groupAssociationValueIdentifiers.findProperty(new QName(null,"uid")); - PrismAsserts.assertPropertyValue(groupAssociationUidProp, GROUP_DUMMY_MAPMAKERS_NAME); + assertEquals("wrong number of containers in "+activationContainerWrapper, 1, activationContainerWrapper.getValues().size()); + ContainerValueWrapper activationContainerValueWrapper = activationContainerWrapper.getValues().iterator().next(); + WrapperTestUtil.assertPropertyWrapper(activationContainerValueWrapper, ActivationType.F_ADMINISTRATIVE_STATUS, ActivationStatusType.ENABLED); + WrapperTestUtil.assertPropertyWrapper(activationContainerValueWrapper, ActivationType.F_LOCKOUT_STATUS, null); + + //TODO: fix +// ContainerWrapper associationContainerWrapper = objectWrapper.findContainerWrapper(new ItemPath(ShadowType.F_ASSOCIATION)); +// assertNotNull("No association container wrapper", associationContainerWrapper); +// assertEquals("wrong number of items in "+associationContainerWrapper, 2, associationContainerWrapper.getItems().size()); +// ItemWrapper groupAssociationWrapper = associationContainerWrapper.findPropertyWrapper(RESOURCE_DUMMY_ASSOCIATION_GROUP_QNAME); +// assertNotNull("No group association property wrapper", groupAssociationWrapper); +// assertTrue("Wrong type of group association property wrapper: "+groupAssociationWrapper.getClass(), groupAssociationWrapper instanceof AssociationWrapper); +// List groupAssociationValues = groupAssociationWrapper.getValues(); +// assertEquals("wrong number of values in "+groupAssociationWrapper, 1, groupAssociationValues.size()); +// ValueWrapper groupAssociationValue = groupAssociationValues.get(0); +// PrismContainerValue groupAssociationValuePVal = (PrismContainerValue) groupAssociationValue.getValue(); +// display("groupAssociationValuePVal", groupAssociationValuePVal); +// assertEquals("wrong number of values in "+groupAssociationValue, ValueStatus.NOT_CHANGED, groupAssociationValue.getStatus()); +// assertEquals("Wrong group association name", RESOURCE_DUMMY_ASSOCIATION_GROUP_QNAME, groupAssociationValuePVal.findProperty(ShadowAssociationType.F_NAME).getRealValue()); +// PrismContainer groupAssociationValueIdentifiers = groupAssociationValuePVal.findContainer(ShadowAssociationType.F_IDENTIFIERS); +// PrismProperty groupAssociationUidProp = groupAssociationValueIdentifiers.findProperty(new QName(null,"uid")); +// PrismAsserts.assertPropertyValue(groupAssociationUidProp, GROUP_DUMMY_MAPMAKERS_NAME); } /** @@ -379,35 +395,37 @@ public void test800EditSchemaJackPropReadAllModifySomeUser() throws Exception { ContainerWrapper mainContainerWrapper = objectWrapper.findMainContainerWrapper(); assertEquals("Wrong main container wrapper readOnly", Boolean.FALSE, (Boolean)mainContainerWrapper.isReadonly()); - ItemWrapper nameWrapper = mainContainerWrapper.findPropertyWrapper(UserType.F_NAME); + ContainerValueWrapper mainContainerValueWrapper = mainContainerWrapper.getValues().iterator().next(); + + ItemWrapper nameWrapper = mainContainerValueWrapper.findPropertyWrapper(UserType.F_NAME); assertEquals("Wrong name readOnly", Boolean.TRUE, (Boolean)nameWrapper.isReadonly()); // Is this OK? assertEquals("Wrong name visible", Boolean.TRUE, (Boolean)nameWrapper.isVisible()); assertEquals("Wrong name definition.canRead", Boolean.TRUE, (Boolean)nameWrapper.getItemDefinition().canRead()); assertEquals("Wrong name definition.canAdd", Boolean.FALSE, (Boolean)nameWrapper.getItemDefinition().canAdd()); assertEquals("Wrong name definition.canModify", Boolean.FALSE, (Boolean)nameWrapper.getItemDefinition().canModify()); - ItemWrapper givenNameWrapper = mainContainerWrapper.findPropertyWrapper(UserType.F_GIVEN_NAME); + ItemWrapper givenNameWrapper = mainContainerValueWrapper.findPropertyWrapper(UserType.F_GIVEN_NAME); assertEquals("Wrong givenName readOnly", Boolean.TRUE, (Boolean)givenNameWrapper.isReadonly()); // Is this OK? assertEquals("Wrong givenName visible", Boolean.TRUE, (Boolean)givenNameWrapper.isVisible()); assertEquals("Wrong givenName definition.canRead", Boolean.TRUE, (Boolean)givenNameWrapper.getItemDefinition().canRead()); assertEquals("Wrong givenName definition.canAdd", Boolean.FALSE, (Boolean)givenNameWrapper.getItemDefinition().canAdd()); assertEquals("Wrong givenName definition.canModify", Boolean.FALSE, (Boolean)givenNameWrapper.getItemDefinition().canModify()); - ItemWrapper fullNameWrapper = mainContainerWrapper.findPropertyWrapper(UserType.F_FULL_NAME); + ItemWrapper fullNameWrapper = mainContainerValueWrapper.findPropertyWrapper(UserType.F_FULL_NAME); assertEquals("Wrong fullName readOnly", Boolean.FALSE, (Boolean)fullNameWrapper.isReadonly()); assertEquals("Wrong fullName visible", Boolean.TRUE, (Boolean)fullNameWrapper.isVisible()); assertEquals("Wrong fullName definition.canRead", Boolean.TRUE, (Boolean)fullNameWrapper.getItemDefinition().canRead()); assertEquals("Wrong fullName definition.canAdd", Boolean.FALSE, (Boolean)fullNameWrapper.getItemDefinition().canAdd()); assertEquals("Wrong fullName definition.canModify", Boolean.TRUE, (Boolean)fullNameWrapper.getItemDefinition().canModify()); - ItemWrapper additionalNameWrapper = mainContainerWrapper.findPropertyWrapper(UserType.F_ADDITIONAL_NAME); + ItemWrapper additionalNameWrapper = mainContainerValueWrapper.findPropertyWrapper(UserType.F_ADDITIONAL_NAME); assertEquals("Wrong additionalName readOnly", Boolean.TRUE, (Boolean)additionalNameWrapper.isReadonly()); // Is this OK? assertEquals("Wrong additionalName visible", Boolean.FALSE, (Boolean)additionalNameWrapper.isVisible()); // not visible, because it is empty assertEquals("Wrong additionalName definition.canRead", Boolean.TRUE, (Boolean)additionalNameWrapper.getItemDefinition().canRead()); assertEquals("Wrong additionalName definition.canAdd", Boolean.FALSE, (Boolean)additionalNameWrapper.getItemDefinition().canAdd()); assertEquals("Wrong additionalName definition.canModify", Boolean.FALSE, (Boolean)additionalNameWrapper.getItemDefinition().canModify()); - ItemWrapper localityNameWrapper = mainContainerWrapper.findPropertyWrapper(UserType.F_LOCALITY); + ItemWrapper localityNameWrapper = mainContainerValueWrapper.findPropertyWrapper(UserType.F_LOCALITY); assertEquals("Wrong locality readOnly", Boolean.TRUE, (Boolean)localityNameWrapper.isReadonly()); assertEquals("Wrong locality visible", Boolean.TRUE, (Boolean)localityNameWrapper.isVisible()); assertEquals("Wrong locality definition.canRead", Boolean.TRUE, (Boolean)localityNameWrapper.getItemDefinition().canRead()); @@ -418,7 +436,7 @@ public void test800EditSchemaJackPropReadAllModifySomeUser() throws Exception { objectWrapper.setShowEmpty(true); // THEN - additionalNameWrapper = mainContainerWrapper.findPropertyWrapper(UserType.F_ADDITIONAL_NAME); + additionalNameWrapper = mainContainerValueWrapper.findPropertyWrapper(UserType.F_ADDITIONAL_NAME); assertEquals("Wrong additionalName visible", Boolean.TRUE, (Boolean)additionalNameWrapper.isVisible()); // not visible, because it is empty } @@ -455,14 +473,15 @@ public void test802EditSchemaJackPropReadSomeModifySomeUser() throws Exception { ContainerWrapper mainContainerWrapper = objectWrapper.findMainContainerWrapper(); assertEquals("Wrong main container wrapper readOnly", Boolean.FALSE, (Boolean)mainContainerWrapper.isReadonly()); - ItemWrapper nameWrapper = mainContainerWrapper.findPropertyWrapper(UserType.F_NAME); + ContainerValueWrapper mainContainerValueWrapper = mainContainerWrapper.getValues().iterator().next(); + ItemWrapper nameWrapper = mainContainerValueWrapper.findPropertyWrapper(UserType.F_NAME); assertEquals("Wrong name readOnly", Boolean.TRUE, (Boolean)nameWrapper.isReadonly()); assertEquals("Wrong name visible", Boolean.TRUE, (Boolean)nameWrapper.isVisible()); assertEquals("Wrong name definition.canRead", Boolean.TRUE, (Boolean)nameWrapper.getItemDefinition().canRead()); assertEquals("Wrong name definition.canAdd", Boolean.FALSE, (Boolean)nameWrapper.getItemDefinition().canAdd()); assertEquals("Wrong name definition.canModify", Boolean.FALSE, (Boolean)nameWrapper.getItemDefinition().canModify()); - ItemWrapper givenNameWrapper = mainContainerWrapper.findPropertyWrapper(UserType.F_GIVEN_NAME); + ItemWrapper givenNameWrapper = mainContainerValueWrapper.findPropertyWrapper(UserType.F_GIVEN_NAME); assertEquals("Wrong givenName readOnly", Boolean.TRUE, (Boolean)givenNameWrapper.isReadonly()); // Emphasized property. But the role given no access to this. Therefore is should not be visible. // MID-3206 @@ -471,21 +490,21 @@ public void test802EditSchemaJackPropReadSomeModifySomeUser() throws Exception { assertEquals("Wrong givenName definition.canAdd", Boolean.FALSE, (Boolean)givenNameWrapper.getItemDefinition().canAdd()); assertEquals("Wrong givenName definition.canModify", Boolean.FALSE, (Boolean)givenNameWrapper.getItemDefinition().canModify()); - ItemWrapper fullNameWrapper = mainContainerWrapper.findPropertyWrapper(UserType.F_FULL_NAME); + ItemWrapper fullNameWrapper = mainContainerValueWrapper.findPropertyWrapper(UserType.F_FULL_NAME); assertEquals("Wrong fullName readOnly", Boolean.FALSE, (Boolean)fullNameWrapper.isReadonly()); assertEquals("Wrong fullName visible", Boolean.TRUE, (Boolean)fullNameWrapper.isVisible()); assertEquals("Wrong fullName definition.canRead", Boolean.TRUE, (Boolean)fullNameWrapper.getItemDefinition().canRead()); assertEquals("Wrong fullName definition.canAdd", Boolean.FALSE, (Boolean)fullNameWrapper.getItemDefinition().canAdd()); assertEquals("Wrong fullName definition.canModify", Boolean.TRUE, (Boolean)fullNameWrapper.getItemDefinition().canModify()); - ItemWrapper additionalNameWrapper = mainContainerWrapper.findPropertyWrapper(UserType.F_ADDITIONAL_NAME); + ItemWrapper additionalNameWrapper = mainContainerValueWrapper.findPropertyWrapper(UserType.F_ADDITIONAL_NAME); assertEquals("Wrong additionalName readOnly", Boolean.FALSE, (Boolean)additionalNameWrapper.isReadonly()); assertEquals("Wrong additionalName visible", Boolean.FALSE, (Boolean)additionalNameWrapper.isVisible()); assertEquals("Wrong additionalName definition.canRead", Boolean.FALSE, (Boolean)additionalNameWrapper.getItemDefinition().canRead()); assertEquals("Wrong additionalName definition.canAdd", Boolean.FALSE, (Boolean)additionalNameWrapper.getItemDefinition().canAdd()); assertEquals("Wrong additionalName definition.canModify", Boolean.TRUE, (Boolean)additionalNameWrapper.getItemDefinition().canModify()); - ItemWrapper localityNameWrapper = mainContainerWrapper.findPropertyWrapper(UserType.F_LOCALITY); + ItemWrapper localityNameWrapper = mainContainerValueWrapper.findPropertyWrapper(UserType.F_LOCALITY); assertEquals("Wrong locality readOnly", Boolean.TRUE, (Boolean)localityNameWrapper.isReadonly()); // Is this OK? assertEquals("Wrong locality visible", Boolean.FALSE, (Boolean)localityNameWrapper.isVisible()); assertEquals("Wrong locality definition.canRead", Boolean.FALSE, (Boolean)localityNameWrapper.getItemDefinition().canRead()); @@ -493,7 +512,7 @@ public void test802EditSchemaJackPropReadSomeModifySomeUser() throws Exception { assertEquals("Wrong locality definition.canModify", Boolean.FALSE, (Boolean)localityNameWrapper.getItemDefinition().canModify()); } - private void assertItemWrapperFullConrol(ContainerWrapper containerWrapper, QName propName, + private void assertItemWrapperFullConrol(ContainerValueWrapper containerWrapper, QName propName, boolean visible) { ItemWrapper itemWrapper = containerWrapper.findPropertyWrapper(propName); assertEquals("Wrong "+propName+" readOnly", Boolean.FALSE, (Boolean)itemWrapper.isReadonly()); diff --git a/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/TestUnitObjectWrapperFactory.java b/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/TestUnitObjectWrapperFactory.java index c979c4a4ec8..db2225391e1 100644 --- a/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/TestUnitObjectWrapperFactory.java +++ b/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/TestUnitObjectWrapperFactory.java @@ -27,6 +27,7 @@ import com.evolveum.midpoint.test.IntegrationTestTools; import com.evolveum.midpoint.test.util.TestUtil; import com.evolveum.midpoint.web.component.prism.ContainerStatus; +import com.evolveum.midpoint.web.component.prism.ContainerValueWrapper; import com.evolveum.midpoint.web.component.prism.ContainerWrapper; import com.evolveum.midpoint.web.component.prism.ObjectWrapper; import com.evolveum.midpoint.web.component.prism.ObjectWrapperFactory; @@ -63,15 +64,19 @@ public void testCreateWrapperUser() throws Exception { WrapperTestUtil.assertWrapper(objectWrapper, "user display name", "user description", user, ContainerStatus.MODIFYING); assertEquals("wrong number of containers in "+objectWrapper, 11, objectWrapper.getContainers().size()); - ContainerWrapper mainContainerWrapper = objectWrapper.findContainerWrapper(null); + ContainerWrapper mainContainerWrapper = objectWrapper.findContainerWrapper(null); WrapperTestUtil.assertWrapper(mainContainerWrapper, "prismContainer.mainPanelDisplayName", (ItemPath)null, user, ContainerStatus.MODIFYING); - WrapperTestUtil.assertPropertyWrapper(mainContainerWrapper, UserType.F_NAME, PrismTestUtil.createPolyString("jack")); - WrapperTestUtil.assertPropertyWrapper(mainContainerWrapper, UserType.F_TIMEZONE, null); + assertEquals("wrong number of containers in "+mainContainerWrapper, 1, mainContainerWrapper.getValues().size()); + ContainerValueWrapper mainContainerValueWrapper = mainContainerWrapper.getValues().iterator().next(); + WrapperTestUtil.assertPropertyWrapper(mainContainerValueWrapper, UserType.F_NAME, PrismTestUtil.createPolyString("jack")); + WrapperTestUtil.assertPropertyWrapper(mainContainerValueWrapper, UserType.F_TIMEZONE, null); ContainerWrapper activationContainerWrapper = objectWrapper.findContainerWrapper(new ItemPath(UserType.F_ACTIVATION)); WrapperTestUtil.assertWrapper(activationContainerWrapper, "ActivationType.activation", UserType.F_ACTIVATION, user, ContainerStatus.MODIFYING); - WrapperTestUtil.assertPropertyWrapper(activationContainerWrapper, ActivationType.F_ADMINISTRATIVE_STATUS, ActivationStatusType.ENABLED); - WrapperTestUtil.assertPropertyWrapper(activationContainerWrapper, ActivationType.F_LOCKOUT_STATUS, null); + assertEquals("wrong number of containers in "+activationContainerWrapper, 1, activationContainerWrapper.getValues().size()); + ContainerValueWrapper activationContainerValueWrapper = activationContainerWrapper.getValues().iterator().next(); + WrapperTestUtil.assertPropertyWrapper(activationContainerValueWrapper, ActivationType.F_ADMINISTRATIVE_STATUS, ActivationStatusType.ENABLED); + WrapperTestUtil.assertPropertyWrapper(activationContainerValueWrapper, ActivationType.F_LOCKOUT_STATUS, null); } // We cannot unit test shadow wrapper. It requires initialized resource, resource schema, capabilities, working model service, etc. diff --git a/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/WrapperTestUtil.java b/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/WrapperTestUtil.java index ea9dafa45a0..5c4101058c4 100644 --- a/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/WrapperTestUtil.java +++ b/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/WrapperTestUtil.java @@ -35,6 +35,7 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.web.component.prism.ContainerStatus; +import com.evolveum.midpoint.web.component.prism.ContainerValueWrapper; import com.evolveum.midpoint.web.component.prism.ContainerWrapper; import com.evolveum.midpoint.web.component.prism.ItemWrapper; import com.evolveum.midpoint.web.component.prism.ObjectWrapper; @@ -47,7 +48,7 @@ */ public class WrapperTestUtil { - public static void assertPropertyWrapper(ContainerWrapper containerWrapper, QName itemName, T... expectedValues) { + public static void assertPropertyWrapper(ContainerValueWrapper containerWrapper, QName itemName, T... expectedValues) { ItemWrapper itemWrapper = containerWrapper.findPropertyWrapper(itemName); assertNotNull("No item wrapper "+itemName+" in "+containerWrapper, itemWrapper); List valueWrappers = itemWrapper.getValues(); From 33295b93c95ce2ecec029ddd923378ab5ab9389c Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 18 Sep 2017 13:44:02 +0200 Subject: [PATCH 03/97] Fixed bug preventing use of fallbackMessage for constraint presentation. --- .../evaluators/AssignmentConstraintEvaluator.java | 4 ++-- .../evaluators/CompositeConstraintEvaluator.java | 4 ++-- .../policy/evaluators/ConstraintEvaluatorHelper.java | 11 +++++++---- .../evaluators/ExclusionConstraintEvaluator.java | 4 ++-- .../evaluators/HasAssignmentConstraintEvaluator.java | 8 ++++---- .../evaluators/ModificationConstraintEvaluator.java | 4 ++-- .../evaluators/MultiplicityConstraintEvaluator.java | 4 ++-- .../PolicySituationConstraintEvaluator.java | 8 ++++---- .../policy/evaluators/StateConstraintEvaluator.java | 4 ++-- .../evaluators/TransitionConstraintEvaluator.java | 4 ++-- 10 files changed, 29 insertions(+), 26 deletions(-) diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/AssignmentConstraintEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/AssignmentConstraintEvaluator.java index d33a6ccbb75..ca7131eea3a 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/AssignmentConstraintEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/AssignmentConstraintEvaluator.java @@ -93,12 +93,12 @@ private LocalizableMessage createMessage(JAXBElement ctx, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { - LocalizableMessage defaultMessage = new LocalizableMessageBuilder() + LocalizableMessage builtInMessage = new LocalizableMessageBuilder() .key(SchemaConstants.DEFAULT_POLICY_CONSTRAINT_KEY_PREFIX + kind.value()) .build(); - return evaluatorHelper.createLocalizableMessage(constraint, ctx, defaultMessage, result); + return evaluatorHelper.createLocalizableMessage(constraint, ctx, builtInMessage, result); } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ConstraintEvaluatorHelper.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ConstraintEvaluatorHelper.java index 5217a3dba88..5e6d5ab7a62 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ConstraintEvaluatorHelper.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ConstraintEvaluatorHelper.java @@ -162,19 +162,22 @@ public LocalizableMessage createObjectTypeSpecification(String objectClassName) public LocalizableMessage createLocalizableMessage( AbstractPolicyConstraintType constraint, PolicyRuleEvaluationContext rctx, - LocalizableMessage defaultMessage, OperationResult result) throws ExpressionEvaluationException, + LocalizableMessage builtInMessage, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { if (constraint.getPresentation() != null && constraint.getPresentation().getMessage() != null) { LocalizableMessageType messageType = createLocalizableMessageType(constraint.getPresentation().getMessage(), rctx, result); - return LocalizationUtil.parseLocalizableMessageType(messageType, defaultMessage); + return LocalizationUtil.parseLocalizableMessageType(messageType, + // if user-configured fallback message is present; we ignore the built-in constraint message + // TODO consider ignoring it always if custom presentation/message is provided + messageType.getFallbackMessage() != null ? null : builtInMessage); } else if (constraint.getName() != null) { return new LocalizableMessageBuilder() .key(SchemaConstants.POLICY_CONSTRAINT_KEY_PREFIX + constraint.getName()) - .fallbackLocalizableMessage(defaultMessage) + .fallbackLocalizableMessage(builtInMessage) .build(); } else { - return defaultMessage; + return builtInMessage; } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ExclusionConstraintEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ExclusionConstraintEvaluator.java index 06efe9646b6..abc23207398 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ExclusionConstraintEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ExclusionConstraintEvaluator.java @@ -156,11 +156,11 @@ private EvaluatedExclusionTrigger createTrigger(EvaluatedA private LocalizableMessage createMessage(String infoA, String infoB, ExclusionPolicyConstraintType constraint, PolicyRuleEvaluationContext ctx, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { - LocalizableMessage defaultMessage = new LocalizableMessageBuilder() + LocalizableMessage builtInMessage = new LocalizableMessageBuilder() .key(SchemaConstants.DEFAULT_POLICY_CONSTRAINT_KEY_PREFIX + CONSTRAINT_KEY) .args(infoA, infoB) .build(); - return evaluatorHelper.createLocalizableMessage(constraint, ctx, defaultMessage, result); + return evaluatorHelper.createLocalizableMessage(constraint, ctx, builtInMessage, result); } private ObjectType getConflictingObject(AssignmentPath path, PrismObject defaultObject) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/HasAssignmentConstraintEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/HasAssignmentConstraintEvaluator.java index 1cf9f880537..fa651f343c9 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/HasAssignmentConstraintEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/HasAssignmentConstraintEvaluator.java @@ -123,24 +123,24 @@ public EvaluatedPolicyRuleTrigger evaluate(JAXBElement LocalizableMessage createPositiveMessage(HasAssignmentPolicyConstraintType constraint, PolicyRuleEvaluationContext ctx, PrismObject target, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { - LocalizableMessage defaultMessage = new LocalizableMessageBuilder() + LocalizableMessage builtInMessage = new LocalizableMessageBuilder() .key(SchemaConstants.DEFAULT_POLICY_CONSTRAINT_KEY_PREFIX + CONSTRAINT_KEY_POSITIVE) .arg(evaluatorHelper.createObjectSpecification(target)) .arg(evaluatorHelper.createBeforeAfterMessage(ctx)) .build(); - return evaluatorHelper.createLocalizableMessage(constraint, ctx, defaultMessage, result); + return evaluatorHelper.createLocalizableMessage(constraint, ctx, builtInMessage, result); } private LocalizableMessage createNegativeMessage(HasAssignmentPolicyConstraintType constraint, PolicyRuleEvaluationContext ctx, QName targetType, String targetOid, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { - LocalizableMessage defaultMessage = new LocalizableMessageBuilder() + LocalizableMessage builtInMessage = new LocalizableMessageBuilder() .key(SchemaConstants.DEFAULT_POLICY_CONSTRAINT_KEY_PREFIX + CONSTRAINT_KEY_NEGATIVE) .arg(evaluatorHelper.createObjectTypeSpecification(targetType)) .arg(targetOid) .arg(evaluatorHelper.createBeforeAfterMessage(ctx)) .build(); - return evaluatorHelper.createLocalizableMessage(constraint, ctx, defaultMessage, result); + return evaluatorHelper.createLocalizableMessage(constraint, ctx, builtInMessage, result); } private EvaluatedPolicyRuleTrigger createTriggerIfShouldNotExist(boolean shouldExist, diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ModificationConstraintEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ModificationConstraintEvaluator.java index a45a2b1ad54..d80276b207d 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ModificationConstraintEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ModificationConstraintEvaluator.java @@ -92,11 +92,11 @@ private LocalizableMessage createMessage(JAXBElement boolean modificationConstraintMatches(ModificationPolicyConstraintType constraint, diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/MultiplicityConstraintEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/MultiplicityConstraintEvaluator.java index bf955191e43..e6871b23a81 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/MultiplicityConstraintEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/MultiplicityConstraintEvaluator.java @@ -234,11 +234,11 @@ private LocalizableMessage getMessage(MultiplicityPolicyCo PolicyRuleEvaluationContext rctx, OperationResult result, String key1, String key2, PrismObject target, Object... args) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { - LocalizableMessage defaultMessage = new LocalizableMessageBuilder() + LocalizableMessage builtInMessage = new LocalizableMessageBuilder() .key(SchemaConstants.DEFAULT_POLICY_CONSTRAINT_KEY_PREFIX + CONSTRAINT_KEY_PREFIX + key1 + key2) .arg(evaluatorHelper.createObjectSpecification(target)) .args(args) .build(); - return evaluatorHelper.createLocalizableMessage(constraint, rctx, defaultMessage, result); + return evaluatorHelper.createLocalizableMessage(constraint, rctx, builtInMessage, result); } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/PolicySituationConstraintEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/PolicySituationConstraintEvaluator.java index c3bbf60be63..66ea3c4c149 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/PolicySituationConstraintEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/PolicySituationConstraintEvaluator.java @@ -81,15 +81,15 @@ private LocalizableMessage createMessage(Collection sourceR List> messageTrees = sourceRules.stream() .flatMap(r -> r.extractMessages().stream()) .collect(Collectors.toList()); - LocalizableMessage defaultMessage; + LocalizableMessage builtInMessage; if (messageTrees.size() == 1) { - defaultMessage = messageTrees.get(0).getUserObject(); + builtInMessage = messageTrees.get(0).getUserObject(); } else { - defaultMessage = new LocalizableMessageBuilder() + builtInMessage = new LocalizableMessageBuilder() .key(SchemaConstants.DEFAULT_POLICY_CONSTRAINT_KEY_PREFIX + CONSTRAINT_KEY) .build(); } - return evaluatorHelper.createLocalizableMessage(constraint, ctx, defaultMessage, result); + return evaluatorHelper.createLocalizableMessage(constraint, ctx, builtInMessage, result); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/StateConstraintEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/StateConstraintEvaluator.java index b8370381355..c7e485c6e70 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/StateConstraintEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/StateConstraintEvaluator.java @@ -150,10 +150,10 @@ private LocalizableMessage createMessage(String constraint } else { keySuffix = KEY_UNNAMED; } - LocalizableMessage defaultMessage = new LocalizableMessageBuilder() + LocalizableMessage builtInMessage = new LocalizableMessageBuilder() .key(SchemaConstants.DEFAULT_POLICY_CONSTRAINT_KEY_PREFIX + constraintKeyPrefix + keySuffix) .args(args) .build(); - return evaluatorHelper.createLocalizableMessage(constraint, ctx, defaultMessage, result); + return evaluatorHelper.createLocalizableMessage(constraint, ctx, builtInMessage, result); } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/TransitionConstraintEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/TransitionConstraintEvaluator.java index 0502636a875..00ac606003a 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/TransitionConstraintEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/TransitionConstraintEvaluator.java @@ -85,9 +85,9 @@ private boolean evaluateState(TransitionPolicyConstraintTy private LocalizableMessage createMessage(AbstractPolicyConstraintType constraint, PolicyRuleEvaluationContext ctx, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { - LocalizableMessage defaultMessage = new LocalizableMessageBuilder() + LocalizableMessage builtInMessage = new LocalizableMessageBuilder() .key(SchemaConstants.DEFAULT_POLICY_CONSTRAINT_KEY_PREFIX + CONSTRAINT_KEY) .build(); - return evaluatorHelper.createLocalizableMessage(constraint, ctx, defaultMessage, result); + return evaluatorHelper.createLocalizableMessage(constraint, ctx, builtInMessage, result); } } From 3c692a7e624f4f83950f111d4836fb17df94b92b Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 18 Sep 2017 14:17:51 +0200 Subject: [PATCH 04/97] Fixed bug preventing displaying built-in constraint messages for named constraints. --- .../midpoint/web/util/MidPointStringResourceLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/MidPointStringResourceLoader.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/MidPointStringResourceLoader.java index 0deacb8826a..937b32bde21 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/MidPointStringResourceLoader.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/MidPointStringResourceLoader.java @@ -45,6 +45,6 @@ public String loadStringResource(Component component, String key, Locale locale, locale = Session.exists() ? Session.get().getLocale() : Locale.getDefault(); } - return resourceLoader.translate(key, null, locale, key); + return resourceLoader.translate(key, null, locale); } } From 66d8eb775f95c92bd936ca320465ae607a00d9f0 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 18 Sep 2017 14:38:03 +0200 Subject: [PATCH 05/97] Migrated constraint reference from simple string to extensible structure. --- .../schema/util/PolicyRuleTypeUtil.java | 15 ++--- .../xml/ns/public/common/common-policy-3.xsd | 28 ++++++++- .../complex/system-configuration.xml | 60 ++++++++++++++----- 3 files changed, 79 insertions(+), 24 deletions(-) diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/PolicyRuleTypeUtil.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/PolicyRuleTypeUtil.java index 13420576d70..9bf9fe5bebd 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/PolicyRuleTypeUtil.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/PolicyRuleTypeUtil.java @@ -123,11 +123,11 @@ public static String toShortString(PolicyConstraintsType constraints, char join) sb.append(abbreviation != null ? abbreviation : name.getLocalPart()); } } - for (String ref : constraints.getRef()) { + for (PolicyConstraintReferenceType ref : constraints.getRef()) { if (sb.length() > 0) { sb.append(join); } - sb.append("ref:").append(ref); + sb.append("ref:").append(ref.getName()); } return sb.toString(); } @@ -567,15 +567,16 @@ public static void resolveReferences(PolicyConstraintsType pc, ConstraintResolve @SuppressWarnings("unchecked") private static void resolveLocalReferences(PolicyConstraintsType pc, ConstraintResolver resolver) throws ObjectNotFoundException, SchemaException { - for (String ref : pc.getRef()) { - if (StringUtils.isEmpty(ref)) { + for (PolicyConstraintReferenceType ref : pc.getRef()) { + String refName = ref != null ? ref.getName() : null; + if (StringUtils.isEmpty(refName)) { throw new SchemaException("Illegal empty reference: " + ref); } List pathToRoot = getPathToRoot(pc); - if (pathToRoot.contains(ref)) { - throw new SchemaException("Trying to resolve cyclic reference to constraint '" + ref + "'. Contained in: " + pathToRoot); + if (pathToRoot.contains(refName)) { + throw new SchemaException("Trying to resolve cyclic reference to constraint '" + refName + "'. Contained in: " + pathToRoot); } - JAXBElement resolved = resolver.resolve(ref); + JAXBElement resolved = resolver.resolve(refName); QName constraintName = resolved.getName(); AbstractPolicyConstraintType constraintValue = resolved.getValue(); PrismContainer container = pc.asPrismContainerValue().findOrCreateContainer(constraintName); diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd index aa3803bdac4..21eb0d097e1 100644 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd @@ -218,10 +218,10 @@ - + - References another policy constraint by its name. + References another policy constraint e.g. by its name. The referenced constraint must be present as part of policy rules gathered for a given assignment or object. Also, all declared global constraints are available for referencing, regardless of which objects they are attached to or whether they are active or not. @@ -237,6 +237,29 @@ + + + + References another policy constraint. + + + + 3.7 + + + + + + + Name of the constraint referenced. + + + + + + + + @@ -357,6 +380,7 @@ + diff --git a/model/certification-impl/src/test/resources/complex/system-configuration.xml b/model/certification-impl/src/test/resources/complex/system-configuration.xml index 0b44defee94..ca588c142d4 100644 --- a/model/certification-impl/src/test/resources/complex/system-configuration.xml +++ b/model/certification-impl/src/test/resources/complex/system-configuration.xml @@ -226,8 +226,12 @@ http://sample.org/situations#active-role-with-no-identifier certification fullReport - role-active - c5-no-identifier + + role-active + + + c5-no-identifier + @@ -238,11 +242,21 @@ http://sample.org/situations#incomplete-role-c1-to-c4 fullReport - c1-no-risk-level - c2-no-description-for-high-risk-role - c3-less-than-1-approver-for-non-high-risk-role - c3-less-than-2-approvers-for-high-risk-role - c4-no-role-owner + + c1-no-risk-level + + + c2-no-description-for-high-risk-role + + + c3-less-than-1-approver-for-non-high-risk-role + + + c3-less-than-2-approvers-for-high-risk-role + + + c4-no-role-owner + @@ -255,7 +269,9 @@ false true - role-active + + role-active + @@ -275,8 +291,12 @@ - incomplete-role-c1-to-c4 - role-activation + + incomplete-role-c1-to-c4 + + + role-activation + @@ -293,7 +313,9 @@ true - role-activation + + role-activation + @@ -319,8 +341,12 @@ true - role-activation - c5-no-identifier + + role-activation + + + c5-no-identifier + @@ -348,9 +374,13 @@ true true - active-role-with-no-identifier + + active-role-with-no-identifier + - validity-not-limited + + validity-not-limited + From 1ff985be53a545a894ee8369b0b801eab85ad92a Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 18 Sep 2017 14:38:49 +0200 Subject: [PATCH 06/97] Tentative fix for Oracle quartz initialization script. (cherry picked from commit 930e8b9) --- .../quartzimpl/execution/tables_oracle.sql | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/repo/task-quartz-impl/src/main/resources/com/evolveum/midpoint/task/quartzimpl/execution/tables_oracle.sql b/repo/task-quartz-impl/src/main/resources/com/evolveum/midpoint/task/quartzimpl/execution/tables_oracle.sql index a5db202d113..6bc346baf35 100644 --- a/repo/task-quartz-impl/src/main/resources/com/evolveum/midpoint/task/quartzimpl/execution/tables_oracle.sql +++ b/repo/task-quartz-impl/src/main/resources/com/evolveum/midpoint/task/quartzimpl/execution/tables_oracle.sql @@ -11,17 +11,17 @@ -- there are two semicolons at the end of each of the following lines to work around a bug/feature of ScriptRunner we use BEGIN -BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_calendars'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; -BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_fired_triggers'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; -BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_blob_triggers'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; -BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_cron_triggers'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; -BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_simple_triggers'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; -BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_simprop_triggers'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; -BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_triggers'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; -BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_job_details'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; -BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_paused_trigger_grps'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; -BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_locks'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; -BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_scheduler_state'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; +BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_calendars'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;; +BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_fired_triggers'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;; +BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_blob_triggers'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;; +BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_cron_triggers'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;; +BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_simple_triggers'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;; +BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_simprop_triggers'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;; +BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_triggers'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;; +BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_job_details'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;; +BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_paused_trigger_grps'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;; +BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_locks'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;; +BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_scheduler_state'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;; END; / From 27db56cd41835b846a4cb1d68443e2027460f96b Mon Sep 17 00:00:00 2001 From: kate Date: Mon, 18 Sep 2017 14:44:02 +0200 Subject: [PATCH 07/97] little property key fix --- .../src/main/resources/localization/Midpoint.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint.properties b/gui/admin-gui/src/main/resources/localization/Midpoint.properties index 7318c0cb6c8..57e600c0641 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint.properties @@ -3789,4 +3789,4 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Policy ExclusionPolicyConstraintPanel.exclusionTitle=Exclusion - +comboInput.nullValid=Choose one \ No newline at end of file From d18042b5a5a6a8d7d977168d0d40c72628075c95 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 18 Sep 2017 15:06:36 +0200 Subject: [PATCH 08/97] Approval related triggers on PagePreviewChanges (in progress). --- .../wf/ApprovalProcessesPreviewPanel.html | 1 + .../wf/ApprovalProcessesPreviewPanel.java | 4 ++++ .../ApprovalProcessExecutionInformationDto.java | 14 ++++++++++++-- .../prism/marshaller/PrismUnmarshaller.java | 6 ++++-- .../midpoint/schema/util/WfContextUtil.java | 10 ++++++++++ .../xml/ns/public/common/common-workflows-3.xsd | 1 + .../ApprovalSchemaExecutionInformationHelper.java | 3 +++ 7 files changed, 35 insertions(+), 4 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wf/ApprovalProcessesPreviewPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wf/ApprovalProcessesPreviewPanel.html index 625deadbf36..a09f6677a3a 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wf/ApprovalProcessesPreviewPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wf/ApprovalProcessesPreviewPanel.html @@ -24,6 +24,7 @@

+
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wf/ApprovalProcessesPreviewPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wf/ApprovalProcessesPreviewPanel.java index 48ad8bab2f1..c90f0838acd 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wf/ApprovalProcessesPreviewPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wf/ApprovalProcessesPreviewPanel.java @@ -18,11 +18,13 @@ import com.evolveum.midpoint.gui.api.component.BasePanel; import com.evolveum.midpoint.gui.api.model.LoadableModel; +import com.evolveum.midpoint.web.page.admin.workflow.EvaluatedTriggerGroupPanel; import com.evolveum.midpoint.web.page.admin.workflow.dto.ApprovalProcessExecutionInformationDto; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.model.IModel; +import org.apache.wicket.model.PropertyModel; import java.util.List; @@ -34,6 +36,7 @@ public class ApprovalProcessesPreviewPanel extends BasePanel> model) { super(id, model); @@ -53,6 +56,7 @@ protected void populateItem(ListItem ite } }, false))); item.add(new ApprovalProcessExecutionInformationPanel(ID_PREVIEW, item.getModel())); + item.add(new EvaluatedTriggerGroupPanel(ID_TRIGGERS, new PropertyModel<>(item.getModel(), ApprovalProcessExecutionInformationDto.F_TRIGGERS))); } }; add(list); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/ApprovalProcessExecutionInformationDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/ApprovalProcessExecutionInformationDto.java index 42ddfbdc0ad..5766a4363f8 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/ApprovalProcessExecutionInformationDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/ApprovalProcessExecutionInformationDto.java @@ -42,6 +42,7 @@ public class ApprovalProcessExecutionInformationDto implements Serializable { public static final String F_PROCESS_NAME = "processName"; public static final String F_TARGET_NAME = "targetName"; public static final String F_STAGES = "stages"; + public static final String F_TRIGGERS = "triggers"; private final boolean wholeProcess; // do we represent whole process or only the future stages? private final int currentStageNumber; // current stage number (0 if there's no current stage, i.e. process has not started yet) @@ -49,15 +50,18 @@ public class ApprovalProcessExecutionInformationDto implements Serializable { private final String processName; private final String targetName; private final List stages = new ArrayList<>(); + private final EvaluatedTriggerGroupDto triggers; private final boolean running; private ApprovalProcessExecutionInformationDto(boolean wholeProcess, int currentStageNumber, int numberOfStages, - String processName, String targetName, boolean running) { + String processName, String targetName, + EvaluatedTriggerGroupDto triggers, boolean running) { this.wholeProcess = wholeProcess; this.currentStageNumber = currentStageNumber; this.numberOfStages = numberOfStages; this.processName = processName; this.targetName = targetName; + this.triggers = triggers; this.running = running; } @@ -72,8 +76,10 @@ public static ApprovalProcessExecutionInformationDto createFrom(ApprovalSchemaEx String targetName = WfContextUtil.getTargetName(info); WfContextType wfc = WfContextUtil.getWorkflowContext(info); boolean running = wfc != null && wfc.getEndTimestamp() == null; + EvaluatedTriggerGroupDto triggers = EvaluatedTriggerGroupDto.create(WfContextUtil.getAllRules(info.getPolicyRules())); ApprovalProcessExecutionInformationDto rv = - new ApprovalProcessExecutionInformationDto(wholeProcess, currentStageNumber, numberOfStages, processName, targetName, running); + new ApprovalProcessExecutionInformationDto(wholeProcess, currentStageNumber, numberOfStages, processName, + targetName, triggers, running); int startingStageNumber = wholeProcess ? 1 : currentStageNumber+1; boolean reachable = true; for (int i = startingStageNumber - 1; i < numberOfStages; i++) { @@ -114,4 +120,8 @@ public String getTargetName() { public boolean isRunning() { return running; } + + public EvaluatedTriggerGroupDto getTriggers() { + return triggers; + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/marshaller/PrismUnmarshaller.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/marshaller/PrismUnmarshaller.java index fc29b7ddaa9..3020d11c08e 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/marshaller/PrismUnmarshaller.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/marshaller/PrismUnmarshaller.java @@ -222,10 +222,12 @@ private PrismContainerValue parseContainerValue(@No if (prim.isEmpty()) { return containerDef.createValue(); } else { - throw new IllegalArgumentException("Cannot parse container value from (non-empty) " + node); + pc.warnOrThrow(LOGGER, "Cannot parse container value from (non-empty) " + node); + return containerDef.createValue(); } } else { - throw new IllegalArgumentException("Cannot parse container value from " + node); + pc.warnOrThrow(LOGGER, "Cannot parse container value from " + node); + return containerDef.createValue(); } } diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/WfContextUtil.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/WfContextUtil.java index 21511e99afe..dfcca33a2e4 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/WfContextUtil.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/WfContextUtil.java @@ -747,4 +747,14 @@ public static String getOutcome(ApprovalSchemaExecutionInformationType info) { WfContextType wfc = getWorkflowContext(info); return wfc != null ? wfc.getOutcome() : null; } + + public static List getAllRules(SchemaAttachedPolicyRulesType policyRules) { + List rv = new ArrayList<>(); + for (SchemaAttachedPolicyRuleType entry : policyRules.getEntry()) { + if (!rv.contains(entry.getRule())) { + rv.add(entry.getRule()); + } + } + return rv; + } } diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd index 6ff147cc3a6..6a3dd601cea 100644 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd @@ -278,6 +278,7 @@ + diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/ApprovalSchemaExecutionInformationHelper.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/ApprovalSchemaExecutionInformationHelper.java index 7fd252e0ac2..4ae4cfe37d0 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/ApprovalSchemaExecutionInformationHelper.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/ApprovalSchemaExecutionInformationHelper.java @@ -134,6 +134,9 @@ private ApprovalSchemaExecutionInformationType getApprovalSchemaExecutionInforma } rv.getStage().add(stageExecution); } + if (itemApprovalState.getPolicyRules() != null) { + rv.setPolicyRules(itemApprovalState.getPolicyRules().clone()); + } return rv; } From b8e6edd0c0ae0e15bcbdfa10ad852ee410338bb8 Mon Sep 17 00:00:00 2001 From: kate Date: Tue, 19 Sep 2017 10:14:35 +0200 Subject: [PATCH 09/97] MID-3582 + AuditLogViewerPanel refactoring --- .../objectdetails/ObjectHistoryTabPanel.java | 30 +++-- .../admin/reports/PageAuditLogViewer.java | 2 +- .../component/AuditLogViewerPanel.java | 110 +++++++++--------- 3 files changed, 76 insertions(+), 66 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/ObjectHistoryTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/ObjectHistoryTabPanel.java index a353b39d091..85e1e785037 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/ObjectHistoryTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/ObjectHistoryTabPanel.java @@ -71,13 +71,6 @@ public ObjectHistoryTabPanel(String id, Form mainForm, LoadableModel> focusWrapperModel, final PageAdminObjectDetails page) { - AuditSearchDto searchDto = new AuditSearchDto(); - ObjectReferenceType ort = new ObjectReferenceType(); - ort.setOid(focusWrapperModel.getObject().getOid()); - searchDto.setTargetNames(asList(ort)); - - searchDto.setEventStage(AuditEventStageType.EXECUTION); - Map visibilityMap = new HashMap<>(); visibilityMap.put(AuditLogViewerPanel.TARGET_NAME_LABEL_VISIBILITY, false); visibilityMap.put(AuditLogViewerPanel.TARGET_NAME_FIELD_VISIBILITY, false); @@ -88,12 +81,31 @@ private void initLayout(final LoadableModel> focusWrapperModel, visibilityMap.put(AuditLogViewerPanel.EVENT_STAGE_COLUMN_VISIBILITY, false); visibilityMap.put(AuditLogViewerPanel.TARGET_COLUMN_VISIBILITY, false); visibilityMap.put(AuditLogViewerPanel.TARGET_OWNER_COLUMN_VISIBILITY, false); - AuditLogViewerPanel panel = new AuditLogViewerPanel(ID_MAIN_PANEL, page, searchDto, visibilityMap) { + AuditLogViewerPanel panel = new AuditLogViewerPanel(ID_MAIN_PANEL, visibilityMap) { + private static final long serialVersionUID = 1L; + + @Override + protected AuditSearchDto initAuditSearchDto(){ + AuditSearchDto searchDto = new AuditSearchDto(); + ObjectReferenceType ort = new ObjectReferenceType(); + ort.setOid(focusWrapperModel.getObject().getOid()); + searchDto.setTargetNames(asList(ort)); + searchDto.setEventStage(AuditEventStageType.EXECUTION); + + return searchDto; + } + + @Override + protected boolean useSessionStorageOnPanelLoad(){ + return false; + } + @Override protected List> initColumns() { List> columns = super.initColumns(); IColumn column = new MultiButtonColumn(new Model(), 2) { + private static final long serialVersionUID = 1L; private final DoubleButtonColumn.BUTTON_COLOR_CLASS[] colors = { DoubleButtonColumn.BUTTON_COLOR_CLASS.INFO, @@ -191,6 +203,8 @@ private void viewObjectXmlButtonClicked(String oid, String eventIdentifier, Clas setResponsePage(new PageXmlDataReview(getPageBase().createStringResource("PageXmlDataReview.aceEditorPanelTitle", name, date), new IModel() { + private static final long serialVersionUID = 1L; + @Override public String getObject() { PrismContext context = getPageBase().getPrismContext(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.java index 50b0968b4f6..51e153fb01c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/PageAuditLogViewer.java @@ -23,7 +23,7 @@ public PageAuditLogViewer() { } private void initLayout(){ - AuditLogViewerPanel panel = new AuditLogViewerPanel(ID_PANEL, PageAuditLogViewer.this); + AuditLogViewerPanel panel = new AuditLogViewerPanel(ID_PANEL, null); panel.setOutputMarkupId(true); add(panel); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AuditLogViewerPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AuditLogViewerPanel.java index 30524b1561c..3a1a818ae42 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AuditLogViewerPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AuditLogViewerPanel.java @@ -65,7 +65,6 @@ import com.evolveum.midpoint.web.page.admin.reports.PageAuditLogDetails; import com.evolveum.midpoint.web.page.admin.reports.dto.AuditEventRecordProvider; import com.evolveum.midpoint.web.page.admin.reports.dto.AuditSearchDto; -import com.evolveum.midpoint.web.page.admin.users.PageUser; import com.evolveum.midpoint.web.session.AuditLogStorage; import com.evolveum.midpoint.web.session.UserProfileStorage; import com.evolveum.midpoint.web.util.DateValidator; @@ -81,8 +80,7 @@ /** * Created by honchar. */ -public class AuditLogViewerPanel extends BasePanel { - +public class AuditLogViewerPanel extends BasePanel { private static final long serialVersionUID = 1L; private static final String ID_PARAMETERS_PANEL = "parametersPanel"; private static final String ID_TABLE = "table"; @@ -127,38 +125,42 @@ public class AuditLogViewerPanel extends BasePanel { + ".resolveReferenceName()"; private static final int DEFAULT_PAGE_SIZE = 10; - private IModel auditSearchModel; private PageBase pageBase; private Map visibilityMap; - private AuditLogStorage auditLogStorage; - - public AuditLogViewerPanel(String id, PageBase pageBase){ - this(id, pageBase, null); - } + protected AuditLogStorage auditLogStorage; - public AuditLogViewerPanel(String id, PageBase pageBase, AuditSearchDto searchDto) { - this(id, pageBase, searchDto, new HashMap()); + public AuditLogViewerPanel(String id, Map visibilityMap){ + super(id, Model.of(new AuditSearchDto())); + this.visibilityMap = visibilityMap; } - public AuditLogViewerPanel(String id, PageBase pageBase, AuditSearchDto searchDto, Map visibilityMap){ - super(id); - this.pageBase = pageBase; - this.visibilityMap = visibilityMap; - initAuditSearchModel(searchDto); + @Override + protected void onInitialize(){ + super.onInitialize(); + pageBase = getPageBase(); + setAuditSearchModelObject(); initLayout(); } - private void initAuditSearchModel(AuditSearchDto searchDto){ - if (pageBase instanceof PageUser){ - auditLogStorage = pageBase.getSessionStorage().getUserHistoryAuditLog(); - } else { + private void setAuditSearchModelObject(){ + AuditSearchDto searchDto; + if (useSessionStorageOnPanelLoad()){ auditLogStorage = pageBase.getSessionStorage().getAuditLog(); - } - if (searchDto == null){ searchDto = auditLogStorage.getSearchDto(); + } else { + searchDto = initAuditSearchDto(); + auditLogStorage = pageBase.getSessionStorage().getUserHistoryAuditLog(); + auditLogStorage.setSearchDto(searchDto); } - auditSearchModel = new Model(searchDto); + getModel().setObject(searchDto); + } + protected AuditSearchDto initAuditSearchDto(){ + return new AuditSearchDto(); + } + + protected boolean useSessionStorageOnPanelLoad(){ + return true; } private void initLayout() { @@ -167,12 +169,8 @@ private void initLayout() { mainForm.setOutputMarkupId(true); add(mainForm); -// FeedbackPanel feedback = new FeedbackPanel(ID_FEEDBACK); -// feedback.setOutputMarkupId(true); -// mainForm.add(feedback); - initParametersPanel(mainForm); - addOrReplaceTable(mainForm); + initAuditLogViewerTable(mainForm); } private void initParametersPanel(Form mainForm) { @@ -181,7 +179,7 @@ private void initParametersPanel(Form mainForm) { mainForm.add(parametersPanel); PropertyModel fromModel = new PropertyModel( - auditSearchModel, AuditSearchDto.F_FROM); + getModel(), AuditSearchDto.F_FROM); DatePanel from = new DatePanel(ID_FROM, fromModel); DateValidator dateFromValidator = WebComponentUtil.getRangeValidator(mainForm, @@ -195,7 +193,7 @@ private void initParametersPanel(Form mainForm) { from.setOutputMarkupId(true); parametersPanel.add(from); - PropertyModel toModel = new PropertyModel(auditSearchModel, + PropertyModel toModel = new PropertyModel(getModel(), AuditSearchDto.F_TO); DatePanel to = new DatePanel(ID_TO, toModel); DateValidator dateToValidator = WebComponentUtil.getRangeValidator(mainForm, @@ -209,7 +207,7 @@ private void initParametersPanel(Form mainForm) { to.setOutputMarkupId(true); parametersPanel.add(to); - PropertyModel changedItemModel = new PropertyModel(auditSearchModel, + PropertyModel changedItemModel = new PropertyModel(getModel(), AuditSearchDto.F_CHANGED_ITEM); ItemPathPanel changedItemPanel = new ItemPathPanel(ID_CHANGED_ITEM, changedItemModel, pageBase); @@ -218,7 +216,7 @@ private void initParametersPanel(Form mainForm) { changedItemPanel.setOutputMarkupId(true); parametersPanel.add(changedItemPanel); - PropertyModel hostIdentifierModel = new PropertyModel<>(auditSearchModel, + PropertyModel hostIdentifierModel = new PropertyModel<>(getModel(), AuditSearchDto.F_HOST_IDENTIFIER); TextPanel hostIdentifier = new TextPanel<>(ID_HOST_IDENTIFIER, hostIdentifierModel); hostIdentifier.getBaseFormComponent().add(new EmptyOnChangeAjaxFormUpdatingBehavior()); @@ -229,7 +227,7 @@ private void initParametersPanel(Form mainForm) { ListModel eventTypeListModel = new ListModel( Arrays.asList(AuditEventTypeType.values())); PropertyModel eventTypeModel = new PropertyModel( - auditSearchModel, AuditSearchDto.F_EVENT_TYPE); + getModel(), AuditSearchDto.F_EVENT_TYPE); DropDownChoicePanel eventType = new DropDownChoicePanel( ID_EVENT_TYPE, eventTypeModel, eventTypeListModel, new EnumChoiceRenderer(), true); @@ -246,7 +244,7 @@ private void initParametersPanel(Form mainForm) { ListModel eventStageListModel = new ListModel( Arrays.asList(AuditEventStageType.values())); PropertyModel eventStageModel = new PropertyModel( - auditSearchModel, AuditSearchDto.F_EVENT_STAGE); + getModel(), AuditSearchDto.F_EVENT_STAGE); DropDownChoicePanel eventStageField = new DropDownChoicePanel( ID_EVENT_STAGE_FIELD, eventStageModel, eventStageListModel, new EnumChoiceRenderer(), true); @@ -259,7 +257,7 @@ private void initParametersPanel(Form mainForm) { ListModel outcomeListModel = new ListModel( Arrays.asList(OperationResultStatusType.values())); PropertyModel outcomeModel = new PropertyModel( - auditSearchModel, AuditSearchDto.F_OUTCOME); + getModel(), AuditSearchDto.F_OUTCOME); DropDownChoicePanel outcome = new DropDownChoicePanel( ID_OUTCOME, outcomeModel, outcomeListModel, new EnumChoiceRenderer(), true); @@ -278,7 +276,7 @@ private void initParametersPanel(Form mainForm) { } } ListModel channelListModel = new ListModel(channelQnameList); - PropertyModel channelModel = new PropertyModel(auditSearchModel, + PropertyModel channelModel = new PropertyModel(getModel(), AuditSearchDto.F_CHANNEL); DropDownChoicePanel channel = new DropDownChoicePanel(ID_CHANNEL, channelModel, channelListModel, new QNameChoiceRenderer(), true); @@ -291,18 +289,18 @@ private void initParametersPanel(Form mainForm) { allowedClasses.add(UserType.class); MultiValueChoosePanel chooseInitiatorPanel = new SingleValueChoosePanel( ID_INITIATOR_NAME, allowedClasses, objectReferenceTransformer, - new PropertyModel(auditSearchModel, AuditSearchDto.F_INITIATOR_NAME)); + new PropertyModel(getModel(), AuditSearchDto.F_INITIATOR_NAME)); parametersPanel.add(chooseInitiatorPanel); WebMarkupContainer targetOwnerName = new WebMarkupContainer(ID_TARGET_OWNER_NAME); targetOwnerName.add(visibilityByKey(visibilityMap, TARGET_OWNER_LABEL_VISIBILITY)); parametersPanel.add(targetOwnerName); - MultiValueChoosePanel chooseTargerOwnerPanel = new SingleValueChoosePanel( - ID_TARGET_OWNER_NAME_FIELD, allowedClasses, objectReferenceTransformer, new PropertyModel(auditSearchModel, AuditSearchDto.F_TARGET_OWNER_NAME)); + MultiValueChoosePanel chooseTargetOwnerPanel = new SingleValueChoosePanel( + ID_TARGET_OWNER_NAME_FIELD, allowedClasses, objectReferenceTransformer, new PropertyModel(getModel(), AuditSearchDto.F_TARGET_OWNER_NAME)); - chooseTargerOwnerPanel.add(visibilityByKey(visibilityMap, TARGET_OWNER_FIELD_VISIBILITY)); - targetOwnerName.add(chooseTargerOwnerPanel); + chooseTargetOwnerPanel.add(visibilityByKey(visibilityMap, TARGET_OWNER_FIELD_VISIBILITY)); + targetOwnerName.add(chooseTargetOwnerPanel); WebMarkupContainer targetName = new WebMarkupContainer(ID_TARGET_NAME); targetName.add(visibilityByKey(visibilityMap, TARGET_NAME_LABEL_VISIBILITY)); @@ -312,7 +310,7 @@ private void initParametersPanel(Form mainForm) { MultiValueChoosePanel chooseTargetPanel = new MultiValueChoosePanel( ID_TARGET_NAME_FIELD, - new PropertyModel>(auditSearchModel, AuditSearchDto.F_TARGET_NAMES_OBJECTS), + new PropertyModel>(getModel(), AuditSearchDto.F_TARGET_NAMES_OBJECTS), allowedClassesAll); chooseTargetPanel.setOutputMarkupId(true); chooseTargetPanel.add(visibilityByKey(visibilityMap, TARGET_NAME_FIELD_VISIBILITY)); @@ -324,7 +322,8 @@ private void initParametersPanel(Form mainForm) { @Override protected void onSubmit(AjaxRequestTarget target, Form form) { - searchUpdatePerformed(target, form, auditSearchModel.getObject()); + auditLogStorage.setSearchDto(getModel().getObject()); + searchUpdatePerformed(target); } @Override @@ -341,8 +340,9 @@ protected void onError(AjaxRequestTarget target, Form form){ @Override protected void onSubmit(AjaxRequestTarget target, Form form) { - auditSearchModel.setObject(new AuditSearchDto()); - searchUpdatePerformed(target, form, new AuditSearchDto()); + getModel().setObject(initAuditSearchDto()); + auditLogStorage.setSearchDto(getModel().getObject()); + searchUpdatePerformed(target); } @Override @@ -359,7 +359,7 @@ protected void onError(AjaxRequestTarget target, Form form){ MultiValueChoosePanel chooseValueRefTargetNamePanel = new MultiValueChoosePanel( ID_VALUE_REF_TARGET_NAMES_FIELD, - new PropertyModel>(auditSearchModel, AuditSearchDto.F_VALUE_REF_TARGET_NAME), + new PropertyModel>(getModel(), AuditSearchDto.F_VALUE_REF_TARGET_NAME), allowedClassesAll); chooseValueRefTargetNamePanel.setOutputMarkupId(true); chooseValueRefTargetNamePanel.add(visibilityByKey(visibilityMap, VALUE_REF_TARGET_NAME_FIELD_VISIBILITY)); @@ -388,14 +388,14 @@ public boolean isVisible(){ }; } - private void addOrReplaceTable(Form mainForm) { + private void initAuditLogViewerTable(Form mainForm) { AuditEventRecordProvider provider = new AuditEventRecordProvider(AuditLogViewerPanel.this) { private static final long serialVersionUID = 1L; public Map getParameters() { Map parameters = new HashMap(); - AuditSearchDto search = auditSearchModel.getObject(); + AuditSearchDto search = AuditLogViewerPanel.this.getModelObject(); parameters.put("from", search.getFrom()); parameters.put("to", search.getTo()); @@ -489,7 +489,7 @@ public void setShowPaging(boolean show) { table.setShowPaging(true); table.setCurrentPage(auditLogStorage.getPageNumber()); table.setOutputMarkupId(true); - mainForm.addOrReplace(table); + mainForm.add(table); } private BoxedTablePanel getAuditLogViewerTable(){ @@ -617,20 +617,16 @@ private void createReferenceColumn(ObjectReferenceType ref, Item item, String co item.add(new AttributeModifier("style", new Model("width: 10%;"))); } - private void searchUpdatePerformed(AjaxRequestTarget target, Form form, AuditSearchDto searchDto){ - auditLogStorage.setSearchDto(searchDto); + private void searchUpdatePerformed(AjaxRequestTarget target){ auditLogStorage.setPageNumber(0); - Form mainForm = getMainFormComponent(); - addOrReplaceTable(mainForm); +// Form mainForm = getMainFormComponent(); +// initAuditLogViewerTable(mainForm); pageBase.getFeedbackPanel().getFeedbackMessages().clear(); target.add(pageBase.getFeedbackPanel()); - target.add(mainForm); + target.add(getMainFormComponent()); } private Form getMainFormComponent(){ return (Form) get(ID_MAIN_FORM); } -// public WebMarkupContainer getFeedbackPanel() { -// return (FeedbackPanel) get(pageBase.createComponentPath(ID_MAIN_FORM, ID_FEEDBACK)); -// } } From b06ab1a9a575043154f41239864a86926cefd36b Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 19 Sep 2017 11:24:44 +0200 Subject: [PATCH 10/97] "Reasons for the approval process" - preliminary implementation --- .../prism/show/PagePreviewChanges.java | 2 +- .../page/admin/server/TaskWfChildPanel.html | 10 +++++- .../page/admin/server/TaskWfChildPanel.java | 12 +++++++ .../web/page/admin/server/dto/TaskDto.java | 12 +++++++ .../workflow/EvaluatedTriggerGroupPanel.java | 8 ----- .../admin/workflow/EvaluatedTriggerPanel.html | 2 +- .../admin/workflow/EvaluatedTriggerPanel.java | 13 +++++-- .../page/admin/workflow/WorkItemPanel.html | 9 +++++ .../page/admin/workflow/WorkItemPanel.java | 10 ++++++ .../dto/AlreadyShownTriggerRecord.java | 33 +++++++++++++++++ ...pprovalProcessExecutionInformationDto.java | 2 +- .../workflow/dto/EvaluatedTriggerDto.java | 35 ++++++++++++++++--- .../dto/EvaluatedTriggerGroupDto.java | 4 +-- .../page/admin/workflow/dto/WorkItemDto.java | 27 +++++++++++++- .../localization/Midpoint.properties | 1 + .../schema/util/LocalizationUtil.java | 2 +- .../midpoint/schema/util/WfContextUtil.java | 21 +++++++++++ .../itemApproval/PrepareForTaskCreation.java | 2 +- 18 files changed, 181 insertions(+), 24 deletions(-) create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/AlreadyShownTriggerRecord.java diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/show/PagePreviewChanges.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/show/PagePreviewChanges.java index 29dda023b64..4e1b95e43e5 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/show/PagePreviewChanges.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/show/PagePreviewChanges.java @@ -138,7 +138,7 @@ public SceneDto getObject() { ? modelContext.getHookPreviewResult(PolicyRuleEnforcerHookPreviewOutputType.class) : null; List triggerGroups = enforcements != null - ? Collections.singletonList(EvaluatedTriggerGroupDto.create(enforcements.getRule())) + ? Collections.singletonList(EvaluatedTriggerGroupDto.createFrom(enforcements.getRule(), false, null)) : Collections.emptyList(); policyViolationsModel = Model.ofList(triggerGroups); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskWfChildPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskWfChildPanel.html index afada21dd1b..906e49fad09 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskWfChildPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskWfChildPanel.html @@ -21,7 +21,15 @@
-
+
+
+
+

+
+
+
+
+
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskWfChildPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskWfChildPanel.java index e405cf81d14..933ac168474 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskWfChildPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskWfChildPanel.java @@ -21,13 +21,16 @@ import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.web.component.util.ListDataProvider; +import com.evolveum.midpoint.web.component.util.VisibleBehaviour; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; import com.evolveum.midpoint.web.component.wf.SwitchableApprovalProcessPreviewsPanel; import com.evolveum.midpoint.web.component.wf.WorkItemsPanel; import com.evolveum.midpoint.web.component.wf.processes.itemApproval.ItemApprovalHistoryPanel; import com.evolveum.midpoint.web.page.admin.server.dto.TaskChangesDto; import com.evolveum.midpoint.web.page.admin.server.dto.TaskDto; +import com.evolveum.midpoint.web.page.admin.workflow.EvaluatedTriggerGroupListPanel; import com.evolveum.midpoint.web.page.admin.workflow.ProcessInstancesPanel; +import com.evolveum.midpoint.web.page.admin.workflow.dto.EvaluatedTriggerGroupDto; import com.evolveum.midpoint.web.page.admin.workflow.dto.ProcessInstanceDto; import com.evolveum.midpoint.web.page.admin.workflow.dto.WorkItemDto; import com.evolveum.midpoint.web.session.UserProfileStorage; @@ -55,6 +58,8 @@ public class TaskWfChildPanel extends Panel { private static final long serialVersionUID = 1L; private static final String ID_CHANGES = "changes"; + private static final String ID_TRIGGERS_CONTAINER = "triggersContainer"; + private static final String ID_TRIGGERS = "triggers"; private static final String ID_HISTORY = "history"; private static final String ID_HISTORY_HELP = "approvalHistoryHelp"; private static final String ID_CURRENT_WORK_ITEMS_CONTAINER = "currentWorkItemsContainer"; @@ -86,6 +91,13 @@ private void initLayout(final IModel taskDtoModel) { changesPanel.setOutputMarkupId(true); add(changesPanel); + WebMarkupContainer triggersContainer = new WebMarkupContainer(ID_TRIGGERS_CONTAINER); + PropertyModel> triggersModel = new PropertyModel<>(taskDtoModel, TaskDto.F_TRIGGERS); + WebMarkupContainer triggers = new EvaluatedTriggerGroupListPanel(ID_TRIGGERS, triggersModel); + triggersContainer.add(triggers); + triggersContainer.add(new VisibleBehaviour(() -> !triggersModel.getObject().isEmpty())); + add(triggersContainer); + final ItemApprovalHistoryPanel history = new ItemApprovalHistoryPanel(ID_HISTORY, new PropertyModel<>(taskDtoModel, TaskDto.F_WORKFLOW_CONTEXT), UserProfileStorage.TableId.PAGE_TASK_HISTORY_PANEL, diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java index 3b5045da3d4..ec48125fbc6 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/dto/TaskDto.java @@ -53,6 +53,7 @@ import com.evolveum.midpoint.web.page.admin.server.handlers.HandlerDtoFactory; import com.evolveum.midpoint.web.page.admin.server.handlers.dto.HandlerDto; import com.evolveum.midpoint.web.page.admin.server.handlers.dto.ResourceRelatedHandlerDto; +import com.evolveum.midpoint.web.page.admin.workflow.dto.EvaluatedTriggerGroupDto; import com.evolveum.midpoint.web.page.admin.workflow.dto.ProcessInstanceDto; import com.evolveum.midpoint.web.page.admin.workflow.dto.WorkItemDto; import com.evolveum.midpoint.web.security.MidPointApplication; @@ -74,6 +75,7 @@ import static com.evolveum.midpoint.schema.GetOperationOptions.createRetrieve; import static com.evolveum.midpoint.schema.SelectorOptions.createCollection; +import static com.evolveum.midpoint.web.page.admin.workflow.dto.WorkItemDto.computeTriggers; /** * @author lazyman @@ -128,6 +130,7 @@ public class TaskDto extends Selectable implements InlineMenuable { public static final long RUNS_CONTINUALLY = -1L; public static final long ALREADY_PASSED = -2L; public static final long NOW = 0L; + public static final String F_TRIGGERS = "triggers"; @NotNull private final TaskType taskType; @@ -157,6 +160,7 @@ public class TaskDto extends Selectable implements InlineMenuable { // other private List menuItems; private HandlerDto handlerDto; + private List triggers; // initialized on demand //region Construction public TaskDto(@NotNull TaskType taskType, ModelService modelService, TaskService taskService, ModelInteractionService modelInteractionService, @@ -1133,4 +1137,12 @@ public String getAllowedNodes(List nodes) { .collect(Collectors.joining(", ")); return n.isEmpty() ? "-" : n; } + + public List getTriggers() { + if (triggers == null) { + triggers = computeTriggers(getWorkflowContext()); + } + return triggers; + } + } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/EvaluatedTriggerGroupPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/EvaluatedTriggerGroupPanel.java index d3600befeec..5dcf7f76a1d 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/EvaluatedTriggerGroupPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/EvaluatedTriggerGroupPanel.java @@ -17,22 +17,14 @@ package com.evolveum.midpoint.web.page.admin.workflow; import com.evolveum.midpoint.gui.api.component.BasePanel; -import com.evolveum.midpoint.gui.api.util.WebComponentUtil; -import com.evolveum.midpoint.web.component.util.LocalizableMessageModel; -import com.evolveum.midpoint.web.component.util.VisibleBehaviour; import com.evolveum.midpoint.web.page.admin.workflow.dto.EvaluatedTriggerDto; import com.evolveum.midpoint.web.page.admin.workflow.dto.EvaluatedTriggerGroupDto; -import com.evolveum.midpoint.xml.ns._public.common.common_3.InformationPartType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.InformationType; -import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; -import java.util.List; - /** * @author mederly */ diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/EvaluatedTriggerPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/EvaluatedTriggerPanel.html index 9d660b80817..510e2834c2c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/EvaluatedTriggerPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/EvaluatedTriggerPanel.html @@ -16,7 +16,7 @@ --> -
+
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/EvaluatedTriggerPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/EvaluatedTriggerPanel.java index 9eaefbfc024..80537abdd26 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/EvaluatedTriggerPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/EvaluatedTriggerPanel.java @@ -20,6 +20,8 @@ import com.evolveum.midpoint.web.component.util.LocalizableMessageModel; import com.evolveum.midpoint.web.page.admin.workflow.dto.EvaluatedTriggerDto; import com.evolveum.midpoint.web.page.admin.workflow.dto.EvaluatedTriggerGroupDto; +import org.apache.wicket.behavior.AttributeAppender; +import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; @@ -29,6 +31,7 @@ */ public class EvaluatedTriggerPanel extends BasePanel { + private static final String ID_FRAME = "frame"; private static final String ID_MESSAGE = "message"; private static final String ID_CHILDREN = "children"; @@ -40,12 +43,18 @@ public EvaluatedTriggerPanel(String id, IModel model) { protected void initLayout() { EvaluatedTriggerDto trigger = getModelObject(); - add(new Label(ID_MESSAGE, + WebMarkupContainer frame = new WebMarkupContainer(ID_FRAME); + if (trigger.isHighlighted()) { + frame.add(new AttributeAppender("style", "background-color: #fcffd3")); // TODO skin + } + add(frame); + + frame.add(new Label(ID_MESSAGE, new LocalizableMessageModel(Model.of(trigger.getMessage()), this))); EvaluatedTriggerGroupDto children = trigger.getChildren(); EvaluatedTriggerGroupPanel childrenPanel = new EvaluatedTriggerGroupPanel(ID_CHILDREN, Model.of(children)); childrenPanel.setVisible(!children.getTriggers().isEmpty()); - add(childrenPanel); + frame.add(childrenPanel); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/WorkItemPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/WorkItemPanel.html index 18d860df47d..15294838282 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/WorkItemPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/WorkItemPanel.html @@ -109,6 +109,15 @@

+
+
+

+
+
+
+
+
+

diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/WorkItemPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/WorkItemPanel.java index 449d9cdf274..4d7815cc191 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/WorkItemPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/WorkItemPanel.java @@ -33,6 +33,7 @@ import com.evolveum.midpoint.web.component.wf.processes.itemApproval.ItemApprovalHistoryPanel; import com.evolveum.midpoint.web.page.admin.server.PageTaskEdit; import com.evolveum.midpoint.web.page.admin.server.TaskChangesPanel; +import com.evolveum.midpoint.web.page.admin.workflow.dto.EvaluatedTriggerGroupDto; import com.evolveum.midpoint.web.page.admin.workflow.dto.ProcessInstanceDto; import com.evolveum.midpoint.web.page.admin.workflow.dto.WorkItemDto; import com.evolveum.midpoint.web.session.UserProfileStorage; @@ -89,6 +90,8 @@ public class WorkItemPanel extends BasePanel { private static final String ID_RELATED_REQUESTS_CONTAINER = "relatedRequestsContainer"; private static final String ID_RELATED_REQUESTS = "relatedRequests"; private static final String ID_RELATED_REQUESTS_HELP = "relatedRequestsHelp"; + private static final String ID_TRIGGERS_CONTAINER = "triggersContainer"; + private static final String ID_TRIGGERS = "triggers"; private static final String ID_ADDITIONAL_INFORMATION = "additionalInformation"; private static final String ID_CUSTOM_FORM = "customForm"; private static final String ID_APPROVER_COMMENT = "approverComment"; @@ -216,6 +219,13 @@ public void onClick(AjaxRequestTarget target) { }); add(WebComponentUtil.createHelp(ID_SHOW_REQUEST_HELP)); + WebMarkupContainer triggersContainer = new WebMarkupContainer(ID_TRIGGERS_CONTAINER); + PropertyModel> triggersModel = new PropertyModel<>(getModel(), WorkItemDto.F_TRIGGERS); + WebMarkupContainer triggers = new EvaluatedTriggerGroupListPanel(ID_TRIGGERS, triggersModel); + triggersContainer.add(triggers); + triggersContainer.add(new VisibleBehaviour(() -> !triggersModel.getObject().isEmpty())); + add(triggersContainer); + WebMarkupContainer additionalInformation = new InformationListPanel(ID_ADDITIONAL_INFORMATION, new PropertyModel<>(getModel(), WorkItemDto.F_ADDITIONAL_INFORMATION)); add(additionalInformation); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/AlreadyShownTriggerRecord.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/AlreadyShownTriggerRecord.java new file mode 100644 index 00000000000..895c12aed18 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/AlreadyShownTriggerRecord.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.web.page.admin.workflow.dto; + +import com.evolveum.midpoint.xml.ns._public.common.common_3.EvaluatedPolicyRuleTriggerType; + +/** + * @author mederly + */ +public class AlreadyShownTriggerRecord { + final EvaluatedTriggerDto originalTriggerDto; + final EvaluatedPolicyRuleTriggerType anonymizedTrigger; + + public AlreadyShownTriggerRecord(EvaluatedTriggerDto originalTriggerDto, + EvaluatedPolicyRuleTriggerType anonymizedTrigger) { + this.originalTriggerDto = originalTriggerDto; + this.anonymizedTrigger = anonymizedTrigger; + } +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/ApprovalProcessExecutionInformationDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/ApprovalProcessExecutionInformationDto.java index 5766a4363f8..187844924a4 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/ApprovalProcessExecutionInformationDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/ApprovalProcessExecutionInformationDto.java @@ -76,7 +76,7 @@ public static ApprovalProcessExecutionInformationDto createFrom(ApprovalSchemaEx String targetName = WfContextUtil.getTargetName(info); WfContextType wfc = WfContextUtil.getWorkflowContext(info); boolean running = wfc != null && wfc.getEndTimestamp() == null; - EvaluatedTriggerGroupDto triggers = EvaluatedTriggerGroupDto.create(WfContextUtil.getAllRules(info.getPolicyRules())); + EvaluatedTriggerGroupDto triggers = EvaluatedTriggerGroupDto.createFrom(WfContextUtil.getAllRules(info.getPolicyRules()), false, new ArrayList<>()); ApprovalProcessExecutionInformationDto rv = new ApprovalProcessExecutionInformationDto(wholeProcess, currentStageNumber, numberOfStages, processName, targetName, triggers, running); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/EvaluatedTriggerDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/EvaluatedTriggerDto.java index 672355b45a3..85a6dbb6c84 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/EvaluatedTriggerDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/EvaluatedTriggerDto.java @@ -33,10 +33,13 @@ public class EvaluatedTriggerDto implements Serializable { public static final String F_CHILDREN = "children"; @NotNull private final EvaluatedPolicyRuleTriggerType trigger; - @NotNull private final EvaluatedTriggerGroupDto children = new EvaluatedTriggerGroupDto(null); + @NotNull private final EvaluatedTriggerGroupDto children; + private boolean highlighted; - public EvaluatedTriggerDto(@NotNull EvaluatedPolicyRuleTriggerType trigger) { + private EvaluatedTriggerDto(@NotNull EvaluatedPolicyRuleTriggerType trigger, boolean highlighted) { this.trigger = trigger; + this.children = new EvaluatedTriggerGroupDto(null); + this.highlighted = highlighted; } @NotNull @@ -54,21 +57,39 @@ public EvaluatedTriggerGroupDto getChildren() { } // copies logic from EvaluatedPolicyRuleImpl.createMessageTreeNode - public static void create(List resultList, EvaluatedPolicyRuleTriggerType trigger) { + public static void create(List resultList, EvaluatedPolicyRuleTriggerType trigger, boolean highlighted, + List triggersAlreadyShown) { boolean hidden = Boolean.TRUE.equals(trigger.isHidden()); boolean isFinal = Boolean.TRUE.equals(trigger.isFinal()); if (!hidden) { - EvaluatedTriggerDto newTriggerDto = new EvaluatedTriggerDto(trigger); + EvaluatedTriggerDto newTriggerDto = new EvaluatedTriggerDto(trigger, highlighted); + if (triggersAlreadyShown != null && alreadyShown(triggersAlreadyShown, newTriggerDto)) { + return; + } resultList.add(newTriggerDto); resultList = newTriggerDto.getChildren().getTriggers(); } if (!isFinal) { // it's possible that this was pre-filtered e.g. by policy enforcer hook for (EvaluatedPolicyRuleTriggerType innerTrigger : getChildTriggers(trigger)) { - create(resultList, innerTrigger); + create(resultList, innerTrigger, highlighted, triggersAlreadyShown); } } } + private static boolean alreadyShown(List triggersAlreadyShown, EvaluatedTriggerDto newTriggerDto) { + EvaluatedPolicyRuleTriggerType anonymizedTrigger = newTriggerDto.trigger.clone().ruleName(null); + for (AlreadyShownTriggerRecord alreadyShown : triggersAlreadyShown) { + if (alreadyShown.anonymizedTrigger.equals(anonymizedTrigger)) { + if (newTriggerDto.highlighted) { + alreadyShown.originalTriggerDto.highlighted = true; + } + return true; + } + } + triggersAlreadyShown.add(new AlreadyShownTriggerRecord(newTriggerDto, anonymizedTrigger)); + return false; + } + private static List getChildTriggers(EvaluatedPolicyRuleTriggerType trigger) { if (trigger instanceof EvaluatedEmbeddingTriggerType) { return ((EvaluatedEmbeddingTriggerType) trigger).getEmbedded(); @@ -82,4 +103,8 @@ private static List getChildTriggers(EvaluatedPo return Collections.emptyList(); } } + + public boolean isHighlighted() { + return highlighted; + } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/EvaluatedTriggerGroupDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/EvaluatedTriggerGroupDto.java index 69859333c98..026e90f4624 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/EvaluatedTriggerGroupDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/EvaluatedTriggerGroupDto.java @@ -50,11 +50,11 @@ public List getTriggers() { return triggers; } - public static EvaluatedTriggerGroupDto create(List rules) { + public static EvaluatedTriggerGroupDto createFrom(List rules, boolean highlighted, List triggersAlreadyShown) { EvaluatedTriggerGroupDto group = new EvaluatedTriggerGroupDto(null); for (EvaluatedPolicyRuleType rule : rules) { for (EvaluatedPolicyRuleTriggerType trigger : rule.getTrigger()) { - EvaluatedTriggerDto.create(group.getTriggers(), trigger); + EvaluatedTriggerDto.create(group.getTriggers(), trigger, highlighted, triggersAlreadyShown); } } return group; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/WorkItemDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/WorkItemDto.java index 660f28c2827..fba2dc0b1b8 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/WorkItemDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/WorkItemDto.java @@ -80,6 +80,7 @@ public class WorkItemDto extends Selectable { public static final String F_ESCALATION_LEVEL_INFO = "escalationLevelInfo"; public static final String F_ESCALATION_LEVEL_NUMBER = "escalationLevelNumber"; public static final String F_ADDITIONAL_INFORMATION = "additionalInformation"; + public static final String F_TRIGGERS = "triggers"; public static final String F_OTHER_WORK_ITEMS = "otherWorkItems"; public static final String F_RELATED_WORKFLOW_REQUESTS = "relatedWorkflowRequests"; @@ -105,12 +106,13 @@ public class WorkItemDto extends Selectable { // // Depending on expected use (work item list vs. work item details) - private WorkItemType workItem; + private final WorkItemType workItem; private TaskType taskType; private List relatedTasks; @Deprecated private SceneDto deltas; private TaskChangesDto changes; private String approverComment; + private List triggers; // initialized on demand private ObjectType focus; @@ -370,6 +372,29 @@ public Integer getEscalationLevelNumber() { return number > 0 ? number : null; } + public List getTriggers() { + if (triggers == null) { + triggers = computeTriggers(getWorkflowContext()); + } + return triggers; + } + + public static List computeTriggers(WfContextType wfc) { + List triggers = new ArrayList<>(); + if (wfc == null) { + return triggers; + } + List triggersAlreadyShown = new ArrayList<>(); + List> rulesPerStageList = WfContextUtil.getRulesPerStage(wfc); + for (int i = 0; i < rulesPerStageList.size(); i++) { + Integer stageNumber = i + 1; + boolean highlighted = stageNumber.equals(wfc.getStageNumber()); + EvaluatedTriggerGroupDto group = EvaluatedTriggerGroupDto.createFrom(rulesPerStageList.get(i), highlighted, triggersAlreadyShown); + triggers.add(group); + } + return triggers; + } + public List getAdditionalInformation() { return workItem.getAdditionalInformation(); } diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint.properties b/gui/admin-gui/src/main/resources/localization/Midpoint.properties index 57e600c0641..f9e7df22d8c 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint.properties @@ -2333,6 +2333,7 @@ TaskWfParentPanel.requestsHelp=All approval processes for changes displayed here workItemPanel.otherWorkItems=Other work items for this request workItemPanel.requests=Requests workItemPanel.relatedRequests=Related requests +workItemPanel.reasons=Reasons for the approval process workItemPanel.approverComment=Approver comment workItemPanel.approverInstruction=Approver instruction pageWorkItems.button.approve=Approve diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/LocalizationUtil.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/LocalizationUtil.java index 109b54685f9..c86d3b303f7 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/LocalizationUtil.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/LocalizationUtil.java @@ -62,7 +62,7 @@ public static LocalizableMessageType createLocalizableMessageType(LocalizableMes messageArgument = new LocalizableMessageArgumentType() .localizable(createLocalizableMessageType(((LocalizableMessage) argument))); } else { - messageArgument = new LocalizableMessageArgumentType().value(argument != null ? String.valueOf(argument) : null); + messageArgument = new LocalizableMessageArgumentType().value(argument != null ? argument.toString() : null); } rv.getArgument().add(messageArgument); } diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/WfContextUtil.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/WfContextUtil.java index dfcca33a2e4..f41150736cb 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/WfContextUtil.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/WfContextUtil.java @@ -757,4 +757,25 @@ public static List getAllRules(SchemaAttachedPolicyRule } return rv; } + + public static List> getRulesPerStage(WfContextType wfc) { + List> rv = new ArrayList<>(); + ItemApprovalProcessStateType info = getItemApprovalProcessInfo(wfc); + if (info == null || info.getPolicyRules() == null) { + return rv; + } + List entries = info.getPolicyRules().getEntry(); + for (int i = 0; i < info.getApprovalSchema().getStage().size(); i++) { + int stageNumber = i+1; + List rulesForStage = new ArrayList<>(); + for (SchemaAttachedPolicyRuleType entry : entries) { + if (entry.getStageMin() != null && stageNumber >= entry.getStageMin() + && entry.getStageMax() != null && stageNumber <= entry.getStageMax()) { + rulesForStage.add(entry.getRule()); + } + } + rv.add(rulesForStage); + } + return rv; + } } diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/PrepareForTaskCreation.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/PrepareForTaskCreation.java index 864c114ea01..116a3c0de7e 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/PrepareForTaskCreation.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/PrepareForTaskCreation.java @@ -84,7 +84,7 @@ public void execute(DelegateExecution execution) { throw new SystemException("Couldn't evaluate additional information expression in " + execution, t); } } else { - additionalInformation = new AdditionalInformationGenerator().getDefaultAdditionalInformation(wfTask, stageDef.getNumber()); + additionalInformation = Collections.emptyList(); } if (!additionalInformation.isEmpty()) { execution.setVariableLocal(CommonProcessVariableNames.ADDITIONAL_INFORMATION, From c88fd04719754a7f6bca99795d742a8852df9129 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 19 Sep 2017 13:08:00 +0200 Subject: [PATCH 11/97] Another attempt to fix Quartz tables initialization. --- .../midpoint/task/quartzimpl/execution/tables_oracle.sql | 3 --- 1 file changed, 3 deletions(-) diff --git a/repo/task-quartz-impl/src/main/resources/com/evolveum/midpoint/task/quartzimpl/execution/tables_oracle.sql b/repo/task-quartz-impl/src/main/resources/com/evolveum/midpoint/task/quartzimpl/execution/tables_oracle.sql index 6bc346baf35..268c71d0c2e 100644 --- a/repo/task-quartz-impl/src/main/resources/com/evolveum/midpoint/task/quartzimpl/execution/tables_oracle.sql +++ b/repo/task-quartz-impl/src/main/resources/com/evolveum/midpoint/task/quartzimpl/execution/tables_oracle.sql @@ -10,7 +10,6 @@ -- there are two semicolons at the end of each of the following lines to work around a bug/feature of ScriptRunner we use -BEGIN BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_calendars'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;; BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_fired_triggers'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;; BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_blob_triggers'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;; @@ -22,8 +21,6 @@ BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_job_details'; EXCEPTION WHE BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_paused_trigger_grps'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;; BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_locks'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;; BEGIN EXECUTE IMMEDIATE 'DROP TABLE qrtz_scheduler_state'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;; -END; -/ CREATE TABLE qrtz_job_details ( From 7cce36dd55f3b5be301aca650344d74c22b334bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Ga=C5=A1par=C3=ADk?= Date: Tue, 19 Sep 2017 14:22:28 +0200 Subject: [PATCH 12/97] key correction --- .../src/main/resources/localization/Midpoint.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint.properties b/gui/admin-gui/src/main/resources/localization/Midpoint.properties index f9e7df22d8c..f36345f53fb 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint.properties @@ -3166,7 +3166,7 @@ ChangePasswordPanel.helpInfo=

This portion of the credentials dialog controls ChangePasswordPanel.helpPopupTitle=Password propagation help PageBase.button.tooltip.clearSearch=Clear mainForm.uploadTooLarge = Upload must be less than ${maxSize}. -mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage}PageSelfCredentials.couldntResolve=Couldn't resolve resource. +mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage} PageSelfCredentials.couldntResolve=Couldn't resolve resource. roleMemberPanel.type=Type: roleMemberPanel.tenant=Tenant: From 2c71a527bdcf59358b79317d3a62e4382f0facda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Ga=C5=A1par=C3=ADk?= Date: Tue, 19 Sep 2017 14:28:30 +0200 Subject: [PATCH 13/97] Translation update small --- .../localization/Midpoint_cs.properties | 106 +++--- .../localization/Midpoint_de.properties | 7 +- .../localization/Midpoint_en.properties | 2 +- .../localization/Midpoint_es.properties | 2 +- .../localization/Midpoint_et.properties | 4 +- .../localization/Midpoint_fi.properties | 4 +- .../localization/Midpoint_hu.properties | 2 +- .../localization/Midpoint_pl.properties | 4 +- .../localization/Midpoint_pt_BR.properties | 17 +- .../localization/Midpoint_ru.properties | 2 +- .../localization/Midpoint_sk.properties | 304 +++++++++--------- .../localization/Midpoint_tr.properties | 2 +- .../localization/Midpoint_zh_CN.properties | 5 +- .../localization/schema_cs.properties | 20 +- 14 files changed, 222 insertions(+), 259 deletions(-) diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_cs.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_cs.properties index 19178eea6c1..5be7053d9b3 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_cs.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_cs.properties @@ -52,13 +52,13 @@ AssignmentEditorPanel.name.focus=(mapování vzorového objektu) AssignmentEditorPanel.name.noTarget=(žádný cíl) AssignmentEditorPanel.orgRef=Org. jednotka/Projekt AssignmentEditorPanel.relation.notSpecified="Nespecifikováno" -AssignmentEditorPanel.relation=Vazba +AssignmentEditorPanel.relation=Vztah AssignmentEditorPanel.resource=Připojená aplikace AssignmentEditorPanel.showEmpty=Zobrazit prázdné AssignmentEditorPanel.showMore=Zobrazít více AssignmentEditorPanel.targetError=Cíl přiřazení nebyl nalezen. Cílové OID je chybné nebo neexistuje cílový objekt. AssignmentEditorPanel.target=Cíl -AssignmentEditorPanel.tenantRef=Partaj +AssignmentEditorPanel.tenantRef=Klient AssignmentEditorPanel.undefined=Nedefinováno AssignmentEditorPanel.metadataBlock={0} Metadata AssignmentActivationPopupPanel.title=Aktivace @@ -95,7 +95,7 @@ AssignmentPreviewDialog.column.intent=Záměr AssignmentPreviewDialog.column.kind=Druh AssignmentPreviewDialog.column.name=Název AssignmentPreviewDialog.column.orgRef=Organizace -AssignmentPreviewDialog.column.tenant=Partaj +AssignmentPreviewDialog.column.tenant=Klient AssignmentPreviewDialog.label=Zobrazit přímá i nepřímá přiřazení AssignmentPreviewDialog.delegationPreviewLabel=Omezit výsady AssignmentPreviewDialog.type.direct=Přímé @@ -159,13 +159,11 @@ CapabilityStep.activation.tooltip.attributeName=Název atributu, který obsahuje CapabilityStep.activation.tooltip.disableList=Seznam hodnot atributů, které představují stav "zakázáno". Pokud některá z těchto hodnot se bude vyskytovat v atributu, potom objekt bude považován ve stavu "zakázáno". Typické hodnoty jsou "false", "disabled", "0" nebo prázdná hodnota. CapabilityStep.activation.tooltip.enabled=Pravda, pokud tato schopnost je aktivní. Nepravda, pokud je je schopnost zakázána. Zakázaná schopnost znamená to samé, jako kdyby nebyla vůbec nastavena. Schopnosti mohou být zakázány například z důvodu obejití chyby na konektoru, z důvodu přepnutí aplikace do režimu čtení, a podobně. CapabilityStep.activation.tooltip.enableList=Seznam hodnot atributů, které představují stav "povoleno". Pokud některá z těchto hodnot se bude v atributu vyskytovat, potom objekt bude považován ve stavu "povoleno". Typické hodnoty jsou "true", "enabled", "1" a podobně. -CapabilityStep.activation.tooltip.ignoreAttribute=Pokud je povoleno, pak atribut, který je použit pro simulovanou aktivaci, bude ve schématu označen jako ignorovaný. To znamená, že systém bude předpokládat, že takový atribut neexistuje, a použije pouze standardní atribut administrativeStatus. Toto je výchozí nastavení. -Pokud není povoleno, potom atribut bude ve schématu viditelný a jak atribut administrativeStatus, tak původní atribut bude fungovat. Toto je třeba v případě, že atribut má bohatší sadu statusů, než atribut administrativeStatus. V takovém případě je však dobré se vyvarovat konfliktů mezi atributem administrativeStatus a původním atributem. +CapabilityStep.activation.tooltip.ignoreAttribute=Pokud je povoleno, pak atribut, který je použit pro simulovanou aktivaci, bude ve schématu označen jako ignorovaný. To znamená, že systém bude předpokládat, že takový atribut neexistuje, a použije pouze standardní atribut administrativeStatus. Toto je výchozí nastavení.\nPokud není povoleno, potom atribut bude ve schématu viditelný a jak atribut administrativeStatus, tak původní atribut bude fungovat. Toto je třeba v případě, že atribut má bohatší sadu statusů, než atribut administrativeStatus. V takovém případě je však dobré se vyvarovat konfliktů mezi atributem administrativeStatus a původním atributem. CapabilityStep.activation.tooltip.lockoutAttributeName=Název atributu, který obsahuje hodnotu simulovaného atributu lockoutStatus. Toto je obvykle atribut, který obsahuje nějaký druh informace typu obvyklý/zamknutý. CapabilityStep.activation.tooltip.lockoutNormalList=Seznam hodnot atributů, které představují stav "obvyklý". Pokud některá z těchto hodnot se bude v atributu vyskytovat, potom objekt bude považován za v běžném stavu. CapabilityStep.activation.tooltip.lockoutLockedList=Seznam hodnot atributů, které představují stav "zamknutý". Pokud některá z těchto hodnot se bude v atributu vyskytovat, potom objekt bude považován za v uzamknutém stavu. -CapabilityStep.activation.tooltip.lockoutIgnoreAttribute=Pokud je zapnuto, pak atribut, který je použit pro simulovanou aktivaci, bude ve schématu označen jako ignorovaný. To znamená, že systém bude předpokládat, že takový atribut neexistuje, a použije pouze standardní atribut lockoutStatus. Toto je výchozí nastavení. -Pokud není zapnuto, potom atribut bude ve schématu viditelný a jak atribut lockoutStatus, tak původní atribut bude fungovat. Toto je třeba v případě, že atribut má bohatší sadu statusů, než atribut administrativeStatus. V takovém případě je však dobré se vyvarovat konfliktů mezi atributem lockoutStatus a původním atributem. +CapabilityStep.activation.tooltip.lockoutIgnoreAttribute=Pokud je zapnuto, pak atribut, který je použit pro simulovanou aktivaci, bude ve schématu označen jako ignorovaný. To znamená, že systém bude předpokládat, že takový atribut neexistuje, a použije pouze standardní atribut lockoutStatus. Toto je výchozí nastavení.\nPokud není zapnuto, potom atribut bude ve schématu viditelný a jak atribut lockoutStatus, tak původní atribut bude fungovat. Toto je třeba v případě, že atribut má bohatší sadu statusů, než atribut administrativeStatus. V takovém případě je však dobré se vyvarovat konfliktů mezi atributem lockoutStatus a původním atributem. CapabilityStep.activation.tooltip.returnedByDefault=Pokud je povoleno, potom aktivační atribut je vrácen rovnou spolu s objekty aplikace a není třeba o něj žádat zvlášť. Pokud není povoleno, potom aktivační atribut musí být zvlášť vyžádán. CapabilityStep.activation.tooltip.validFromEnabled=Pravda, pokud aplikace podporuje aktivační vlastnost validFrom. CapabilityStep.activation.tooltip.validFromReturned=Pravda, pokud aktivační vlastnost validFrom je rovnou vrácena. Nepravda, pokud musí být výslovně vyžádána. @@ -181,17 +179,14 @@ CapabilityStep.capability.script.tooltip=Schopnost spustit skripty na konektoru CapabilityStep.capability.testConnection.tooltip=Schopnost provádět test spojení s aplikací. CapabilityStep.capability.update.tooltip=Schopnost aktualizovat (modifikovat) existující objekty v aplikaci. CapabilityStep.configured=Konfigurováno -CapabilityStep.credentials.tooltip.enabled=Pravda, pokud je tato schopnost aktivní. Nepravda, pokud je zakázaná. -Zakázaná schopnost se chová stejně, jako by nebyla vůbec nadefinována. Schopnosti jsou zakázané například z důvodu obejití chyby konektoru, zakázání zápisů do aplikace a podobně. +CapabilityStep.credentials.tooltip.enabled=Pravda, pokud je tato schopnost aktivní. Nepravda, pokud je zakázaná. \nZakázaná schopnost se chová stejně, jako by nebyla vůbec nadefinována. Schopnosti jsou zakázané například z důvodu obejití chyby konektoru, zakázání zápisů do aplikace a podobně. CapabilityStep.credentials.tooltip.passEnabled=Pravda, pokud aplikace podporuje hesla. CapabilityStep.credentials.tooltip.passReturned=Pravda, pokud heslo je rovnou vráceno. Nepravda, pokud musí být výslovně vyžádáno. CapabilityStep.message.cantLoadCaps=Nepodařilo se načíst schopnosti CapabilityStep.native=Nativní CapabilityStep.script.tooltip.enabled=Pravda, pokud tato schopnost je aktivní. Nepravda, pokud je je schopnost zakázána. Zakázaná schopnost znamená to sané, jako kdyby nebyla vůbec nastavena. Schopnosti mohou být zakázány například z důvodu obejití chyby na konektoru, z důvodu přepnutí aplikace do režimu čtení, a podobně. -CapabilityStep.script.tooltip.onConnector=Schopnost spustit skripty na konektoru. -To znamená, že skripty budou spouštěny na serveru, kde je konektor nainstalován. To je obvykle systémový úzel nebo konektorový server. -CapabilityStep.script.tooltip.onResource=Schopnost spouštět skripty na aplikaci. -To znamená, že skripty budou spouštěny na serveru, ke kterému se konektor připojuje. To je obvykle server, který hostí aplikaci (Active Directory server, vzdálený Unixový stroj, databázový server a podobně). +CapabilityStep.script.tooltip.onConnector=Schopnost spustit skripty na konektoru. \nTo znamená, že skripty budou spouštěny na serveru, kde je konektor nainstalován. To je obvykle systémový úzel nebo konektorový server. +CapabilityStep.script.tooltip.onResource=Schopnost spouštět skripty na aplikaci. \nTo znamená, že skripty budou spouštěny na serveru, ke kterému se konektor připojuje. To je obvykle server, který hostí aplikaci (Active Directory server, vzdálený Unixový stroj, databázový server a podobně). CapabilityStep.title=Schopnosti capabilityValuePanel.label.capability.create=Schopnost vytvářet capabilityValuePanel.label.capability.delete=Schopnost mazat @@ -222,7 +217,7 @@ chooseTypeDialog.button.cancel=Zrušit chooseTypeDialog.column.name=Název chooseTypeDialog.message.queryError=Chyba při překladu vyhledávacího dotazu do filtru. chooseTypeDialog.title=Vybrat objekt -chooseTypePanel.ObjectNameValue.badOid=(partaj nenalezena) +chooseTypePanel.ObjectNameValue.badOid=(klient nenalezen) chooseTypePanel.ObjectNameValue.null=Žádný com.evolveum.midpoint.notifications.api.transports.MailTransport.send=Poslat e-mail (Notifications) com.evolveum.midpoint.notifications.api.transports.SimpleSmsTransport.send=Poslat SMS (Notifications) @@ -1232,8 +1227,7 @@ PageRepositoryQuery.sample.UserType_UsersThatHaveARole=Uživatelé s aktivním p PageRepositoryQuery.sample.UserType_SpecifiedCostCenters=Uživatelé v nákladových střediscích 100000 až 999999 nebo X100 až X999 PageRepositoryQuery.sample.ShadowType_ShadowsOnGivenResource=Stínové účty nad danou aplikací PageRepositoryQuery.sample.UserType_UsersWithShadowOnGivenResource=Uživatelé s navázaným stínovým účtem na dané aplikaci -PageRepositoryQuery.queryVsFilterNote=Poznámka: Systémové dotazy obvykle obsahují filtr a stránkovací příkazy, obalené elementem . Když je však tento dotaz použit v Identity Manageru ve volbě "Rozšířený filtr", je použit jen pod-element -O stránkování se stará grafické rozhraní samo. +PageRepositoryQuery.queryVsFilterNote=Poznámka: Systémové dotazy obvykle obsahují filtr a stránkovací příkazy, obalené elementem . Když je však tento dotaz použit v Identity Manageru ve volbě "Rozšířený filtr", je použit jen pod-element \nO stránkování se stará grafické rozhraní samo. PageCert.ago=před {0} PageCertCampaign.basic=Základní PageCertCampaign.button.back=Zpět @@ -1402,8 +1396,8 @@ PageCert.message.textIntent=Záměr: {0}. PageCert.message.textKind=Druh: {0}. PageCert.message.textOrder=Pořadí: {0}. PageCert.message.textOrg=Organizace: {0}. -PageCert.message.textRelation=Vazba: {0}. -PageCert.message.textTenant=Partaj: {0}. +PageCert.message.textRelation=Vztah: {0}. +PageCert.message.textTenant=Klient: {0}. PageCert.message.textValidFrom=Platný od: {0}. PageCert.message.textValidTo=Platný do: {0}. PageCert.now=Nyní @@ -1890,7 +1884,7 @@ pageResource.version=Verze PageResourceWizard.title=Nová aplikace PageResourceWizard.title.edit=Upravit aplikaci '{0}' pageRole.members=Členové -pageRole.governance=Dozor +pageRole.governance=Dohled PageRoleEditor.extension=Rozšířené PageRoleEditor.label.approverRef=Schvalovatel PageRoleEditor.label.approverRef.placeholder=Nastavit schvalovatele @@ -2266,7 +2260,7 @@ MultipleAssignmentSelectorPanel.availableRoles=Dostupné role MultipleAssignmentSelectorPanel.parameters=Parametry MultipleAssignmentSelectorPanel.currentRoles=Přiřazené role MultipleAssignmentSelector.filterByUser=Filtrovat dle uživatele -MultipleAssignmentSelector.tenant=Partaj +MultipleAssignmentSelector.tenant=Klient MultipleAssignmentSelector.orgUnit=Org. jednotka pageValuePolicies.table.description=Popis pageValuePolicies.button.delete=Smazat @@ -2378,7 +2372,7 @@ PrismObjectPanel.maximize=Maximalizovat PrismObjectPanel.minimize=Minimalizovat PrismObjectPanel.protectedAccount=Chráněný účet PrismObjectPanel.showEmpty=Zobrazit prázdné položky -PrismObjectPanel.sortProperties=Vlastnosti třídění +PrismObjectPanel.sortProperties=Seřazení vlastností PrismObjectPanel.showMetadata=Zobrazit metadata PrismObjectPanel.hideMetadata=Skrýt metadata prismOptionButtonPanel.hideEmpty=Skrýt prázdné položky @@ -2553,19 +2547,11 @@ ResourceWizard.expression.tooltip.language=Programovací jazyk, ve ktrerém je s ResourceWizard.expression.tooltip.policyRef=Odkaz na objekt politiky výrazu. Uvedená politika výrazu bude použita jako šablona pro vygenerování hodnoty. ResourceWizard.expression.tooltip.type=Typ výrazu. Toto určuje, zda je výraz skript, generátor hodnoty či něco jiného. ResourceWizard.help.capabilityStep=

To, co je aplikace umí, popisují její schopnosti. Ne všechny aplikace jsou si rovny ve svých schopnostech. Například, jedna aplikace může podporovat aktivaci účtu (povolení a zakázání účtu), zatímco druhá ne. A zatímco jedna aplikace může poskytovat přístup pro čtení i zápis, druhá může být v režimu jen pro čtení. Nebo může být rozdíl v tom, jak která aplikace podporuje synchronizaci v reálném čase. Možností je více. Schopnosti popisují, které vlastnosti aplikace podporuje, takže se k ní může systém odpovídajícně chovat.

Všechny schopnosti mohou být zakázané (tj. vypnuté). Zakázání schopnosti způsobí, že systém nebude používat tuto část konektoru nebo aplikace. Schopnosti jsou obvykle zakázány v případě, že jsou chybové. Například, pokud je chyba v konektoru nebo na aplikaci, pak je možné ji obejít tím, že příslušná schopnosti je zakázaná. Schopnosti však mohou být vypnuté i z administrativních důvodů. Například zakázáním schopností Vytvořit, Aktualizovat and Smazat se aplikace efektivně přepne do režimu pouze ke čtení.

Některé schopnosti mohou být simulovány. To znamená, že systém bude předstírat, že aplikace danou schopnost má, ačkoli tomu tak není. Například schopnost activation může být simulována nastavením specifického atributu účtu. Takto simulovaná schopnost obvykle vyžaduje dodatečnou konfiguraci. Ta je dostupná na této stránce.

Více informací je k dispozici na wiki stránce Resource Capabilities (anglicky).

-ResourceWizard.help.configurationStep=

Tato fáze průvodce konfiguruje vlastnosti konfigurace konektoru. Tyto vlastnosti obvykle určují síťové parametry použité pro přístup k aplikaci, jako je název hostitele a čísla portů. Dalšími síťovými parametry, které zde mohou být konfigurovány, jsou například časové limity pro síťové operace a konfigurace fondu spojení.

-

vlastnosti konfigurace konektoru jsou unikátní pro každý konektor. Specifická sada konfiguračních vlastností je určena systémem dle konfiguračního schématu konektoru. Proto tedy obsah této stránky odvisí od typu konektoru, který byl zvolen.

+ResourceWizard.help.configurationStep=

Tato fáze průvodce konfiguruje vlastnosti konfigurace konektoru. Tyto vlastnosti obvykle určují síťové parametry použité pro přístup k aplikaci, jako je název hostitele a čísla portů. Dalšími síťovými parametry, které zde mohou být konfigurovány, jsou například časové limity pro síťové operace a konfigurace fondu spojení.

\n

vlastnosti konfigurace konektoru jsou unikátní pro každý konektor. Specifická sada konfiguračních vlastností je určena systémem dle konfiguračního schématu konektoru. Proto tedy obsah této stránky odvisí od typu konektoru, který byl zvolen.

ResourceWizard.help.nameStep=

Tato fáze konfiguračního průvodce konfiguruje základní vlastnosti připojované aplikace. Lze zde konfigurovat název a popis aplikace. Název konektoru je povinný, a musí být unikátní. Konektor, který bude použit pro připojení k aplikaci, musí být taktéž nakonfigurován. Konektory se rozmísťují na hostitele konektorů. Pokud konektorový hostitel není vyplněn, potom jsou použity konektory rozmístěné přímo na instanci Identity manageru.

Detailní popis konfigurace aplikace je k k dispozici na wiki stránce Resource Configuration (anglicky).

-ResourceWizard.help.schemaHandlingStep=

Tento krok se používá ke konfiguraci zpracování schématu aplikace. Konfigurace, která je zobrazena na této stránce, říká systému co dělat s atributy a třídami objektů aplikace. Obsahuje konfiguraci mapování mezi užívatelskými vlastnostmi a atributy účtu, konfiguraci typů účtu, skupin, závislostí provisioningu, mapování hesel a podobně.

-

Tato konfigurace je seskupena do typů objektů. Každý typ objektu definuje chování specifického typu účtu, typu nároku druh a záměr.

-

Druh definuje, jakým druhem objekt je:

  • kind=account znamená, že objekt je účet, tj., že představuje uživatele.
  • kind=entitlement je aplikován na skupiny, role, privilegia, ACI a podobné objekty, které mohou být asociovány s účty a které dávají účtu privilegia nebo práva k přístupu.
  • kind=generic se aplikuje na ostatní objekty, jako jsou organizační jednotky (OU), domény a podobně.
-Záměr je prostý řetězec, který může být použit pro rozlišení různých typů objektů. Například může být použit pro odlišení některých typů účtů, jako je "výchozí uživatelský účet", "administrativní účet", "testovací účet" a podobně. Více informací je k dispozici na wiki stránce Kind, Intent and ObjectClass (anglicky).

-

Podrobnější popis konfigurace zpracování schematu je k dispozici na wiki stránce Resource Schema Handling (anglicky). -ResourceWizard.help.schemaStep=

Tato stránka zobrazuje schéma aplikace. Schéma aplikace definuje třídy objektů, které umí konektor spravovat, například účty, skupiny, organizační jednotky a podobně. Schéma definuje pro každou třídu objektu sadu atributů. Schema je zde zobrazeno jen k náhledu, abyste jej mohli prozkoumat a seznámit se s datovým modelem, který aplikace poskytuje.

-

Schéma aplikace předložené na této stránce je obvykle získáno z aplikace a automaticky vygenerováno systémem. Schéma aplikace popisuje to, co aplikace může dělat, které třídy objektů definuje a jaké atributy jsou použity v třídách objektů. Proto je schéma pouze k náhledu. Toto není konfigurace. Schéma nedefinuje, jak Identity Manager používá objektové třídy a atributy. Toto se defnujr v dalším kroku tohoto průvodce.

-

Podrobnější vysvětlení konceptu schématu aplikace je k dispozici na wiki stránce Resource Schema (anglicky).

-ResourceWizard.help.synchronizationStep=

Konfigurace synchronizace definuje, co Identity Manager udělá, když rozpozná, že objekt v aplikaci se změnil. Konfigurace například popisuje, jak systém reaguje na nový účet, když rozpozná, že skupina, která by měla existovat, neexistuje, a podobně. Obvykle nezáleží na způsobu, jak byla změna objevena, reakce je obvykle stejná (ačkoli výjimky jsou možné specifikováním kanálu). Proto politika nakonfigurovaná zde, obvykle platí pro živou synchronizaci, rekonciliaci, import, prozkoumávání (mechanismus konzistence) a další možné mechanismy, které mohou být v budoucnu implementovány.

-

Více podrobností je k dispozici na wiki stránce Synchronization Configuration (anglicky). +ResourceWizard.help.schemaHandlingStep=

Tento krok se používá ke konfiguraci zpracování schématu aplikace. Konfigurace, která je zobrazena na této stránce, říká systému co dělat s atributy a třídami objektů aplikace. Obsahuje konfiguraci mapování mezi užívatelskými vlastnostmi a atributy účtu, konfiguraci typů účtu, skupin, závislostí provisioningu, mapování hesel a podobně.

\n

Tato konfigurace je seskupena do typů objektů. Každý typ objektu definuje chování specifického typu účtu, typu nároku druh a záměr.

\n

Druh definuje, jakým druhem objekt je:

  • kind=account znamená, že objekt je účet, tj., že představuje uživatele.
  • kind=entitlement je aplikován na skupiny, role, privilegia, ACI a podobné objekty, které mohou být asociovány s účty a které dávají účtu privilegia nebo práva k přístupu.
  • kind=generic se aplikuje na ostatní objekty, jako jsou organizační jednotky (OU), domény a podobně.
\nZáměr je prostý řetězec, který může být použit pro rozlišení různých typů objektů. Například může být použit pro odlišení některých typů účtů, jako je "výchozí uživatelský účet", "administrativní účet", "testovací účet" a podobně. Více informací je k dispozici na wiki stránce Kind, Intent and ObjectClass (anglicky).

\n

Podrobnější popis konfigurace zpracování schematu je k dispozici na wiki stránce Resource Schema Handling (anglicky). +ResourceWizard.help.schemaStep=

Tato stránka zobrazuje schéma aplikace. Schéma aplikace definuje třídy objektů, které umí konektor spravovat, například účty, skupiny, organizační jednotky a podobně. Schéma definuje pro každou třídu objektu sadu atributů. Schema je zde zobrazeno jen k náhledu, abyste jej mohli prozkoumat a seznámit se s datovým modelem, který aplikace poskytuje.

\n

Schéma aplikace předložené na této stránce je obvykle získáno z aplikace a automaticky vygenerováno systémem. Schéma aplikace popisuje to, co aplikace může dělat, které třídy objektů definuje a jaké atributy jsou použity v třídách objektů. Proto je schéma pouze k náhledu. Toto není konfigurace. Schéma nedefinuje, jak Identity Manager používá objektové třídy a atributy. Toto se defnujr v dalším kroku tohoto průvodce.

\n

Podrobnější vysvětlení konceptu schématu aplikace je k dispozici na wiki stránce Resource Schema (anglicky).

+ResourceWizard.help.synchronizationStep=

Konfigurace synchronizace definuje, co Identity Manager udělá, když rozpozná, že objekt v aplikaci se změnil. Konfigurace například popisuje, jak systém reaguje na nový účet, když rozpozná, že skupina, která by měla existovat, neexistuje, a podobně. Obvykle nezáleží na způsobu, jak byla změna objevena, reakce je obvykle stejná (ačkoli výjimky jsou možné specifikováním kanálu). Proto politika nakonfigurovaná zde, obvykle platí pro živou synchronizaci, rekonciliaci, import, prozkoumávání (mechanismus konzistence) a další možné mechanismy, které mohou být v budoucnu implementovány.

\n

Více podrobností je k dispozici na wiki stránce Synchronization Configuration (anglicky). ResourceWizard.saveAndVisualize=Uložit a vizualizovat ResourceWizard.visualize=Vizualizovat runReportPopupContent.button.run=Spustit report @@ -2602,16 +2588,11 @@ SchemaHandlingStep.activation.tooltip.inbound=Příchozí mapování mapuje hodn SchemaHandlingStep.activation.tooltip.outbound=Odchozí mapování mapuje hodnoty z Identity Manageru (obvykle z uživatele) do aplikace (obvykle do účtu). SchemaHandlingStep.association.label.associationName=Název asociace SchemaHandlingStep.association.label.associationNamespace=Jmenný prostor -SchemaHandlingStep.association.tooltip.associationAttribute=Název atributu, který "váže" asociaci. Tj. atribut, který obsahuje identifikátor asociovaného objektu. Obvykle se jedná o atribut jako "member", "groups", "roles" a podobně. -V asociaci subjektu na objekt je toto atribut subjektu (například atribut "groups"). V asociaci objektu na subjekt je toto atribut objektu (například skupinový atribut "members"). +SchemaHandlingStep.association.tooltip.associationAttribute=Název atributu, který "váže" asociaci. Tj. atribut, který obsahuje identifikátor asociovaného objektu. Obvykle se jedná o atribut jako "member", "groups", "roles" a podobně. \nV asociaci subjektu na objekt je toto atribut subjektu (například atribut "groups"). V asociaci objektu na subjekt je toto atribut objektu (například skupinový atribut "members"). SchemaHandlingStep.association.tooltip.associationLocalPart=TODO: SchemaHandlingStep.association.tooltip.associationLocalPart SchemaHandlingStep.association.tooltip.associationNamespace=TODO: SchemaHandlingStep.association.tooltip.associationNamespace -SchemaHandlingStep.association.tooltip.direction=Určuje směr asociace.
-Asociace objektu na subjekt: Objekt (například skupina) má atribut, který obsahuje identifikátor subjektu (například účtu).
-Asociace subjektu na objekt: Subjekt (například účet) má atribut, který obsahuje identifikátor objektu (například skupiny). -SchemaHandlingStep.association.tooltip.explicitRefIntegrity=Výslovná referenční integrita.
-Pokud je vypnuto, potom Identity Manager předpokládá, že aplikace obsahuje referenční integritu. Identity Manager tak například předpokládá, že aplikace automaticky aktualizuje asociační identifikátory, pokud je účet přejmenován a Identity Manager se tedy nemusí o nic starat.
-Pokud je zapnuto, potom Identity Manager dělá výslovnou referenční integritu. V tomto případě Identity Manager výslovně aktualizuje asociační atributy, pokud je účet přejmenován. +SchemaHandlingStep.association.tooltip.direction=Určuje směr asociace.
\nAsociace objektu na subjekt: Objekt (například skupina) má atribut, který obsahuje identifikátor subjektu (například účtu).
\nAsociace subjektu na objekt: Subjekt (například účet) má atribut, který obsahuje identifikátor objektu (například skupiny). +SchemaHandlingStep.association.tooltip.explicitRefIntegrity=Výslovná referenční integrita.
\nPokud je vypnuto, potom Identity Manager předpokládá, že aplikace obsahuje referenční integritu. Identity Manager tak například předpokládá, že aplikace automaticky aktualizuje asociační identifikátory, pokud je účet přejmenován a Identity Manager se tedy nemusí o nic starat.
\nPokud je zapnuto, potom Identity Manager dělá výslovnou referenční integritu. V tomto případě Identity Manager výslovně aktualizuje asociační atributy, pokud je účet přejmenován. SchemaHandlingStep.association.tooltip.intent=Záměr asociace cílového typu objektu. Cílový druh a záměr určuje typ objektu, který je cílem asociace - například skupinu, privilegium, role, a podobně. SchemaHandlingStep.association.tooltip.kind=Druh asociace cílového typu objektu. Obvykle se jedná o "nárok". Cílový druh a záměr určuje typ objektu, který je cílem asociace - například skupinu, privilegium, role, a podobně. SchemaHandlingStep.association.tooltip.valueAttribute=Název atributu, který je zdrojem hodnoty pro asociaci. Hodnota atributu bude načtena a uložena do asociačního atributu aby tak utvořila asociaci. Toto je obvykle atribut, který obsahuje identifikátor nebo jméno účtu, jako jsou "uid", "id", "name" a podobně. V asociaci subjektu na objekt je toto atribut objektu (například skupiny). V asociaci objektu na subjekt je toto atribut subjektu (například účtu). @@ -2690,8 +2671,7 @@ SchemaHandlingStep.protected.tooltip.name=TODO: SchemaHandlingStep.protected.too SchemaHandlingStep.protected.tooltip.uid=TODO: SchemaHandlingStep.protected.tooltip.uid SchemaHandlingStep.title=Zpracování schématu SchemaHandlingStep.tooltip.activation=Popis jak mapovat aktivační stavy (povolený/zakázaný/archivovaný) a data (platnost od a do). -SchemaHandlingStep.tooltip.assignmentPolicyRef=Politika přiřazení popisuje, jak přísně jsou přiřazení vynucována.

    -
  • Žádná - přiřazení nejsou vynucována vůbec
  • Kladná - přiřazení pouze přidávají hodnoty (nikdy neodebírají)
  • Relativní - propagovány jsou jenom změny, stávající hodnoty jsou ponechány nedotčeny
  • Plná - vše je přísně vynuceno (jak změněné, tak stávající hodnoty).
+SchemaHandlingStep.tooltip.assignmentPolicyRef=Politika přiřazení popisuje, jak přísně jsou přiřazení vynucována.
    \n
  • Žádná - přiřazení nejsou vynucována vůbec
  • Kladná - přiřazení pouze přidávají hodnoty (nikdy neodebírají)
  • Relativní - propagovány jsou jenom změny, stávající hodnoty jsou ponechány nedotčeny
  • Plná - vše je přísně vynuceno (jak změněné, tak stávající hodnoty).
SchemaHandlingStep.tooltip.associations=Popis, jak jsou zpracovány asociace nároků. SchemaHandlingStep.tooltip.attributes=Popis, jak jsou zpracovány jednotlivé atributy. Každá definice může obsahovat příchozí/odchozí mapování, omezení atributů, a podobně. SchemaHandlingStep.tooltip.credentials=Popis, jak zpracovat pověření, jako jsou například hesla. @@ -2844,11 +2824,9 @@ SynchronizationStep.message.unsupportedActionFormat=Používáte zastaralý atri SynchronizationStep.reaction.tooltip.action=Výslovná akce. Toto nastavení udává, co systém provede jako reakci na synchronizační událost. SynchronizationStep.reaction.tooltip.channel=Omezení kanálu. Pokud synchronizační situace pochází z tohoto konkrétního kanálu (například živá synchronizace, rekonciliace nebo import), potom bude provedena odpovídající reakce . Jinak je situace ignorována. SynchronizationStep.reaction.tooltip.objectTemplateRef=Šablona objektu, která je použita pro zpracování této konkrétní synchronizační události. Pokud není zvolena žádná šablona objektu, potom bude použita obvyklá výchozí volba. -SynchronizationStep.reaction.tooltip.reconcile=Pokud je zapnuto, potom bude pro tuto synchronizační událost rekonciliační krok vynucen. Atributy budou výslovně získány, pokud nejsou přítomny.
-Pokud je vypnuto, potom bude rekonciliace automatická. V takovém případě se rekonciliace uděje pouze tehdy, pokud budou v synchronizační události atributy přítomny. Pokud atributy přítomny nejsou, nebudou výslovně získávány a reonciliace bude přeskočena. +SynchronizationStep.reaction.tooltip.reconcile=Pokud je zapnuto, potom bude pro tuto synchronizační událost rekonciliační krok vynucen. Atributy budou výslovně získány, pokud nejsou přítomny.
\nPokud je vypnuto, potom bude rekonciliace automatická. V takovém případě se rekonciliace uděje pouze tehdy, pokud budou v synchronizační události atributy přítomny. Pokud atributy přítomny nejsou, nebudou výslovně získávány a reonciliace bude přeskočena. SynchronizationStep.reaction.tooltip.situation=Synchronizační situace. Pokud situace události odpovídá situaci určené zde, potom bude provedena odpovídající reakce . Jinak je situace ignorována. -SynchronizationStep.reaction.tooltip.synchronize=Pokud je zapnuto, potom budou uplatněny obvyklé synchronizační algoritmy (označované jako strojek a projektor), spolu s výslovně uvedenými akcemi níže. Toto je obvyklý případ.
-Pokud je vypnuto, potom budou synchronizační algoritmy přeskočeny a budou vykonány pouze výslovně uvedené akce. +SynchronizationStep.reaction.tooltip.synchronize=Pokud je zapnuto, potom budou uplatněny obvyklé synchronizační algoritmy (označované jako strojek a projektor), spolu s výslovně uvedenými akcemi níže. Toto je obvyklý případ.
\nPokud je vypnuto, potom budou synchronizační algoritmy přeskočeny a budou vykonány pouze výslovně uvedené akce. SynchronizationStep.title=Synchronizace SynchronizationStep.tooltip.condition=Nastavení synchronizace bude uplatněno pouze tehdy, pokud je tato podmínka pravdivá. Podmínka se obvykle používá k třídění objektů stejného druhu podle záměrů. Například podmínka buže rozhodnout, zda uživatelské jméno začíná na "T". Pokud začíná, potom zatřídí uživatele do zámětu "test"; pokud ne, bude mít účet výchozí záměr. SynchronizationStep.tooltip.confirmation=Potvrzující podmínka. Každý výsledek výrazu souvztažnosti bude předán potvrzujícímu výrazu. Pokud potvrzující výraz bude pravdivý, potom objekty budou propojeny. Pokud výraz souvztažnosti definován není, potom jsou všechny objekty, vrácené z dotazu souvztažnosti, automaticky schváleny. Potvrzující výraz může i zatížit aplikaci v rozumné míře, protože je vykonáván až nad objekty, které projdou dotazem na souvztažnost. @@ -2861,8 +2839,7 @@ SynchronizationStep.tooltip.objectClass=Objektová třída, pro kterou tato defi SynchronizationStep.tooltip.objectTemplate=Šablona objektu, která je použita pro zpracování této konkrétní synchronizační události. Pokud není zvolena žádná šablona objektu, potom bude použita obvyklá výchozí volba. SynchronizationStep.tooltip.opportunistic=Pokud je povoleno, potom oportunistická synchronizace (takzvané prozkoumání) bude povoleno během zpracování této události. SynchronizationStep.tooltip.reaction=Určuje, jak systém zareaguje na tuto synchronizační událost. Může být uvedeno více reakcí. Bude vybrána reakce vhodná pro synchronizační situaci události. -SynchronizationStep.tooltip.reconcile=Pokud je zapnuto, potom bude pro tuto synchronizační událost rekonciliační krok vynucen. Atributy budou výslovně získány, pokud nejsou přítomny.
-Pokud je vypnuto, potom bude rekonciliace automatická. V takovém případě se rekonciliace uděje pouze tehdy, pokud budou v synchronizační události atributy přítomny. Pokud atributy přítomny nejsou, nebudou výslovně získávány a reonciliace bude přeskočena. +SynchronizationStep.tooltip.reconcile=Pokud je zapnuto, potom bude pro tuto synchronizační událost rekonciliační krok vynucen. Atributy budou výslovně získány, pokud nejsou přítomny.
\nPokud je vypnuto, potom bude rekonciliace automatická. V takovém případě se rekonciliace uděje pouze tehdy, pokud budou v synchronizační události atributy přítomny. Pokud atributy přítomny nejsou, nebudou výslovně získávány a reonciliace bude přeskočena. SystemConfigPanel.assignmentPolicyEnforcement=Vynucení zásad přiřazení SystemConfigPanel.cleanupPolicy.auditRecords=Interval čištěni auditních záznamů SystemConfigPanel.cleanupPolicy=Zásady vyčištění @@ -3180,18 +3157,18 @@ ChangePasswordPanel.helpInfo=

Tato část dialogu pověření řídí způsob, ChangePasswordPanel.helpPopupTitle=Nápověda pro propagaci hesla PageBase.button.tooltip.clearSearch=Vyčistit mainForm.uploadTooLarge = Nahrávaný soubor musí být menší než ${maxSize}. -mainForm.uploadFailed = Chyba při nahrávání souboru: ${exception.localizedMessage}PageSelfCredentials.couldntResolve=Nepodařilo se kontaktovat aplikaci. +mainForm.uploadFailed = Chyba při nahrávání souboru: ${exception.localizedMessage} PageSelfCredentials.couldntResolve=Nepodařilo se kontaktovat aplikaci. roleMemberPanel.type=Typ: -roleMemberPanel.tenant=Partaj: +roleMemberPanel.tenant=Klient: roleMemberPanel.project=Org. jednotka/Projekt: roleMemberPanel.indirectMembers=Včetně nepřímých členů -roleMemberPanel.allRelations=Zobrazit všechny vazby +roleMemberPanel.allRelations=Zobrazit všechny vztahy roleMemberPanel.menu.createOwner=Vytvořit vlastníka roleMemberPanel.menu.assignOwners=Přiřadit vlastníky roleMemberPanel.menu.createApprover=Vytvořit schvalovatele roleMemberPanel.menu.assignApprovers=Přiřadit schvalovatele -roleMemberPanel.relation=Vazba +roleMemberPanel.relation=Vztah SearchPanel.more=Více... SearchPanel.add=Vložit SearchPanel.close=Zavřít @@ -3382,16 +3359,12 @@ StageDefinitionPanel.notifyWhenNoDecisionHelp=Pokud je zaškrtnuto, je upozorně StageDefinitionPanel.reviewerSpecificationTargetHelp=Výběr ověřitelů na základě přiřazení/dědění vlastníka/schvalovatele cíle. Například lze určit, že vlastník role certifikuje všechna přiřazení "své" role (komukoli). StageDefinitionPanel.reviewerSpecificationObjectHelp=Výběr ověřitelů na základě objektu, ke kterému je něco přiřazeno (či toto něco zdědil). Například lze určit, že vlastník role certifikuje všechna dědění "své" role. StageDefinitionPanel.reviewerUseObjectManagerHelp=Výběr ověřitelů na základě manažerů objektu (typicky uživatele), kteří mají něco přiřazeno či zděděno. Například lze určit, že manažer se používá k certifikaci všech přiřazení pro uživatele ve "své" organizaci. -StageDefinitionPanel.reviewerUseObjectManagerOrgTypeHelp=Vlivy určují manažera uživatele:
Nejprve jsou vzati v potaz všichni manažeři všech organizací, do kterých uživatel patří. Uživatel sám je vyloučen, pokud v takové organizaci je manažerem (a pokud není zvolena volba "Povolit manažerům schvalovat svá vlastní přiřazení").
Pokud je hodnota v tomto poli vyplněna, je použita pro výběr organizací s daným typem - například "funkční" (pokud například v modelu existují "funkční" a "projektové" organizace).
Pokud v tomto není uvedena žádná hodnota, jsou vzaty v potaz všechny organizace.
-Pokud není nalezen žádný vhodný manažer, pokračuje se v nadřazené organizaci (stejného typu, je-li uveden). -StageDefinitionPanel.reviewerUseObjectManagerAllowSelfHelp=Pokud je uživatel manažer v organizaci, může být vybrán jako ověřitel svých vlastních přiřazení? -Ve výchozím nastavení není zvoleno, což znamená, že je hledán manažer na vyšší pozici (viz popis odpovídajícího pole). +StageDefinitionPanel.reviewerUseObjectManagerOrgTypeHelp=Vlivy určují manažera uživatele:
Nejprve jsou vzati v potaz všichni manažeři všech organizací, do kterých uživatel patří. Uživatel sám je vyloučen, pokud v takové organizaci je manažerem (a pokud není zvolena volba "Povolit manažerům schvalovat svá vlastní přiřazení").
Pokud je hodnota v tomto poli vyplněna, je použita pro výběr organizací s daným typem - například "funkční" (pokud například v modelu existují "funkční" a "projektové" organizace).
Pokud v tomto není uvedena žádná hodnota, jsou vzaty v potaz všechny organizace.
\nPokud není nalezen žádný vhodný manažer, pokračuje se v nadřazené organizaci (stejného typu, je-li uveden). +StageDefinitionPanel.reviewerUseObjectManagerAllowSelfHelp=Pokud je uživatel manažer v organizaci, může být vybrán jako ověřitel svých vlastních přiřazení? \nVe výchozím nastavení není zvoleno, což znamená, že je hledán manažer na vyšší pozici (viz popis odpovídajícího pole). StageDefinitionPanel.defaultReviewerRefHelp=Tento ověřitel (ověřitelé) bude použit, pokud podmínce uvedené výše nebude odpovídat žádný ověřitel. StageDefinitionPanel.additionalReviewerRefHelp=Tento ověřitel (ověřitelé) bude použit navíc k ověřitelům. kteří byli vybráni na základě ostatních podmínek. -StageDefinitionPanel.outcomeStrategyHelp=Pokud je vybrán více jak jeden ověřitel, jak mají být kombinovány jejich odpovědi do výsledků této fáze?
-Například, je dostatečné, pokud jeden z nich akceptuje certifikační případ, nebo je třeba, aby akceptovali všichni? Toto pole vybírá odpovídající strategii. -StageDefinitionPanel.outcomeIfNoReviewersHelp=Jaký má být výsledek, pokud nejsou přiřazeni žádní ověřitelé? Toto může nastat například tehdy, pokud je ověřitel definován jako vlastník cílové role, ale daná role nemá žádného vlastníka.
-Poznámka: toto pravidlo nezastupuje případy, kdy ověřitelé přiřazeni sice jsou, ale žádný z nich neodpoví. +StageDefinitionPanel.outcomeStrategyHelp=Pokud je vybrán více jak jeden ověřitel, jak mají být kombinovány jejich odpovědi do výsledků této fáze?
\nNapříklad, je dostatečné, pokud jeden z nich akceptuje certifikační případ, nebo je třeba, aby akceptovali všichni? Toto pole vybírá odpovídající strategii. +StageDefinitionPanel.outcomeIfNoReviewersHelp=Jaký má být výsledek, pokud nejsou přiřazeni žádní ověřitelé? Toto může nastat například tehdy, pokud je ověřitel definován jako vlastník cílové role, ale daná role nemá žádného vlastníka.
\nPoznámka: toto pravidlo nezastupuje případy, kdy ověřitelé přiřazeni sice jsou, ale žádný z nich neodpoví. StageDefinitionPanel.stopReviewOnHelp=Jaký vystup zabrání danému případu, aby postoupil do další fáze certifikace?
Typicky není třeba výchozí hodnotu měnit. Pokud to však je žádoucí, je možné ji změnit přes XML konfiguraci. StageDefinitionPanel.configurationHelpLabel=Pro více informací o konfiguraci certifikační kampaně viz též StageDefinitionPanel.configurationHelpLink=tento dokument @@ -3650,10 +3623,7 @@ PageMergeObjects.warningMessage=Měly by být uvedeny Oid dvou objektů PageSelfRegistration.register=Registrovat PageSelfRegistration.registration.success=Registrace byla úspěšná PageSelfRegistration.registration.error=Registrace selhala, důvod: {0} -PageSelfRegistration.registration.confirm.message=Blahopřejeme!
-
-
-Registrace byla úspěšně dokončena. Pro aktivaci účtu prosím zkontrolujte email a potvrďte registraci. +PageSelfRegistration.registration.confirm.message=Blahopřejeme! \n\n\nRegistrace byla úspěšně dokončena. Pro aktivaci účtu prosím zkontrolujte email a potvrďte registraci. PageRegistrationConfirmation.confirmation.error=Naneštěstí, potvrzení registrace selhalo. Bude pravděpodobně třeba kontaktovat Vašeho správce systému. PageRegistrationConfirmation.continueToLogin=Pokračovat na přihlašovací obrazovku PageRegistrationConfirmation.confirmation.successful=Potvrzení bylo úspěšné @@ -3731,7 +3701,7 @@ AssignmentEditorDto.policyRuleTitle=Pravidlo politiky AssignmentDataTablePanel.targetColumnName=Cíl AssignmentDataTablePanel.validityColumnName=Platnost AssignmentDataTablePanel.organizationColumnName=Organizace -AssignmentDataTablePanel.tenantColumnName=Partaj +AssignmentDataTablePanel.tenantColumnName=Klient AssignmentDataTablePanel.lifecycleColumnName=LifecycleAssignmentsUtil.createAssignmentIconTitleModel(AssignmentDataTablePanel.this, rowModel.getObject().getType()) AssignmentDataTablePanel.activationColumnName=Aktivace AssignmentDataTablePanel.descriptionColumnName=Popis @@ -3753,7 +3723,7 @@ AssignmentType.activation=Aktivace AssignmentType.lifecycleState=Fáze životního cyklu AssignmnetType.accepted=Schváleno AssignmentType.policySituation=Situace politiky -ObjectReferenceType.relation=Vazba +ObjectReferenceType.relation=Vztah FocusType.consents=Souhlasy AbstractAssignmentDetailsPanel.properties=Vlastnosti AssignmentPanel.doneButton=Hotovo @@ -3778,4 +3748,4 @@ AbstractPolicyConstraintType.enforcement=Vynucení ExclusionPolicyConstraintType.targetRef=Cíl ExclusionPolicyConstraintType.policy=Politika ExclusionPolicyConstraintPanel.exclusionTitle=Výlučnost - +comboInput.nullValid=Vyberte jedno z diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_de.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_de.properties index 8971f306d08..ce10bac3283 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_de.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_de.properties @@ -146,8 +146,7 @@ capabilityActivationPanel.list.placeholder=Wert hinzufügen capabilityCredentialsPanel.label=Zugangsdaten konfigurieren capabilityCredentialsPanel.label.enabled=aktiv capabilityCredentialsPanel.label.password=Passwort -capabilityCredentialsPanel.label.returned=Standardmässige Rückkehr - +capabilityCredentialsPanel.label.returned=Standardmässige Rückkehr\n capabilityListRepeater.label.text.placeholder=Sprachen URL capabilityScriptPanel.label.enabled=aktiv capabilityScriptPanel.label.onConnector=Am Connector @@ -3624,7 +3623,7 @@ PageMergeObjects.warningMessage=Zwei Objekt oids sollten spezifiert werden. PageSelfRegistration.register=Registrieren PageSelfRegistration.registration.success=Registrierung war erfolgreich PageSelfRegistration.registration.error=Registrierung fehlgeschlagen: {0} -PageSelfRegistration.registration.confirm.message=Gratulation! \n\n\n Sie wurden erfolgreich Registriert. Zur Aktivierung ihres Accounts sollten Sie eine Email mit erhalten, darin enthalten ein Link zur Bestätigung Ihrer Registrierung. +PageSelfRegistration.registration.confirm.message=Congratulation! \n\n\n You have been successfully registered. To activate your account check your email and confirm your registration. PageRegistrationConfirmation.confirmation.error=Bestätigung Ihrer Registrierung fehlgeschlagen. Bitte Systemadministrator kontaktieren. PageRegistrationConfirmation.continueToLogin=Fahren Sie auf der Login Seite weiter PageRegistrationConfirmation.confirmation.successful=Bestätigung erfolgreich @@ -3749,4 +3748,4 @@ AbstractPolicyConstraintType.enforcement=Zwang ExclusionPolicyConstraintType.targetRef=Zielreferenz ExclusionPolicyConstraintType.policy=Richtlinie ExclusionPolicyConstraintPanel.exclusionTitle=Ausschluss - +comboInput.nullValid=Choose one diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties index 69893922eef..1feeece91ae 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties @@ -3748,4 +3748,4 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Policy ExclusionPolicyConstraintPanel.exclusionTitle=Exclusion - +comboInput.nullValid=Choose one diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_es.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_es.properties index 21e481b19f6..a16660a4083 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_es.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_es.properties @@ -3748,4 +3748,4 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Policy ExclusionPolicyConstraintPanel.exclusionTitle=Exclusion - +comboInput.nullValid=Choose one diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_et.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_et.properties index 307287ad82f..e0567deaf43 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_et.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_et.properties @@ -3623,7 +3623,7 @@ PageMergeObjects.warningMessage=Määratlema peab kahe objekti oid-d PageSelfRegistration.register=Registreeru PageSelfRegistration.registration.success=Registreerumine oli edukas PageSelfRegistration.registration.error=Registreerumine nurjus : {0} -PageSelfRegistration.registration.confirm.message=Õnnitlused! \n\n\n Oled edukalt registreerunud. Enda konto aktiveerimiseks kontrolli oma elektronposti ja kinnita oma registreerumine. +PageSelfRegistration.registration.confirm.message=Congratulation! \n\n\n You have been successfully registered. To activate your account check your email and confirm your registration. PageRegistrationConfirmation.confirmation.error=Sinu registreerumise kinnitamine nurjus. Meil on kahju, kuid sa peaksid tõenäoliselt võtma ühendust süsteemiadministraatoriga. PageRegistrationConfirmation.continueToLogin=Mine edasi sisselogimislehele PageRegistrationConfirmation.confirmation.successful=Kinnitamine oli edukas @@ -3748,4 +3748,4 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Poliitika ExclusionPolicyConstraintPanel.exclusionTitle=Välistus - +comboInput.nullValid=Choose one diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_fi.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_fi.properties index c6b1d7b9942..43c67be6ae9 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_fi.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_fi.properties @@ -3623,7 +3623,7 @@ PageMergeObjects.warningMessage=Kaksi objektien OIDia pitäisi tarkentaa PageSelfRegistration.register=Rekisteröi PageSelfRegistration.registration.success=Rekisteröinti onnistui PageSelfRegistration.registration.error=Rekisteröinti epäonnistui: {0} -PageSelfRegistration.registration.confirm.message=Onnea! \n\n\n Teidät on onnistuneesti reksteröity. Aktivoidaksenne tilinne tarkistakaa sähköpostinne ja vahvistakaa rekistöintinne. +PageSelfRegistration.registration.confirm.message=Congratulation! \n\n\n You have been successfully registered. To activate your account check your email and confirm your registration. PageRegistrationConfirmation.confirmation.error=Rekisteröintinne varmistaminen epäonnistui. Olemme pahoillamme, mutta joutunette ottamaan yhteyttä järjestelmänvalvojaan. PageRegistrationConfirmation.continueToLogin=Jatka sisäänkirjautumis sivulle PageRegistrationConfirmation.confirmation.successful=Vahvistus onnistui @@ -3748,4 +3748,4 @@ AbstractPolicyConstraintType.enforcement=Valvonta ExclusionPolicyConstraintType.targetRef=Kohde viittaus ExclusionPolicyConstraintType.policy=Linjaus ExclusionPolicyConstraintPanel.exclusionTitle=Poissulku - +comboInput.nullValid=Choose one diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_hu.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_hu.properties index f667df804a7..14b724c7248 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_hu.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_hu.properties @@ -3748,4 +3748,4 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Policy ExclusionPolicyConstraintPanel.exclusionTitle=Exclusion - +comboInput.nullValid=Choose one diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_pl.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_pl.properties index 480a8d4c42f..6e99ea9ed72 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_pl.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_pl.properties @@ -3623,7 +3623,7 @@ PageMergeObjects.warningMessage=Powinny być podane dwa identyfikatory oid obiek PageSelfRegistration.register=Zarejestruj PageSelfRegistration.registration.success=Rejestracja zakończona powodzeniem PageSelfRegistration.registration.error=Rejestracja nieudana : {0} -PageSelfRegistration.registration.confirm.message=Gratulacje! \n\n\n Twoja rejestracja przebiegła pomyślnie. Aby aktywować swoje konto sprawdź pocztę e-mail i potwierdź rejestrację. +PageSelfRegistration.registration.confirm.message=Gratulacje!\n\n\nZostałeś poprawnie zarejestrowany. Aby aktywować swoje konto sprawdź pocztę i potwierdź rejestrację. PageRegistrationConfirmation.confirmation.error=Nie udało się potwierdzić rejestracji. Proszę o kontakt z administratorem systemu. PageRegistrationConfirmation.continueToLogin=Przejdź do strony logowania PageRegistrationConfirmation.confirmation.successful=Potwierdzenie zakończone pomyślnie @@ -3748,4 +3748,4 @@ AbstractPolicyConstraintType.enforcement=Wymuszenie ExclusionPolicyConstraintType.targetRef=Odniesienie do celu ExclusionPolicyConstraintType.policy=Polityka ExclusionPolicyConstraintPanel.exclusionTitle=Wykluczenie - +comboInput.nullValid=Wybierz diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_pt_BR.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_pt_BR.properties index c9dec8c86ba..1a742449737 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_pt_BR.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_pt_BR.properties @@ -623,8 +623,7 @@ objectSyncConfig.editorObjectTemplate.nullValid=Escolher Um objectTemplateRef.nullValid=Escolher Um ObjectTypeGuiDescriptor.abstractRole=Perfil abstrato ObjectTypeGuiDescriptor.accessCertificationCampaign=Acessar campanha de certificação -ObjectTypeGuiDescriptor.accessCertificationDefinition=Access certification campaign - +ObjectTypeGuiDescriptor.accessCertificationDefinition=Access certification campaign\n ObjectTypeGuiDescriptor.account=Conta ObjectTypeGuiDescriptor.connector=Conector ObjectTypeGuiDescriptor.connectorHost=Host do conector @@ -905,8 +904,7 @@ operation.linkShadow=Listar conta (Modelo) operation.org.identityconnectors.framework.api.ConnectorFacade.addAttributeValues=Incluir valores de atributo (Icf) operation.org.identityconnectors.framework.api.ConnectorFacade.create=Criar (Icf) operation.org.identityconnectors.framework.api.ConnectorFacade.delete=Deletar objeto (ICF) -operation.org.identityconnectors.framework.api.ConnectorFacade.getObject= - +operation.org.identityconnectors.framework.api.ConnectorFacade.getObject=\n operation.org.identityconnectors.framework.api.ConnectorFacade.schema=Esquema ICF operation.org.identityconnectors.framework.api.ConnectorFacade.update=Atualizar (Icf) operation.com.evolveum.midpoint.web.component.wizard.resource.NameStep.saveResource=Salvar informação básica de recurso @@ -965,8 +963,7 @@ PageAbout.button.testRepository=Auto-teste de repositório PageAbout.message.couldntObtainJvmParams=Não foi possível obter parâmetro JVM de JMX. PageAbout.midPointRevision=${git.describe} PageAbout.builtAt=Gerar em -PageAbout.build=${timestamp} - +PageAbout.build=${timestamp}\n PageAbout.midPointRevisionTitle=Git descrever PageAbout.midPointVersion=${pom.version} PageAbout.midPointVersionTitle=Versão @@ -2028,8 +2025,7 @@ pageTaskEdit.oid=OID pageTaskEdit.opResult.message=Mensagem pageTaskEdit.opResult.operation=Operação pageTaskEdit.opResult.status=Status -pageTaskEdit.opResult.token=Token - +pageTaskEdit.opResult.token=Token\n pageTaskEdit.options=Opções pageTaskEdit.parent=Tarefa pai pageTaskEdit.owner=Dono da tarefa @@ -2139,8 +2135,7 @@ pageTask.scheduleValidation.invalidCronSpecification='Cron-like specification' n pageTask.scheduleValidation.neitherIntervalNorCron=Apenas uma de 'Schedule interval' ou 'Cron-like specification' pode ser especificada. pageTask.scheduleValidation.noInterval='Intervalo de agendamento' deve ser especificado. pageTasks.dialog.title.confirmDelete=Confirmar a deleção -pageTasks.inForNotRunningTasks=(em {0}) - +pageTasks.inForNotRunningTasks=(em {0})\n pageTasks.in=em {0} pageTasks.retryIn=tentar em {0} pageTasks.message.alreadyResumed=Tarefa '{0}' não pode ser retomada: já está rodando ou foi finalizada. @@ -3753,4 +3748,4 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Policy ExclusionPolicyConstraintPanel.exclusionTitle=Exclusion - +comboInput.nullValid=Choose one diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_ru.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_ru.properties index 025e442e61a..e11aad2dac6 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_ru.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_ru.properties @@ -3748,4 +3748,4 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Policy ExclusionPolicyConstraintPanel.exclusionTitle=Exclusion - +comboInput.nullValid=Choose one diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_sk.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_sk.properties index d9e48f9aeaf..c1d0229f6db 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_sk.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_sk.properties @@ -52,8 +52,8 @@ AssignmentEditorPanel.name.focus=(mapovanie focusu) AssignmentEditorPanel.name.noTarget=(žiadny cieľ) AssignmentEditorPanel.orgRef=Organizačná jednotka/Projekt AssignmentEditorPanel.relation.notSpecified="Nešpecifikovaný" -AssignmentEditorPanel.relation=Relácia -AssignmentEditorPanel.resource=Zdroj +AssignmentEditorPanel.relation=Vzťah +AssignmentEditorPanel.resource=Koncový systém AssignmentEditorPanel.showEmpty=Zobraziť prázdne AssignmentEditorPanel.showMore=Zobraziť viac AssignmentEditorPanel.targetError=Priradený cieľ nebol nájdený. Buď je oid nesprávne alebo cieľový objekt neexistuje. @@ -61,9 +61,9 @@ AssignmentEditorPanel.target=Cieľ AssignmentEditorPanel.tenantRef=Tenant AssignmentEditorPanel.undefined=Nedefinovaný AssignmentEditorPanel.metadataBlock={0} Metadata -AssignmentActivationPopupPanel.title=Activation +AssignmentActivationPopupPanel.title=Aktivácia AssignmentActivationPopupPanel.okButton=OK -AssignmentActivationPopupPanel.cancelButton=Cancel +AssignmentActivationPopupPanel.cancelButton=Zrušiť MetadataPanel.requestTimestamp=Request timestamp MetadataPanel.requestorRef=Requester MetadataPanel.createTimestamp=Create timestamp @@ -98,8 +98,8 @@ AssignmentPreviewDialog.column.orgRef=Org AssignmentPreviewDialog.column.tenant=Tenant AssignmentPreviewDialog.label=Zobraziť priame & nepriame priradenia AssignmentPreviewDialog.delegationPreviewLabel=Limit privileges -AssignmentPreviewDialog.type.direct=Priamy -AssignmentPreviewDialog.type.indirect=Nepriamy +AssignmentPreviewDialog.type.direct=Priame +AssignmentPreviewDialog.type.indirect=Nepriame AssignmentTablePanel.menu.assign=Priradiť účet AssignmentTablePanel.menu.assignOrg=Priradiť org. AssignmentTablePanel.menu.assignOrg.noorgs=No organization structure defined. @@ -150,14 +150,14 @@ capabilityCredentialsPanel.label.returned=Vrátené v predvolenom nastavení capabilityListRepeater.label.text.placeholder=URL jazyka capabilityScriptPanel.label.enabled=Povolený capabilityScriptPanel.label.onConnector=Pripojenie konektora -capabilityScriptPanel.label.onResource=V zdroji +capabilityScriptPanel.label.onResource=V koncovom systéme capabilityScriptPanel.label=Konfigurácia skriptu CapabilityStep.capabilities=Možnosti CapabilityStep.addCapabilities=Add capabilities CapabilityStep.disabled=(disabled) CapabilityStep.activation.tooltip.attributeName=Meno atribútu, ktorý obsahuje hodnotu pre simulovaný administrativeStatus. To je zvyčajne atribút, ktorý obsahuje nejaký druh povolenej/ zakázanej informácie. Typickými príkladmi sú atribúty, ako je "povolený", "ds-pwp-account-disabled", "accountStatus", etc. CapabilityStep.activation.tooltip.disableList=Zoznam hodnôt atribútov, ktoré predstavujú "zakázaný" stav. Ak niektorá z týchto hodnôt je prítomná v atribúte, potom bude objekt považovaný za zakázaný. Typické hodnoty sú "nepravda", "zakázaný", "0" alebo prázdne hodnoty. -CapabilityStep.activation.tooltip.enabled=Pravda je, pokiaľ táto možnosť je aktívna. Nepravda je, ak je to zakázané. Zakázaný pôsobí rovnakým spôsobom, ako keby tam nebola. Možnosti možno vypnúť napr. chybou konektora, zdroj len na čítanie, atď. +CapabilityStep.activation.tooltip.enabled=Pravda je, pokiaľ táto možnosť je aktívna. Nepravda je, ak je to zakázané. Zakázaný pôsobí rovnakým spôsobom, ako keby tam nebola. Možnosti možno vypnúť napr. chybou konektora, koncový systém len na čítanie, atď. CapabilityStep.activation.tooltip.enableList=Zoznam hodnôt atribútov, ktoré predstavujú "povolený" stav. Ak niektorá z týchto hodnôt je prítomná v atribúte, potom bude objekt považovaný za povolený. Typické hodnoty sú "pravda", "povolený", "1" atď. CapabilityStep.activation.tooltip.ignoreAttribute=If set to true then the attribute which is used for simulated activation will be marked as ignored in the schema. I.e. system will pretend that this attribute does not exist and only use the standard administrativeStatus. This is the default. If set to false then the attribute will also be visible in the schema and both the administrativeStatus and the original attribute will work. This may be needed if the attribute has a richer set of states than the administrativeStatus attribute. But in this case beware of value conflicts between administrativeStatus and the original attribute. CapabilityStep.activation.tooltip.lockoutAttributeName=Name of the attribute that contains a value for simulated lockoutStatus. This is usually an attribute that contains some kind of normal/locked information. @@ -165,28 +165,28 @@ CapabilityStep.activation.tooltip.lockoutNormalList=List of attribute values tha CapabilityStep.activation.tooltip.lockoutLockedList=List of attribute values that represent the "locked" state. If any of these values are present in the attribute then the object will be considered to be in a locked state. CapabilityStep.activation.tooltip.lockoutIgnoreAttribute=If set to true then the attribute which is used for simulated activation will be marked as ignored in the schema. I.e. system will pretend that this attribute does not exist and only use the standard lockoutStatus. This is the default. If set to false then the attribute will also be visible in the schema and both the lockoutStatus and the original attribute will work. This may be needed if the attribute has a richer set of states than the lockoutStatus attribute. But in this case beware of value conflicts between lockoutStatus and the original attribute. CapabilityStep.activation.tooltip.returnedByDefault=Ak je pravda, potom je aktivačný atribút vrátený so zdrojom v predvolenom nastavení a netreba ho požadovať. Ak je nepravda, potom o aktivačný atribút treba požiadať. -CapabilityStep.activation.tooltip.validFromEnabled=Pravda, ak zdroj podporuje validFrom aktivačnú vlastnosť. +CapabilityStep.activation.tooltip.validFromEnabled=Pravda, ak koncový systém podporuje validFrom aktivačnú vlastnosť. CapabilityStep.activation.tooltip.validFromReturned=True if the validFrom property is returned by default. False if it needs to be explicitly requested. -CapabilityStep.activation.tooltip.validToEnabled=Pravda, ak zdroj podporuje validTo aktivačnú vlastnosť. +CapabilityStep.activation.tooltip.validToEnabled=Pravda, ak koncový systém podporuje validTo aktivačnú vlastnosť. CapabilityStep.activation.tooltip.validToReturned=True if the validTo property is returned by default. False if it needs to be explicitly requested. CapabilityStep.capability.activation.tooltip=Možnosť aktivácie . Možnosť povoliť/zakázať účty, nastaviť dobu platnosti atď -CapabilityStep.capability.create.tooltip=Možnosť vytvoriť (pridať) nový objekt do zdroja. -CapabilityStep.capability.credentials.tooltip=Možnosť nastaviť poverenia pre účty zdroja. -CapabilityStep.capability.delete.tooltip=Schopnosť zmazať existujúci objekt zo zdroja. +CapabilityStep.capability.create.tooltip=Možnosť vytvoriť (pridať) nový objekt do koncového systému. +CapabilityStep.capability.credentials.tooltip=Možnosť nastaviť poverenia pre účty koncového systému. +CapabilityStep.capability.delete.tooltip=Schopnosť zmazať existujúci objekt z koncového systému. CapabilityStep.capability.liveSync.tooltip=Schopnosť priamej synchronizácie. Schopnosť účinne priniesť zmeny dát v takmer reálnom čase. -CapabilityStep.capability.read.tooltip=Schopnosť čítať údaje zo zdroja. -CapabilityStep.capability.script.tooltip=Schopnosť vykonať skripty na pripojenom zdroji. -CapabilityStep.capability.testConnection.tooltip=Schopnosť vytestovať spojenie so zdrojom. -CapabilityStep.capability.update.tooltip=Schopnosť aktualizovať (zmeniť) existujúci objekt v zdroji. +CapabilityStep.capability.read.tooltip=Schopnosť čítať údaje z koncového synchronizácie. +CapabilityStep.capability.script.tooltip=Schopnosť vykonať skripty na pripojenom koncovom systéme. +CapabilityStep.capability.testConnection.tooltip=Schopnosť otestovať spojenie s koncovým systémomm. +CapabilityStep.capability.update.tooltip=Schopnosť aktualizovať (zmeniť) existujúci objekt v koncovom systéme. CapabilityStep.configured=Nakonfigurovaný -CapabilityStep.credentials.tooltip.enabled=Pravda je, pokiaľ táto schopnosť je aktívna. Nepravda je, ak je to zakázané. Zakázaný pôsobí rovnakým spôsobom, ako keby tam nebola. Schopnosti možno vypnúť napr. chybou konektora, zdroj len na čítanie, atď. -CapabilityStep.credentials.tooltip.passEnabled=Pravda, ak zdroj podporuje nastavenie hesla. +CapabilityStep.credentials.tooltip.enabled=Pravda je, pokiaľ táto schopnosť je aktívna. Nepravda je, ak je to zakázané. Zakázaný pôsobí rovnakým spôsobom, ako keby tam nebola. Schopnosti možno vypnúť napr. chybou konektora, koncový systém len na čítanie, atď. +CapabilityStep.credentials.tooltip.passEnabled=Pravda, ak koncový systém podporuje nastavenie hesla. CapabilityStep.credentials.tooltip.passReturned=True if the password is returned by default. False if it needs to be explicitly requested. CapabilityStep.message.cantLoadCaps=Nepodarilo sa načítať možnosti CapabilityStep.native=Prirodzený -CapabilityStep.script.tooltip.enabled=Pravda je, pokiaľ táto možnosť je aktívna. Nepravda je, ak je to zakázané. Zakázaný pôsobí rovnakým spôsobom, ako keby tam nebola. Možnosti možno vypnúť napr. chybou konektora, zdroj len na čítanie, atď. +CapabilityStep.script.tooltip.enabled=Pravda je, pokiaľ táto možnosť je aktívna. Nepravda je, ak je to zakázané. Zakázaný pôsobí rovnakým spôsobom, ako keby tam nebola. Možnosti možno vypnúť napr. chybou konektora, koncový systém len na čítanie, atď. CapabilityStep.script.tooltip.onConnector=Capability to execute scripts "on connector". This means that the scripts will be executed on the machine where the connector is installed. This is usually system node or a connector server. -CapabilityStep.script.tooltip.onResource=Možnosť vykonávať skripty "na zdroji". To znamená, že skripty budú vykonané na počítači, na ktorý sa konektor pripojí. To je zvyčajne server, ktorý je hostiteľom zdroja (AD server, vzdialený Unix stroj, databázový server, atď.) +CapabilityStep.script.tooltip.onResource=Možnosť vykonávať skripty "na koncovom systéme". To znamená, že skripty budú vykonané na počítači, na ktorý sa konektor pripojí. To je zvyčajne server, ktorý je hostiteľom koncového systému (AD server, vzdialený Unix stroj, databázový server, atď.) CapabilityStep.title=Možnosti capabilityValuePanel.label.capability.create=Create capability capabilityValuePanel.label.capability.delete=Delete capability @@ -282,7 +282,7 @@ DoubleButtonPanel.download=Stiahnuť DropDownChoicePanel.empty=Vyberte jednu DropDownChoicePanel.notDefined=Nedefinovaný EmptyProcessDetailsPanel.message=Detaily procesu nie sú k dispozícii. -ExecuteChangeOptionsPanel.label.executeAfterAllApprovals=Vykonať po odsúhlasení +ExecuteChangeOptionsPanel.label.executeAfterAllApprovals=Vykonať po ukončení všetkých schvaľovaní ExecuteChangeOptionsPanel.label.force=Vynútiť ExecuteChangeOptionsPanel.label.keepDisplayingResults=Ponechať výsledky zobrazené ExecuteChangeOptionsPanel.label.reconcileAffected=Vykonať rekonciliáciu dotknutých objektov @@ -378,7 +378,7 @@ HandlerUriActions.ACTION_UNLINK_ACCOUNT=Unlink account (deprecated) HandlerUriActions.ACTION_UNLINK=Odpojiť HoursValidator.range=Pole '${label}' musí byť medzi ${minimum} a ${maximum}. ImportOptionsPanel.errorCount=Chybný účet -importOptionsPanel.fetchResourceSchema=Načítať schému zdroja +importOptionsPanel.fetchResourceSchema=Načítať schému koncového systému importOptionsPanel.keepOid=Podržať OID ImportOptionsPanel.options=Voľby importOptionsPanel.overwriteExistingObject=Prepísať existujúci objekt @@ -437,7 +437,7 @@ LimitationsEditorDialog.deny=Zamietnuť LimitationsEditorDialog.inherit=Zdediť LimitationsEditorDialog.label.add=Pridať LimitationsEditorDialog.label.close=Zatvoriť -LimitationsEditorDialog.label=Upraviť obmedzenia zdroja +LimitationsEditorDialog.label=Upraviť obmedzenia koncového systému LimitationsEditorDialog.label.ignore=Ignorovať LimitationsEditorDialog.label.layers=Vrstvy LimitationsEditorDialog.label.maxOccurs=Max. výskyt @@ -561,15 +561,15 @@ MultiplicityPolicyDialog.message.badUpdate=Nie je možné zobraziť konfiguráci MultiplicityPolicyDialog.message.invalidMultiplicity=Neplatná hodnota multiplicity. Nastavte čísla (0, 1, ...), alebo hodnotu "neobmedzený" (použite checkbox) MultiValueField.nameNotSpecified=(Meno nebolo špecifikované) MyAccountsPanel.account.name=Meno -MyAccountsPanel.account.resource=Zdroj +MyAccountsPanel.account.resource=Koncový systém MyAssignmentsPanel.assignment.displayName=Názov -MyAssignmentsPanel.assignment.description=Description +MyAssignmentsPanel.assignment.description=Popis MyAssignmentsPanel.type.accountConstruction=Vytvorenie účtu MyAssignmentsPanel.type.error=Chyba MyAssignmentsPanel.type.orgUnit=Org. jednotka MyAssignmentsPanel.type.role=Rola -MyAssignmentsPanel.type.service=Service -MyAssignmentsPanel.type.user=User +MyAssignmentsPanel.type.service=Služba +MyAssignmentsPanel.type.user=Používateľ MyAssignmentsPanel.type.policyRule=Policy rule NameStep.arrowToTurotialText=Každý krok sprievodcu má tlačidlo nápovedy. Stlačte toto tlačidlo na získanie informácií o ciele konkrétneho kroku konfigurácie. NameStep.connectorBundle=Balík @@ -581,7 +581,7 @@ NameStep.connectorType=Konektor NameStep.connectorVersion=Verzia konektora NameStep.description=Popis NameStep.hostNotUsed=Nepoužíva sa -NameStep.name=Meno zdroja +NameStep.name=Meno koncového systému NameStep.title=Zdroj základy NameStep.undefinedName=Nedefinované meno NameStep.undefinedVersion=Nedefinovaná verzia @@ -638,7 +638,7 @@ ObjectTypeGuiDescriptor.orgManager=Org. manažér ObjectTypeGuiDescriptor.org=Organizácia ObjectTypeGuiDescriptor.reportOutput=Reportovať výstup ObjectTypeGuiDescriptor.report=Report -ObjectTypeGuiDescriptor.resource=Zdroj +ObjectTypeGuiDescriptor.resource=Koncový systém ObjectTypeGuiDescriptor.role=Rola ObjectTypeGuiDescriptor.securityPolicy=Politika zabezpečenia ObjectTypeGuiDescriptor.sequence=Postupnosť @@ -653,7 +653,7 @@ operation.com.evolveum.midpoint.common.crypto.CryptoUtil.securitySelfTest=Test z operation.com.evolveum.midpoint.common.operation.import.object=Importovať objekt operation.com.evolveum.midpoint.common.policy.PasswordPolicyUtils.passwordValidation=Validácia hesla podľa bezpečnostnej politky operation.com.evolveum.midpoint.common.validator.Validator.objectBasicsCheck=Základná kontrola -operation.com.evolveum.midpoint.common.validator.Validator.resourceNamespaceCheck=Kontrola namespacu zdroja +operation.com.evolveum.midpoint.common.validator.Validator.resourceNamespaceCheck=Kontrola namespacu koncového systému operation.com.evolveum.midpoint.common.validator.Validator.validateSchema=Validácia schémy operation.com.evolveum.midpoint.model.api.ModelDiagnosticService.provisioningSelfTest=Auto - test provizií (Model) operation.com.evolveum.midpoint.model.api.ModelDiagnosticService.repositorySelfTest=Auto - test repozitára (Model) @@ -704,7 +704,7 @@ operation.com.evolveum.midpoint.model.controller.SchemaHandler.processPropertyCo operation.com.evolveum.midpoint.model.impl.controller.ModelDiagController.repositorySelfTest.user=Auto - test repozitára, používateľ (Model) operation.com.evolveum.midpoint.model.impl.controller.ModelDiagController.repositorySelfTest.lookupTable=Repository self test, lookup table (Model) operation.com.evolveum.midpoint.model.importer.ImportAccountsFromResourceTaskHandler.launch=Importovať účty zo systému -operation.com.evolveum.midpoint.model.importer.ObjectImporter.checkResourceSchema=Skontrolovať schému zdroja +operation.com.evolveum.midpoint.model.importer.ObjectImporter.checkResourceSchema=Skontrolovať schému koncového systému operation.com.evolveum.midpoint.model.importer.ObjectImporter.encryptValues=Šifrovanie operation.com.evolveum.midpoint.model.importer.ObjectImporter.importObjectToRepository=Uložiť objekt do repozitára operation.com.evolveum.midpoint.model.importer.ObjectImporter.resolveReference=Vyriešiť referenciu @@ -799,7 +799,7 @@ operation.com.evolveum.midpoint.task.quartzimpl.LocalExecutionManager.getLocally operation.com.evolveum.midpoint.task.quartzimpl.TaskManagerQuartzImpl.addTaskToRepositoryAndQuartz=Pridať úlohy do repozitára a Quartz Job Store (Úloha) operation.com.evolveum.midpoint.web.component.assignment.AssignmentEditorPanel.loadAttributes=Načítať atribúty (Gui) operation.com.evolveum.midpoint.web.component.assignment.AssignmentEditorPanel.loadObject=Načítať objekt (Gui) -operation.com.evolveum.midpoint.web.component.assignment.AssignmentEditorPanel.loadResource=Načítať zdroj (Gui) +operation.com.evolveum.midpoint.web.component.assignment.AssignmentEditorPanel.loadResource=Načítať koncový systém (Gui) operation.com.evolveum.midpoint.web.component.orgStruct.BookmarkableFolderContent.loadOrgUnit=Načítať org. jednotku operation.com.evolveum.midpoint.web.component.prism.ContainerWrapper.createProperties=Vytvoriť vlastnosti (Gui) operation.com.evolveum.midpoint.web.component.prism.ObjectWrapper.createContainers=Vytvoriť kontajnery (Gui) @@ -830,16 +830,16 @@ operation.com.evolveum.midpoint.web.page.admin.resources.content.dto.AccountCont operation.com.evolveum.midpoint.web.page.admin.resources.content.PageAccount.saveAccount=Uložiť účty (Gui) operation.com.evolveum.midpoint.web.page.admin.resources.content.PageContentAccounts.changeOwner=Zmeniť vlastníka (Gui) operation.com.evolveum.midpoint.web.page.admin.resources.content.PageContentAccounts.createUserFromAccount=Vytvoriť používateľa z účtu (Gui) -operation.com.evolveum.midpoint.web.page.admin.resources.dto.ResourceDtoProvider.countResources=Spočítať zdroje (Gui) -operation.com.evolveum.midpoint.web.page.admin.resources.dto.ResourceDtoProvider.listResources=Zoznam zdrojov (Gui) -operation.com.evolveum.midpoint.web.page.admin.resources.PageAdminResources.loadResource=Načítať zdroj (Gui) -operation.com.evolveum.midpoint.web.page.admin.resources.PageResourceEdit.saveResource=Uložiť zdroj (Gui) +operation.com.evolveum.midpoint.web.page.admin.resources.dto.ResourceDtoProvider.countResources=Spočítať koncové systémy (Gui) +operation.com.evolveum.midpoint.web.page.admin.resources.dto.ResourceDtoProvider.listResources=Zoznam koncových systémov (Gui) +operation.com.evolveum.midpoint.web.page.admin.resources.PageAdminResources.loadResource=Načítať koncový systém (Gui) +operation.com.evolveum.midpoint.web.page.admin.resources.PageResourceEdit.saveResource=Uložiť koncový systém (Gui) operation.com.evolveum.midpoint.web.page.admin.resources.PageResource.importFromResource=Import zo systému operation.com.evolveum.midpoint.web.page.admin.resources.PageResources.connectorDiscovery=Objaviť konektor (Gui) operation.com.evolveum.midpoint.web.page.admin.resources.PageResources.deleteHosts=Zmazať hosts (Gui) -operation.com.evolveum.midpoint.web.page.admin.resources.PageResources.deleteResources=Zmazať zdroje (Gui) +operation.com.evolveum.midpoint.web.page.admin.resources.PageResources.deleteResources=Zmazať koncové systémy (Gui) operation.com.evolveum.midpoint.web.page.admin.resources.PageResources.syncStatus=Stav synchronizácie (Gui) -operation.com.evolveum.midpoint.web.page.admin.resources.PageResources.testResource=Test zdroja (Gui) +operation.com.evolveum.midpoint.web.page.admin.resources.PageResources.testResource=Test koncového systému (Gui) operation.com.evolveum.midpoint.web.page.admin.roles.PageRole.loadRole=Načítať rolu (Gui) operation.com.evolveum.midpoint.web.page.admin.roles.PageRole.saveRole=Uložiť rolu (Gui) operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.deleteRoles=Zmazať role (Gui) @@ -899,7 +899,7 @@ operation.com.evolveum.midpoint.xml.ns._public.model.model_1_wsdl.ModelPortType. operation.com.evolveum.midpoint.xml.ns._public.model.model_1_wsdl.ModelPortType.listResourceObjects=Model web servisu zoznam zdrojových objektov operation.com.evolveum.midpoint.xml.ns._public.model.model_1_wsdl.ModelPortType.modifyObject=Model web servisu pre modifikáciu objektu operation.com.evolveum.midpoint.xml.ns._public.model.model_1_wsdl.ModelPortType.searchObjects=Model web servisu pre vyhľadávanie objektov -operation.com.evolveum.midpoint.xml.ns._public.model.model_1_wsdl.ModelPortType.testResource=Model web servisu pre testovanie zdrojov +operation.com.evolveum.midpoint.xml.ns._public.model.model_1_wsdl.ModelPortType.testResource=Model web servisu pre testovanie koncových systémov operation.linkShadow=Pripojiť účet (Model) operation.org.identityconnectors.framework.api.ConnectorFacade.addAttributeValues=Pridať hodnoty atribútov (Icf) operation.org.identityconnectors.framework.api.ConnectorFacade.create=Vytvoriť (Icf) @@ -1093,18 +1093,18 @@ PageAdmin.menu.top.workItems.listProcessInstancesRequestedFor=Požiadavky na mň PageAdmin.menu.top.workItems=Pracovné položky pageAdmin.reports.description=Auditné zostavy pageAdmin.reports=Reporty -PageAdmin.menu.top.users.requestAssign=Request Assignment -PageAdminObjectDetails.title.editUserType=Edit user '{0}' -PageAdminObjectDetails.title.newUserType=Create new user -PageAdminObjectDetails.title.editRoleType=Edit role '{0}' -PageAdminObjectDetails.title.newServiceType=Create new service -PageAdminObjectDetails.title.editServiceType=Edit service '{0}' -PageAdminObjectDetails.title.newRoleType=Create new role -PageAdminObjectDetails.title.editOrgType=Edit organization '{0}' -PageAdminObjectDetails.title.newOrgType=Create new organization -PageAdminObjectDetails.noChangesSave=There were no changes to be saved. +PageAdmin.menu.top.users.requestAssign=Žiadosť o priradenie +PageAdminObjectDetails.title.editUserType=Upraviť používateľa '{0}' +PageAdminObjectDetails.title.newUserType=Vytvoriť nového používateľa +PageAdminObjectDetails.title.editRoleType=Upraviť rolu '{0}' +PageAdminObjectDetails.title.newServiceType=Vytvoriť novú službu +PageAdminObjectDetails.title.editServiceType=Upraviť službu '{0}' +PageAdminObjectDetails.title.newRoleType=Vytvoriť novú rolu +PageAdminObjectDetails.title.editOrgType=Upraviť organizáciu '{0}' +PageAdminObjectDetails.title.newOrgType=Vytvoriť novú organizáciu +PageAdminObjectDetails.noChangesSave=Neboli vykonané žiadne zmeny, ktoré by sa dali uložiť. PageAdminObjectDetails.noChangesPreview=There are no changes to be previewed. -pageAdminFocus.basic=Základný +pageAdminFocus.basic=Základné pageAdminFocus.message.cantEditFocus=Unknown error occurred, can't edit focus object. pageAdminFocus.message.cantNewFocus=Unknown error occurred, can't create new focus object. pageAdminFocus.message.illegalAccountState=Neplatný stav tieňa '{0}'. @@ -1489,8 +1489,8 @@ pageCreatedReports.table.type=Typ reportu PageCreatedReports.title=Vytvorené reporty PageDashboard.accounts=Moje účty PageDashboard.activeTasks=Aktívne úlohy -PageDashboard.activeUsers=Aktívny používatelia -PageDashboard.assignments=My assignments +PageDashboard.activeUsers=Aktívni používatelia +PageDashboard.assignments=Moje priradenia PageDashboard.personalInfo=Osobné údaje PageDashboard.serverLoad=Server Load PageDashboard.systemInfo=Stav systému @@ -1795,7 +1795,7 @@ PageReport.title=Konfigurácia reportu PageResource.resource.mappings=Mappings PageResource.resource.source=Zdroj PageResource.resource.target=Cieľ -PageResource.resource.sourceAndTarget=Source and Target +PageResource.resource.sourceAndTarget=Zdroj a cieľ PageResource.resource.noMappings=No mappings PageResource.resource.sync=Synchronization defined PageResource.resource.up=Resource is UP @@ -1828,10 +1828,10 @@ pageResource.conSanity=Stav konektora pageResource.conSchema=Schéma konektora pageResource.deleteSyncToken=Zmazať synch. token pageResourceEdit.edit=Upraviť -pageResourceEdit.message.emptyXml=Nie je možné uložiť prázdne xml ako zdroj. +pageResourceEdit.message.emptyXml=Nie je možné uložiť prázdne xml ako koncový systém. pageResourceEdit.options=Voľby -pageResource.editResource=Editovať systém -PageResourceEdit.title=Nový systém +pageResource.editResource=Editovať koncový systém +PageResourceEdit.title=Nový koncový systém pageResource.import=Import pageResource.message.invalidTaskSearch=Hľadanie Synchronizačnej úlohy neskončilo korektne. pageResource.message.oidNotDefined=Oid koncového systému nebolo definované. @@ -1881,8 +1881,8 @@ pageResource.sync=Synchronizácia PageResource.title=Detaily koncového systému pageResource.type=Typ pageResource.version=Verzia -PageResourceWizard.title=Nový systém -PageResourceWizard.title.edit=Edit resource '{0}' +PageResourceWizard.title=Nový koncový systém +PageResourceWizard.title.edit=Upraviť koncový systém '{0}' pageRole.members=Členovia pageRole.governance=Governance PageRoleEditor.extension=Rozšírenia @@ -2174,15 +2174,15 @@ PageTasks.title=Zoznam úloh pageTasks.unknownRefName=Neznámy objekt pageTask.threadStop=Thread stop akcia pageTask.title.edit=Detaily pre '{0}' -pageTask.type=Type: +pageTask.type=Typ: page.title.edit={0} page.title.editResource=Editovať systém pageUser.accounts=Účty pageUser.assignment.active=Aktívny pageUser.assignment.name=Meno pageUser.assignments=Priradenia -pageAdminFocus.request=Request a role -pageAdminFocus.objectHistory=History +pageAdminFocus.request=Žiadať o rolu +pageAdminFocus.objectHistory=História pageUser.assignment.type=Typ pageUser.button.abort=Skončiť pageUser.button.addAccount=Pridať účet @@ -2229,18 +2229,18 @@ pageUsers.menu.delete=Zmazať pageUsers.menu.merge=Merge pageUsers.menu.disable=Zakázať pageUsers.menu.enable=Povoliť -pageUsers.menu.reconcile=Odsúhlasiť +pageUsers.menu.reconcile=Rekoncilovať pageUsers.menu.unlock=Odomknúť pageUsers.message.deleteUserConfirm=Naozaj chcete vymazať {0} vybraných používateľ/ov? pageUsers.message.deleteUserConfirmSingle=Naozaj chcete vymazať používateľa '{0}'? pageUsers.message.confirmationMessageForSingleObject=Do you really want to {0} user '{1}'? pageUsers.message.confirmationMessageForMultipleObject=Do you really want to {0} selected {1} user(s)? -pageUsers.message.enableAction=enable -pageUsers.message.disableAction=disable -pageUsers.message.reconcileAction=reconcile -pageUsers.message.unlockAction=unlock -pageUsers.message.deleteAction=delete -pageUsers.message.confirmActionPopupTitle=Confirm action +pageUsers.message.enableAction=povoliť +pageUsers.message.disableAction=zakázať +pageUsers.message.reconcileAction=rekoncilovať +pageUsers.message.unlockAction=odomknúť +pageUsers.message.deleteAction=zmazať +pageUsers.message.confirmActionPopupTitle=Potvrdiť akciu pageUsers.message.nothingSelected=Nebol vybraný žiaden používateľ. pageUsers.message.queryError=Nastala chyba pri preklade dopytu pre vyhľadávanie. PageUsers.title=User List @@ -2347,9 +2347,9 @@ pageWorkItem.trackingData=Sledovanie údajov pageWorkItem.workItemCreatedOn=This work item created on: passwordPanel.error=Heslá sa nezhodujú. passwordPanel.passwordChange=Zmeniť -passwordPanel.passwordRemove=Remove +passwordPanel.passwordRemove=Odstrániť passwordPanel.passwordSet=heslo je nastavené -passwordPanel.passwordRemoveLabel=password will be removed +passwordPanel.passwordRemoveLabel=heslo bude odstránené past.ChangeType.ADD=Pridané past.ChangeType.DELETE=Zmazané past.ChangeType.MODIFY=Zmenené @@ -2364,7 +2364,7 @@ PersonalInfoPanel.other=Iný PersonalInfoPanel.passwordExp=Dátum expirácie účtu PersonalInfoPanel.undefined=Nedefinovaný policyRef.nullValid=Vyberte jednu -prismContainer.mainPanelDisplayName=Properties +prismContainer.mainPanelDisplayName=Vlastnosti prismContainer.shadow.associations=Asociácie prismContainer.shadow.mainPanelDisplayName=Atribúty PrismObjectPanel.hideEmpty=Skryť prázdne polia @@ -2372,9 +2372,9 @@ PrismObjectPanel.maximize=Maximalizovať PrismObjectPanel.minimize=Minimalizovať PrismObjectPanel.protectedAccount=Chránený účet PrismObjectPanel.showEmpty=Zobraziť prázdne polia -PrismObjectPanel.sortProperties=Sort properties -PrismObjectPanel.showMetadata=Show metadata -PrismObjectPanel.hideMetadata=Hide metadata +PrismObjectPanel.sortProperties=Zoradiť vlastnosti +PrismObjectPanel.showMetadata=Zobraziť metadáta +PrismObjectPanel.hideMetadata=Skryť metadáta prismOptionButtonPanel.hideEmpty=Skryť prázdne polia prismOptionButtonPanel.maximize=Maximalizovať prismOptionButtonPanel.minimize=Minimalizovať @@ -2568,7 +2568,7 @@ runReportPopupContent.param.name.to = Dátum do runReportPopupContent.param.value=Hodnota parametra runReportPopupContent.param.name.alsoClosedCampaigns=Also closed campaigns? (default is false) runReportPopupContent.param.name.campaignName=Meno kampane -runReportPopupContent.param.name.resource=Zdroj +runReportPopupContent.param.name.resource=Koncový systém runReportPopupContent.param.name.intent=Účel runReportPopupContent.param.name.objectClass=Object name runReportPopupContent.param.name.kind=Druh @@ -2983,7 +2983,7 @@ TreeTablePanel.managers=Manažéri TreeTablePanel.members=Členovia TreeTablePanel.menu.addManager=Pridať manažéra TreeTablePanel.menu.addMember=Pridať člena -TreeTablePanel.menu.deleteMember=Delete member +TreeTablePanel.menu.deleteMember=Zmazať člena TreeTablePanel.menu.deleteAllMembers=Delete all (focus) members TreeTablePanel.menu.addOrgUnit=Pridať org. jednotku TreeTablePanel.menu.addToHierarchy=Pridať do org. jednotky @@ -2991,10 +2991,10 @@ TreeTablePanel.menu.delete=Zmazať TreeTablePanel.menu.disable=Zakázať TreeTablePanel.menu.enable=Povoliť TreeTablePanel.menu.move=Presunúť -TreeTablePanel.menu.recompute=Recompute +TreeTablePanel.menu.recompute=Prepočítať TreeTablePanel.menu.removeFromHierarchy=Odstrániť z org. jednotky TreeTablePanel.message.warn.deleteTreeObjectConfirm=Warning! {0} has members. Do you really want to delete this org. unit? -TreeTablePanel.message.deleteTreeObjectConfirm=Do you really want to delete org. unit "{0}"? +TreeTablePanel.message.deleteTreeObjectConfirm=Chcete naozaj zmazať org. jednotku "{0}"? TreeTablePanel.message.deleteObjectConfirm=Naozaj chcete zmazať vybrané {0} objekt(y)? TreeTablePanel.message.deleteRootConfirm=Naozaj chcete zmazať {0} ({1})? TreeTablePanel.message.nothingSelected=Nebol vybratý objekt. @@ -3004,8 +3004,8 @@ TreeTablePanel.recomputeRoot=Prepočítať koreň TreeTablePanel.recomputeTask=Prepočítať používateľov v organizáciách {0} TreeTablePanel.search.scope.one=Jedna úroveň TreeTablePanel.search.scope.subtree=Podstrom -TreeTablePanel.fullName.displayName=Fullname/Display name -TreeTablePanel.identifier.description=Identifier/Description +TreeTablePanel.fullName.displayName=Celé meno/Zobrazované meno +TreeTablePanel.identifier.description=Identifikátor/Popis TreeTablePanel.warning.childrenExist=Organization which is going to be deleted has members. Do you really want to delete it? Type.AUDIT=Auditný type.nullValid=Vyberte jednu @@ -3034,7 +3034,7 @@ userBrowserDialog.title=Vyberte používateľa userBrowserDialog.type=Typ User.disabled=Zakázaný UserMenuPanel.editPasswordQuestions=Znulovať bezpečnostné otázky -UserMenuPanel.editProfile=Edit profil +UserMenuPanel.editProfile=Upraviť profil UserMenuPanel.logout=Odhlásiť UserMenuPanel.resetPasswords=Znulovať heslá UserOrgReferenceChoosePanel.type.org=Org. jednotka @@ -3044,12 +3044,12 @@ UserReportConfigPanel.dateFrom=Od UserReportConfigPanel.dateTo=Do UserReportConfigPanel.exportFileType=Typ exportu UserReportConfigPanel.title.basic=Základná konfigurácia pre používateľský report -user.enduser=End user -user.noAssignments=No assignments -user.superuser=Superuser +user.enduser=Koncový používateľ +user.noAssignments=Žiadne priradenia +user.superuser=Privilegovaný používateľ user.orgManager=Manažér user.orgMember=Člen -user.noOrgs=No organizations +user.noOrgs=Žiadne organizácie validFromFetchStrategy.nullValid=Vyberte jednu validToFetchStrategy.nullValid=Vyberte jednu valueAttribute.nullValid=Vyberte jednu @@ -3058,14 +3058,14 @@ WebModelUtils.couldntSaveObject=Couldn't save object. WebModelUtils.couldntSearchObjects=Couldn't search objects. WebModelUtils.couldntDeleteObject=Couldn't delete object. WebModelUtils.couldntCountObjects=Couldn't count objects. -web.security.provider.access.denied=Access denied. You don't have permission to access, please contact Identity Manager's administrators. -web.security.provider.denied=Access denied. +web.security.provider.access.denied=Prístup zamietnutý. Nemáte právo na prístup, kontaktujte prosím správcov systému. +web.security.provider.denied=Prístup zamietnutý. web.security.provider.disabled=Používateľ je zablokovaný. web.security.provider.invalid=Nesprávne použ. meno a/alebo heslo. web.security.provider.invalid.link=Invalid link web.security.provider.locked=Používateľ je zablokovaný, prosím počkajte. web.security.provider.password.bad=Používateľ nemá definované heslo. -web.security.provider.password.encoding=Couldn't authenticate user, reason: couldn't encode password. +web.security.provider.password.encoding=Nie je možné prihlásenie používateľa, dôvod: nemožno zašifrovať heslo. web.security.provider.unavailable=Momentálne nie je možné spracovať Vašu požiadavku. Skúste prosím neskôr. web.security.ldap.access.denied=Access denied. You don't have permission to access, please contact Identity Manager's administrators. web.security.ldap.denied=Permission denied. @@ -3081,7 +3081,7 @@ WfDeltasPanel.label.deltaOutListEmpty=(žiadny) WfDeltasPanel.label.deltaOut=Process output: delta(s) resulting from the approval WfHistoryPanel.label.event=Udalosť WfHistoryPanel.label.timestamp=Čas -WizardHelpDialog.button.ok=Ok, Got It! +WizardHelpDialog.button.ok=Ok, hotovo! WizardHelpDialog.label=Get Help With Resource Wizard! Wizard.message.cancel=Editovanie systému bolo zrušené Wizard.correctErrorsFirst=Please correct the errors before saving. @@ -3102,20 +3102,20 @@ PageAdmin.menu.selfDashboard=Domov PageAdmin.menu.selfService=SAMOOBSLUHA PageAdmin.menu.mainNavigation=ADMINISTRÁCIA PageAdmin.menu.additional=ADDITIONAL -PageAdmin.menu.profile=Profile +PageAdmin.menu.profile=Profil PageAdmin.menu.assignments=Priradenia -PageAdmin.menu.credentials=Nastavenia -PageAdmin.menu.request=Request a role -PageTemplate.version=Version: -PageTemplate.copy=Copyright © 2010-2017 Evolveum® and partners.  +PageAdmin.menu.credentials=Heslá +PageAdmin.menu.request=Žiadať o rolu +PageTemplate.version=Verzia: +PageTemplate.copy=Copyright © 2010-2017 Evolveum® a partneri.  PageTemplate.toggleNavigation=Toggle navigation PageTemplate.user=používateľ PageTemplate.couldntNavigateBreadcrumb=Couldn't navigate breadcrumb, reason: {0} SystemInfoPanel.starttime=Start time SystemInfoPanel.uptime=Uptime -CountToolbar.label.unknownCount=Displaying {0,number,integer} to {1,number,integer}, unknown number of matching results. +CountToolbar.label.unknownCount=Zobrazuje sa {0,number,integer} až {1,number,integer}, nie je známy počet vyhovujúcich výsledkov. TableConfigurationPanel.pageSize=Veľkosť stránky -TableConfigurationPanel.tableColumns=Table columnsCountToolbar.label.unknownCount=Displaying {0,number,integer} to {1,number,integer}, unknown number of matching results. +TableConfigurationPanel.tableColumns=Tabuľka columnsCountToolbar.label.unknownCount=Zobrazuje sa {0,number,integer} až {1,number,integer}, nie je známy počet vyhovujúcich výsledkov. MyRequestsPanel.started = Naštartovaný MyRequestsPanel.rejected = Rejected MyRequestsPanel.approved = Approved @@ -3124,69 +3124,69 @@ MyRequestsPanel.unknown = Unknown MyRequestsPanel.future = Future MyRequestsPanel.cancelled = Cancelled MyRequestsPanel.name = Meno -PageSelfProfile.title=Edit profil +PageSelfProfile.title=Upraviť profil PageSelfDashboard.title=Domov PageSelfDashboard.workItems=Moje pracovné položky PageSelfDashboard.myRequests=Moje požiadavky -PageAdmin.menu.top.serverTasks.edit=Edit task +PageAdmin.menu.top.serverTasks.edit=Upraviť úlohu PageAdmin.menu.top.configuration.repositoryObjectView=Edit object PageAdmin.menu.top.reports.configure=Configure report PageAdmin.menu.top.users.edit=Upraviť používateľa -PageAdmin.menu.top.roles.edit=Edit role -PageAdmin.menu.top.users.org.edit=Edit organization +PageAdmin.menu.top.roles.edit=Upraviť rolu +PageAdmin.menu.top.users.org.edit=Upraviť organizáciu PageSelfCredentials.tabs.password=Heslo -PageSelfCredentials.title=Nastavenia +PageSelfCredentials.title=Zmena hesla PageSelfCredentials.oldPasswordLabel=Staré heslo -PageSelfCredentials.passwordLabel1=New password -PageSelfCredentials.passwordLabel2=Confirm password -PageSelfCredentials.accountMidpoint=Identity Manager -PageSelfCredentials.resourceMidpoint=Identity Repository +PageSelfCredentials.passwordLabel1=Nové heslo +PageSelfCredentials.passwordLabel2=Potvrdiť heslo +PageSelfCredentials.accountMidpoint=Správa identít +PageSelfCredentials.resourceMidpoint=Repozitár identít PageSelfCredentials.noAccountSelected=Heslo nebolo zmenené. Nebol vybraný žiadny účet. -PageSelfCredentials.emptyPasswordFiled=New password fields values are to be specified. -PageSelfCredentials.incorrectOldPassword=Password not changed. Old password is incorrect. -PageSelfCredentials.specifyOldPasswordMessage=Please, specify old password value -ChangePasswordPanel.accountsTable.header=Password propagation +PageSelfCredentials.emptyPasswordFiled=Je potrebné vyplniť položky pre nové heslo. +PageSelfCredentials.incorrectOldPassword=Heslo nebolo zmenené. Staré heslo nie je správne. +PageSelfCredentials.specifyOldPasswordMessage=Zadajte, prosím, staré heslo +ChangePasswordPanel.accountsTable.header=Propagácia hesla ChangePasswordPanel.name=Meno -ChangePasswordPanel.resourceName=Zdroj -ChangePasswordPanel.enabled=Account enabled -ChangePasswordPanel.legendMessage.selected= - Password will be changed -ChangePasswordPanel.legendMessage.propagated= - Automatic password propagation (based on policies defined in resources definitions) -ChangePasswordPanel.legendMessage.deselected= - Password will not be changed -ChangePasswordPanel.legendMessage.no.password.capability= - Password capability is not supported by resource -ChangePasswordPanel.helpInfo=

This portion of the credentials dialog controls how the password change will be propagated to each individual system. The first line defines whether the password will be changed in the Identity Manager itself. Following lines represent each system for which the password can be changed. The password propagation is controlled by the icons:

  • Password will be changed. Password for this system will be changed to the value specified in the password dialog above.
  • Automatic password propagation. The password might be changed. Whether the password is changed or not depends on the policies set up by identity administrator. This usually means that the password will be changed if it makes sense for the current situation and settings. This is the reasonable default choice.
  • Password will not be changed for this system.
  • Password capability is not supported for this system. As the result, password will not be changed for this system.

You can adjust the password propagation settings by clicking on the icons and thus fine-tune how the password change is propagated to each individual system.

-ChangePasswordPanel.helpPopupTitle=Password propagation help +ChangePasswordPanel.resourceName=Koncový systém +ChangePasswordPanel.enabled=Účet povolený +ChangePasswordPanel.legendMessage.selected= - Heslo bude zmenené +ChangePasswordPanel.legendMessage.propagated= - Automatická propagácia hesla (heslo môže byť zmenené v závislosti od nastavenia koncového systému) +ChangePasswordPanel.legendMessage.deselected= - Heslo nebude zmenené +ChangePasswordPanel.legendMessage.no.password.capability= - Správa hesiel nie je na tomto systéme podporovaná +ChangePasswordPanel.helpInfo=

Táto časť dialógu na zmenu hesla riadi propagáciu hesla do jednotlivých koncových systémov. Prvý riadok definuje, či sa heslo zmení v správcovi identít. Ostatné riadky reprezentujú jednotlivé koncové systémy, kde sa má heslo zmeniť. Propagácia hesla sa ovláda nasledovnými ikonami:

  • Heslo bude zmenené. Heslo pre tento systém sa nastaví na hodnotu určenú v dialógu pre zmenu hesla.
  • Automatická propagácia hesla. Heslo môže byť zmenené. Závisí to od politík nastavených správcom identít. Zvyčajne to znamená, že heslo bude zmenené, pokiaľ to v danej situácii a pri daných nastaveniach má zmysel. Toto je rozumné predvolené nastavenie.
  • Heslo nebude v tomto systéme zmenené.
  • Tento systém nepodporuje zmenu hesla. Preto v tomto systéme nedôjde k zmene hesla.

Nastavenia propagácie hesla môžete zmeniť kliknutím na ikony, čím určíte, ako sa má heslo propagovať do jednotlivých systémov.

+ChangePasswordPanel.helpPopupTitle=Pomoc pre propagáciu hesla PageBase.button.tooltip.clearSearch=Vymazať -mainForm.uploadTooLarge = Upload must be less than ${maxSize}. +mainForm.uploadTooLarge = Nahrávaný súbor musí byť menší ako ${maxSize}. mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage}PageSelfCredentials.couldntResolve=Couldn't resolve resource. PageSelfCredentials.couldntResolve=Nepodarilo sa získať informácie o koncovom systéme. roleMemberPanel.type=Typ: roleMemberPanel.tenant=Tenant: -roleMemberPanel.project=Org/Project: -roleMemberPanel.indirectMembers=Include indirect members -roleMemberPanel.allRelations=Show all relations -roleMemberPanel.menu.createOwner=Create owner -roleMemberPanel.menu.assignOwners=Assign owners -roleMemberPanel.menu.createApprover=Create approver -roleMemberPanel.menu.assignApprovers=Assign approvers -roleMemberPanel.relation=Relation -SearchPanel.more=More... +roleMemberPanel.project=Org/Projekt: +roleMemberPanel.indirectMembers=Vrátane nepriamych členov +roleMemberPanel.allRelations=Zobraziť všetky vzťahy +roleMemberPanel.menu.createOwner=Vytvoriť vlastníka +roleMemberPanel.menu.assignOwners=Priradiť vlastníka +roleMemberPanel.menu.createApprover=Vytvoriť schvaľovateľa +roleMemberPanel.menu.assignApprovers=Priradiť schvaľovateľa +roleMemberPanel.relation=Vzťah +SearchPanel.more=Viac... SearchPanel.add=Pridať SearchPanel.close=Zatvoriť -SearchPanel.properties=Properties +SearchPanel.properties=Vlastnosti SearchPanel.fullText=Full text SearchPanel.fullTextSearch=Full text search SearchItemPanel.all=Všetko SearchItemPanel.update=Aktualizovať SearchItemPanel.close=Zatvoriť SearchItemPanel.add=Pridať -SearchItemPanel.remove=Remove +SearchItemPanel.remove=Odobrať SearchItemPanel.browse=Prehliadať -SearchItemPanel.or=or +SearchItemPanel.or=alebo operation.com.evolveum.midpoint.schema.constants.ConnectorTestOperation.connectorSchema=Schéma konektora FeedbackAlertMessageDetails.operation=Operácia FeedbackAlertMessageDetails.message=Správa -FeedbackAlertMessageDetails.params=Parameters -FeedbackAlertMessageDetails.contexts=Context +FeedbackAlertMessageDetails.params=Parametre +FeedbackAlertMessageDetails.contexts=Kontext FeedbackAlertMessageDetails.count=Počet FeedbackAlertMessageDetails.error=Chyba operation.com.evolveum.midpoint.model.impl.lens.projector.InboundProcessor.processInbound=Spracovanie vstupu (Model) @@ -3221,7 +3221,7 @@ PageResource.tab.content.generic=Generics PageResource.tab.content.others=Uncategorized PageResource.tab.content.tasks=Defined Tasks ResourceContentTabPanel.searchType.repository=Repozitár -ResourceContentTabPanel.searchType.resource=Zdroj +ResourceContentTabPanel.searchType.resource=Koncový systém ResourceContentTabPanel.searchType=Search In: PagePreviewChanges.primaryChangesOne=Primary changes: {0} object PagePreviewChanges.primaryChangesMore=Primary changes: {0} objects @@ -3252,7 +3252,7 @@ TaskSummaryPanel.lastProcessed=Last object processed: {0} ResourceContentResourcePanel.showExisting=Show existing ResourceContentResourcePanel.newTask=Create new SearchPanel.advanced=Rozšírené -SearchPanel.basic=Základný +SearchPanel.basic=Základné SearchPanel.search=Vyhľadať SearchPanel.debug=DEBUG ResourceContentResourcePanel.realSearch=(In fact) Searching by: @@ -3311,9 +3311,9 @@ ReportCreateHandlerPanel.downloadCreatedReport=Download created report ReportCreateHandlerPanel.reportParameters=Reportovať parametre OperationResultPanel.showTask=(show task) PageResources.inlineMenuItem.test=Testovať spojenie -PageRequestRole.title=Request a role -MainObjectListPanel.refresh=Refresh -MainObjectListPanel.newObject=New +PageRequestRole.title=Žiadať o rolu +MainObjectListPanel.refresh=Aktualizovať +MainObjectListPanel.newObject=Nový MainObjectListPanel.import=Import MainObjectListPanel.export=Export MainObjectListPanel.exportFileName=export @@ -3334,7 +3334,7 @@ TreeTablePanel.menu.deleteManagersAll.confirm=All defined managers will be perma TreeTablePanel.move=Presunúť TreeTablePanel.makeRoot=Make root TreeTablePanel.delete=Zmazať -TreeTablePanel.recompute=Recompute +TreeTablePanel.recompute=Prepočítať TreeTablePanel.edit=Editovať TreeTablePanel.viewDetails=View details TreeTablePanel.createChild=Create child @@ -3477,7 +3477,7 @@ ColumnUtils.getUserIconColumn.createTitleModel.down=down FocusListInlineMenuHelper.menu.delete=Zmazať FocusListInlineMenuHelper.menu.disable=Zakázať FocusListInlineMenuHelper.menu.enable=Povoliť -FocusListInlineMenuHelper.menu.reconcile=Odsúhlasiť +FocusListInlineMenuHelper.menu.reconcile=Rekoncilovať FocusListInlineMenuHelper.message.deleteObjectConfirm=Naozaj chcete zmazať vybrané {0} objekt(y)? FocusListInlineMenuHelper.message.deleteObjectConfirmSingle=Do you really want to delete object '{0}'? FocusListInlineMenuHelper.message.nothingSelected=Nebol vybratý objekt. @@ -3650,7 +3650,7 @@ PageResetPassword.reset.successful=New password was set successfully. Continue w PageForgotPassword.form.submited.message=Confirmation link was sent to the email provided. To reset your password, click on the confirmation link and follow instructions. pageForgetPassword.message.policy.not.found=Reset password not allowed PageAbstractSelfCredentials.save.password.failed=Failed to change password: {0} -PageResetPassword.title=Znulovať heslá +PageResetPassword.title=Reset hesla PageResetPasswordConfirmation.title=Reset password confirmation PageResetPasswordConfirmation.confirmation.error=Reset password is not allowed. We are sorry, but probably you'll need to contact system administrator. PageResetPasswordConfirmation.authnetication.failed=Incorrect username and/or password @@ -3698,13 +3698,13 @@ PageWorkItem.noRequest=Couldn't display the work item, as it is not associated w CsvDownloadButtonPanel.export=CSV export CsvDownloadButtonPanel.confirmationMessage=CSV export size is limited to {0} entries. Continue? AssignmentEditorDto.policyRuleTitle=Policy rule -AssignmentDataTablePanel.targetColumnName=Target -AssignmentDataTablePanel.validityColumnName=Validity -AssignmentDataTablePanel.organizationColumnName=Organization +AssignmentDataTablePanel.targetColumnName=Cieľ +AssignmentDataTablePanel.validityColumnName=Platnosť +AssignmentDataTablePanel.organizationColumnName=Organizácia AssignmentDataTablePanel.tenantColumnName=Tenant AssignmentDataTablePanel.lifecycleColumnName=LifecycleAssignmentsUtil.createAssignmentIconTitleModel(AssignmentDataTablePanel.this, rowModel.getObject().getType()) -AssignmentDataTablePanel.activationColumnName=Activation -AssignmentDataTablePanel.descriptionColumnName=Description +AssignmentDataTablePanel.activationColumnName=Aktivácia +AssignmentDataTablePanel.descriptionColumnName=Popis PolicyRulesPanel.imageTitle=Policy rule PolicyRulesPanel.nameColumn=Name PolicyRulesPanel.constraintsColumn=Constraints @@ -3714,7 +3714,7 @@ PolicyRulesPanel.orderColumn=Order PolicyRule.constraintsLabel=Constraints PolicyRule.situationLabel=Situation PolicyRule.actionLabel=Action -AbstractAssignmentDetailsPanel.doneButton=Done +AbstractAssignmentDetailsPanel.doneButton=Hotovo ApprovalProcessesPreviewPanel.processRelatedTo=Approval process related to {0} ApprovalProcessesPreviewPanel.process=Approval process ApprovalProcessExecutionInformationPanel.stage=Stage {0}/{1} @@ -3723,11 +3723,11 @@ AssignmentType.activation=Activation AssignmentType.lifecycleState=Lifecycle state AssignmnetType.accepted=Accepted AssignmentType.policySituation=Policy situation -ObjectReferenceType.relation=Relation +ObjectReferenceType.relation=Vzťah FocusType.consents=Consents -AbstractAssignmentDetailsPanel.properties=Properties -AssignmentPanel.doneButton=Done -AssignmentPanel.cancelButton=Cancel +AbstractAssignmentDetailsPanel.properties=Vlastnosti +AssignmentPanel.doneButton=Hotovo +AssignmentPanel.cancelButton=Zrušiť AssignmentPanel.noName=n/a ObjectPolicyConfigurationEditor.conflictResolution=(conflict resolution) PageSelfConsents.title=Consents @@ -3748,4 +3748,4 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Policy ExclusionPolicyConstraintPanel.exclusionTitle=Exclusion - +comboInput.nullValid=Vyberte hodnotu diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_tr.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_tr.properties index f789a4d2471..d5f171d0a08 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_tr.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_tr.properties @@ -3748,4 +3748,4 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Policy ExclusionPolicyConstraintPanel.exclusionTitle=Exclusion - +comboInput.nullValid=Choose one diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_zh_CN.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_zh_CN.properties index cd04d20510f..47aca56b5c7 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_zh_CN.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_zh_CN.properties @@ -163,8 +163,7 @@ CapabilityStep.activation.tooltip.ignoreAttribute=如果设置为 true, 则用 CapabilityStep.activation.tooltip.lockoutAttributeName=包含模拟 lockoutStatus 值的属性的名称。这通常是一个包含某种普通/锁定信息的属性。 CapabilityStep.activation.tooltip.lockoutNormalList=表示 "正常" 状态的属性值的列表。如果这些值中的任何一个存在于属性中,则该对象将被视为处于正常状态。 CapabilityStep.activation.tooltip.lockoutLockedList=表示 "锁定" 状态的属性值的列表。如果这些值中的任何一个存在于属性中,则该对象将被视为处于锁定状态。 -CapabilityStep.activation.tooltip.lockoutIgnoreAttribute=如果设置为 true,则用于模拟激活的属性将在架构中被标记为忽略。即系统将假装此属性不存在,并且只使用标准的 lockoutStatus。这是默认值。如果设置为 false,则该属性也将在架构中可见,并且 lockoutStatus 和原始属性都将起作用。如果属性具有比 lockoutStatus 属性更丰富的状态集,则可能需要这样做。但在这种情况下,注意lockoutStatus 和原始属性之间的值冲突。 - +CapabilityStep.activation.tooltip.lockoutIgnoreAttribute=如果设置为 true,则用于模拟激活的属性将在架构中被标记为忽略。即系统将假装此属性不存在,并且只使用标准的 lockoutStatus。这是默认值。如果设置为 false,则该属性也将在架构中可见,并且 lockoutStatus 和原始属性都将起作用。如果属性具有比 lockoutStatus 属性更丰富的状态集,则可能需要这样做。但在这种情况下,注意lockoutStatus 和原始属性之间的值冲突。\n CapabilityStep.activation.tooltip.returnedByDefault=如果为 true, 则默认情况下, 激活属性包含在返回资源对象, 并且不需要请求它。如果为 false, 则必须显式请求激活属性。 CapabilityStep.activation.tooltip.validFromEnabled=如果资源支持 validFrom 激活属性,则为 true。 CapabilityStep.activation.tooltip.validFromReturned=如果默认情况下返回 validFrom 属性,则为 true。如果需要显式请求,则为 false。 @@ -3749,4 +3748,4 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Policy ExclusionPolicyConstraintPanel.exclusionTitle=Exclusion - +comboInput.nullValid=Choose one diff --git a/infra/schema/src/main/resources/localization/schema_cs.properties b/infra/schema/src/main/resources/localization/schema_cs.properties index 350603dd24a..d86e0d888c4 100644 --- a/infra/schema/src/main/resources/localization/schema_cs.properties +++ b/infra/schema/src/main/resources/localization/schema_cs.properties @@ -402,12 +402,12 @@ ExclusionPolicyType.ENFORCE=Vynutit ExclusionPolicyType.APPROVE=Schválit ExclusionPolicyType.REPORT=Report TechnicalObjectSpecification={0} {1} (OID {2}) -DefaultPolicyConstraint.assignmentModification.toBeAdded=Přiřazení pro {0} (vazba {1}) má být přidáno -DefaultPolicyConstraint.assignmentModification.wasAdded=Přiřazení pro {0} (vazba {1}) bylo přidáno -DefaultPolicyConstraint.assignmentModification.toBeDeleted=Přiřazení pro {0} (vazba {1}) má být smazáno -DefaultPolicyConstraint.assignmentModification.wasDeleted=Přiřazení pro {0} (vazba {1}) bylo smazáno -DefaultPolicyConstraint.assignmentModification.toBeModified=Přiřazení pro {0} (vazba {1}) má být upraveno -DefaultPolicyConstraint.assignmentModification.wasModified=Přiřazení pro {0} (vazba {1}) bylo upraveno +DefaultPolicyConstraint.assignmentModification.toBeAdded=Přiřazení pro {0} (vztah {1}) má být přidáno +DefaultPolicyConstraint.assignmentModification.wasAdded=Přiřazení pro {0} (vztah {1}) bylo přidáno +DefaultPolicyConstraint.assignmentModification.toBeDeleted=Přiřazení pro {0} (vztah {1}) má být smazáno +DefaultPolicyConstraint.assignmentModification.wasDeleted=Přiřazení pro {0} (vztah {1}) bylo smazáno +DefaultPolicyConstraint.assignmentModification.toBeModified=Přiřazení pro {0} (vztah {1}) má být upraveno +DefaultPolicyConstraint.assignmentModification.wasModified=Přiřazení pro {0} (vztah {1}) bylo upraveno DefaultPolicyConstraint.objectModification.toBeAdded={0} má být přidáno DefaultPolicyConstraint.objectModification.wasAdded={0} bylo přidáno DefaultPolicyConstraint.objectModification.toBeDeleted={0} má být smazáno @@ -423,10 +423,10 @@ DefaultPolicyConstraint.assignmentState.named=Stav přiřazení {0} odpovídá o DefaultPolicyConstraint.exclusion=Porušení SoD politiky: {0} je ve výlučnosti s {1}, nemohou být přiřazeny v jeden okamžik DefaultPolicyConstraint.hasAssignment=Přiřazení pro {0} ({1}) existuje DefaultPolicyConstraint.hasNoAssignment=Pro {0} {1} ({2}) neexistuje přiřazení -DefaultPolicyConstraint.multiplicityConstraint.min.object={0} vyžaduje minimálně {1} příjemců s vazbou '{2}' -DefaultPolicyConstraint.multiplicityConstraint.max.object={0} vyžaduje maximálně {1} příjemců s vazbou '{2}' -DefaultPolicyConstraint.multiplicityConstraint.min.target={0} vyžaduje minimálně {1} příjemců s vazbou '{2}'. Operace by vedla na {3} příjemců. -DefaultPolicyConstraint.multiplicityConstraint.max.target={0} vyžaduje maximálně {1} příjemců s vazbou '{2}'. Operace by vedla na {3} příjemců. +DefaultPolicyConstraint.multiplicityConstraint.min.object={0} vyžaduje minimálně {1} příjemců se vztahem '{2}' +DefaultPolicyConstraint.multiplicityConstraint.max.object={0} vyžaduje maximálně {1} příjemců se vztahem '{2}' +DefaultPolicyConstraint.multiplicityConstraint.min.target={0} vyžaduje minimálně {1} příjemců s vztahem '{2}'. Operace by vedla na {3} příjemců. +DefaultPolicyConstraint.multiplicityConstraint.max.target={0} vyžaduje maximálně {1} příjemců se vztahem '{2}'. Operace by vedla na {3} příjemců. DefaultPolicyConstraint.and=Všechna vložená omezení byla spuštěna DefaultPolicyConstraint.or=Minimálně jedno z vložených omezení bylo spuštěno DefaultPolicyConstraint.not=Vložená omezení nebyla spuštěna From 2e6748b4cb1d99fc2260894b61cceb33cd753015 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 19 Sep 2017 15:15:35 +0200 Subject: [PATCH 14/97] Preliminary implementation of variables for bulk actions. --- .../midpoint/model/api/PipelineItem.java | 31 +++ .../impl/scripting/ExecutionContext.java | 19 +- .../model/impl/scripting/PipelineData.java | 96 +++------- .../ScriptingExpressionEvaluator.java | 28 ++- .../actions/DiscoverConnectorsExecutor.java | 2 +- .../actions/PurgeSchemaExecutor.java | 4 +- .../expressions/SearchEvaluator.java | 180 +++++++++++------- .../expressions/SelectEvaluator.java | 2 +- .../intest/scripting/TestScriptingBasic.java | 34 +++- .../search-for-users-with-expressions.xml | 45 +++++ 10 files changed, 279 insertions(+), 162 deletions(-) create mode 100644 model/model-intest/src/test/resources/scripting/search-for-users-with-expressions.xml diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/PipelineItem.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/PipelineItem.java index 2d33d22c0aa..edb1bf0da06 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/PipelineItem.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/PipelineItem.java @@ -17,12 +17,15 @@ package com.evolveum.midpoint.model.api; import com.evolveum.midpoint.prism.PrismValue; +import com.evolveum.midpoint.prism.util.CloneUtil; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.DebugUtil; import org.jetbrains.annotations.NotNull; import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; /** * @author mederly @@ -31,12 +34,19 @@ public class PipelineItem implements DebugDumpable, Serializable { @NotNull private PrismValue value; @NotNull private OperationResult result; + @NotNull private final Map variables = new HashMap<>(); public PipelineItem(@NotNull PrismValue value, @NotNull OperationResult result) { this.value = value; this.result = result; } + public PipelineItem(@NotNull PrismValue value, @NotNull OperationResult result, @NotNull Map variables) { + this.value = value; + this.result = result; + copyClonedVariables(variables, this.variables); + } + @NotNull public PrismValue getValue() { return value; @@ -55,15 +65,36 @@ public void setResult(@NotNull OperationResult result) { this.result = result; } + @NotNull + public Map getVariables() { + return variables; + } + + @SuppressWarnings("unchecked") + public X getVariable(String name) { + return (X) variables.get(name); + } + @Override public String debugDump(int indent) { StringBuilder sb = new StringBuilder(); DebugUtil.debugDumpWithLabelLn(sb, "value", value, indent+1); DebugUtil.debugDumpWithLabel(sb, "result", result, indent+1); + DebugUtil.debugDumpWithLabel(sb, "variables", result, indent+1); return sb.toString(); } public void computeResult() { result.computeStatus(); } + + public PipelineItem cloneMutableState() { + PipelineItem rv = new PipelineItem(value, result.clone()); + copyClonedVariables(variables, rv.getVariables()); + return rv; + } + + public static void copyClonedVariables(Map sourceMap, Map targetMap) { + sourceMap.forEach((key, value) -> targetMap.put(key, CloneUtil.clone(value))); + } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java index 8b1d9cc41d7..d76ae51be53 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java @@ -42,14 +42,17 @@ public class ExecutionContext { private final Task task; private final ScriptingExpressionEvaluator scriptingExpressionEvaluator; private final StringBuilder consoleOutput = new StringBuilder(); - private final Map variables = new HashMap<>(); + private final Map globalVariables = new HashMap<>(); // will probably remain unused + private final Map initialVariables; // used e.g. when there are no data in a pipeline private PipelineData finalOutput; // used only when passing result to external clients (TODO do this more cleanly) public ExecutionContext(ScriptingExpressionEvaluationOptionsType options, Task task, - ScriptingExpressionEvaluator scriptingExpressionEvaluator) { + ScriptingExpressionEvaluator scriptingExpressionEvaluator, + Map initialVariables) { this.options = options; this.task = task; this.scriptingExpressionEvaluator = scriptingExpressionEvaluator; + this.initialVariables = initialVariables; } public Task getTask() { @@ -68,12 +71,16 @@ public boolean isHideOperationResults() { return options != null && Boolean.TRUE.equals(options.isHideOperationResults()); } - public PipelineData getVariable(String variableName) { - return variables.get(variableName); + public PipelineData getGlobalVariable(String name) { + return globalVariables.get(name); } - public void setVariable(String variableName, PipelineData value) { - variables.put(variableName, value); + public void setGlobalVariable(String name, PipelineData value) { + globalVariables.put(name, value); + } + + public Map getInitialVariables() { + return initialVariables; } public String getConsoleOutput() { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/PipelineData.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/PipelineData.java index 079d04538d0..cd7b613825e 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/PipelineData.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/PipelineData.java @@ -36,11 +36,11 @@ import org.jetbrains.annotations.NotNull; import javax.xml.namespace.QName; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; +import java.util.*; import java.util.stream.Collectors; +import static java.util.Collections.emptyMap; + /** * Data that are passed between individual scripting actions. * @@ -74,12 +74,16 @@ public String debugDump(int indent) { } public static PipelineData create(PrismValue value) { + return create(value, emptyMap()); + } + + public static PipelineData create(PrismValue value, Map variables) { PipelineData d = createEmpty(); - d.add(new PipelineItem(value, newOperationResult())); + d.add(new PipelineItem(value, newOperationResult(), variables)); return d; } - private static OperationResult newOperationResult() { + public static OperationResult newOperationResult() { return new OperationResult(ITEM_OPERATION_NAME); } @@ -97,16 +101,14 @@ public void addAllFrom(PipelineData otherData) { } } - public void addValue(PrismValue value) { - addValue(value, null); + public void addValue(PrismValue value, Map variables) { + addValue(value, null, variables); } - public void addValue(PrismValue value, OperationResult result) { - data.add(new PipelineItem(value, result != null ? result : newOperationResult())); - } - - public void addValues(@NotNull List values, OperationResult result) { - values.forEach((v) -> addValue(v, result)); + public void addValue(PrismValue value, OperationResult result, Map variables) { + data.add(new PipelineItem(value, + result != null ? result : newOperationResult(), + variables != null ? variables : emptyMap())); } public String getDataAsSingleString() throws ScriptExecutionException { @@ -121,55 +123,10 @@ public String getDataAsSingleString() throws ScriptExecutionException { } } - static PipelineData createItem(PrismValue value) throws SchemaException { + static PipelineData createItem(@NotNull PrismValue value, Map variables) throws SchemaException { PipelineData data = createEmpty(); - if (value != null) { - data.addValue(value); - } - return data; -// // TODO fix this temporary solution (haven't we somewhere universal method to do this?) -// if (value instanceof PrismReferenceValue) { -// PrismReference ref = new PrismReference(new QName("reference")); -// ref.add((PrismReferenceValue) value); -// return create(ref); -// } else if (value instanceof PrismContainerValue) { -// PrismContainerValue pcv = (PrismContainerValue) value; -// return create(pcv.asSingleValuedContainer(new QName("container"))); -// } else if (value instanceof PrismPropertyValue) { -// if (value.isRaw()) { -// throw new IllegalArgumentException("Value cannot be raw at this point: " + value); -// } -// Class clazz = value.getRealClass(); -// assert clazz != null; -// PrismPropertyDefinition propertyDefinition; -// List defs = prismContext.getSchemaRegistry() -// .findItemDefinitionsByCompileTimeClass(clazz, PrismPropertyDefinition.class); -// if (defs.size() == 1) { -// propertyDefinition = defs.get(0); -// } else if (String.class.isAssignableFrom(clazz)) { -// propertyDefinition = new PrismPropertyDefinitionImpl<>(PLAIN_STRING_ELEMENT_NAME, DOMUtil.XSD_STRING, prismContext); -// } else if (ObjectDeltaType.class.isAssignableFrom(clazz)) { -// propertyDefinition = new PrismPropertyDefinitionImpl<>(SchemaConstants.T_OBJECT_DELTA, SchemaConstants.T_OBJECT_DELTA_TYPE, prismContext); -// } else if (EventHandlerType.class.isAssignableFrom(clazz)) { -// propertyDefinition = new PrismPropertyDefinitionImpl<>(SchemaConstants.C_EVENT_HANDLER, EventHandlerType.COMPLEX_TYPE, prismContext); -// } else { -// // maybe determine type from class would be sufficient -// TypeDefinition td = prismContext.getSchemaRegistry().findTypeDefinitionByCompileTimeClass(clazz, TypeDefinition.class); -// if (td != null) { -// propertyDefinition = new PrismPropertyDefinitionImpl<>(SchemaConstants.C_VALUE, td.getTypeName(), prismContext); -// } else { -// throw new IllegalStateException( -// "Unsupported data class (to be put into scripting data as property): " + clazz); -// } -// } -// PrismProperty property = propertyDefinition.instantiate(); -// property.add((PrismPropertyValue) value); -// return create(property); -// } else if (value == null) { -// return createEmpty(); -// } else { -// throw new IllegalArgumentException("Unsupported prism value: " + value); -// } + data.addValue(value, variables); + return data; } public Collection getDataAsReferences(QName defaultTargetType, Class typeForQuery, @@ -224,7 +181,8 @@ private Collection resolveQuery(Class return objects.stream().map(o -> ObjectTypeUtil.createObjectRef(o)).collect(Collectors.toList()); } - static PipelineData parseFrom(ValueListType input, PrismContext prismContext) { + static PipelineData parseFrom(ValueListType input, Map initialVariables, + PrismContext prismContext) { PipelineData rv = new PipelineData(); if (input != null) { for (Object o : input.getValue()) { @@ -233,22 +191,28 @@ static PipelineData parseFrom(ValueListType input, PrismContext prismContext) { RawType raw = (RawType) o; PrismValue prismValue = raw.getAlreadyParsedValue(); if (prismValue != null) { - rv.addValue(prismValue); + rv.addValue(prismValue, initialVariables); } else { throw new IllegalArgumentException("Raw value in the input data: " + DebugUtil.debugDump(raw.getXnode())); // TODO attempt to parse it somehow (e.g. by passing to the pipeline and then parsing based on expected type) } } else { if (o instanceof Containerable) { - rv.addValue(((Containerable) o).asPrismContainerValue()); + rv.addValue(((Containerable) o).asPrismContainerValue(), initialVariables); } else if (o instanceof Referencable) { - rv.addValue(((Referencable) o).asReferenceValue()); + rv.addValue(((Referencable) o).asReferenceValue(), initialVariables); } else { - rv.addValue(new PrismPropertyValue<>(o, prismContext)); + rv.addValue(new PrismPropertyValue<>(o, prismContext), initialVariables); } } } } return rv; } + + public PipelineData cloneMutableState() { + PipelineData rv = new PipelineData(); + data.forEach(d -> rv.add(d.cloneMutableState())); + return rv; + } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java index af888a52ab2..c34fc099f08 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java @@ -43,8 +43,11 @@ import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; import java.util.HashMap; +import java.util.List; import java.util.Map; +import static java.util.Collections.emptyMap; + /** * Main entry point for evaluating scripting expressions. * @@ -138,24 +141,30 @@ public void evaluateExpressionInBackground(ExecuteScriptType executeScriptComman */ public ExecutionContext evaluateExpression(ScriptingExpressionType expression, Task task, OperationResult result) throws ScriptExecutionException { - ExecutionContext context = evaluateExpression(expression, PipelineData.createEmpty(), null, task, result); + ExecutionContext context = evaluateExpression(expression, PipelineData.createEmpty(), null, emptyMap(), task, result); context.computeResults(); return context; } public ExecutionContext evaluateExpression(@NotNull ExecuteScriptType executeScript, Task task, OperationResult result) throws ScriptExecutionException { + return evaluateExpression(executeScript, emptyMap(), task, result); + } + + // TEMPORARY! + public ExecutionContext evaluateExpression(@NotNull ExecuteScriptType executeScript, @NotNull Map initialVariables, Task task, OperationResult result) throws ScriptExecutionException { Validate.notNull(executeScript.getScriptingExpression(), "Scripting expression must be present"); ExecutionContext context = evaluateExpression(executeScript.getScriptingExpression().getValue(), - PipelineData.parseFrom(executeScript.getInput(), prismContext), executeScript.getOptions(), task, result); + PipelineData.parseFrom(executeScript.getInput(), initialVariables, prismContext), executeScript.getOptions(), initialVariables, task, result); context.computeResults(); return context; } // main entry point from the outside private ExecutionContext evaluateExpression(ScriptingExpressionType expression, PipelineData data, - ScriptingExpressionEvaluationOptionsType options, Task task, OperationResult result) throws ScriptExecutionException { - ExecutionContext context = new ExecutionContext(options, task, this); + ScriptingExpressionEvaluationOptionsType options, Map initialVariables, + Task task, OperationResult result) throws ScriptExecutionException { + ExecutionContext context = new ExecutionContext(options, task, this, initialVariables); PipelineData output; try { output = evaluateExpression(expression, data, context, result); @@ -226,8 +235,11 @@ private PipelineData executePipeline(ExpressionPipelineType pipeline, PipelineDa private PipelineData executeSequence(ExpressionSequenceType sequence, PipelineData input, ExecutionContext context, OperationResult result) throws ScriptExecutionException { PipelineData lastOutput = null; - for (JAXBElement expressionType : sequence.getScriptingExpression()) { - lastOutput = evaluateExpression(expressionType, input, context, result); + List> scriptingExpression = sequence.getScriptingExpression(); + for (int i = 0; i < scriptingExpression.size(); i++) { + JAXBElement expressionType = scriptingExpression.get(i); + PipelineData branchInput = i < scriptingExpression.size() - 1 ? input.cloneMutableState() : input; + lastOutput = evaluateExpression(expressionType, branchInput, context, result); } return lastOutput; } @@ -252,7 +264,7 @@ public PipelineData evaluateConstantExpression(@NotNull RawType constant, @Nulla if (value.isRaw()) { throw new IllegalStateException("Raw value while " + desc + ": " + value + ". Please specify type of the value."); } - return PipelineData.createItem(value); + return PipelineData.createItem(value, context.getInitialVariables()); } catch (SchemaException e) { throw new ScriptExecutionException(e.getMessage(), e); } @@ -261,7 +273,7 @@ public PipelineData evaluateConstantExpression(@NotNull RawType constant, @Nulla public PipelineData evaluateConstantStringExpression(RawType constant, ExecutionContext context, OperationResult result) throws ScriptExecutionException { try { String value = constant.getParsedRealValue(String.class); - return PipelineData.createItem(new PrismPropertyValue<>(value)); + return PipelineData.createItem(new PrismPropertyValue<>(value), context.getInitialVariables()); } catch (SchemaException e) { throw new ScriptExecutionException(e.getMessage(), e); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/DiscoverConnectorsExecutor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/DiscoverConnectorsExecutor.java index 7d9b9b52b5f..834d79dec37 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/DiscoverConnectorsExecutor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/DiscoverConnectorsExecutor.java @@ -91,7 +91,7 @@ public PipelineData execute(ActionExpressionType expression, PipelineData input, context.println((exception != null ? "Attempted to discover " : "Discovered " + newConnectors.size()) + " new connector(s) from " + connectorHostTypePrismObject + exceptionSuffix(exception)); for (ConnectorType connectorType : newConnectors) { - output.addValue(connectorType.asPrismObject().getValue(), item.getResult()); + output.addValue(connectorType.asPrismObject().getValue(), item.getResult(), item.getVariables()); } try { if (rebind) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/PurgeSchemaExecutor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/PurgeSchemaExecutor.java index 9410d11057f..1b9a11c8121 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/PurgeSchemaExecutor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/PurgeSchemaExecutor.java @@ -67,10 +67,10 @@ public PipelineData execute(ActionExpressionType expression, PipelineData input, if (delta != null) { operationsHelper.applyDelta(delta, ModelExecuteOptions.createRaw(), context, result); context.println("Purged schema information from " + resourceTypePrismObject); - output.addValue(operationsHelper.getObject(ResourceType.class, resourceTypePrismObject.getOid(), true, context, result).getValue(), item.getResult()); + output.addValue(operationsHelper.getObject(ResourceType.class, resourceTypePrismObject.getOid(), true, context, result).getValue(), item.getResult(), item.getVariables()); } else { context.println("There's no schema information to be purged in " + value); - output.addValue(resourceTypePrismObject.getValue(), item.getResult()); + output.addValue(resourceTypePrismObject.getValue(), item.getResult(), item.getVariables()); } operationsHelper.recordEnd(context, resourceType, started, null); } catch (Throwable ex) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/expressions/SearchEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/expressions/SearchEvaluator.java index c401c5a8329..5a9896296e2 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/expressions/SearchEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/expressions/SearchEvaluator.java @@ -16,15 +16,20 @@ package com.evolveum.midpoint.model.impl.scripting.expressions; +import com.evolveum.midpoint.model.api.PipelineItem; import com.evolveum.midpoint.model.api.ScriptExecutionException; import com.evolveum.midpoint.model.impl.scripting.ExecutionContext; import com.evolveum.midpoint.model.impl.scripting.PipelineData; import com.evolveum.midpoint.model.impl.scripting.helpers.ExpressionHelper; import com.evolveum.midpoint.model.impl.scripting.helpers.OperationsHelper; +import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.marshaller.QueryConvertor; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.QueryJaxbConvertor; +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.schema.GetOperationOptions; import com.evolveum.midpoint.schema.ResultHandler; import com.evolveum.midpoint.schema.SelectorOptions; @@ -43,7 +48,10 @@ import org.springframework.stereotype.Component; import javax.xml.bind.JAXBElement; +import javax.xml.namespace.QName; import java.util.Collection; +import java.util.Collections; +import java.util.List; /** * @author mederly @@ -55,86 +63,110 @@ public class SearchEvaluator extends BaseExpressionEvaluator { @Autowired private ExpressionHelper expressionHelper; @Autowired private OperationsHelper operationsHelper; + @Autowired private ExpressionFactory expressionFactory; private static final String PARAM_NO_FETCH = "noFetch"; public PipelineData evaluate(SearchExpressionType searchExpression, PipelineData input, - ExecutionContext context, OperationResult globalResult) throws ScriptExecutionException { + ExecutionContext context, OperationResult globalResult) + throws ScriptExecutionException { Validate.notNull(searchExpression.getType()); - boolean noFetch = expressionHelper.getArgumentAsBoolean(searchExpression.getParameter(), PARAM_NO_FETCH, input, context, false, "search", globalResult); - - @SuppressWarnings({ "unchecked", "raw" }) - Class objectClass = (Class) ObjectTypes.getObjectTypeFromTypeQName(searchExpression.getType()).getClassDefinition(); - - ObjectQuery objectQuery = null; - if (searchExpression.getQuery() != null) { - try { - objectQuery = QueryJaxbConvertor.createObjectQuery(objectClass, searchExpression.getQuery(), prismContext); - } catch (SchemaException e) { - throw new ScriptExecutionException("Couldn't parse object query due to schema exception", e); - } - } else if (searchExpression.getSearchFilter() != null) { - // todo resolve variable references in the filter - objectQuery = new ObjectQuery(); - try { - ObjectFilter filter = QueryConvertor.parseFilter(searchExpression.getSearchFilter(), objectClass, prismContext); - objectQuery.setFilter(filter); - } catch (SchemaException e) { - throw new ScriptExecutionException("Couldn't parse object filter due to schema exception", e); - } - } - - final String variableName = searchExpression.getVariable(); - final PipelineData oldVariableValue = variableName != null - ? context.getVariable(variableName) - : null; - final PipelineData outputData = PipelineData.createEmpty(); - final MutableBoolean atLeastOne = new MutableBoolean(false); - - ResultHandler handler = (object, parentResult) -> { - context.checkTaskStop(); - atLeastOne.setValue(true); - if (searchExpression.getScriptingExpression() != null) { - if (variableName != null) { - context.setVariable(variableName, PipelineData.create(object.getValue())); - } - JAXBElement childExpression = searchExpression.getScriptingExpression(); - try { - outputData.addAllFrom(scriptingExpressionEvaluator.evaluateExpression( - (ScriptingExpressionType) childExpression.getValue(), PipelineData.create(object.getValue()), context, globalResult)); - globalResult.setSummarizeSuccesses(true); - globalResult.summarize(); - } catch (ScriptExecutionException e) { - // todo think about this - if (context.isContinueOnAnyError()) { - LoggingUtils.logUnexpectedException(LOGGER, "Exception when evaluating item from search result list.", e); - } else { - throw new SystemException(e); - } - } - } else { - outputData.addValue(object.getValue()); - } - return true; - }; - - try { - Collection> options = operationsHelper.createGetOptions(searchExpression.getOptions(), noFetch); - modelService.searchObjectsIterative(objectClass, objectQuery, handler, options, context.getTask(), globalResult); - } catch (SchemaException | ObjectNotFoundException | SecurityViolationException | CommunicationException | ConfigurationException | ExpressionEvaluationException e) { - // TODO continue on any error? - throw new ScriptExecutionException("Couldn't execute searchObjects operation: " + e.getMessage(), e); - } - - if (atLeastOne.isFalse()) { - String matching = objectQuery != null ? "matching " : ""; - context.println("Warning: no " + matching + searchExpression.getType().getLocalPart() + " object found"); // temporary hack, this will be configurable - } - - if (variableName != null) { - context.setVariable(variableName, oldVariableValue); - } + List data = input.getData(); + if (data.isEmpty()) { + // TODO fix this brutal hack (with dummyValue) + PrismContainerValue dummyValue = new PrismContainerValue<>(prismContext); + PipelineItem dummyItem = new PipelineItem(dummyValue, PipelineData.newOperationResult()); + PipelineItem.copyClonedVariables(context.getInitialVariables(), dummyItem.getVariables()); + data = Collections.singletonList(dummyItem); + } + + final PipelineData outputData = PipelineData.createEmpty(); + final MutableBoolean atLeastOne = new MutableBoolean(false); + + for (PipelineItem item : data) { + + // TODO variables from current item + // TODO operation result handling (global vs local) + boolean noFetch = expressionHelper.getArgumentAsBoolean(searchExpression.getParameter(), PARAM_NO_FETCH, input, context, false, "search", globalResult); + + @SuppressWarnings({ "unchecked", "raw" }) + Class objectClass = (Class) ObjectTypes.getObjectTypeFromTypeQName(searchExpression.getType()).getClassDefinition(); + + ObjectQuery unresolvedObjectQuery = null; + if (searchExpression.getQuery() != null) { + try { + unresolvedObjectQuery = QueryJaxbConvertor.createObjectQuery(objectClass, searchExpression.getQuery(), prismContext); + } catch (SchemaException e) { + throw new ScriptExecutionException("Couldn't parse object query due to schema exception", e); + } + } else if (searchExpression.getSearchFilter() != null) { + unresolvedObjectQuery = new ObjectQuery(); + try { + ObjectFilter filter = QueryConvertor.parseFilter(searchExpression.getSearchFilter(), objectClass, prismContext); + unresolvedObjectQuery.setFilter(filter); + } catch (SchemaException e) { + throw new ScriptExecutionException("Couldn't parse object filter due to schema exception", e); + } + } + ObjectQuery objectQuery; + if (unresolvedObjectQuery != null) { + ExpressionVariables variables = new ExpressionVariables(); + item.getVariables().forEach((name, value) -> variables.addVariableDefinition(new QName(name), value)); + try { + objectQuery = ExpressionUtil + .evaluateQueryExpressions(unresolvedObjectQuery, variables, expressionFactory, prismContext, + "bulk action query", context.getTask(), globalResult); + } catch (SchemaException | ObjectNotFoundException | ExpressionEvaluationException e) { + // TODO continue on any error? + throw new ScriptExecutionException("Couldn't evaluate expressions in object query: " + e.getMessage(), e); + } + } else { + objectQuery = null; + } + + final String variableName = searchExpression.getVariable(); + + ResultHandler handler = (object, parentResult) -> { + context.checkTaskStop(); + atLeastOne.setValue(true); + if (searchExpression.getScriptingExpression() != null) { + if (variableName != null) { + // TODO + } + JAXBElement childExpression = searchExpression.getScriptingExpression(); + try { + outputData.addAllFrom(scriptingExpressionEvaluator.evaluateExpression( + (ScriptingExpressionType) childExpression.getValue(), + PipelineData.create(object.getValue(), item.getVariables()), context, globalResult)); + globalResult.setSummarizeSuccesses(true); + globalResult.summarize(); + } catch (ScriptExecutionException e) { + // todo think about this + if (context.isContinueOnAnyError()) { + LoggingUtils.logUnexpectedException(LOGGER, "Exception when evaluating item from search result list.", e); + } else { + throw new SystemException(e); + } + } + } else { + outputData.addValue(object.getValue(), item.getVariables()); + } + return true; + }; + + try { + Collection> options = operationsHelper.createGetOptions(searchExpression.getOptions(), noFetch); + modelService.searchObjectsIterative(objectClass, objectQuery, handler, options, context.getTask(), globalResult); + } catch (SchemaException | ObjectNotFoundException | SecurityViolationException | CommunicationException | ConfigurationException | ExpressionEvaluationException e) { + // TODO continue on any error? + throw new ScriptExecutionException("Couldn't execute searchObjects operation: " + e.getMessage(), e); + } + } + + if (atLeastOne.isFalse()) { + context.println("Warning: no matching object found"); // temporary hack, this will be configurable + } return outputData; } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/expressions/SelectEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/expressions/SelectEvaluator.java index 4b854829b8b..92782fb79b2 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/expressions/SelectEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/expressions/SelectEvaluator.java @@ -47,7 +47,7 @@ public PipelineData evaluate(SelectExpressionType selectExpression, PipelineData if (o instanceof Item) { List values = ((Item) o).getValues(); values.forEach((v) -> - output.addValue(v, item.getResult().clone())); // clone to avoid aggregating subresults into unrelated results + output.addValue(v, item.getResult().clone(), item.getVariables())); // clone to avoid aggregating subresults into unrelated results } else { throw new ScriptExecutionException( "In 'select' commands, only property/container/reference selection is supported for now. Select on '" diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/scripting/TestScriptingBasic.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/scripting/TestScriptingBasic.java index 46965781615..a2d98ae25ef 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/scripting/TestScriptingBasic.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/scripting/TestScriptingBasic.java @@ -52,10 +52,8 @@ import javax.xml.namespace.QName; import java.io.File; import java.io.IOException; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; +import java.util.stream.Collectors; import static org.testng.AssertJUnit.*; @@ -71,6 +69,7 @@ public class TestScriptingBasic extends AbstractInitializedModelIntegrationTest private static final String DOT_CLASS = TestScriptingBasic.class.getName() + "."; private static final File LOG_FILE = new File(TEST_DIR, "log.xml"); private static final File SEARCH_FOR_USERS_FILE = new File(TEST_DIR, "search-for-users.xml"); + private static final File SEARCH_FOR_USERS_WITH_EXPRESSIONS_FILE = new File(TEST_DIR, "search-for-users-with-expressions.xml"); private static final File SEARCH_FOR_USERS_RESOLVE_NAMES_FOR_ROLE_MEMBERSHIP_REF_FILE = new File(TEST_DIR, "search-for-users-resolve-names-for-roleMembershipRef.xml"); private static final File SEARCH_FOR_USERS_RESOLVE_ROLE_MEMBERSHIP_REF_FILE = new File(TEST_DIR, "search-for-users-resolve-roleMembershipRef.xml"); private static final File SEARCH_FOR_SHADOWS_FILE = new File(TEST_DIR, "search-for-shadows.xml"); @@ -228,6 +227,33 @@ public void test200SearchUser() throws Exception { //assertEquals("administrator", ((PrismObject) output.getData().get(0)).asObjectable().getName().getOrig()); } + @Test + public void test202SearchUserWithExpressions() throws Exception { + final String TEST_NAME = "test202SearchUserWithExpressions"; + TestUtil.displayTestTitle(this, TEST_NAME); + + // GIVEN + Task task = createTask(DOT_CLASS + TEST_NAME); + OperationResult result = task.getResult(); + ExecuteScriptType executeScript = prismContext.parserFor(SEARCH_FOR_USERS_WITH_EXPRESSIONS_FILE).parseRealValue(); + Map variables = new HashMap<>(); + variables.put("value1", "administrator"); + variables.put("value2", "jack"); + + // WHEN + ExecutionContext output = scriptingExpressionEvaluator.evaluateExpression(executeScript, variables, task, result); + + // THEN + dumpOutput(output, result); + result.computeStatus(); + TestUtil.assertSuccess(result); + assertEquals(2, output.getFinalOutput().getData().size()); + assertEquals(new HashSet<>(Arrays.asList("administrator", "jack")), + output.getFinalOutput().getData().stream() + .map(i -> ((PrismObjectValue) i.getValue()).getName().getOrig()) + .collect(Collectors.toSet())); + } + @Test public void test205SearchForResources() throws Exception { final String TEST_NAME = "test205SearchForResources"; diff --git a/model/model-intest/src/test/resources/scripting/search-for-users-with-expressions.xml b/model/model-intest/src/test/resources/scripting/search-for-users-with-expressions.xml new file mode 100644 index 00000000000..2df06058580 --- /dev/null +++ b/model/model-intest/src/test/resources/scripting/search-for-users-with-expressions.xml @@ -0,0 +1,45 @@ + + + + + + c:UserType + + + + + c:name + + + value1 + + + + + c:name + + + value2 + + + + + + + + From 3d89f5788e69cb6c1ffe1ef2ece0ba8877e0af31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Ga=C5=A1par=C3=ADk?= Date: Tue, 19 Sep 2017 15:48:01 +0200 Subject: [PATCH 15/97] Small translation fix --- .../main/resources/localization/Midpoint_cs.properties | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_cs.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_cs.properties index 5be7053d9b3..d2ad9f20957 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_cs.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_cs.properties @@ -1970,7 +1970,7 @@ pageTask.category.UserRecomputation=Přepočítání uživatelů pageTask.category.Workflow=Workflow pageTask.createSuspended=Vytvořit ve stavu POZASTAVENO pageTask.cronHelp=Specifikace plánované úlohy (ve stylu cronu) je v následujícím tvaru: VTEŘINY MINUTY HODINY DEN-V-MĚSÍCI MĚSÍC DEN-V-TÝDNU ROK (volitelné), např. '0 0 12 ? * WED' znamená 'každé úterý v 12:00:00 pm'. -pageTask.cronHelpLink=Více informací je k dispozici na +pageTask.cronHelpLink=Více informací je k dispozici zde: pageTask.cronHelpLinkTutorial=návod pageTask.cronSpec=Plánování spouštění pageTask.dryRun=Spustit nanečisto @@ -1990,7 +1990,7 @@ pageTaskEdit.button.save=Uložit pageTaskEdit.button.suspend=Pozastavit pageTaskEdit.category=Kategorie pageTaskEdit.cronHelp=Specifikace plánované úlohy (ve stylu cronu) je v následujícím tvaru: VTEŘINY MINUTY HODINY DEN-V-MĚSÍCI MĚSÍC DEN-V-TÝDNU ROK (volitelné), např. '0 0 12 ? * WED' znamená 'každé úterý v 12:00:00 pm'. -pageTaskEdit.cronHelpLink=Více informací je k dispozici na +pageTaskEdit.cronHelpLink=Více informací je k dispozici zde: pageTaskEdit.cronHelpLinkTutorial=návod pageTaskEdit.cronSpec=Plánování spouštění pageTaskEdit.description=Popis @@ -3100,7 +3100,7 @@ WorkItemsPanel.escalationLevel=Úroveň eskalace PageAdmin.menu.dashboard=Nástěnka PageAdmin.menu.selfDashboard=Domů PageAdmin.menu.selfService=SAMOOBSLUHA -PageAdmin.menu.mainNavigation=ADMINISTRACE +PageAdmin.menu.mainNavigation=NABÍDKA PageAdmin.menu.additional=Přídavný PageAdmin.menu.profile=Profil PageAdmin.menu.assignments=Přiřazení @@ -3409,7 +3409,7 @@ PageResourceVisualization.title=Vizualizace mapování pro {0} PageResourceVisualization.dotMessage=Vykreslování DOT grafu nemohlo být dokončeno. Prosím zkontrolujte chybovou hlášku níže a ujistěte se, že: PageResourceVisualization.dot1=Vykreslovací software DOR je nainstalován na serveru. Doporučený SW je Graphviz. PageResourceVisualization.dot2=Cesta k spustitelnému souboru pro DOT vykreslování je správně nastavena v xonfig.xml souboru. -PageResourceVisualization.moreInformation=Více informací je k dispozici na +PageResourceVisualization.moreInformation=Více informací je k dispozici zde: PageResourceVisualization.moreInformationLink=tento článek PageResourceVisualization.errorMessage=Chybová hláška: PageResourceVisualization.seeOnline=Můžete též vyzkoušet online DOT vykreslovač, například From 5fbe1d55088495fc2e096fda92979b4ff9414fae Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Tue, 19 Sep 2017 16:04:12 +0200 Subject: [PATCH 16/97] mutlivalue container, small prism wrappers cleanup --- .../gui/api/util/WebComponentUtil.java | 5 + .../AbstractAssignmentDetailsPanel.html | 135 ++++----- .../AbstractAssignmentDetailsPanel.java | 83 ++++-- .../AbstractRoleAssignmentDetailsPanel.java | 270 ++++++++++-------- .../AbstractRoleAssignmentPanel.java | 5 +- .../component/assignment/AssignmentPanel.java | 6 +- .../PolicyRuleConstraintsExpandablePanel.java | 59 ++-- .../assignment/PolicyRuleDetailsPanel.java | 57 ++-- .../assignment/PolicyRulePropertiesPanel.java | 27 +- .../assignment/PolicyRulesPanel.java | 5 +- .../objectdetails/FocusDetailsTabPanel.html | 4 +- .../objectdetails/FocusDetailsTabPanel.java | 50 ++-- .../FocusProjectionsTabPanel.java | 7 +- .../component/prism/ContainerValuePanel.java | 14 +- .../prism/ContainerValueWrapper.java | 35 ++- .../web/component/prism/ContainerWrapper.java | 29 +- .../prism/ContainerWrapperFactory.java | 28 +- .../prism/DynamicFieldGroupPanel.java | 2 +- .../web/component/prism/DynamicFormPanel.java | 2 +- .../prism/ItemVisibilityHandler.java | 10 + .../web/component/prism/ItemWrapper.java | 3 + .../web/component/prism/ObjectWrapper.java | 63 ++-- .../component/prism/ObjectWrapperFactory.java | 11 +- .../prism/PrismContainerHeaderPanel.java | 5 + .../component/prism/PrismContainerPanel.html | 4 +- .../component/prism/PrismContainerPanel.java | 19 +- .../prism/PrismContainerValueHeaderPanel.java | 31 +- .../web/component/prism/PrismHeaderPanel.java | 75 ++--- .../prism/PrismOptionButtonPanel.java | 6 +- .../web/component/prism/PrismPanel.html | 28 ++ .../web/component/prism/PrismPanel.java | 114 ++++++++ .../prism/PropertyOrReferenceWrapper.java | 18 +- .../wizard/resource/ConfigurationStep.java | 2 +- ...nerValueWrapperFromObjectWrapperModel.java | 75 +++++ ...inerWrapperListFromObjectWrapperModel.java | 83 ++++++ .../page/admin/PageAdminObjectDetails.java | 2 +- .../admin/resources/content/PageAccount.java | 18 +- .../server/handlers/GenericHandlerPanel.java | 2 +- 38 files changed, 940 insertions(+), 452 deletions(-) create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemVisibilityHandler.java create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismPanel.html create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismPanel.java create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/model/ContainerValueWrapperFromObjectWrapperModel.java create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/model/ContainerWrapperListFromObjectWrapperModel.java diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java index 5b7c7a863e9..e43ce5d1569 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java @@ -386,6 +386,11 @@ public static DateValidator getRangeValidator(Form form, ItemPath path) { return validator; } + + public static boolean isItemVisible(List visibleItems, ItemPath itemToBeFound) { + return ItemPath.containsSubpathOrEquivalent(visibleItems, itemToBeFound); + + } public static Class qnameToClass(PrismContext prismContext, QName type) { return prismContext.getSchemaRegistry().determineCompileTimeClass(type); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.html index b83b8a84365..dbe081b1464 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.html @@ -17,20 +17,25 @@ xmlns:wicket="http://wicket.apache.org"> +
+
+
-
-
+ + -
-
-
-
- - - -
+ + + + + + + + -
+ + + @@ -47,20 +52,20 @@ -
-
-
- -
-
-
-
-
-
-
-
-
-
+ + + + + + + + + + + + + + @@ -77,23 +82,23 @@ -
-
-
- -
-
-
-
+ + + + + + + + -
-
-
- -
-
-
-
+ + + + + + + + @@ -106,36 +111,36 @@ -
-
- -
-
-
-
- -
- -
-
-
-
+ + + + + + + + + + + + + + -
-
-
+ + + -
+ -
-
-
-
-
-
+ + + + + + diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.java index ae2ddc21410..0ac8679f5f8 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.java @@ -28,15 +28,23 @@ import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.web.component.form.Form; +import com.evolveum.midpoint.web.component.prism.ContainerValuePanel; +import com.evolveum.midpoint.web.component.prism.PrismContainerPanel; +import com.evolveum.midpoint.web.component.prism.PropertyOrReferenceWrapper; +import com.evolveum.midpoint.web.model.ContainerValueWrapperFromObjectWrapperModel; +import com.evolveum.midpoint.web.model.ContainerWrapperFromObjectWrapperModel; +import com.evolveum.midpoint.web.page.admin.PageAdminObjectDetails; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; /** * Created by honchar */ -public abstract class AbstractAssignmentDetailsPanel extends BasePanel{ +public abstract class AbstractAssignmentDetailsPanel extends BasePanel{ private static final long serialVersionUID = 1L; private final static String ID_DISPLAY_NAME = "displayName"; @@ -56,15 +64,19 @@ public abstract class AbstractAssignmentDetailsPanel extends BasePanel form, IModel assignmentModel, PageBase pageBase){ + public AbstractAssignmentDetailsPanel(String id, Form form, IModel assignmentModel){ super(id, assignmentModel); - this.pageBase= pageBase; - initLayout(form); + + + } + + @Override + protected void onInitialize() { + super.onInitialize(); + initLayout(); } - protected void initLayout(Form form){ + protected void initLayout(){ DisplayNamePanel displayNamePanel = new DisplayNamePanel(ID_DISPLAY_NAME, new AbstractReadOnlyModel() { @@ -74,9 +86,9 @@ protected void initLayout(Form form){ public C getObject() { AssignmentDto assignemtn = getModelObject(); if (assignemtn.isAssignableObject()) { - Task task = AbstractAssignmentDetailsPanel.this.pageBase.createSimpleTask("Load target"); + Task task = getPageBase().createSimpleTask("Load target"); com.evolveum.midpoint.schema.result.OperationResult result = task.getResult(); - return (C) WebModelServiceUtils.loadObject(getModelObject().getAssignment().getTargetRef(), AbstractAssignmentDetailsPanel.this.pageBase, task, result).asObjectable(); + return (C) WebModelServiceUtils.loadObject(getModelObject().getAssignment().getTargetRef(), getPageBase(), task, result).asObjectable(); } AssignmentType assignmentType = assignemtn.getAssignment(); if (assignmentType.getConstruction() != null) { @@ -97,28 +109,37 @@ public C getObject() { displayNamePanel.setOutputMarkupId(true); add(displayNamePanel); - - WebMarkupContainer properties = new WebMarkupContainer(ID_PROPERTIES_PANEL); - add(properties); - properties.setOutputMarkupId(true); - - initPropertiesPanel(properties); - - - AssignmentActivationPopupablePanel activationPanel = new AssignmentActivationPopupablePanel(ID_ACTIVATION_PANEL, new PropertyModel(getModel(), AssignmentDto.F_VALUE + "." + AssignmentType.F_ACTIVATION.getLocalPart())){ - private static final long serialVersionUID = 1L; - - @Override - protected boolean getButtonsPanelVisibility() { - return false; - } - }; - activationPanel.setOutputMarkupId(true); - add(activationPanel); - + + PageAdminObjectDetails pageBase = (PageAdminObjectDetails)getPageBase(); + + ItemPath assignmentPath = getModel().getObject().getAssignment().asPrismContainerValue().getPath(); + ContainerValueWrapperFromObjectWrapperModel assignmentModel = + new ContainerValueWrapperFromObjectWrapperModel(pageBase.getObjectModel(), assignmentPath); + + Form form = new Form<>("form"); + + ContainerValuePanel assignmentPanel = new ContainerValuePanel("basic", assignmentModel, true, form, itemWrapper -> PropertyOrReferenceWrapper.class.isAssignableFrom(itemWrapper.getClass()), pageBase); + add(assignmentPanel); + + ContainerWrapperFromObjectWrapperModel activationModel = new ContainerWrapperFromObjectWrapperModel(pageBase.getObjectModel(), assignmentPath.append(AssignmentType.F_ACTIVATION)); + PrismContainerPanel acitvationContainer = new PrismContainerPanel<>(ID_ACTIVATION_PANEL, activationModel, false, form, itemWrapper -> getActivationVisibileItems(itemWrapper.getPath(), assignmentPath), pageBase); + add(acitvationContainer); + + } + + protected abstract boolean getVisibilityModel(ItemPath pathToBeFound, ItemPath parentPath); + + private boolean getActivationVisibileItems(ItemPath pathToCheck, ItemPath assignmentPath) { + if (assignmentPath.subPath(new ItemPath(AssignmentType.F_ACTIVATION, ActivationType.F_LOCKOUT_EXPIRATION_TIMESTAMP)).equivalent(pathToCheck)){ + return false; + } + + if (assignmentPath.subPath(new ItemPath(AssignmentType.F_ACTIVATION, ActivationType.F_LOCKOUT_STATUS)).equivalent(pathToCheck)){ + return false; + } + + return true; } - - protected IModel getAdditionalNameLabelStyleClass(){ @@ -131,6 +152,6 @@ protected boolean isVisible(Object path) { protected abstract List getHiddenItems(); - protected abstract void initPropertiesPanel(WebMarkupContainer propertiesPanel); +// protected abstract void initPropertiesPanel(WebMarkupContainer propertiesPanel); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentDetailsPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentDetailsPanel.java index 3a868ed1c0f..4babe8ebe24 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentDetailsPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentDetailsPanel.java @@ -17,6 +17,7 @@ import com.evolveum.midpoint.gui.api.GuiStyleConstants; import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.NotFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; @@ -25,13 +26,20 @@ import com.evolveum.midpoint.web.component.form.Form; import com.evolveum.midpoint.web.component.input.DropDownChoicePanel; import com.evolveum.midpoint.web.component.input.TextPanel; +import com.evolveum.midpoint.web.component.prism.ContainerValuePanel; +import com.evolveum.midpoint.web.component.prism.ItemWrapper; +import com.evolveum.midpoint.web.component.prism.ObjectWrapper; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; +import com.evolveum.midpoint.web.model.ContainerValueWrapperFromObjectWrapperModel; +import com.evolveum.midpoint.web.page.admin.PageAdminObjectDetails; import com.evolveum.midpoint.web.page.admin.configuration.component.ChooseTypePanel; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; -public class AbstractRoleAssignmentDetailsPanel extends AbstractAssignmentDetailsPanel { +public class AbstractRoleAssignmentDetailsPanel extends AbstractAssignmentDetailsPanel { private static final long serialVersionUID = 1L; @@ -51,131 +59,153 @@ public class AbstractRoleAssignmentDetailsPanel extends AbstractAssignmentDetail hiddenItems.add(AssignmentType.F_POLICY_RULE); }; - public AbstractRoleAssignmentDetailsPanel(String id, Form form, IModel assignmentModel, PageBase pageBase) { - super(id, form, assignmentModel, pageBase); + public AbstractRoleAssignmentDetailsPanel(String id, Form form, IModel assignmentModel) { + super(id, form, assignmentModel); } @Override protected List getHiddenItems() { return hiddenItems; } - - @Override - protected void initPropertiesPanel(WebMarkupContainer propertiesPanel) { - WebMarkupContainer relationContainer = new WebMarkupContainer(ID_RELATION_CONTAINER); - DropDownChoicePanel relation = WebComponentUtil.createEnumPanel(RelationTypes.class, ID_RELATION, - WebComponentUtil.createReadonlyModelFromEnum(RelationTypes.class), new PropertyModel(getModel(), AssignmentDto.F_RELATION_TYPE), this, true); - relation.getBaseFormComponent().add(new AjaxFormComponentUpdatingBehavior("change") { - private static final long serialVersionUID = 1L; - - @Override - protected void onUpdate(AjaxRequestTarget target) { - target.add(AbstractRoleAssignmentDetailsPanel.this); - } - }); - relationContainer.add(relation); - propertiesPanel.add(relationContainer); - relationContainer.setOutputMarkupId(true); - - AssignmentType assignmentType = getModel().getObject().getAssignment(); - - WebMarkupContainer tenantContainer = new WebMarkupContainer(ID_TENANT_CONTAINER); - ChooseTypePanel tenantChooser = createParameterChooserPanel(ID_TENANT, assignmentType.getTenantRef(), true); - tenantContainer.add(tenantChooser); - propertiesPanel.add(tenantContainer); - tenantContainer.setOutputMarkupId(true); - tenantContainer.add(new VisibleEnableBehaviour() { - - private static final long serialVersionUID = 1L; - - @Override - public boolean isVisible() { - return AbstractRoleAssignmentDetailsPanel.this.isVisible(AssignmentType.F_TENANT_REF); - } - }); - - WebMarkupContainer projectContainer = new WebMarkupContainer(ID_PROJECT_CONTAINER); - ChooseTypePanel projectChooser = createParameterChooserPanel(ID_PROJECT, assignmentType.getOrgRef(), false); - projectContainer.add(projectChooser); - propertiesPanel.add(projectContainer); - projectContainer.setOutputMarkupId(true); - projectContainer.add(new VisibleEnableBehaviour() { - - private static final long serialVersionUID = 1L; - - @Override - public boolean isVisible() { - return AbstractRoleAssignmentDetailsPanel.this.isVisible(AssignmentType.F_ORG_REF); - } - }); - - ListView policySituations = new ListView(ID_POLICY_SITUATIONS, new PropertyModel>(getModel(), AssignmentDto.F_VALUE + "." + AssignmentType.F_POLICY_SITUATION.getLocalPart())) { - - private static final long serialVersionUID = 1L; - - @Override - protected void populateItem(ListItem item) { - TextPanel textPanel = new TextPanel(ID_POLICY_SITUATION, item.getModel()); - textPanel.setOutputMarkupId(true); - item.add(textPanel); - - } - }; - policySituations.setOutputMarkupId(true); - propertiesPanel.add(policySituations); - } - - private ChooseTypePanel createParameterChooserPanel(String id, ObjectReferenceType ref, boolean isTenant){ - ChooseTypePanel orgSelector = new ChooseTypePanel(id, ref) { - - private static final long serialVersionUID = 1L; - - @Override - protected void executeCustomAction(AjaxRequestTarget target, OrgType object) { - if (isTenant) { - AbstractRoleAssignmentDetailsPanel.this.getModelObject().getAssignment().setTenantRef(ObjectTypeUtil.createObjectRef(object)); - } else { - AbstractRoleAssignmentDetailsPanel.this.getModelObject().getAssignment().setOrgRef(ObjectTypeUtil.createObjectRef(object)); - } - target.add(AbstractRoleAssignmentDetailsPanel.this); - } - - @Override - protected void executeCustomRemoveAction(AjaxRequestTarget target) { - if (isTenant) { - AbstractRoleAssignmentDetailsPanel.this.getModelObject().getAssignment().setTenantRef(null); - } else { - AbstractRoleAssignmentDetailsPanel.this.getModelObject().getAssignment().setOrgRef(null); - } - target.add(AbstractRoleAssignmentDetailsPanel.this); - } - - @Override - protected ObjectQuery getChooseQuery() { - ObjectFilter tenantFilter = QueryBuilder.queryFor(OrgType.class, getPageBase().getPrismContext()).item(OrgType.F_TENANT).eq(true).buildFilter(); - - if (isTenant) { - return ObjectQuery.createObjectQuery(tenantFilter); - } - return ObjectQuery.createObjectQuery(NotFilter.createNot(tenantFilter)); - } - - @Override - protected boolean isSearchEnabled() { - return true; - } - - @Override - public Class getObjectTypeClass() { - return OrgType.class; - } - - }; - orgSelector.setOutputMarkupId(true); - return orgSelector; - - } - + protected boolean getVisibilityModel(ItemPath itemToBeFound, ItemPath parentAssignmentPath) { + AssignmentType assignment = getModelObject().getAssignment(); + ObjectReferenceType targetRef = assignment.getTargetRef(); + List pathsToHide = new ArrayList<>(); + QName targetType = null; + if (targetRef != null) { + targetType = targetRef.getType(); + } + pathsToHide.add(parentAssignmentPath.append(AssignmentType.F_TARGET_REF)); + + if (OrgType.COMPLEX_TYPE.equals(targetType)) { + pathsToHide.add(parentAssignmentPath.append(AssignmentType.F_TENANT_REF)); + pathsToHide.add(parentAssignmentPath.append(AssignmentType.F_ORG_REF)); + } + + if (assignment.getConstruction() == null) { + pathsToHide.add(parentAssignmentPath.append(AssignmentType.F_CONSTRUCTION)); + } + pathsToHide.add(parentAssignmentPath.append(AssignmentType.F_PERSONA_CONSTRUCTION)); + pathsToHide.add(parentAssignmentPath.append(AssignmentType.F_POLICY_RULE)); + + return !WebComponentUtil.isItemVisible(pathsToHide, itemToBeFound); + } +// private ChooseTypePanel createParameterChooserPanel(String id, ObjectReferenceType ref, boolean isTenant){ +// ChooseTypePanel orgSelector = new ChooseTypePanel(id, ref) { +// +// private static final long serialVersionUID = 1L; +// +// @Override +// protected void executeCustomAction(AjaxRequestTarget target, OrgType object) { +// if (isTenant) { +// AbstractRoleAssignmentDetailsPanel.this.getModelObject().getAssignment().setTenantRef(ObjectTypeUtil.createObjectRef(object)); +// } else { +// AbstractRoleAssignmentDetailsPanel.this.getModelObject().getAssignment().setOrgRef(ObjectTypeUtil.createObjectRef(object)); +// } +// target.add(AbstractRoleAssignmentDetailsPanel.this); +// } +// +// @Override +// protected void executeCustomRemoveAction(AjaxRequestTarget target) { +// if (isTenant) { +// AbstractRoleAssignmentDetailsPanel.this.getModelObject().getAssignment().setTenantRef(null); +// } else { +// AbstractRoleAssignmentDetailsPanel.this.getModelObject().getAssignment().setOrgRef(null); +// } +// target.add(AbstractRoleAssignmentDetailsPanel.this); +// } +// +// @Override +// protected ObjectQuery getChooseQuery() { +// ObjectFilter tenantFilter = QueryBuilder.queryFor(OrgType.class, getPageBase().getPrismContext()).item(OrgType.F_TENANT).eq(true).buildFilter(); +// +// if (isTenant) { +// return ObjectQuery.createObjectQuery(tenantFilter); +// } +// return ObjectQuery.createObjectQuery(NotFilter.createNot(tenantFilter)); +// +// } +// +// @Override +// protected boolean isSearchEnabled() { +// return true; +// } +// +// @Override +// public Class getObjectTypeClass() { +// return OrgType.class; +// } +// +// }; +// orgSelector.setOutputMarkupId(true); +// return orgSelector; +// +// } + + +// private void initStatic(WebMarkupContainer propertiesPanel){ +// WebMarkupContainer relationContainer = new WebMarkupContainer(ID_RELATION_CONTAINER); +// DropDownChoicePanel relation = WebComponentUtil.createEnumPanel(RelationTypes.class, ID_RELATION, +// WebComponentUtil.createReadonlyModelFromEnum(RelationTypes.class), new PropertyModel(getModel(), AssignmentDto.F_RELATION_TYPE), this, true); +// relation.getBaseFormComponent().add(new AjaxFormComponentUpdatingBehavior("change") { +// private static final long serialVersionUID = 1L; +// +// @Override +// protected void onUpdate(AjaxRequestTarget target) { +// target.add(AbstractRoleAssignmentDetailsPanel.this); +// } +// }); +// relationContainer.add(relation); +// propertiesPanel.add(relationContainer); +// relationContainer.setOutputMarkupId(true); +// +// AssignmentType assignmentType = getModel().getObject().getAssignment(); +// +// WebMarkupContainer tenantContainer = new WebMarkupContainer(ID_TENANT_CONTAINER); +// ChooseTypePanel tenantChooser = createParameterChooserPanel(ID_TENANT, assignmentType.getTenantRef(), true); +// tenantContainer.add(tenantChooser); +// propertiesPanel.add(tenantContainer); +// tenantContainer.setOutputMarkupId(true); +// tenantContainer.add(new VisibleEnableBehaviour() { +// +// private static final long serialVersionUID = 1L; +// +// @Override +// public boolean isVisible() { +// return AbstractRoleAssignmentDetailsPanel.this.isVisible(AssignmentType.F_TENANT_REF); +// } +// }); +// +// WebMarkupContainer projectContainer = new WebMarkupContainer(ID_PROJECT_CONTAINER); +// ChooseTypePanel projectChooser = createParameterChooserPanel(ID_PROJECT, assignmentType.getOrgRef(), false); +// projectContainer.add(projectChooser); +// propertiesPanel.add(projectContainer); +// projectContainer.setOutputMarkupId(true); +// projectContainer.add(new VisibleEnableBehaviour() { +// +// private static final long serialVersionUID = 1L; +// +// @Override +// public boolean isVisible() { +// return AbstractRoleAssignmentDetailsPanel.this.isVisible(AssignmentType.F_ORG_REF); +// } +// }); +// +// ListView policySituations = new ListView(ID_POLICY_SITUATIONS, new PropertyModel>(getModel(), AssignmentDto.F_VALUE + "." + AssignmentType.F_POLICY_SITUATION.getLocalPart())) { +// +// private static final long serialVersionUID = 1L; +// +// @Override +// protected void populateItem(ListItem item) { +// TextPanel textPanel = new TextPanel(ID_POLICY_SITUATION, item.getModel()); +// textPanel.setOutputMarkupId(true); +// item.add(textPanel); +// +// } +// }; +// policySituations.setOutputMarkupId(true); +// propertiesPanel.add(policySituations); +// } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java index ba3672ee5d8..4e4c2fb7001 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java @@ -301,9 +301,8 @@ private QName getRelation() { } @Override - protected AbstractAssignmentDetailsPanel createDetailsPanel(String idAssignmentDetails, Form form, IModel model, - PageBase parentPage) { - return new AbstractRoleAssignmentDetailsPanel(ID_ASSIGNMENT_DETAILS, form, model, getParentPage()); + protected AbstractAssignmentDetailsPanel createDetailsPanel(String idAssignmentDetails, Form form, IModel model) { + return new AbstractRoleAssignmentDetailsPanel(ID_ASSIGNMENT_DETAILS, form, model); } protected boolean isRelationVisible() { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentPanel.java index 316a0d94af9..6ab880a0563 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentPanel.java @@ -338,8 +338,7 @@ public List getObject() { @Override protected void populateItem(ListItem item) { Form form = this.findParent(Form.class); - AbstractAssignmentDetailsPanel details = createDetailsPanel(ID_ASSIGNMENT_DETAILS, form, item.getModel(), - getParentPage()); + AbstractAssignmentDetailsPanel details = createDetailsPanel(ID_ASSIGNMENT_DETAILS, form, item.getModel()); item.add(details); details.setOutputMarkupId(true); @@ -385,8 +384,7 @@ protected BoxedTablePanel getAssignmentTable() { return (BoxedTablePanel) get(createComponentPath(ID_ASSIGNMENTS, ID_ASSIGNMENTS_TABLE)); } - protected abstract AbstractAssignmentDetailsPanel createDetailsPanel(String idAssignmentDetails, Form form, IModel model, - PageBase parentPage); + protected abstract AbstractAssignmentDetailsPanel createDetailsPanel(String idAssignmentDetails, Form form, IModel model); private List getSelectedAssignments() { BoxedTablePanel assignemntTable = getAssignmentTable(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleConstraintsExpandablePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleConstraintsExpandablePanel.java index 793e4d4cf01..1e9c5be7a9c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleConstraintsExpandablePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleConstraintsExpandablePanel.java @@ -33,40 +33,41 @@ public PolicyRuleConstraintsExpandablePanel(String id, IModel

model){ @Override protected void onInitialize() { super.onInitialize(); - initContainerWrapper(); +// initContainerWrapper(); initLayout(); } - private void initContainerWrapper(){ - ContainerWrapperFactory cwf = new ContainerWrapperFactory(getPageBase()); - ItemPath exclusionContainerPath = new ItemPath(AssignmentType.F_POLICY_RULE, PolicyRuleType.F_POLICY_CONSTRAINTS, - PolicyConstraintsType.F_EXCLUSION); - -// if (exclusionContainer != null) { - policyRuleConstraintsContainerWrapper = cwf.createContainerWrapper(getModelObject().asPrismContainerValue().getContainer(), ContainerStatus.MODIFYING, exclusionContainerPath, true); -// } else { -// exclusionContainer = containerDef.instantiate(); -// containerWrapper = cwf.createContainerWrapper(exclusionContainer, ContainerStatus.ADDING, exclusionContainerPath, false); -// } - - } +// private void initContainerWrapper(){ +// ContainerWrapperFactory cwf = new ContainerWrapperFactory(getPageBase()); +// ItemPath exclusionContainerPath = new ItemPath(AssignmentType.F_POLICY_RULE, PolicyRuleType.F_POLICY_CONSTRAINTS, +// PolicyConstraintsType.F_EXCLUSION); +// +//// if (exclusionContainer != null) { +// policyRuleConstraintsContainerWrapper = cwf.createContainerWrapper(getModelObject().asPrismContainerValue().getContainer(), ContainerStatus.MODIFYING, exclusionContainerPath, true); +//// } else { +//// exclusionContainer = containerDef.instantiate(); +//// containerWrapper = cwf.createContainerWrapper(exclusionContainer, ContainerStatus.ADDING, exclusionContainerPath, false); +//// } +// +// } private void initLayout(){ - Label boxTitle = new Label(ID_BOX_TITLE, getModel().getObject().asPrismContainerValue().getPath().last()); - add(boxTitle); - - AjaxButton removeRowButton = new AjaxButton(ID_REMOVE_BUTTON) { - @Override - public void onClick(AjaxRequestTarget ajaxRequestTarget) { -// policyRuleConstraintsContainerWrapper.getStatus(). - } - }; - add(removeRowButton); - - PrismContainerPanel propertiesPanel = new PrismContainerPanel(ID_PROPERTIES_CONTAINER, - Model.of(policyRuleConstraintsContainerWrapper), false, null, getPageBase()); - propertiesPanel.setOutputMarkupId(true); - add(propertiesPanel); +// Label boxTitle = new Label(ID_BOX_TITLE, getModel().getObject().asPrismContainerValue().getPath().last()); +// add(boxTitle); +// +// AjaxButton removeRowButton = new AjaxButton(ID_REMOVE_BUTTON) { +// @Override +// public void onClick(AjaxRequestTarget ajaxRequestTarget) { +//// policyRuleConstraintsContainerWrapper.getStatus(). +// } +// }; +// add(removeRowButton); +// +// +// PrismContainerPanel propertiesPanel = new PrismContainerPanel(ID_PROPERTIES_CONTAINER, +// Model.of(policyRuleConstraintsContainerWrapper), false, null, getPageBase()); +// propertiesPanel.setOutputMarkupId(true); +// add(propertiesPanel); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleDetailsPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleDetailsPanel.java index 1d2cf4481cb..6e0da2893f8 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleDetailsPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleDetailsPanel.java @@ -25,9 +25,14 @@ import org.apache.wicket.model.IModel; import com.evolveum.midpoint.gui.api.page.PageBase; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.web.component.form.Form; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; + import org.apache.wicket.model.PropertyModel; /** @@ -47,8 +52,8 @@ public class PolicyRuleDetailsPanel extends AbstractAssignmentDetailsPanel { hiddenItems.add(ID_PROPERTIES_PANEL); }; - public PolicyRuleDetailsPanel(String id, Form form, IModel model, PageBase pageBase){ - super(id, form, model, pageBase); + public PolicyRuleDetailsPanel(String id, Form form, IModel model){ + super(id, form, model); } @Override @@ -56,21 +61,39 @@ protected List getHiddenItems() { return hiddenItems; } - @Override -protected void initPropertiesPanel(WebMarkupContainer propertiesPanel) { - PolicyRulePropertiesPanel policyDetails = new PolicyRulePropertiesPanel(ID_POLICY_RULE, - new PropertyModel<>(getModel(), pageBase.createPropertyModelExpression(AssignmentDto.F_VALUE, AssignmentType.F_POLICY_RULE.getLocalPart())), pageBase); - policyDetails.setOutputMarkupId(true); - policyDetails.add(new VisibleEnableBehaviour() { - - private static final long serialVersionUID = 1L; + protected boolean getVisibilityModel(ItemPath itemToBeFound, ItemPath parentAssignmentPath) { +// AssignmentType assignment = getModelObject().getAssignment(); +// ObjectReferenceType targetRef = assignment.getTargetRef(); + List pathsToHide = new ArrayList<>(); + + pathsToHide.add(parentAssignmentPath.append(AssignmentType.F_TARGET_REF)); + + pathsToHide.add(parentAssignmentPath.append(AssignmentType.F_TENANT_REF)); + pathsToHide.add(parentAssignmentPath.append(AssignmentType.F_ORG_REF)); + + pathsToHide.add(parentAssignmentPath.append(AssignmentType.F_CONSTRUCTION)); + pathsToHide.add(parentAssignmentPath.append(AssignmentType.F_PERSONA_CONSTRUCTION)); +// pathsToHide.add(parentAssignmentPath.append(AssignmentType.F_POLICY_RULE)); + + return !WebComponentUtil.isItemVisible(pathsToHide, itemToBeFound); + } - @Override - public boolean isVisible() { - return PolicyRuleDetailsPanel.this.isVisible(AssignmentType.F_POLICY_RULE); - } - }); - propertiesPanel.add(policyDetails); -} + +// @Override +//protected void initPropertiesPanel(WebMarkupContainer propertiesPanel) { +// PolicyRulePropertiesPanel policyDetails = new PolicyRulePropertiesPanel(ID_POLICY_RULE, +// new PropertyModel<>(getModel(), getPageBase().createPropertyModelExpression(AssignmentDto.F_VALUE, AssignmentType.F_POLICY_RULE.getLocalPart()))); +// policyDetails.setOutputMarkupId(true); +// policyDetails.add(new VisibleEnableBehaviour() { +// +// private static final long serialVersionUID = 1L; +// +// @Override +// public boolean isVisible() { +// return PolicyRuleDetailsPanel.this.isVisible(AssignmentType.F_POLICY_RULE); +// } +// }); +// propertiesPanel.add(policyDetails); +//} } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRulePropertiesPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRulePropertiesPanel.java index be304e26316..613451a0feb 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRulePropertiesPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRulePropertiesPanel.java @@ -59,12 +59,15 @@ public class PolicyRulePropertiesPanel extends BasePanel{ private static final String ID_ADD_TIME_VALIDITY = "addTimeValidityConstraints"; private static final String ID_ADD_SITUATION = "addSituationConstraints"; - private PageBase pageBase; - - public PolicyRulePropertiesPanel(String id, IModel policyRuleModel, PageBase pageBase){ + + public PolicyRulePropertiesPanel(String id, IModel policyRuleModel){ super(id, policyRuleModel); - this.pageBase = pageBase; - initLayout(); +// initLayout(); + } + + @Override + protected void onInitialize() { + initLayout(); } private void initLayout(){ @@ -125,7 +128,7 @@ public void onClick(AjaxRequestTarget ajaxRequestTarget) { private void initConstraintsContainer(WebMarkupContainer constraintsContainer){ ListView exclusionRepeater = new ListView(ID_EXCLUSION_REPEATER, new PropertyModel<>(getModel(), - pageBase.createPropertyModelExpression(PolicyRuleType.F_POLICY_CONSTRAINTS.getLocalPart(), PolicyConstraintsType.F_EXCLUSION.getLocalPart()))) { + getPageBase().createPropertyModelExpression(PolicyRuleType.F_POLICY_CONSTRAINTS.getLocalPart(), PolicyConstraintsType.F_EXCLUSION.getLocalPart()))) { @Override protected void populateItem(final ListItem listItem) { PolicyRuleConstraintsExpandablePanel exclusionPropertiesPanel = @@ -136,7 +139,7 @@ protected void populateItem(final ListItem listIt constraintsContainer.addOrReplace(exclusionRepeater); ListView minAssigneesRepeater = new ListView(ID_MIN_ASSIGNEES_REPEATER, new PropertyModel<>(getModel(), - pageBase.createPropertyModelExpression(PolicyRuleType.F_POLICY_CONSTRAINTS.getLocalPart(), PolicyConstraintsType.F_MIN_ASSIGNEES.getLocalPart()))) { + getPageBase().createPropertyModelExpression(PolicyRuleType.F_POLICY_CONSTRAINTS.getLocalPart(), PolicyConstraintsType.F_MIN_ASSIGNEES.getLocalPart()))) { @Override protected void populateItem(final ListItem listItem) { PolicyRuleConstraintsExpandablePanel minAssigneesPropertiesPanel = @@ -147,7 +150,7 @@ protected void populateItem(final ListItem lis constraintsContainer.addOrReplace(minAssigneesRepeater); ListView maxAssigneesRepeater = new ListView(ID_MAX_ASSIGNEES_REPEATER, new PropertyModel<>(getModel(), - pageBase.createPropertyModelExpression(PolicyRuleType.F_POLICY_CONSTRAINTS.getLocalPart(), PolicyConstraintsType.F_MAX_ASSIGNEES.getLocalPart()))) { + getPageBase().createPropertyModelExpression(PolicyRuleType.F_POLICY_CONSTRAINTS.getLocalPart(), PolicyConstraintsType.F_MAX_ASSIGNEES.getLocalPart()))) { @Override protected void populateItem(final ListItem listItem) { PolicyRuleConstraintsExpandablePanel maxAssigneesPropertiesPanel = @@ -158,7 +161,7 @@ protected void populateItem(final ListItem lis constraintsContainer.addOrReplace(maxAssigneesRepeater); ListView modificationRepeater = new ListView(ID_MODIFICATION_REPEATER, new PropertyModel<>(getModel(), - pageBase.createPropertyModelExpression(PolicyRuleType.F_POLICY_CONSTRAINTS.getLocalPart(), PolicyConstraintsType.F_MODIFICATION.getLocalPart()))) { + getPageBase().createPropertyModelExpression(PolicyRuleType.F_POLICY_CONSTRAINTS.getLocalPart(), PolicyConstraintsType.F_MODIFICATION.getLocalPart()))) { @Override protected void populateItem(final ListItem listItem) { PolicyRuleConstraintsExpandablePanel modificationPropertiesPanel = @@ -169,7 +172,7 @@ protected void populateItem(final ListItem lis constraintsContainer.addOrReplace(modificationRepeater); ListView assignmentRepeater = new ListView(ID_ASSIGNMENT_REPEATER, new PropertyModel<>(getModel(), - pageBase.createPropertyModelExpression(PolicyRuleType.F_POLICY_CONSTRAINTS.getLocalPart(), PolicyConstraintsType.F_ASSIGNMENT.getLocalPart()))) { + getPageBase().createPropertyModelExpression(PolicyRuleType.F_POLICY_CONSTRAINTS.getLocalPart(), PolicyConstraintsType.F_ASSIGNMENT.getLocalPart()))) { @Override protected void populateItem(final ListItem listItem) { PolicyRuleConstraintsExpandablePanel assignmentPropertiesPanel = @@ -180,7 +183,7 @@ protected void populateItem(final ListItem listI constraintsContainer.addOrReplace(assignmentRepeater); ListView timeValidityRepeater = new ListView(ID_TIME_VALIDITY_REPEATER, new PropertyModel<>(getModel(), - pageBase.createPropertyModelExpression(PolicyRuleType.F_POLICY_CONSTRAINTS.getLocalPart(), PolicyConstraintsType.F_TIME_VALIDITY.getLocalPart()))) { + getPageBase().createPropertyModelExpression(PolicyRuleType.F_POLICY_CONSTRAINTS.getLocalPart(), PolicyConstraintsType.F_TIME_VALIDITY.getLocalPart()))) { @Override protected void populateItem(final ListItem listItem) { PolicyRuleConstraintsExpandablePanel timeValidityPropertiesPanel = @@ -191,7 +194,7 @@ protected void populateItem(final ListItem lis constraintsContainer.addOrReplace(timeValidityRepeater); ListView situationRepeater = new ListView(ID_SITUATION_REPEATER, new PropertyModel<>(getModel(), - pageBase.createPropertyModelExpression(PolicyRuleType.F_POLICY_CONSTRAINTS.getLocalPart(), PolicyConstraintsType.F_SITUATION.getLocalPart()))) { + getPageBase().createPropertyModelExpression(PolicyRuleType.F_POLICY_CONSTRAINTS.getLocalPart(), PolicyConstraintsType.F_SITUATION.getLocalPart()))) { @Override protected void populateItem(final ListItem listItem) { PolicyRuleConstraintsExpandablePanel exclusionPropertiesPanel = diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRulesPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRulesPanel.java index 4b2e9968d1c..fb92e76b9a6 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRulesPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRulesPanel.java @@ -160,9 +160,8 @@ protected ObjectQuery createObjectQuery() { } @Override - protected AbstractAssignmentDetailsPanel createDetailsPanel(String idAssignmentDetails, Form form, IModel model, - PageBase parentPage) { - return new PolicyRuleDetailsPanel(idAssignmentDetails, form, model, parentPage); + protected AbstractAssignmentDetailsPanel createDetailsPanel(String idAssignmentDetails, Form form, IModel model) { + return new PolicyRuleDetailsPanel(idAssignmentDetails, form, model); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.html index b5c862f5caf..2e05e369f6f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.html @@ -22,8 +22,8 @@

-
-
+ +
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.java index e14c0f2e296..5b35e181a6b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.java @@ -15,12 +15,16 @@ */ package com.evolveum.midpoint.web.component.objectdetails; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import org.apache.wicket.model.IModel; import org.apache.wicket.request.resource.PackageResourceReference; import com.evolveum.midpoint.gui.api.model.LoadableModel; import com.evolveum.midpoint.gui.api.page.PageBase; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.util.logging.Trace; @@ -28,10 +32,12 @@ import com.evolveum.midpoint.web.component.assignment.AssignmentDto; import com.evolveum.midpoint.web.component.assignment.AssignmentEditorDto; import com.evolveum.midpoint.web.component.form.Form; +import com.evolveum.midpoint.web.component.prism.ContainerWrapper; import com.evolveum.midpoint.web.component.prism.ObjectWrapper; import com.evolveum.midpoint.web.component.prism.PrismContainerPanel; -import com.evolveum.midpoint.web.component.prism.PrismObjectPanel; +import com.evolveum.midpoint.web.component.prism.PrismPanel; import com.evolveum.midpoint.web.model.ContainerWrapperFromObjectWrapperModel; +import com.evolveum.midpoint.web.model.ContainerWrapperListFromObjectWrapperModel; import com.evolveum.midpoint.web.page.admin.users.dto.FocusSubwrapperDto; import com.evolveum.midpoint.web.resource.img.ImgResources; import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; @@ -43,10 +49,10 @@ public class FocusDetailsTabPanel extends AbstractFocusTabPanel { private static final long serialVersionUID = 1L; -// protected static final String ID_FOCUS_FORM = "focusDetails"; - protected static final String ID_FOCUS_MAIN_PANEL = "focusDetails"; - protected static final String ID_FOCUS_ACTIVATION_PANEL = "activation"; - protected static final String ID_FOCUS_PASSWORD_PANEL = "password"; + protected static final String ID_FOCUS_FORM = "focusDetails"; +// protected static final String ID_FOCUS_MAIN_PANEL = "focusDetails"; +// protected static final String ID_FOCUS_ACTIVATION_PANEL = "activation"; +// protected static final String ID_FOCUS_PASSWORD_PANEL = "password"; private static final Trace LOGGER = TraceManager.getTrace(FocusDetailsTabPanel.class); @@ -62,22 +68,28 @@ public FocusDetailsTabPanel(String id, Form mainForm, private void initLayout() { - ContainerWrapperFromObjectWrapperModel basicContainerModel = new ContainerWrapperFromObjectWrapperModel<>(getObjectWrapperModel(), ItemPath.EMPTY_PATH); - PrismContainerPanel mainContainer = new PrismContainerPanel<>(ID_FOCUS_MAIN_PANEL, basicContainerModel, false, getMainForm(), getPageBase()); - add(mainContainer); +// ContainerWrapperFromObjectWrapperModel basicContainerModel = new ContainerWrapperFromObjectWrapperModel<>(getObjectWrapperModel(), ItemPath.EMPTY_PATH); +// PrismContainerPanel mainContainer = new PrismContainerPanel<>(ID_FOCUS_MAIN_PANEL, basicContainerModel, false, getMainForm(), getPageBase()); +// add(mainContainer); +// +// ContainerWrapperFromObjectWrapperModel activationContainerModel = new ContainerWrapperFromObjectWrapperModel<>(getObjectWrapperModel(), SchemaConstants.PATH_ACTIVATION); +// PrismContainerPanel activationContainerPanel = new PrismContainerPanel<>(ID_FOCUS_ACTIVATION_PANEL, activationContainerModel, false, getMainForm(), getPageBase()); +// add(activationContainerPanel); +// +// ContainerWrapperFromObjectWrapperModel passwordContainerModel = new ContainerWrapperFromObjectWrapperModel<>(getObjectWrapperModel(), SchemaConstants.PATH_PASSWORD); +// PrismContainerPanel passwordContainerPanel = new PrismContainerPanel<>(ID_FOCUS_PASSWORD_PANEL, passwordContainerModel, false, getMainForm(), getPageBase()); +// add(passwordContainerPanel); - ContainerWrapperFromObjectWrapperModel activationContainerModel = new ContainerWrapperFromObjectWrapperModel<>(getObjectWrapperModel(), SchemaConstants.PATH_ACTIVATION); - PrismContainerPanel activationContainerPanel = new PrismContainerPanel<>(ID_FOCUS_ACTIVATION_PANEL, activationContainerModel, false, getMainForm(), getPageBase()); - add(activationContainerPanel); - ContainerWrapperFromObjectWrapperModel passwordContainerModel = new ContainerWrapperFromObjectWrapperModel<>(getObjectWrapperModel(), SchemaConstants.PATH_PASSWORD); - PrismContainerPanel passwordContainerPanel = new PrismContainerPanel<>(ID_FOCUS_PASSWORD_PANEL, passwordContainerModel, false, getMainForm(), getPageBase()); - add(passwordContainerPanel); - - -// PrismObjectPanel panel = new PrismObjectPanel(ID_FOCUS_FORM, getObjectWrapperModel(), -// new PackageResourceReference(ImgResources.class, ImgResources.USER_PRISM), getMainForm(), getPageBase()); -// add(panel); + PrismPanel panel = new PrismPanel(ID_FOCUS_FORM, new ContainerWrapperListFromObjectWrapperModel(getObjectWrapperModel(), getVisibleContainers()), + new PackageResourceReference(ImgResources.class, ImgResources.USER_PRISM), getMainForm(), + null, getPageBase()); + add(panel); } + + private List getVisibleContainers() { + return Arrays.asList(ItemPath.EMPTY_PATH, SchemaConstants.PATH_ACTIVATION, SchemaConstants.PATH_PASSWORD); + } + } 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 eafa9bab1f1..3b03841fdd5 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 @@ -65,6 +65,7 @@ import com.evolveum.midpoint.web.component.menu.cog.InlineMenuItemAction; import com.evolveum.midpoint.web.component.util.ObjectWrapperUtil; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; +import com.evolveum.midpoint.web.model.ContainerWrapperListFromObjectWrapperModel; import com.evolveum.midpoint.web.page.admin.PageAdminFocus; import com.evolveum.midpoint.web.page.admin.resources.content.PageAccount; import com.evolveum.midpoint.web.page.admin.users.dto.FocusSubwrapperDto; @@ -127,9 +128,9 @@ protected void populateItem(final ListItem> item) if (dto.isLoadedOK()) { packageRef = new PackageResourceReference(ImgResources.class, ImgResources.HDD_PRISM); - shadowPanel = new PrismObjectPanel(ID_SHADOW, - new PropertyModel>(item.getModel(), "object"), packageRef, - getMainForm(), getPageBase()); + shadowPanel = new PrismPanel(ID_SHADOW, + new ContainerWrapperListFromObjectWrapperModel<>(objectWrapperModel, null), packageRef, + getMainForm(), null, getPageBase()); } else { shadowPanel = new SimpleErrorPanel(ID_SHADOW, item.getModel()) { private static final long serialVersionUID = 1L; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValuePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValuePanel.java index 15f459d7e38..c5acfc8565f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValuePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValuePanel.java @@ -49,7 +49,7 @@ public class ContainerValuePanel extends Panel { private PageBase pageBase; - public ContainerValuePanel(String id, final IModel> model, boolean showHeader, Form form, PageBase pageBase) { + public ContainerValuePanel(String id, final IModel> model, boolean showHeader, Form form, ItemVisibilityHandler isPanelVisible, PageBase pageBase) { super(id, model); setOutputMarkupId(true); this.pageBase = pageBase; @@ -64,16 +64,16 @@ public boolean isVisible() { LOGGER.trace("Creating container panel for {}", model.getObject()); - initLayout(model, form, showHeader); + initLayout(model, form, isPanelVisible, showHeader); } - private void initLayout(final IModel> model, final Form form, boolean showHeader) { + private void initLayout(final IModel> model, final Form form, ItemVisibilityHandler isPanelVisible, boolean showHeader) { PrismContainerValueHeaderPanel header = new PrismContainerValueHeaderPanel(ID_HEADER, model) { private static final long serialVersionUID = 1L; @Override protected void onButtonClick(AjaxRequestTarget target) { - addOrReplaceProperties(model, form, true); + addOrReplaceProperties(model, form, isPanelVisible, true); target.add(ContainerValuePanel.this); } @@ -89,7 +89,7 @@ public boolean isVisible() { add(header); header.setOutputMarkupId(true); - addOrReplaceProperties(model, form, false); + addOrReplaceProperties(model, form, isPanelVisible, false); } public PageBase getPageBase(){ @@ -108,7 +108,7 @@ public String getObject() { }; } - private void addOrReplaceProperties(IModel> model, final Form form, boolean isToBeReplaced){ + private void addOrReplaceProperties(IModel> model, final Form form, ItemVisibilityHandler isPanaleVisible, boolean isToBeReplaced){ ListView properties = new ListView("properties", new PropertyModel>(model, "properties")) { private static final long serialVersionUID = 1L; @@ -116,7 +116,7 @@ private void addOrReplaceProperties(IModel item) { if (item.getModel().getObject() instanceof ContainerWrapper) { - PrismContainerPanel containerPanel = new PrismContainerPanel("property", (IModel>) item.getModel(), true, form, pageBase); + PrismContainerPanel containerPanel = new PrismContainerPanel("property", (IModel>) item.getModel(), true, form, isPanaleVisible, pageBase); containerPanel.setOutputMarkupId(true); item.add(containerPanel); return; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java index 41b99651af8..2ee4fb025d7 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java @@ -421,7 +421,7 @@ public void collectModifications(ObjectDelta delta) th private ItemDelta computePropertyDeltas(PropertyWrapper propertyWrapper, ItemPath containerPath) { ItemDefinition itemDef = propertyWrapper.getItemDefinition(); - ItemDelta pDelta = itemDef.createEmptyDelta(containerPath.subPath(itemDef.getName())); + ItemDelta pDelta = itemDef.createEmptyDelta(propertyWrapper.getItem().getPath()); addItemDelta(propertyWrapper, pDelta, itemDef, containerPath); return pDelta; } @@ -556,6 +556,10 @@ public boolean isVisible() { return false; } + if (def.getTypeName().equals(MetadataType.COMPLEX_TYPE)) { + return isShowMetadata(); + } + //TODO: emphasized switch (status) { case NOT_CHANGED : @@ -568,7 +572,7 @@ public boolean isVisible() { } private boolean isNotEmptyAndCanReadAndModify(PrismContainerDefinition def) { - return def.canRead() && def.canModify() && !getContainerValue().isEmpty(); + return def.canRead() && def.canModify(); } private boolean showEmptyCanReadAndModify(PrismContainerDefinition def) { @@ -576,7 +580,7 @@ private boolean showEmptyCanReadAndModify(PrismContainerDefinition def) { } private boolean showEmptyAndCanAdd(PrismContainerDefinition def) { - return def.canAdd() && isShowEmpty(); + return def.canAdd(); } private boolean emphasizedAndCanAdd(PrismContainerDefinition def) { @@ -591,6 +595,17 @@ public void setShowEmpty(boolean showEmpty) { }); } + @Override + public void setShowMetadata(boolean showMetadata) { + super.setShowMetadata(showMetadata); + getItems().forEach(value -> { + if (value instanceof ContainerWrapper) { + ((ContainerWrapper) value).setShowMetadata(showMetadata); + } + }); + } + + // @Override public boolean checkRequired(PageBase pageBase) { boolean rv = true; @@ -626,7 +641,19 @@ public ContainerWrapper findContainerWrapper(ItemPath path) { return containerWrapper; } - return ((ContainerWrapper)wrapper).findContainerWrapper(path); +// return ((ContainerWrapper)wrapper).findContainerWrapper(path); + + } + return null; + } + + public ContainerValueWrapper findContainerValueWrapper(ItemPath path) { + Validate.notNull(path, "QName must not be null."); + for (ItemWrapper wrapper : getItems()) { + if (!(wrapper instanceof ContainerValueWrapper)) { + continue; + } + return ((ContainerValueWrapper)wrapper).findContainerValueWrapper(path); } return null; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java index c4178abe2a2..1d0fcc98068 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java @@ -164,6 +164,22 @@ public ContainerWrapper findContainerWrapper(ItemPath path) { } return null; } + + public ContainerValueWrapper findContainerValueWrapper(ItemPath path) { + Validate.notNull(path, "QName must not be null."); + for (ContainerValueWrapper wrapper : getValues()) { + + if (path.equivalent(wrapper.getPath())) { + return wrapper; + } + + ContainerValueWrapper containerWrapper = wrapper.findContainerValueWrapper(path); + if (containerWrapper != null) { + return containerWrapper; + } + } + return null; + } public void computeStripes() { int visibleProperties = 0; @@ -622,6 +638,12 @@ public void setShowEmpty(boolean showEmpty) { super.setShowEmpty(showEmpty); getValues().forEach(value -> value.setShowEmpty(showEmpty)); } + + @Override + public void setShowMetadata(boolean showMetadata) { + super.setShowMetadata(showMetadata); + getValues().forEach(value -> value.setShowMetadata(showMetadata)); + } @Override public boolean isEnforceRequiredFields() { @@ -638,11 +660,10 @@ public ContainerWrapper getParent() { public boolean isVisible() { PrismContainerDefinition def = getItemDefinition(); - if (def.isIgnored() || (def.isOperational() && !def.getTypeName().equals(MetadataType.COMPLEX_TYPE))) { + if (def.isIgnored() || (def.isOperational()) && (!def.getTypeName().equals(MetadataType.COMPLEX_TYPE))) { return false; } - //TODO: emphasized switch (status) { case MODIFYING : return isNotEmptyAndCanReadAndModify(def) || showEmptyCanReadAndModify(def); @@ -654,7 +675,7 @@ public boolean isVisible() { } private boolean isNotEmptyAndCanReadAndModify(PrismContainerDefinition def) { - return def.canRead() && def.canModify() && !getItem().isEmpty(); + return def.canRead() && def.canModify(); } private boolean showEmptyCanReadAndModify(PrismContainerDefinition def) { @@ -662,7 +683,7 @@ private boolean showEmptyCanReadAndModify(PrismContainerDefinition def) { } private boolean showEmptyAndCanAdd(PrismContainerDefinition def) { - return def.canAdd() && isShowEmpty(); + return def.canAdd(); } private boolean emphasizedAndCanAdd(PrismContainerDefinition def) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java index 2c123751704..d9f8966347a 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java @@ -314,9 +314,9 @@ private List create if (itemDef.isIgnored() || skipProperty(itemDef)) { return; } - if (!cWrapper.isShowInheritedObjectAttributes() && INHERITED_OBJECT_ATTRIBUTES.contains(itemDef.getName())) { - return; - } +// if (!cWrapper.isShowInheritedObjectAttributes() && INHERITED_OBJECT_ATTRIBUTES.contains(itemDef.getName())) { +// return; +// } createPropertyOrReferenceWrapper(itemDef, cWrapper, propertyOrReferenceWrappers); createContainerWrapper(itemDef, cWrapper, containerWrappers); @@ -347,7 +347,7 @@ private void createPropertyOrReferenceWrapper(ItemDefi // return; // } - PrismContainerValue containerValue = cWrapper.getContainerValue(); +// PrismContainerValue containerValue = cWrapper.getContainerValue(); //TODO temporary decision to hide adminGuiConfiguration attribute (MID-3305) // if (itemDef != null && itemDef.getName() != null && itemDef.getName().getLocalPart() != null && @@ -366,14 +366,14 @@ private void createPropertyOrReferenceWrapper(ItemDefi private void createContainerWrapper(ItemDefinition itemDef, ContainerValueWrapper cWrapper, List> properties) { - if (itemDef.isIgnored() || skipProperty(itemDef)) { - return; - } - if (!cWrapper.isShowInheritedObjectAttributes() && INHERITED_OBJECT_ATTRIBUTES.contains(itemDef.getName())) { - return; - } +// if (itemDef.isIgnored() || skipProperty(itemDef)) { +// return; +// } +// if (!cWrapper.isShowInheritedObjectAttributes() && INHERITED_OBJECT_ATTRIBUTES.contains(itemDef.getName())) { +// return; +// } - PrismContainerValue containerValue = cWrapper.getContainerValue(); +// PrismContainerValue containerValue = cWrapper.getContainerValue(); //TODO temporary decision to hide adminGuiConfiguration attribute (MID-3305) // if (itemDef != null && itemDef.getName() != null && itemDef.getName().getLocalPart() != null && @@ -383,7 +383,7 @@ private void createContainerWrapper(ItemDefinition ite if (itemDef instanceof PrismContainerDefinition) { - if (cWrapper.isMain() && !ObjectType.F_EXTENSION.equals(itemDef.getName())) { + if (cWrapper.isMain() && !ObjectType.F_EXTENSION.equals(itemDef.getName()) && !ObjectType.F_METADATA.equals(itemDef.getName())) { return; } @@ -464,10 +464,10 @@ private ContainerWrapper createContainerWrapper(Pri private boolean isItemReadOnly(ItemDefinition def, ContainerValueWrapper cWrapper) { if (cWrapper == null || cWrapper.getStatus() == ValueStatus.NOT_CHANGED) { - return cWrapper.isReadonly() || !def.canModify(); + return MetadataType.COMPLEX_TYPE.equals(cWrapper.getDefinition().getName()) || cWrapper.isReadonly() || !def.canModify(); } - return cWrapper.isReadonly() || !def.canAdd(); + return MetadataType.COMPLEX_TYPE.equals(cWrapper.getDefinition().getName()) || cWrapper.isReadonly() || !def.canAdd(); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/DynamicFieldGroupPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/DynamicFieldGroupPanel.java index d928b0adab5..a2c2cd67cc7 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/DynamicFieldGroupPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/DynamicFieldGroupPanel.java @@ -91,7 +91,7 @@ private void initLayout(String groupName, List formItems, if (itemWrapper instanceof ContainerWrapper) { PrismContainerPanel containerPanel = new PrismContainerPanel(itemView.newChildId(), - Model.of((ContainerWrapper) itemWrapper), true, mainForm, getPageBase()); + Model.of((ContainerWrapper) itemWrapper), true, mainForm, w -> {return true;}, getPageBase()); containerPanel.setOutputMarkupId(true); itemView.add(containerPanel); } else { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/DynamicFormPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/DynamicFormPanel.java index 515e04e694e..9cbdc1f2c58 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/DynamicFormPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/DynamicFormPanel.java @@ -121,7 +121,7 @@ private ObjectWrapper createObjectWrapper(ObjectWrapperFactory owf, Task task ObjectWrapper objectWrapper = owf.createObjectWrapper("DisplayName", "description", prismObject, prismObject.getOid() == null ? ContainerStatus.ADDING : ContainerStatus.MODIFYING, authorizationPhase, task); -// objectWrapper.setShowEmpty(true); + objectWrapper.setShowEmpty(true); objectWrapper.setEnforceRequiredFields(enforceRequiredFields); return objectWrapper; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemVisibilityHandler.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemVisibilityHandler.java new file mode 100644 index 00000000000..269086a4504 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemVisibilityHandler.java @@ -0,0 +1,10 @@ +package com.evolveum.midpoint.web.component.prism; + +import java.io.Serializable; + +@FunctionalInterface +public interface ItemVisibilityHandler extends Serializable{ + + + public boolean isVisible(ItemWrapper wrapper); +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapper.java index b1bfc25851f..d2099e90d4a 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ItemWrapper.java @@ -25,6 +25,7 @@ import com.evolveum.midpoint.prism.Item; import com.evolveum.midpoint.prism.ItemDefinition; import com.evolveum.midpoint.prism.Revivable; +import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.util.DebugDumpable; /** @@ -39,6 +40,8 @@ public interface ItemWrapper exten void setDisplayName(String name); I getItem(); + + ItemPath getPath(); /** * Item definition. diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java index 0f453018f7f..b3a61a6b31d 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java @@ -202,47 +202,6 @@ public String getDescription() { return description; } -// @Override -// public boolean isMinimalized() { -// return minimalized; -// } -// -// @Override -// public void setMinimalized(boolean minimalized) { -// this.minimalized = minimalized; -// } -// -// @Override -// public boolean isSorted() { -// return sorted; -// } -// -// @Override -// public void setSorted(boolean sorted) { -// this.sorted = sorted; -// } -// -// @Override -// public boolean isShowMetadata() { -// return showMetadata; -// } -// -// @Override -// public void setShowMetadata(boolean showMetadata) { -// this.showMetadata = showMetadata; -// } -// -// @Override -// public boolean isShowEmpty() { -// return showEmpty; -// } -// -// @Override -// public void setShowEmpty(boolean showEmpty) { -// this.showEmpty = showEmpty; -// computeStripes(); -// } - public boolean isSelectable() { return selectable; } @@ -259,7 +218,7 @@ public void setSelected(boolean selected) { this.selected = selected; } - public List> getContainers() { + public List> getContainers() { if (containers == null) { containers = new ArrayList<>(); } @@ -288,6 +247,24 @@ public ContainerWrapper findContainerWrapper(ItemPa return containerWrapper.findContainerWrapper(path); } + + public ContainerValueWrapper findContainerValueWrapper(ItemPath path) { + if (path == null || path.isEmpty()) { + ContainerWrapper mainContainer = (ContainerWrapper) findMainContainerWrapper(); + if (mainContainer == null) { + return null; + } + return mainContainer.getValues().iterator().next(); + } + + ContainerWrapper containerWrapper = findContainerWrapper(path.head()); + if (containerWrapper == null) { + return null; + } + + return containerWrapper.findContainerValueWrapper(path); + + } public ContainerWrapper findMainContainerWrapper() { for (ContainerWrapper wrapper : getContainers()) { @@ -575,7 +552,7 @@ public void setShowAssignments(boolean showAssignments) { @Override public void setShowEmpty(boolean showEmpty) { super.setShowEmpty(showEmpty); - getContainers().forEach(container -> container.setShowEmpty(true)); + getContainers().forEach(container -> container.setShowEmpty(showEmpty)); } public boolean isReadonly() { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java index ed871410db5..c9cb7a1e5bf 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java @@ -68,6 +68,7 @@ public class ObjectWrapperFactory { OperationExecutionType.COMPLEX_TYPE, ApprovalSchemaType.COMPLEX_TYPE, PasswordHistoryEntryType.COMPLEX_TYPE, + SecurityQuestionsCredentialsType.COMPLEX_TYPE, NonceType.COMPLEX_TYPE); private ModelServiceLocator modelServiceLocator; @@ -144,12 +145,12 @@ private ObjectWrapper createObjectWrapper(String displ object.setDefinition(objectDefinitionForEditing); } - ObjectWrapper objectWrapper = new ObjectWrapper<>(displayName, description, object, - objectClassDefinitionForEditing, status); + ObjectWrapper objectWrapper = new ObjectWrapper<>(displayName, description, object, objectClassDefinitionForEditing, + status); - List> containerWrappers = createContainerWrappers(objectWrapper, object, + List> containerWrappers = createContainerWrappers(objectWrapper, object, objectDefinitionForEditing, status, this.result); - objectWrapper.setContainers(containerWrappers); + objectWrapper.setContainers(containerWrappers); this.result.computeStatusIfUnknown(); @@ -178,7 +179,7 @@ private List> c } else if (ReportType.class.isAssignableFrom(clazz)) { addReportContainers(containerWrappers, oWrapper, object, result); } else { - ContainerWrapper mainContainerWrapper = cwf.createContainerWrapper(object, cStatus, null); + ContainerWrapper mainContainerWrapper = cwf.createContainerWrapper(object, cStatus, ItemPath.EMPTY_PATH); mainContainerWrapper.setDisplayName("prismContainer.mainPanelDisplayName"); result.addSubresult(cwf.getResult()); containerWrappers.add(mainContainerWrapper); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerHeaderPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerHeaderPanel.java index e701cbbc681..d9c7f31dbbd 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerHeaderPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerHeaderPanel.java @@ -52,6 +52,11 @@ private void addValue(AjaxRequestTarget target) { private boolean isContainerMultivalue(){ return getModelObject().isVisible() && getModelObject().getItemDefinition().isMultiValue(); } + + @Override + protected String getLabel() { + return getModelObject().getDisplayName(); + } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.html index 992504b10dc..02a034168d1 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.html @@ -20,8 +20,8 @@
- -
+ +
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.java index 291c9060eec..4d0220ca5f8 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerPanel.java @@ -49,7 +49,7 @@ public class PrismContainerPanel extends Panel { private PageBase pageBase; - public PrismContainerPanel(String id, final IModel> model, boolean showHeader, Form form, PageBase pageBase) { + public PrismContainerPanel(String id, final IModel> model, boolean showHeader, Form form, ItemVisibilityHandler isPanelVisible, PageBase pageBase) { super(id); setOutputMarkupId(true); this.pageBase = pageBase; @@ -61,22 +61,25 @@ public PrismContainerPanel(String id, final IModel> model, b @Override public boolean isVisible() { + if (isPanelVisible!= null && !isPanelVisible.isVisible(model.getObject())) { + return false; + } return model.getObject() !=null && model.getObject().isVisible(); } }); - initLayout(model, form, showHeader); + initLayout(model, form, isPanelVisible, showHeader); } - private void initLayout(final IModel> model, final Form form, boolean showHeader) { + private void initLayout(final IModel> model, final Form form, ItemVisibilityHandler isPanelVisible, boolean showHeader) { PrismContainerHeaderPanel header = new PrismContainerHeaderPanel(ID_HEADER, model) { private static final long serialVersionUID = 1L; @Override protected void onButtonClick(AjaxRequestTarget target) { - addOrReplaceProperties(model, form, true); - target.add(PrismContainerPanel.this.findParent(PrismObjectPanel.class)); + addOrReplaceProperties(model, form, isPanelVisible, true); + target.add(PrismContainerPanel.this.findParent(PrismPanel.class)); } @@ -84,7 +87,7 @@ protected void onButtonClick(AjaxRequestTarget target) { header.setOutputMarkupId(true); add(header); - addOrReplaceProperties(model, form, false); + addOrReplaceProperties(model, form, isPanelVisible, false); } public PageBase getPageBase(){ @@ -103,7 +106,7 @@ public String getObject() { }; } - private void addOrReplaceProperties(IModel> model, final Form form, boolean isToBeReplaced){ + private void addOrReplaceProperties(IModel> model, final Form form, ItemVisibilityHandler isPanelVisible, boolean isToBeReplaced){ ListView> values = new ListView>("values", new PropertyModel>>(model, "values")) { @@ -112,7 +115,7 @@ private void addOrReplaceProperties(IModel> model, final For @Override protected void populateItem(ListItem> item) { - ContainerValuePanel containerPanel = new ContainerValuePanel("value", item.getModel(), true, form, pageBase); + ContainerValuePanel containerPanel = new ContainerValuePanel("value", item.getModel(), true, form, isPanelVisible, pageBase); containerPanel.setOutputMarkupId(true); item.add(containerPanel); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java index 4217ac7099f..69ac20a1e8c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java @@ -9,15 +9,15 @@ import com.evolveum.midpoint.gui.api.component.togglebutton.ToggleIconButton; import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; +import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType; public class PrismContainerValueHeaderPanel extends PrismHeaderPanel> { private static final long serialVersionUID = 1L; - - private static final String ID_SHOW_EMPTY_FIELDS = "showEmptyFields"; - private static final String ID_SORT_PROPERTIES = "sortProperties"; + private static final String ID_SORT_PROPERTIES = "sortProperties"; private static final String ID_SHOW_METADATA = "showMetadata"; + private static final String ID_SHOW_EMPTY_FIELDS = "showEmptyFields"; public PrismContainerValueHeaderPanel(String id, IModel> model) { @@ -41,10 +41,8 @@ public boolean isVisible() { @Override public void onClick(AjaxRequestTarget target) { -// ObjectWrapper objectWrapper = getObjectWrapper(model); -// PrismWrapper wrapper = PrismHeaderPanel.this.getModelObject(); -// wrapper.setShowMetadata(wrapper.isShowMetadata()); -// objectWrapper.setShowMetadata(!objectWrapper.isShowMetadata()); + ContainerValueWrapper wrapper = PrismContainerValueHeaderPanel.this.getModelObject(); + wrapper.setShowMetadata(!wrapper.isShowMetadata()); onButtonClick(target); } @@ -62,7 +60,19 @@ public Object getObject() { createStringResource("PrismObjectPanel.showMetadata").getString()); } })); - showMetadataButton.add(buttonsVisibleBehaviour); + showMetadataButton.add(new VisibleEnableBehaviour() { + + @Override + public boolean isVisible() { + for (ItemWrapper wrapper : getModelObject().getItems()) { + if (MetadataType.COMPLEX_TYPE.equals(wrapper.getItemDefinition().getTypeName())) { + return true; + } + } + return false; + } + + }); add(showMetadataButton); ToggleIconButton showEmptyFieldsButton = new ToggleIconButton(ID_SHOW_EMPTY_FIELDS, @@ -109,5 +119,10 @@ public boolean isOn() { add(sortPropertiesButton); } + + @Override + protected String getLabel() { + return getModel().getObject().getDisplayName(); + } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismHeaderPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismHeaderPanel.java index 50076009406..f9d16b9412e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismHeaderPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismHeaderPanel.java @@ -16,19 +16,15 @@ package com.evolveum.midpoint.web.component.prism; -import com.evolveum.midpoint.gui.api.GuiStyleConstants; +import org.apache.commons.lang3.StringUtils; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.StringResourceModel; + import com.evolveum.midpoint.gui.api.component.BasePanel; -import com.evolveum.midpoint.gui.api.component.togglebutton.ToggleIconButton; -import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; - -import org.apache.wicket.AttributeModifier; -import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.markup.html.basic.Label; -import org.apache.wicket.markup.html.panel.Panel; -import org.apache.wicket.model.*; /** * @author semancik @@ -56,32 +52,37 @@ private void initLayout() { initButtons(); - IModel headerLabelModel = new AbstractReadOnlyModel() { - private static final long serialVersionUID = 1L; - - @Override - public String getObject() { - - PrismWrapper wrapper = getModelObject(); - String displayName = "displayName.not.set"; - if (wrapper instanceof ContainerValueWrapper) { - displayName = ((ContainerValueWrapper) wrapper).getDisplayName(); - } else if (wrapper instanceof ContainerWrapper) { - displayName = ((ContainerWrapper)wrapper).getDisplayName(); - } else if (wrapper instanceof ObjectWrapper) { - // HACK HACK HACK - // If we would display label for the object itself, display label for main container instead - // the "object label" is actually displayed in front of main container - ContainerWrapper mainContainerWrapper = ((ObjectWrapper) wrapper).findMainContainerWrapper(); - if (mainContainerWrapper != null) { - displayName = mainContainerWrapper.getDisplayName(); - } else { - displayName = ((ObjectWrapper) wrapper).getDisplayName(); // e.g. resource wizard needs this - } - } - return getString(displayName, null, displayName); - } - }; + String displayName = getLabel(); + if (StringUtils.isEmpty(displayName)) { + displayName = "displayName.not.set"; + } + StringResourceModel headerLabelModel = createStringResource(displayName); +// IModel headerLabelModel = new AbstractReadOnlyModel() { +// private static final long serialVersionUID = 1L; +// +// @Override +// public String getObject() { +// +// PrismWrapper wrapper = getModelObject(); +// String displayName = "displayName.not.set"; +// if (wrapper instanceof ContainerValueWrapper) { +// displayName = ((ContainerValueWrapper) wrapper).getDisplayName(); +// } else if (wrapper instanceof ContainerWrapper) { +// displayName = ((ContainerWrapper)wrapper).getDisplayName(); +// } else if (wrapper instanceof ObjectWrapper) { +// // HACK HACK HACK +// // If we would display label for the object itself, display label for main container instead +// // the "object label" is actually displayed in front of main container +// ContainerWrapper mainContainerWrapper = ((ObjectWrapper) wrapper).findMainContainerWrapper(); +// if (mainContainerWrapper != null) { +// displayName = mainContainerWrapper.getDisplayName(); +// } else { +// displayName = ((ObjectWrapper) wrapper).getDisplayName(); // e.g. resource wizard needs this +// } +// } +// return getString(displayName, null, displayName); +// } +// }; add(new Label(ID_LABEL, headerLabelModel)); } @@ -92,6 +93,8 @@ public String getObject() { protected void onButtonClick(AjaxRequestTarget target) { } + + protected abstract String getLabel(); public boolean isButtonsVisible() { return true; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismOptionButtonPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismOptionButtonPanel.java index 18b6a78de6b..8cc2ad5eae7 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismOptionButtonPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismOptionButtonPanel.java @@ -89,7 +89,7 @@ public Object getObject() { // return new PackageResourceReference(PrismObjectPanel.class, // "ShowEmptyFalse.png"); // } - return new PackageResourceReference(PrismObjectPanel.class, + return new PackageResourceReference(PrismPanel.class, "ShowEmptyTrue.png"); } }); @@ -123,11 +123,11 @@ public void onClick(AjaxRequestTarget target) { public Object getObject() { ObjectWrapper wrapper = model.getObject(); if (wrapper.isMinimalized()) { - return new PackageResourceReference(PrismObjectPanel.class, + return new PackageResourceReference(PrismPanel.class, "Maximize.png"); } - return new PackageResourceReference(PrismObjectPanel.class, + return new PackageResourceReference(PrismPanel.class, "Minimize.png"); } }); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismPanel.html new file mode 100644 index 00000000000..5f11a1d2161 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismPanel.html @@ -0,0 +1,28 @@ + + + + + +
+ +
+
+ +
+
+ + diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismPanel.java new file mode 100644 index 00000000000..4b5a48e4c03 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismPanel.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.web.component.prism; + +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.apache.wicket.Component; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.list.ListItem; +import org.apache.wicket.markup.html.list.ListView; +import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.model.AbstractReadOnlyModel; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.PropertyModel; +import org.apache.wicket.request.resource.ResourceReference; + +import com.evolveum.midpoint.gui.api.page.PageBase; +import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.web.component.assignment.MetadataPanel; +import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; +import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; + +/** + * @author lazyman + */ +public class PrismPanel extends Panel { + private static final long serialVersionUID = 1L; + + private static final String STRIPED_CLASS = "striped"; + + private static final String ID_HEADER = "header"; + private static final String ID_CONTAINERS = "containers"; + private static final String ID_CONTAINER = "container"; + private static final String ID_CONTAINER_METADATA = "containerMetadata"; + + private static final Trace LOGGER = TraceManager.getTrace(PrismPanel.class); + + private PageBase pageBase; + + public PrismPanel(String id, IModel>> model, ResourceReference image, Form form, ItemVisibilityHandler isPanelVisible, PageBase pageBase) { + super(id, model); + setOutputMarkupId(true); + + LOGGER.trace("Creating object panel for {}", model.getObject()); + + this.pageBase = pageBase; + initLayout(image, isPanelVisible, form); + } + + private void initLayout(ResourceReference image, final ItemVisibilityHandler isPanelVisible, Form form) { + addOrReplaceContainers(form, isPanelVisible, false); + + } + + public void removeAllContainerWrappers() { + ((ListView) get(ID_CONTAINERS)).removeAll(); + } + + + private void addOrReplaceContainers(final Form form, ItemVisibilityHandler isPanelVisible, boolean isToBeReplaced){ + ListView> containers = new ListView>(ID_CONTAINERS, + getModel()) { + private static final long serialVersionUID = 1L; + + @Override + protected void populateItem(ListItem> item) { + createContainerPanel(item, isPanelVisible, form); + +// createMetadataPanel(model, item, containerPanel); + } + }; + containers.setReuseItems(true); + + if (isToBeReplaced) { + replace(containers); + } else { + add(containers); + } + } + + protected PrismContainerPanel createContainerPanel(ListItem> item, ItemVisibilityHandler isPanelVisible, Form form){ + PrismContainerPanel panel = new PrismContainerPanel(ID_CONTAINER, item.getModel(), false, form, isPanelVisible, pageBase); + panel.setOutputMarkupPlaceholderTag(true); + item.add(panel); + return panel; + } + + private IModel>> getModel() { + return (IModel>>) getInnermostModel(); + } + +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyOrReferenceWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyOrReferenceWrapper.java index 3aa2254b920..c3d01ab43ce 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyOrReferenceWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyOrReferenceWrapper.java @@ -18,7 +18,10 @@ import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType; + import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; @@ -84,7 +87,7 @@ public ContainerWrapper getParent() { public boolean isVisible() { - if (getItemDefinition().isOperational()) { // TODO ...or use itemDefinition instead? + if (getItemDefinition().isOperational() && !isMetadataContainer()) { // TODO ...or use itemDefinition instead? return false; } switch (status) { @@ -193,15 +196,28 @@ public boolean hasChanged() { return false; } + private boolean isMetadataContainer() { + return getParent().getItemDefinition().getTypeName().equals(MetadataType.COMPLEX_TYPE); + } @Override public boolean isReadonly() { + //TODO this is probably not good idea + if (isMetadataContainer()) { + return true; + } + return readonly; } public void setReadonly(boolean readonly) { this.readonly = readonly; } + + @Override + public ItemPath getPath() { + return item.getPath(); + } @Override public boolean isEmpty() { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/ConfigurationStep.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/ConfigurationStep.java index 656da4854ae..277f904c02a 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/ConfigurationStep.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/ConfigurationStep.java @@ -213,7 +213,7 @@ private void updateConfigurationTabs() { tabs.add(new AbstractTab(new Model<>(tabName)) { @Override public WebMarkupContainer getPanel(String panelId) { - return new PrismContainerPanel(panelId, new Model<>(wrapper), true, form, parentPage); + return new PrismContainerPanel(panelId, new Model<>(wrapper), true, form, null, parentPage); } }); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/model/ContainerValueWrapperFromObjectWrapperModel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/model/ContainerValueWrapperFromObjectWrapperModel.java new file mode 100644 index 00000000000..f93a90ad7b9 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/model/ContainerValueWrapperFromObjectWrapperModel.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.web.model; + +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.web.component.prism.ContainerValueWrapper; +import com.evolveum.midpoint.web.component.prism.ContainerWrapper; +import com.evolveum.midpoint.web.component.prism.ObjectWrapper; +import com.evolveum.midpoint.web.component.prism.PropertyWrapper; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; + +import org.apache.commons.lang.Validate; +import org.apache.wicket.model.IModel; + +import javax.xml.namespace.QName; + +/** + * Model that returns property real values. This implementation works on ObjectWrapper models (not PrismObject). + * + * @author katkav + * + */ +public class ContainerValueWrapperFromObjectWrapperModel extends AbstractWrapperModel ,O> { + + private static final long serialVersionUID = 1L; + + private static final Trace LOGGER = TraceManager.getTrace(ContainerValueWrapperFromObjectWrapperModel.class); + + private ItemPath path; + + public ContainerValueWrapperFromObjectWrapperModel(IModel> model, QName item) { + this(model, new ItemPath(item)); + } + + public ContainerValueWrapperFromObjectWrapperModel(IModel> model, ItemPath path) { + super(model); + Validate.notNull(path, "Item path must not be null."); + this.path = path; + } + + + @Override + public void detach() { + } + + @Override + public ContainerValueWrapper getObject() { + ContainerValueWrapper containerWrapper = getWrapper().findContainerValueWrapper(path); + return containerWrapper; + } + + @Override + public void setObject(ContainerValueWrapper arg0) { + throw new UnsupportedOperationException("ContainerWrapperFromObjectWrapperModel.setObject called"); + + } + +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/model/ContainerWrapperListFromObjectWrapperModel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/model/ContainerWrapperListFromObjectWrapperModel.java new file mode 100644 index 00000000000..85666064ead --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/model/ContainerWrapperListFromObjectWrapperModel.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.web.model; + +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.web.component.prism.ContainerWrapper; +import com.evolveum.midpoint.web.component.prism.ObjectWrapper; +import com.evolveum.midpoint.web.component.prism.PropertyWrapper; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; + +import org.apache.commons.lang.Validate; +import org.apache.wicket.model.IModel; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.namespace.QName; + +/** + * Model that returns property real values. This implementation works on ObjectWrapper models (not PrismObject). + * + * + * @author katkav + */ +public class ContainerWrapperListFromObjectWrapperModel extends AbstractWrapperModel> ,O> { + + private static final long serialVersionUID = 1L; + + private static final Trace LOGGER = TraceManager.getTrace(ContainerWrapperListFromObjectWrapperModel.class); + + private List paths; + + + public ContainerWrapperListFromObjectWrapperModel(IModel> model, List paths) { + super(model); +// Validate.notNull(paths, "Item path must not be null."); + this.paths = paths; + } + + + @Override + public void detach() { + } + + @Override + public List> getObject() { + List> wrappers = new ArrayList<>(); + if (paths == null) { + return (List) getWrapper().getContainers(); + } + for (ItemPath path : paths) { + ContainerWrapper containerWrapper = getWrapper().findContainerWrapper(path); + if (containerWrapper != null) { + wrappers.add(containerWrapper); + } + } + return wrappers; + } + + @Override + public void setObject(List> arg0) { + throw new UnsupportedOperationException("ContainerWrapperFromObjectWrapperModel.setObject called"); + + } + +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminObjectDetails.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminObjectDetails.java index 70a2e726a4c..e2a19e751d1 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminObjectDetails.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminObjectDetails.java @@ -339,7 +339,7 @@ protected ObjectWrapper loadObjectWrapper(PrismObject objectToEdit) { loadParentOrgs(wrapper, task, result); -// wrapper.setShowEmpty(!isEditingFocus()); + wrapper.setShowEmpty(!isEditingFocus()); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Loaded focus wrapper:\n{}", wrapper.debugDump()); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/content/PageAccount.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/content/PageAccount.java index 0637b67fa98..9b950080189 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/content/PageAccount.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/content/PageAccount.java @@ -20,8 +20,10 @@ import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; +import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.security.api.AuthorizationConstants; import com.evolveum.midpoint.task.api.Task; @@ -36,9 +38,10 @@ import com.evolveum.midpoint.web.component.AjaxSubmitButton; import com.evolveum.midpoint.web.component.prism.ContainerStatus; import com.evolveum.midpoint.web.component.prism.ObjectWrapper; -import com.evolveum.midpoint.web.component.prism.PrismObjectPanel; +import com.evolveum.midpoint.web.component.prism.PrismPanel; import com.evolveum.midpoint.web.component.util.ObjectWrapperUtil; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; +import com.evolveum.midpoint.web.model.ContainerWrapperListFromObjectWrapperModel; import com.evolveum.midpoint.web.page.admin.resources.PageAdminResources; import com.evolveum.midpoint.web.page.admin.resources.PageResources; import com.evolveum.midpoint.web.resource.img.ImgResources; @@ -58,7 +61,9 @@ import org.apache.wicket.util.string.StringValue; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.List; /** * @author lazyman @@ -136,12 +141,17 @@ public boolean isVisible() { }); mainForm.add(protectedMessage); - PrismObjectPanel userForm = new PrismObjectPanel("account", accountModel, new PackageResourceReference( - ImgResources.class, ImgResources.HDD_PRISM), mainForm, this); + PrismPanel userForm = new PrismPanel("account", new ContainerWrapperListFromObjectWrapperModel<>(accountModel, getItemsToShow()), new PackageResourceReference( + ImgResources.class, ImgResources.HDD_PRISM), mainForm, + null, this); mainForm.add(userForm); - + initButtons(mainForm); } + + private List getItemsToShow() { + return Arrays.asList(new ItemPath(ShadowType.F_ATTRIBUTES), SchemaConstants.PATH_ACTIVATION, SchemaConstants.PATH_PASSWORD); + } private void initButtons(Form mainForm) { AjaxSubmitButton save = new AjaxSubmitButton("save", createStringResource("pageAccount.button.save")) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/GenericHandlerPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/GenericHandlerPanel.java index d2b64fd0a12..c0183dd49bf 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/GenericHandlerPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/GenericHandlerPanel.java @@ -40,7 +40,7 @@ public GenericHandlerPanel(String id, IModel model, PageTaskE private void initLayout(final PageTaskEdit parentPage) { PrismContainerPanel containerPanel = new PrismContainerPanel( ID_CONTAINER, new PropertyModel<>(getModel(), GenericHandlerDto.F_CONTAINER), - false, parentPage.getForm(), parentPage); + false, parentPage.getForm(), null, parentPage); add(containerPanel); } From 73ce5b6ec2288c827fc41cacf5ba09b99ff9f8a6 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 19 Sep 2017 19:08:39 +0200 Subject: [PATCH 17/97] Fixed failed tests in model-intest (at least some of them). --- .../src/test/resources/common/system-configuration.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/model/model-impl/src/test/resources/common/system-configuration.xml b/model/model-impl/src/test/resources/common/system-configuration.xml index 502c672abb5..4d8c4909fca 100644 --- a/model/model-impl/src/test/resources/common/system-configuration.xml +++ b/model/model-impl/src/test/resources/common/system-configuration.xml @@ -37,7 +37,9 @@ global-assignment-notification-for-judge - assignment-added + + assignment-added + From 96accc3781c45800998b9d554e398a0dcf3e325d Mon Sep 17 00:00:00 2001 From: matus Date: Wed, 20 Sep 2017 10:16:48 +0200 Subject: [PATCH 18/97] Addition of some valuePolicy detail page related classes --- .../midpoint/gui/api/GuiStyleConstants.java | 2 + .../midpoint/gui/api/page/PageBase.java | 13 +- .../admin/valuePolicy/PageValuePolicies.html | 3 +- .../admin/valuePolicy/PageValuePolicies.java | 2 +- .../admin/valuePolicy/PageValuePolicy.html | 29 ++++ .../admin/valuePolicy/PageValuePolicy.java | 153 ++++++++++++++++++ .../component/ValuePolicyBasicPanel.html | 43 +++++ .../component/ValuePolicyBasicPanel.java | 50 ++++++ .../valuePolicy/component/ValuePolicyDto.java | 45 ++++++ .../component/ValuePolicySummaryPanel.java | 52 ++++++ .../localization/Midpoint.properties | 8 +- .../localization/Midpoint_en.properties | 2 +- 12 files changed, 393 insertions(+), 9 deletions(-) create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/PageValuePolicy.html create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/PageValuePolicy.java create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/component/ValuePolicyBasicPanel.html create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/component/ValuePolicyBasicPanel.java create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/component/ValuePolicyDto.java create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/component/ValuePolicySummaryPanel.java diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/GuiStyleConstants.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/GuiStyleConstants.java index 7548af4a89e..db3e90822e1 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/GuiStyleConstants.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/GuiStyleConstants.java @@ -158,4 +158,6 @@ public class GuiStyleConstants { public static final String CLASS_POLICY_RULES_ICON = "fa fa-balance-scale"; public static final String CLASS_POLICY_RULES_ICON_COLORED = "fa fa-balance-scale"; //TODO + public static final String CLASS_VALUE_POLICY_ICON = "fa fa-asterisk"; + } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java index ae3f6c46ebd..c879ea3f852 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java @@ -66,6 +66,7 @@ import com.evolveum.midpoint.web.component.dialog.MainPopupDialog; import com.evolveum.midpoint.web.component.dialog.Popupable; import com.evolveum.midpoint.web.component.menu.*; +import com.evolveum.midpoint.web.component.menu.MenuItem; import com.evolveum.midpoint.web.component.menu.top.LocalePanel; import com.evolveum.midpoint.web.component.message.FeedbackAlerts; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; @@ -92,6 +93,7 @@ import com.evolveum.midpoint.web.page.admin.users.PageUser; import com.evolveum.midpoint.web.page.admin.users.PageUsers; import com.evolveum.midpoint.web.page.admin.valuePolicy.PageValuePolicies; +import com.evolveum.midpoint.web.page.admin.valuePolicy.PageValuePolicy; import com.evolveum.midpoint.web.page.admin.workflow.*; import com.evolveum.midpoint.web.page.login.PageLogin; import com.evolveum.midpoint.web.page.self.*; @@ -109,6 +111,7 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; import org.apache.wicket.*; +import org.apache.wicket.Component; import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.AjaxLink; @@ -145,8 +148,10 @@ import javax.management.MBeanServer; import javax.management.MBeanServerFactory; import javax.management.ObjectName; +import java.awt.*; import java.io.Serializable; import java.util.*; +import java.util.List; /** * @author lazyman @@ -1418,10 +1423,12 @@ private MainMenuItem createResourcesItems() { private MainMenuItem createValuePolicieItems(){ MainMenuItem item = new MainMenuItem("fa fa-asterisk", createStringResource("PageAdmin.menu.top.valuePolicies"),null); - List submenu = item.getItems(); + // List submenu = item.getItems(); - MenuItem list = new MenuItem(createStringResource("PageAdmin.menu.top.valuePolicies.list"), PageValuePolicies.class); - submenu.add(list); + // MenuItem list = new MenuItem(createStringResource("PageAdmin.menu.top.valuePolicies.list"), PageValuePolicies.class); + addMenuItem(item, "PageAdmin.menu.top.valuePolicies.list", PageValuePolicies.class); + addMenuItem(item,"PageAdmin.menu.top.valuePolicies.new", PageValuePolicy.class); + // submenu.add(list); return item; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/PageValuePolicies.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/PageValuePolicies.html index 0d0716e3d95..4add3520c24 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/PageValuePolicies.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/PageValuePolicies.html @@ -16,11 +16,12 @@ --> +
- + \ No newline at end of file diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/PageValuePolicies.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/PageValuePolicies.java index 155e2188bda..56e78c4bb09 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/PageValuePolicies.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/PageValuePolicies.java @@ -69,7 +69,7 @@ public PageValuePolicies() { initLayout(); } - private void initLayout() { + protected void initLayout() { Form mainForm = new Form(ID_MAIN_FORM); add(mainForm); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/PageValuePolicy.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/PageValuePolicy.html new file mode 100644 index 00000000000..914a1e8afd0 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/PageValuePolicy.html @@ -0,0 +1,29 @@ + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/PageValuePolicy.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/PageValuePolicy.java new file mode 100644 index 00000000000..d664780261c --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/PageValuePolicy.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.web.page.admin.valuePolicy; + +import com.evolveum.midpoint.gui.api.model.LoadableModel; +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.PrismObjectValue; +import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.SelectorOptions; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.security.api.AuthorizationConstants; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.SystemException; +import com.evolveum.midpoint.util.logging.LoggingUtils; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.web.application.AuthorizationAction; +import com.evolveum.midpoint.web.application.PageDescriptor; +import com.evolveum.midpoint.web.application.Url; +import com.evolveum.midpoint.web.component.form.Form; +import com.evolveum.midpoint.web.page.admin.valuePolicy.component.ValuePolicyBasicPanel; +import com.evolveum.midpoint.web.page.admin.valuePolicy.component.ValuePolicyDto; +import com.evolveum.midpoint.web.page.admin.valuePolicy.component.ValuePolicySummaryPanel; +import com.evolveum.midpoint.web.util.OnePageParameterEncoder; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ValuePolicyType; +import org.apache.wicket.model.PropertyModel; +import org.apache.wicket.request.mapper.parameter.PageParameters; + +import java.util.Collection; + +/** + * Created by matus on 9/11/2017. + */ + +@PageDescriptor( + urls = { + @Url(mountUrl = "/admin/valuepolicy", matchUrlForSecurity = "/admin/valuepolicy") + }, + action = { + @AuthorizationAction(actionUri = PageAdminValuePolicies.AUTH_VALUE_POLICIES_ALL, + label = PageAdminValuePolicies.AUTH_VALUE_POLICIES_ALL_LABEL, + description = PageAdminValuePolicies.AUTH_VALUE_POLICIES_ALL_DESCRIPTION), + @AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_VALUE_POLICY_URL, + label = "PageValuePolicy.auth.valuePolcy.label", + description = "PageValuePolicy.auth.valuePolicy.description") + }) + + +public class PageValuePolicy extends PageAdminValuePolicies { + + private static final long serialVersionUID = 1L; + + + private static final Trace LOGGER = TraceManager.getTrace(PageValuePolicy.class); + + private static final String DOT_CLASS = PageValuePolicy.class.getName() + "."; + + private static final String OPERATION_LOAD_DEFINITION = DOT_CLASS + "loadDefinition"; + + private static final String ID_MAIN_FORM = "mainForm"; + private static final String ID_BASIC_INFO_CONTAINER = "constructBasicInfoContainer"; + private static final String ID_VALUE_POLICY_NAME = "valuePolicyName"; + private static final String ID_SUMMARY_PANEL = "summaryPanel"; + private static final String ID_BASIC_PANEL = "basicPanel"; + + private LoadableModel valuePolicyModel; + private String policyOid; + + public PageValuePolicy(PageParameters parameters) { + policyOid = parameters.get(OnePageParameterEncoder.PARAMETER).toString(); + getPageParameters().overwriteWith(parameters); + initModels(); + initLayout(); + } + + private void initModels() { + valuePolicyModel = new LoadableModel(false) { + @Override + protected ValuePolicyDto load() { + if (policyOid != null) { + return loadValuePolicy(policyOid); + } else { + try { + return createValuePolicy(); + } catch (SchemaException e) { + throw new SystemException(e.getMessage(), e); + } + } + } + }; + } + + private ValuePolicyDto createValuePolicy() throws SchemaException { + + ValuePolicyType valuePolicy = getPrismContext().createObjectable(ValuePolicyType.class); + + return new ValuePolicyDto(valuePolicy); + } + + private ValuePolicyDto loadValuePolicy(String policyOid) { + Task task = createSimpleTask(OPERATION_LOAD_DEFINITION); + OperationResult result = task.getResult(); + ValuePolicyDto valuePolicyDto = null; + try { + Collection> options = SelectorOptions.createCollection(GetOperationOptions.createResolveNames()); + PrismObject valuePolicyObject = + WebModelServiceUtils.loadObject(ValuePolicyType.class, policyOid, options, + PageValuePolicy.this, task, result); + ValuePolicyType valuePolicyType = PrismObjectValue.asObjectable(valuePolicyObject); + valuePolicyDto = new ValuePolicyDto(valuePolicyType); + result.recordSuccessIfUnknown(); + } catch (Exception ex) { + LoggingUtils.logUnexpectedException(LOGGER, "Couldn't get definition", ex); + result.recordFatalError("Couldn't get definition.", ex); + } + result.recomputeStatus(); + + if (!WebComponentUtil.isSuccessOrHandledError(result)) { + showResult(result); + } + return valuePolicyDto; + } + + + protected void initLayout() { + ValuePolicySummaryPanel summaryPanel = new ValuePolicySummaryPanel(ID_SUMMARY_PANEL, new PropertyModel<>(valuePolicyModel, "prismObject"), this); + add(summaryPanel); + + Form mainForm = new Form(ID_MAIN_FORM); + add(mainForm); + ValuePolicyBasicPanel basicPanel = new ValuePolicyBasicPanel(ID_BASIC_PANEL, valuePolicyModel); + mainForm.add(basicPanel); + + } + +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/component/ValuePolicyBasicPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/component/ValuePolicyBasicPanel.html new file mode 100644 index 00000000000..d3ba7ab4fe5 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/component/ValuePolicyBasicPanel.html @@ -0,0 +1,43 @@ + + + + + + + + + + diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/component/ValuePolicyBasicPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/component/ValuePolicyBasicPanel.java new file mode 100644 index 00000000000..16ec50123a9 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/component/ValuePolicyBasicPanel.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.web.page.admin.valuePolicy.component; + +import com.evolveum.midpoint.gui.api.component.BasePanel; +import com.evolveum.midpoint.web.component.form.TextFormGroup; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.PropertyModel; + +/** + * Created by matus on 9/18/2017. + */ +public class ValuePolicyBasicPanel extends BasePanel { + + private static final String ID_NAME = "name"; + private static final String ID_DESCRIPTION = "description"; + + private static final String ID_LABEL_SIZE = "col-md-4"; + private static final String ID_INPUT_SIZE = "col-md-8"; + + public ValuePolicyBasicPanel(String id, IModel model) { + super(id, model); + + initializeBasicLayout(); + } + + private void initializeBasicLayout() { + + TextFormGroup nameField = new TextFormGroup(ID_NAME, new PropertyModel<>(getModel(), "valuePolicy.name"), createStringResource("ValuePolicyBasicPanel.valuePolicy.name"), ID_LABEL_SIZE, ID_INPUT_SIZE, true); + TextFormGroup descriptionField = new TextFormGroup(ID_DESCRIPTION, new PropertyModel<>(getModel(), "valuePolicy.description"), createStringResource("ValuePolicyBasicPanel.valuePolicy.description"), ID_LABEL_SIZE, ID_INPUT_SIZE, false); + + add(nameField); + add(descriptionField); + + } + +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/component/ValuePolicyDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/component/ValuePolicyDto.java new file mode 100644 index 00000000000..744c3435887 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/component/ValuePolicyDto.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.web.page.admin.valuePolicy.component; + +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ValuePolicyType; + +import java.io.Serializable; + +/** + * Created by matus on 9/19/2017. + */ +public class ValuePolicyDto implements Serializable { + + public static final String F_PRISM_OBJECT = "prismObject"; + public static final String F_NAME = "name"; + public static final String F_DESCRIPTION = "description"; + + + private ValuePolicyType valuePolicy; + + public ValuePolicyDto(ValuePolicyType valuePolicy) { + this.valuePolicy = valuePolicy; + } + + public PrismObject getPrismObject() { + return valuePolicy.asPrismObject(); + } + + +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/component/ValuePolicySummaryPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/component/ValuePolicySummaryPanel.java new file mode 100644 index 00000000000..6573a4a0c07 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/valuePolicy/component/ValuePolicySummaryPanel.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.web.page.admin.valuePolicy.component; + +import com.evolveum.midpoint.gui.api.GuiStyleConstants; +import com.evolveum.midpoint.gui.api.util.ModelServiceLocator; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.web.component.FocusSummaryPanel; +import com.evolveum.midpoint.web.component.ObjectSummaryPanel; +import com.evolveum.midpoint.web.component.prism.ObjectWrapper; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ValuePolicyType; +import org.apache.wicket.model.IModel; + +import javax.xml.namespace.QName; + +/** + * Created by matus on 9/12/2017. + */ +public class ValuePolicySummaryPanel extends ObjectSummaryPanel { + + public ValuePolicySummaryPanel(String id, IModel> model, ModelServiceLocator serviceLocator) { + super(id, ValuePolicyType.class, model, serviceLocator); + initLayoutCommon(serviceLocator); + } + + @Override + protected String getIconCssClass() { return GuiStyleConstants.CLASS_VALUE_POLICY_ICON; } + + @Override + protected String getIconBoxAdditionalCssClass() { return "summary-panel-value-policy"; } + + @Override + protected String getBoxAdditionalCssClass() { return "summary-panel-value-policy"; } + + @Override + protected boolean isIdentifierVisible() { + return false; + } +} diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint.properties b/gui/admin-gui/src/main/resources/localization/Midpoint.properties index 7318c0cb6c8..c1367c2fc48 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint.properties @@ -1083,6 +1083,7 @@ PageAdmin.menu.top.users.org=Org. structure PageAdmin.menu.top.users.org.tree=Organization tree PageAdmin.menu.top.users=Users PageAdmin.menu.top.valuePolicies.list= List value policies +PageAdmin.menu.top.valuePolicies.new = New value policy PageAdmin.menu.top.valuePolicies= Value policies PageAdmin.menu.top.workItems.listClaimable=Items claimable by me PageAdmin.menu.top.workItems.list=My items @@ -2269,6 +2270,7 @@ MultipleAssignmentSelector.orgUnit=Org. unit pageValuePolicies.table.description=Description pageValuePolicies.button.delete=Delete PageValuePolicies.title=List value policies +PageValuePolicy.title = Value policy pageWorkItem.accordionLabel.additionalData=Related data (technical information) pageWorkItem.accordionLabel.objectNew=Object after proposed change (technical information) pageWorkItem.accordionLabel.objectOld=Object before change (technical information) @@ -2861,7 +2863,6 @@ SystemConfigPanel.deploymentInformation.logoImageUrl = Logo image URL SystemConfigPanel.deploymentInformation.logoCssClass = Icon css class SystemConfigPanel.deploymentInformation.customerUrl = Customer url SystemConfigPanel.deploymentInformation.partnerName = Partner name -SystemConfigPanel.deploymentInformation.skin = Template skin SystemConfigPanel.deploymentInformation.subscriptionIdentifier = Subscription identifier SystemConfigPanel.deprecated.objectPolicy=This part of configuration is deprecated. It is kept here for compatibility purposes. Please, use the component below to define object policies. SystemConfigPanel.mail.config.placeholder=New Configuration @@ -2891,7 +2892,7 @@ SystemConfigPanel.title.passwordPolicy=Global password policy SystemConfigPanel.title.securityPolicy=Global security policy SystemConfigPanel.title.userTemplate=Default user template SystemConfigPanel.tooltip.duration=Format: P[n][p], n-number, p-period (d - days, m - months, ...), P3M - cleanup every 3 months -SystemConfigPanel.tooltip.color = Hex format, e.g. #3e934a for a "dark green" +SystemConfigPanel.tooltip.color =Hex format, e.g. #3c8dbc for the default "blue-light" color SystemInfoPanel.cpuUsage=CPU Usage SystemInfoPanel.heapMemory=Heap memory (used/committed/max) SystemInfoPanel.nonHeapMemory=Non heap memory (used/committed/max) @@ -3789,4 +3790,5 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Policy ExclusionPolicyConstraintPanel.exclusionTitle=Exclusion - +ValuePolicyBasicPanel.valuePolicy.name=Name +ValuePolicyBasicPanel.valuePolicy.description=Description diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties index d8f5988c51e..d65a7fba277 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties @@ -2879,7 +2879,7 @@ SystemConfigPanel.title.passwordPolicy=Global password policy SystemConfigPanel.title.securityPolicy=Global security policy SystemConfigPanel.title.userTemplate=Default user template SystemConfigPanel.tooltip.duration=Format: P[n][p], n-number, p-period (d - days, m - months, ...), P3M - cleanup every 3 months -SystemConfigPanel.tooltip.color = Hex format, e.g. #3e934a for a "dark green" +SystemConfigPanel.tooltip.color =Hex format, e.g. #3c8dbc for the default "blue-light" color SystemInfoPanel.cpuUsage=CPU Usage SystemInfoPanel.heapMemory=Heap memory (used/committed/max) SystemInfoPanel.nonHeapMemory=Non heap memory (used/committed/max) From b650d901e653c59c6732fcd00a67cec4707c857f Mon Sep 17 00:00:00 2001 From: kate Date: Wed, 20 Sep 2017 10:46:19 +0200 Subject: [PATCH 19/97] MID-4133, user's assignments button --- .../assignment/AssignmentEditorPanel.java | 4 +- .../TargetUserSelectorComponent.java | 223 ------------------ ...omponent.html => UserSelectionButton.html} | 6 +- .../assignment/UserSelectionButton.java | 182 ++++++++++++++ .../page/self/PageAssignmentShoppingKart.html | 4 +- .../page/self/PageAssignmentShoppingKart.java | 214 +++++++++++------ .../web/page/self/PageAssignmentsList.java | 64 ++++- .../dto/ShoppingCartConfigurationDto.java | 22 +- .../web/session/RoleCatalogStorage.java | 12 +- .../localization/Midpoint.properties | 6 +- .../localization/Midpoint_en.properties | 6 +- 11 files changed, 420 insertions(+), 323 deletions(-) delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/TargetUserSelectorComponent.java rename gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/{TargetUserSelectorComponent.html => UserSelectionButton.html} (71%) create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/UserSelectionButton.java diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorPanel.java index da9d7305b7f..b4a1966290c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorPanel.java @@ -1145,11 +1145,11 @@ private ItemSecurityDecisions loadSecurityDecisions(){ operationObject = ((PageAdminFocus)pageBase).getObjectWrapper().getObject(); } else if ((pageBase instanceof PageAssignmentDetails || pageBase instanceof PageAssignmentsList) //shopping cart assignment details panels && !pageBase.getSessionStorage().getRoleCatalog().isMultiUserRequest()){ - List> targetUserList = pageBase.getSessionStorage().getRoleCatalog().getTargetUserList(); + List targetUserList = pageBase.getSessionStorage().getRoleCatalog().getTargetUserList(); if (targetUserList == null || targetUserList.size() == 0){ operationObject = pageBase.loadUserSelf(); } else { - operationObject = targetUserList.get(0); + operationObject = targetUserList.get(0).asPrismObject(); } } if (operationObject == null){ diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/TargetUserSelectorComponent.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/TargetUserSelectorComponent.java deleted file mode 100644 index 7f297072110..00000000000 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/TargetUserSelectorComponent.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2016-2017 Evolveum - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.evolveum.midpoint.web.component.assignment; - -import com.evolveum.midpoint.gui.api.component.BasePanel; -import com.evolveum.midpoint.gui.api.component.ObjectBrowserPanel; -import com.evolveum.midpoint.gui.api.model.LoadableModel; -import com.evolveum.midpoint.gui.api.page.PageBase; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; -import com.evolveum.midpoint.web.session.RoleCatalogStorage; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; -import org.apache.commons.lang3.StringUtils; -import org.apache.poi.util.StringUtil; -import org.apache.wicket.AttributeModifier; -import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.ajax.markup.html.AjaxLink; -import org.apache.wicket.behavior.AttributeAppender; -import org.apache.wicket.markup.html.WebMarkupContainer; -import org.apache.wicket.markup.html.basic.Label; -import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; -import org.apache.wicket.model.StringResourceModel; - -import javax.xml.namespace.QName; -import java.util.*; - -/** - * Created by honchar. - */ -public class TargetUserSelectorComponent extends BasePanel { - - private static final String ID_TARGET_USER_BUTTON = "targetUserButton"; - private static final String ID_DELETE_TARGET_USER_BUTTON = "deleteTargetUserButton"; - private static final String ID_TARGET_USER_LABEL = "targetUserLabel"; - private static final int TARGET_USERS_TITLE_ROWS = 30; - - private PageBase pageBase; - private boolean showUserSelectionPopup = true; - private String additionalButtonStyle; - - public TargetUserSelectorComponent(String id, PageBase pageBase){ - this(id, "", pageBase); - } - - public TargetUserSelectorComponent(String id, String additionalButtonStyle, PageBase pageBase){ - super(id); - this.additionalButtonStyle = additionalButtonStyle; - this.pageBase = pageBase; - initLayout(); - } - - private void initLayout(){ - AjaxLink targetUserButton = new AjaxLink(ID_TARGET_USER_BUTTON) { - private static final long serialVersionUID = 1L; - @Override - public void onClick(AjaxRequestTarget target) { - if (showUserSelectionPopup) { - initUserSelectionPopup(createStringResource("AssignmentCatalogPanel.selectTargetUser"), true, target); - } - showUserSelectionPopup = true; - } - }; - targetUserButton.add(new AttributeAppender("class", "btn btn-default" - + (StringUtils.isEmpty(additionalButtonStyle) ? "" : " " + additionalButtonStyle))); - - targetUserButton.setOutputMarkupId(true); - targetUserButton.add(new AttributeAppender("title", getTargetUsersButtonTitle())); - add(targetUserButton); - - Label label = new Label(ID_TARGET_USER_LABEL, getTargetUserButtonLabel()); - label.setRenderBodyOnly(true); - targetUserButton.add(label); - - AjaxLink deleteButton = new AjaxLink(ID_DELETE_TARGET_USER_BUTTON) { - private static final long serialVersionUID = 1L; - @Override - public void onClick(AjaxRequestTarget target) { - showUserSelectionPopup = false; - getRoleCatalogStorage().setTargetUserList(null); - target.add(pageBase); - } - }; - deleteButton.add(new VisibleEnableBehaviour(){ - private static final long serialVersionUID = 1L; - @Override - public boolean isVisible(){ - return getRoleCatalogStorage().getTargetUserList() != null && - getRoleCatalogStorage().getTargetUserList().size() > 0; - } - }); - targetUserButton.add(deleteButton); - } - - private IModel getTargetUserButtonLabel(){ - return new IModel() { - private static final long serialVersionUID = 1L; - - @Override - public String getObject() { - if (getRoleCatalogStorage().isSelfRequest()){ - return createStringResource("AssignmentCatalogPanel.requestForMe").getString(); - } else if (getRoleCatalogStorage().isMultiUserRequest()){ - return createStringResource("AssignmentCatalogPanel.selectTargetUser").getString() + " (" + - createStringResource("AssignmentCatalogPanel.requestForMultiple", - getRoleCatalogStorage().getTargetUserList().size()).getString() - + ")"; - } else { - String name = getRoleCatalogStorage().getTargetUserList().get(0).asObjectable().getName().getOrig(); - return createStringResource("AssignmentCatalogPanel.requestFor").getString() + " " + name; - } - } - - @Override - public void setObject(String s) { - - } - - @Override - public void detach() { - - } - }; - - } - - private void initUserSelectionPopup(StringResourceModel title, boolean multiselect, AjaxRequestTarget target) { - - List supportedTypes = new ArrayList<>(); - supportedTypes.add(pageBase.getPrismContext().getSchemaRegistry() - .findObjectDefinitionByCompileTimeClass(UserType.class).getTypeName()); - ObjectBrowserPanel focusBrowser = new ObjectBrowserPanel(pageBase.getMainPopupBodyId(), - UserType.class, supportedTypes, multiselect, pageBase, null, getSelectedObjects()) { - @Override - protected void addPerformed(AjaxRequestTarget target, QName type, List selected) { - super.addPerformed(target, type, selected); - List> userList = new ArrayList<>(); - for (UserType user : selected){ - userList.add(user.asPrismObject()); - } - getRoleCatalogStorage().setTargetUserList(userList); - target.add(pageBase); - } - - @Override - public StringResourceModel getTitle() { - return title; - } - - }; - pageBase.showMainPopup(focusBrowser, target); - } - - private List getSelectedObjects(){ - List> selectedUsers = getRoleCatalogStorage().getTargetUserList(); - List users = new ArrayList<>(); - if (selectedUsers != null) { - for (PrismObject user : selectedUsers) { - users.add(user.asObjectable()); - } - } - return users; - } - - private IModel getTargetUsersButtonTitle() { - return new LoadableModel(true) { - public String load() { - if (getRoleCatalogStorage().isSelfRequest()){ - return createStringResource("AssignmentCatalogPanel.requestForMe").getString(); - } - List> targetUsersList = getRoleCatalogStorage().getTargetUserList(); - if (targetUsersList.size() == 1){ - return createStringResource("AssignmentCatalogPanel.requestFor").getString() + - " " + targetUsersList.get(0).getName().getOrig(); - } - - StringBuilder sb = new StringBuilder(); - if (getRoleCatalogStorage().isMultiUserRequest()) { - List> sortedList = getRoleCatalogStorage().getTargetUserList(); - Collections.sort(sortedList, new Comparator>() { - - @Override - public int compare(PrismObject u1, PrismObject u2) { - return String.CASE_INSENSITIVE_ORDER.compare(u1.getName().getOrig(), u2.getName().getOrig()); - } - }); - int columnsAmount = sortedList.size() / TARGET_USERS_TITLE_ROWS; - Iterator> it = sortedList.iterator(); - while (it.hasNext()){ - for (int i=0; i <= columnsAmount; i++){ - if (it.hasNext()){ - PrismObject user = it.next(); - sb.append(user.getName().getOrig()); - if (it.hasNext()){ - sb.append(",\t"); - } - } - } - sb.append(System.lineSeparator()); - } - } - return sb.toString(); - } - }; - } - - private RoleCatalogStorage getRoleCatalogStorage(){ - return pageBase.getSessionStorage().getRoleCatalog(); - } -} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/TargetUserSelectorComponent.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/UserSelectionButton.html similarity index 71% rename from gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/TargetUserSelectorComponent.html rename to gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/UserSelectionButton.html index b1e775ee448..394627d8794 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/TargetUserSelectorComponent.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/UserSelectionButton.html @@ -17,9 +17,9 @@ - - - + + + \ No newline at end of file diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/UserSelectionButton.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/UserSelectionButton.java new file mode 100644 index 00000000000..ff8e9899187 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/UserSelectionButton.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2016-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.web.component.assignment; + +import com.evolveum.midpoint.gui.api.component.BasePanel; +import com.evolveum.midpoint.gui.api.component.ObjectBrowserPanel; +import com.evolveum.midpoint.gui.api.page.PageBase; +import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.AjaxLink; +import org.apache.wicket.behavior.AttributeAppender; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.model.AbstractReadOnlyModel; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.StringResourceModel; + +import javax.xml.namespace.QName; +import java.util.*; + +/** + * Created by honchar. + */ +public abstract class UserSelectionButton extends BasePanel> { + + private static final String ID_USER_SELECTION_BUTTON = "userSelectionButton"; + private static final String ID_DELETE_SELECTED_USER_BUTTON = "deleteSelectedUserButton"; + private static final String ID_USER_SELECTION_BUTTON_LABEL = "userSelectionButtonLabel"; + protected static final int TARGET_USERS_TITLE_ROWS = 30; + + private PageBase pageBase; + private boolean showUserSelectionPopup = true; + private boolean isMultiSelection; + private StringResourceModel titleModel; + + public UserSelectionButton(String id, IModel> selectedUsersListModel, boolean isMultiSelection, + StringResourceModel titleModel){ + super(id, selectedUsersListModel); + this.isMultiSelection = isMultiSelection; + this.titleModel = titleModel; + } + + @Override + protected void onInitialize(){ + super.onInitialize(); + pageBase = getPageBase(); + initLayout(); + } + + private void initLayout(){ + AjaxLink userSelectionButton = new AjaxLink(ID_USER_SELECTION_BUTTON) { + private static final long serialVersionUID = 1L; + @Override + public void onClick(AjaxRequestTarget target) { + if (showUserSelectionPopup) { + initUserSelectionPopup(target); + } + showUserSelectionPopup = true; + } + }; + userSelectionButton.setOutputMarkupId(true); + userSelectionButton.add(new AttributeAppender("title", new AbstractReadOnlyModel() { + private static final long serialVersionUID = 1L; + + @Override + public String getObject() { + return getUserSelectionButtonTitle(); + } + })); + add(userSelectionButton); + + Label label = new Label(ID_USER_SELECTION_BUTTON_LABEL, new AbstractReadOnlyModel() { + private static final long serialVersionUID = 1L; + + @Override + public String getObject() { + return getUserButtonLabel(); + } + }); + label.setRenderBodyOnly(true); + userSelectionButton.add(label); + + AjaxLink deleteButton = new AjaxLink(ID_DELETE_SELECTED_USER_BUTTON) { + private static final long serialVersionUID = 1L; + @Override + public void onClick(AjaxRequestTarget target) { + UserSelectionButton.this.onDeleteSelectedUsersPerformed(target); + } + }; + deleteButton.add(new VisibleEnableBehaviour(){ + private static final long serialVersionUID = 1L; + @Override + public boolean isVisible(){ + return getModelObject() != null && getModelObject().size() > 0; + } + }); + userSelectionButton.add(deleteButton); + } + + protected abstract String getUserButtonLabel(); + + protected void onDeleteSelectedUsersPerformed(AjaxRequestTarget target){ + showUserSelectionPopup = false; + } + + private void initUserSelectionPopup(AjaxRequestTarget target) { + List supportedTypes = new ArrayList<>(); + supportedTypes.add(pageBase.getPrismContext().getSchemaRegistry() + .findObjectDefinitionByCompileTimeClass(UserType.class).getTypeName()); + ObjectBrowserPanel focusBrowser = new ObjectBrowserPanel(pageBase.getMainPopupBodyId(), + UserType.class, supportedTypes, isMultiSelection, pageBase, null, getModelObject()) { + + @Override + protected void onSelectPerformed(AjaxRequestTarget target, UserType object) { + super.onSelectPerformed(target, object); + singleUserSelectionPerformed(target, object); + } + + @Override + protected void addPerformed(AjaxRequestTarget target, QName type, List selected) { + super.addPerformed(target, type, selected); + multipleUsersSelectionPerformed(target, selected); + } + + @Override + public StringResourceModel getTitle() { + return titleModel; + } + + }; + pageBase.showMainPopup(focusBrowser, target); + } + + protected void singleUserSelectionPerformed(AjaxRequestTarget target, UserType user){ + } + + protected void multipleUsersSelectionPerformed(AjaxRequestTarget target, List usersList){ + } + + protected String getUserSelectionButtonTitle() { + if (getModelObject().size() > 1) { + StringBuilder sb = new StringBuilder(); + Collections.sort(getModelObject(), new Comparator() { + + @Override + public int compare(UserType u1, UserType u2) { + return String.CASE_INSENSITIVE_ORDER.compare(u1.getName().getOrig(), u2.getName().getOrig()); + } + }); + int columnsAmount = getModelObject().size() / TARGET_USERS_TITLE_ROWS; + Iterator it = getModelObject().iterator(); + while (it.hasNext()) { + for (int i = 0; i <= columnsAmount; i++) { + if (it.hasNext()) { + UserType user = it.next(); + sb.append(user.getName().getOrig()); + if (it.hasNext()) { + sb.append(",\t"); + } + } + } + sb.append(System.lineSeparator()); + } + return sb.toString(); + } + return titleModel.getString(); + } +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentShoppingKart.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentShoppingKart.html index 347c5335970..5da5f5ee60c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentShoppingKart.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentShoppingKart.html @@ -26,8 +26,8 @@ -
- - - - -
- - diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismOptionButtonPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismOptionButtonPanel.java deleted file mode 100644 index 8cc2ad5eae7..00000000000 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismOptionButtonPanel.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2010-2013 Evolveum - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.evolveum.midpoint.web.component.prism; - -import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; -import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.ajax.markup.html.AjaxLink; -import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox; -import org.apache.wicket.behavior.AttributeAppender; -import org.apache.wicket.markup.html.image.Image; -import org.apache.wicket.markup.html.panel.Panel; -import org.apache.wicket.model.AbstractReadOnlyModel; -import org.apache.wicket.model.IModel; -import org.apache.wicket.model.PropertyModel; -import org.apache.wicket.request.resource.PackageResourceReference; - -/** - * @author mserbak - * @author lazyman - */ -public class PrismOptionButtonPanel extends Panel { - - public PrismOptionButtonPanel(String id, IModel model) { - super(id); - - initLayout(model); - } - - private void initLayout(final IModel model) { - AjaxCheckBox check = new AjaxCheckBox("check", new PropertyModel(model, "selected")) { - - @Override - protected void onUpdate(AjaxRequestTarget target) { - PrismOptionButtonPanel.this.checkBoxOnUpdate(target); - } - }; - check.add(new VisibleEnableBehaviour() { - - @Override - public boolean isVisible() { - return model.getObject().isSelectable(); - } - }); - check.setOutputMarkupId(true); - add(check); - - initButtons(model); - } - - private void initButtons(final IModel model) { - AjaxLink showEmpty = new AjaxLink("showEmptyButton") { - - @Override - public void onClick(AjaxRequestTarget target) { - showEmptyOnClick(target); - } - - }; - add(showEmpty); - - showEmpty.add(new VisibleEnableBehaviour() { - - @Override - public boolean isVisible() { - return !model.getObject().isReadonly(); - } - }); - - Image showEmptyImg = new Image("showEmptyImg", new AbstractReadOnlyModel() { - - @Override - public Object getObject() { - ObjectWrapper wrapper = model.getObject(); -// if (wrapper.isShowEmpty()) { -// return new PackageResourceReference(PrismObjectPanel.class, -// "ShowEmptyFalse.png"); -// } - return new PackageResourceReference(PrismPanel.class, - "ShowEmptyTrue.png"); - } - }); - - showEmptyImg.add(new AttributeAppender("title", new AbstractReadOnlyModel() { - - @Override - public Object getObject() { -// ObjectWrapper wrapper = model.getObject(); -// if (wrapper.isShowEmpty()) { -// return getString("prismOptionButtonPanel.hideEmpty"); -// } - return getString("prismOptionButtonPanel.showEmpty"); - } - }, "")); - - showEmpty.add(showEmptyImg); - - AjaxLink minimize = new AjaxLink("minimizeButton") { - - @Override - public void onClick(AjaxRequestTarget target) { - minimizeOnClick(target); - } - }; - add(minimize); - - Image minimizeImg = new Image("minimizeImg", new AbstractReadOnlyModel() { - - @Override - public Object getObject() { - ObjectWrapper wrapper = model.getObject(); - if (wrapper.isMinimalized()) { - return new PackageResourceReference(PrismPanel.class, - "Maximize.png"); - } - - return new PackageResourceReference(PrismPanel.class, - "Minimize.png"); - } - }); - minimizeImg.add(new AttributeAppender("title", new AbstractReadOnlyModel() { - - @Override - public Object getObject() { - ObjectWrapper wrapper = model.getObject(); - if (wrapper.isMinimalized()) { - return getString("prismOptionButtonPanel.maximize"); - } - - return getString("prismOptionButtonPanel.minimize"); - } - }, "")); - - minimize.add(minimizeImg); - } - - public void minimizeOnClick(AjaxRequestTarget target) { - } - - public void showEmptyOnClick(AjaxRequestTarget target) { - } - - public void checkBoxOnUpdate(AjaxRequestTarget target) { - } -} From 429c5152576743c3a69a333b57f8ef2aa2a3c85d Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Wed, 20 Sep 2017 14:32:06 +0200 Subject: [PATCH 26/97] Interim commit. --- .../evaluators/StateConstraintEvaluator.java | 3 ++ .../resources/lens/policy/role-student.xml | 34 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/StateConstraintEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/StateConstraintEvaluator.java index c7e485c6e70..b1a9658170a 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/StateConstraintEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/StateConstraintEvaluator.java @@ -105,6 +105,9 @@ private EvaluatedPolicyRuleTrigger evaluateForObject(St if (!filter.match(object.getValue(), matchingRuleRegistry)) { match = false; } + } + if (match && constraint.getExecuteScript() != null) { + } if (match && constraint.getExpression() != null) { match = evaluatorHelper.evaluateBoolean(constraint.getExpression(), evaluatorHelper.createExpressionVariables(ctx), diff --git a/model/model-impl/src/test/resources/lens/policy/role-student.xml b/model/model-impl/src/test/resources/lens/policy/role-student.xml index 746804cbe2f..2ccc89aad87 100644 --- a/model/model-impl/src/test/resources/lens/policy/role-student.xml +++ b/model/model-impl/src/test/resources/lens/policy/role-student.xml @@ -415,4 +415,38 @@ + + + no-task-for-this-object + + + + task-for-this-object-exists + + + TaskType + + + + objectRef + + + + + + + + + + + + + + + + From 4ee51934c4a04ace0535eb42472c53155678f9d1 Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Wed, 20 Sep 2017 15:14:40 +0200 Subject: [PATCH 27/97] small fixes after merge --- .../AbstractAssignmentDetailsPanel.java | 22 +----- .../AbstractRoleAssignmentDetailsPanel.java | 4 - .../assignment/PolicyRuleDetailsPanel.html | 79 ------------------- .../assignment/PolicyRuleDetailsPanel.java | 11 --- 4 files changed, 1 insertion(+), 115 deletions(-) delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleDetailsPanel.html diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.java index 69cacbd17a0..3bbb2a51f1f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.java @@ -62,19 +62,6 @@ public abstract class AbstractAssignmentDetailsPanel extend private final static String ID_DISPLAY_NAME = "displayName"; private final static String ID_ACTIVATION_PANEL = "activationPanel"; private final static String ID_CONTAINERS = "otherContainers"; -// private final static String ID_DONE_BUTTON = "doneButton"; - -// private static final String ID_RELATION_CONTAINER = "relationContainer"; -// private static final String ID_RELATION = "relation"; -// -// private static final String ID_TENANT_CONTAINER = "tenantContainer"; -// private static final String ID_TENANT = "tenant"; -// private static final String ID_PROJECT_CONTAINER = "projectContainer"; -// private static final String ID_PROJECT = "project"; -// private static final String ID_POLICY_SITUATIONS = "policySituations"; -// private static final String ID_POLICY_SITUATION = "policySituation"; - -// private static final String ID_POLICY_RULE = "policyRule"; public AbstractAssignmentDetailsPanel(String id, Form form, IModel assignmentModel){ super(id, assignmentModel); @@ -176,7 +163,6 @@ private boolean getAssignmentBasicTabVisibity(ItemWrapper itemWrapper, ItemPath return PropertyOrReferenceWrapper.class.isAssignableFrom(itemWrapper.getClass()) && !WebComponentUtil.isItemVisible(pathsToHide, itemWrapper.getPath()); } - protected abstract boolean getVisibilityModel(ItemPath pathToBeFound, ItemPath parentPath); private boolean getActivationVisibileItems(ItemPath pathToCheck, ItemPath assignmentPath) { if (assignmentPath.subPath(new ItemPath(AssignmentType.F_ACTIVATION, ActivationType.F_LOCKOUT_EXPIRATION_TIMESTAMP)).equivalent(pathToCheck)){ @@ -195,12 +181,6 @@ protected IModel getAdditionalNameLabelStyleClass(){ return Model.of(""); } - protected boolean isVisible(Object path) { - return !getHiddenItems().contains(path); - } - - protected abstract List getHiddenItems(); - -// protected abstract void initPropertiesPanel(WebMarkupContainer propertiesPanel); + } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentDetailsPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentDetailsPanel.java index bdea5623749..6cf53122e56 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentDetailsPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentDetailsPanel.java @@ -36,10 +36,6 @@ public AbstractRoleAssignmentDetailsPanel(String id, Form form, IModel collectContainersToShow() { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleDetailsPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleDetailsPanel.html deleted file mode 100644 index ac89545b076..00000000000 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleDetailsPanel.html +++ /dev/null @@ -1,79 +0,0 @@ - - - - - -
-
- -
-
-
-
- - - -
- -
- - - - - - - - - - - - - - - - - - -
-
-
-
- -
-
-
-
- - -
-
-
- -
- - - -
-
-
-
-
-
- - - diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleDetailsPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleDetailsPanel.java index b4f44593bde..8b7c5e55c10 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleDetailsPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleDetailsPanel.java @@ -47,16 +47,5 @@ protected List collectContainersToShow() { return containersToShow; } - @Override - protected boolean getVisibilityModel(ItemPath pathToBeFound, ItemPath parentPath) { - // TODO Auto-generated method stub - return false; - } - - @Override - protected List getHiddenItems() { - // TODO Auto-generated method stub - return null; - } } From f173e898c2eba792e3f3e71856c9d76f1d322d28 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Wed, 20 Sep 2017 15:18:56 +0200 Subject: [PATCH 28/97] Added "forWholeInput" parameter of execute-script bulk action. Fixed TestPolicyRules2. --- .../prism/schema/SchemaRegistryImpl.java | 1 + .../scripting/actions/NotifyExecutor.java | 2 +- .../scripting/actions/ScriptExecutor.java | 78 ++++++++++------ .../scripting/helpers/OperationsHelper.java | 6 +- .../model/impl/lens/TestPolicyRules2.java | 2 +- .../lens/policy/role-ambiguous-reference.xml | 4 +- .../lens/policy/role-chained-references.xml | 12 ++- .../lens/policy/role-cyclic-references.xml | 10 +- .../resources/lens/policy/role-student.xml | 92 ++++++++++++------- .../policy/role-unresolvable-references.xml | 4 +- 10 files changed, 138 insertions(+), 73 deletions(-) diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistryImpl.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistryImpl.java index 0371867c36b..7bd13cbf200 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistryImpl.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistryImpl.java @@ -435,6 +435,7 @@ private void parsePrismSchema(SchemaDescription schemaDescription, boolean allow detectExtensionSchema(schema); } + // see https://stackoverflow.com/questions/14837293/xsd-circular-import private void parsePrismSchemas(List schemaDescriptions, boolean allowDelayedItemDefinitions) throws SchemaException { List prismSchemaDescriptions = schemaDescriptions.stream() .filter(sd -> sd.isPrismSchema()) diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/NotifyExecutor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/NotifyExecutor.java index 934d7510d07..896a01f4e4e 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/NotifyExecutor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/NotifyExecutor.java @@ -73,7 +73,7 @@ public PipelineData execute(ActionExpressionType expression, PipelineData input, PARAM_STATUS, input, context, EventStatusType.class, globalResult); EventOperationType operation = expressionHelper.getSingleArgumentValue(expression.getParameter(), PARAM_OPERATION, false, false, PARAM_OPERATION, input, context, EventOperationType.class, globalResult); - boolean forWholeInput = expressionHelper.getArgumentAsBoolean(expression.getParameter(), PARAM_FOR_WHOLE_INPUT, input, context, false, PARAM_SUBTYPE, globalResult); + boolean forWholeInput = expressionHelper.getArgumentAsBoolean(expression.getParameter(), PARAM_FOR_WHOLE_INPUT, input, context, false, PARAM_FOR_WHOLE_INPUT, globalResult); if (handler != null) { checkRootAuthorization(globalResult, NAME); // TODO explain that the reason is that handler is not null diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/ScriptExecutor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/ScriptExecutor.java index 4cd7434f959..fcc59cbaf67 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/ScriptExecutor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/ScriptExecutor.java @@ -60,6 +60,7 @@ public class ScriptExecutor extends BaseActionExecutor { private static final String NAME = "execute-script"; private static final String PARAM_SCRIPT = "script"; private static final String PARAM_OUTPUT_ITEM = "outputItem"; // item name or type (as URI!) -- EXPERIMENTAL + private static final String PARAM_FOR_WHOLE_INPUT = "forWholeInput"; @PostConstruct public void init() { @@ -75,6 +76,7 @@ public PipelineData execute(ActionExpressionType expression, PipelineData input, NAME, input, context, ScriptExpressionEvaluatorType.class, globalResult); String outputItem = expressionHelper.getSingleArgumentValue(expression.getParameter(), PARAM_OUTPUT_ITEM, false, false, NAME, input, context, String.class, globalResult); + boolean forWholeInput = expressionHelper.getArgumentAsBoolean(expression.getParameter(), PARAM_FOR_WHOLE_INPUT, input, context, false, PARAM_FOR_WHOLE_INPUT, globalResult); ItemDefinition outputDefinition = getItemDefinition(outputItem); @@ -86,45 +88,69 @@ public PipelineData execute(ActionExpressionType expression, PipelineData input, } PipelineData output = PipelineData.createEmpty(); - for (PipelineItem item: input.getData()) { - PrismValue value = item.getValue(); - OperationResult result = operationsHelper.createActionResult(item, this, context, globalResult); + if (forWholeInput) { + OperationResult result = operationsHelper.createActionResult(null, this, context, globalResult); context.checkTaskStop(); - String valueDescription; - long started; - if (value instanceof PrismObjectValue) { - started = operationsHelper.recordStart(context, asObjectType(value)); - valueDescription = asObjectType(value).asPrismObject().toString(); - } else { - started = 0; - valueDescription = value.toHumanReadableString(); - } Throwable exception = null; try { - Object outObject = executeScript(scriptExpression, value, context, result); + Object outObject = executeScript(scriptExpression, input, context, result); if (outObject != null) { - addToData(outObject, item.getResult(), output); + addToData(outObject, PipelineData.newOperationResult(), output); } else { // no definition means we don't plan to provide any output - so let's just copy the input item to the output // (actually, null definition with non-null outObject should not occur) if (outputDefinition == null) { - output.add(item); + output.addAllFrom(input); } } - if (value instanceof PrismObjectValue) { - operationsHelper.recordEnd(context, asObjectType(value), started, null); - } } catch (Throwable ex) { - if (value instanceof PrismObjectValue) { - operationsHelper.recordEnd(context, asObjectType(value), started, ex); - } - exception = processActionException(ex, NAME, value, context); + exception = processActionException(ex, NAME, null, context); // TODO value for error reporting (3rd parameter) } context.println((exception != null ? "Attempted to execute " : "Executed ") - + "script on " + valueDescription + exceptionSuffix(exception)); + + "script on the pipeline" + exceptionSuffix(exception)); operationsHelper.trimAndCloneResult(result, globalResult, context); - } + } else { + for (PipelineItem item : input.getData()) { + PrismValue value = item.getValue(); + OperationResult result = operationsHelper.createActionResult(item, this, context, globalResult); + + context.checkTaskStop(); + String valueDescription; + long started; + if (value instanceof PrismObjectValue) { + started = operationsHelper.recordStart(context, asObjectType(value)); + valueDescription = asObjectType(value).asPrismObject().toString(); + } else { + started = 0; + valueDescription = value.toHumanReadableString(); + } + Throwable exception = null; + try { + Object outObject = executeScript(scriptExpression, value, context, result); + if (outObject != null) { + addToData(outObject, item.getResult(), output); + } else { + // no definition means we don't plan to provide any output - so let's just copy the input item to the output + // (actually, null definition with non-null outObject should not occur) + if (outputDefinition == null) { + output.add(item); + } + } + if (value instanceof PrismObjectValue) { + operationsHelper.recordEnd(context, asObjectType(value), started, null); + } + } catch (Throwable ex) { + if (value instanceof PrismObjectValue) { + operationsHelper.recordEnd(context, asObjectType(value), started, ex); + } + exception = processActionException(ex, NAME, value, context); + } + context.println((exception != null ? "Attempted to execute " : "Executed ") + + "script on " + valueDescription + exceptionSuffix(exception)); + operationsHelper.trimAndCloneResult(result, globalResult, context); + } + } return output; } @@ -165,10 +191,10 @@ private ItemDefinition getItemDefinition(String itemUri) throws ScriptExecuti throw new ScriptExecutionException("Supplied item identification " + itemUri + " corresponds neither to item name nor type name"); } - private Object executeScript(ScriptExpression scriptExpression, PrismValue prismValue, ExecutionContext context, OperationResult result) + private Object executeScript(ScriptExpression scriptExpression, Object input, ExecutionContext context, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { ExpressionVariables variables = new ExpressionVariables(); - variables.addVariableDefinition(ExpressionConstants.VAR_INPUT, prismValue); + variables.addVariableDefinition(ExpressionConstants.VAR_INPUT, input); variables.addVariableDefinition(ExpressionConstants.VAR_PRISM_CONTEXT, prismContext); ExpressionUtil.addActorVariable(variables, securityEnforcer); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/helpers/OperationsHelper.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/helpers/OperationsHelper.java index dde78721937..cf68f29d75d 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/helpers/OperationsHelper.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/helpers/OperationsHelper.java @@ -154,8 +154,10 @@ public void recordEnd(ExecutionContext context, ObjectType objectType, long star public OperationResult createActionResult(PipelineItem item, ActionExecutor executor, ExecutionContext context, OperationResult globalResult) { OperationResult result = new OperationResult(executor.getClass().getName() + "." + "execute"); - result.addParam("value", String.valueOf(item.getValue())); - item.getResult().addSubresult(result); + if (item != null) { + result.addParam("value", String.valueOf(item.getValue())); + item.getResult().addSubresult(result); + } return result; } diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules2.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules2.java index 9522b3301fa..529585a05ca 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules2.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules2.java @@ -72,7 +72,7 @@ public class TestPolicyRules2 extends AbstractLensTest { protected static final File ROLE_AMBIGUOUS_REFERENCE_FILE = new File(TEST_DIR, "role-ambiguous-reference.xml"); private static final int STUDENT_TARGET_RULES = 5; // one is global - private static final int STUDENT_FOCUS_RULES = 20; + private static final int STUDENT_FOCUS_RULES = 21; private static final String ACTIVITY_DESCRIPTION = "PROJECTOR (test)"; diff --git a/model/model-impl/src/test/resources/lens/policy/role-ambiguous-reference.xml b/model/model-impl/src/test/resources/lens/policy/role-ambiguous-reference.xml index 99962beb598..241d5bc0f6a 100644 --- a/model/model-impl/src/test/resources/lens/policy/role-ambiguous-reference.xml +++ b/model/model-impl/src/test/resources/lens/policy/role-ambiguous-reference.xml @@ -26,7 +26,9 @@ rule-A constraint-A - constraint-B + + constraint-B + diff --git a/model/model-impl/src/test/resources/lens/policy/role-chained-references.xml b/model/model-impl/src/test/resources/lens/policy/role-chained-references.xml index 119155dc5d3..3b9f09c3f46 100644 --- a/model/model-impl/src/test/resources/lens/policy/role-chained-references.xml +++ b/model/model-impl/src/test/resources/lens/policy/role-chained-references.xml @@ -25,7 +25,9 @@ rule1 - mod-description-and-riskLevel-and-inducement + + mod-description-and-riskLevel-and-inducement + @@ -40,7 +42,9 @@ description - mod-riskLevel-and-inducement + + mod-riskLevel-and-inducement + @@ -55,7 +59,9 @@ riskLevel - mod-inducement + + mod-inducement + diff --git a/model/model-impl/src/test/resources/lens/policy/role-cyclic-references.xml b/model/model-impl/src/test/resources/lens/policy/role-cyclic-references.xml index 653e3e22af1..bc875edcd21 100644 --- a/model/model-impl/src/test/resources/lens/policy/role-cyclic-references.xml +++ b/model/model-impl/src/test/resources/lens/policy/role-cyclic-references.xml @@ -20,13 +20,15 @@ xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> - Cyclic references + Cyclic references rule-A constraint-A - constraint-B + + constraint-B + @@ -48,7 +50,9 @@ false true - constraint-A + + constraint-A + diff --git a/model/model-impl/src/test/resources/lens/policy/role-student.xml b/model/model-impl/src/test/resources/lens/policy/role-student.xml index 2ccc89aad87..ea3700cb350 100644 --- a/model/model-impl/src/test/resources/lens/policy/role-student.xml +++ b/model/model-impl/src/test/resources/lens/policy/role-student.xml @@ -19,7 +19,7 @@ xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3"> Student @@ -59,7 +59,9 @@ ambivalent-rule-manually-resolved-to-assignment - always-true + + always-true + @@ -73,7 +75,9 @@ ambivalent-rule-manually-resolved-to-focus - always-true + + always-true + @@ -123,7 +127,9 @@ true true - cc-1900 + + cc-1900 + @@ -140,7 +146,9 @@ false true - cc-1900 + + cc-1900 + @@ -157,7 +165,9 @@ true false - cc-1900 + + cc-1900 + @@ -173,7 +183,9 @@ true - cc-1900 + + cc-1900 + @@ -205,7 +217,9 @@ true true - student-assignment + + student-assignment + @@ -222,7 +236,9 @@ false true - student-assignment + + student-assignment + @@ -239,7 +255,9 @@ true false - student-assignment + + student-assignment + @@ -255,7 +273,9 @@ false - student-assignment + + student-assignment + @@ -419,30 +439,32 @@ no-task-for-this-object - - - task-for-this-object-exists - - - TaskType - - - - objectRef - - - - - - - - - - + + + task-for-this-object-exists + + + TaskType + + + + objectRef + + + + + + + + + + diff --git a/model/model-impl/src/test/resources/lens/policy/role-unresolvable-references.xml b/model/model-impl/src/test/resources/lens/policy/role-unresolvable-references.xml index 255202b9da0..29d55c73360 100644 --- a/model/model-impl/src/test/resources/lens/policy/role-unresolvable-references.xml +++ b/model/model-impl/src/test/resources/lens/policy/role-unresolvable-references.xml @@ -25,7 +25,9 @@ rule-A - unresolvable + + unresolvable + From b86e78a864012856e4790b6c34e54e625b76ad9f Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Wed, 20 Sep 2017 17:17:45 +0200 Subject: [PATCH 29/97] Bulk actions as object state constraint evaluators. --- .../xml/ns/public/common/common-policy-3.xsd | 6 +- ...AssignmentPolicyRuleEvaluationContext.java | 7 ++ .../ObjectPolicyRuleEvaluationContext.java | 7 ++ .../policy/PolicyRuleEvaluationContext.java | 2 +- .../evaluators/StateConstraintEvaluator.java | 58 ++++++++++++----- .../model/impl/lens/TestPolicyRules2.java | 64 +++++++++++++++++++ .../resources/lens/policy/role-student.xml | 42 ++++++++---- 7 files changed, 153 insertions(+), 33 deletions(-) diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd index 9943f527eaf..185dfa04f07 100644 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd @@ -786,21 +786,21 @@ - Filter that is to be used to determine the state. + Filter that is to be used to determine the state. Mutually exclusive with expression and executeScript. - Expression that is to be used to determine the state. + Expression that is to be used to determine the state. Mutually exclusive with filter and executeScript. - Scripting expression (bulk action) to be used to determine the state. + Scripting expression (bulk action) to be used to determine the state. Mutually exclusive with filter and expression. diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/AssignmentPolicyRuleEvaluationContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/AssignmentPolicyRuleEvaluationContext.java index 2ed84218e64..734839749c2 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/AssignmentPolicyRuleEvaluationContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/AssignmentPolicyRuleEvaluationContext.java @@ -93,4 +93,11 @@ public String getShortDescription() { (isDirect ? "directly":"indirectly") + " in " + ObjectTypeUtil.toShortString(focusContext.getObjectAny()) + " / " + state; } + + @SuppressWarnings({ "CloneDoesntDeclareCloneNotSupportedException", "MethodDoesntCallSuperMethod" }) + @Override + public AssignmentPolicyRuleEvaluationContext clone() { + return new AssignmentPolicyRuleEvaluationContext<>(policyRule, evaluatedAssignment, inPlus, inZero, inMinus, + isDirect, lensContext, evaluatedAssignmentTriple, task); + } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/ObjectPolicyRuleEvaluationContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/ObjectPolicyRuleEvaluationContext.java index e42e178ec09..43957ddd5fb 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/ObjectPolicyRuleEvaluationContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/ObjectPolicyRuleEvaluationContext.java @@ -54,4 +54,11 @@ public void triggerRule(Collection> triggers) { public String getShortDescription() { return ObjectTypeUtil.toShortString(focusContext.getObjectAny()) + " / " + state; } + + @SuppressWarnings({ "CloneDoesntDeclareCloneNotSupportedException", "MethodDoesntCallSuperMethod" }) + @Override + public ObjectPolicyRuleEvaluationContext clone() { + return new ObjectPolicyRuleEvaluationContext<>(policyRule, lensContext, task); + } + } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleEvaluationContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleEvaluationContext.java index cd79de1ce17..2442c2cb190 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleEvaluationContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleEvaluationContext.java @@ -30,7 +30,7 @@ /** * @author mederly */ -public abstract class PolicyRuleEvaluationContext { +public abstract class PolicyRuleEvaluationContext implements Cloneable { @NotNull public final EvaluatedPolicyRule policyRule; @NotNull public final LensContext lensContext; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/StateConstraintEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/StateConstraintEvaluator.java index b1a9658170a..8dac51dd762 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/StateConstraintEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/StateConstraintEvaluator.java @@ -16,10 +16,15 @@ package com.evolveum.midpoint.model.impl.lens.projector.policy.evaluators; +import com.evolveum.midpoint.model.api.PipelineItem; +import com.evolveum.midpoint.model.api.ScriptExecutionException; import com.evolveum.midpoint.model.api.context.EvaluatedPolicyRuleTrigger; import com.evolveum.midpoint.model.api.context.EvaluatedStateTrigger; import com.evolveum.midpoint.model.impl.lens.projector.policy.AssignmentPolicyRuleEvaluationContext; import com.evolveum.midpoint.model.impl.lens.projector.policy.PolicyRuleEvaluationContext; +import com.evolveum.midpoint.model.impl.scripting.ExecutionContext; +import com.evolveum.midpoint.model.impl.scripting.PipelineData; +import com.evolveum.midpoint.model.impl.scripting.ScriptingExpressionEvaluator; import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.marshaller.QueryConvertor; import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; @@ -33,6 +38,7 @@ 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.SystemException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; @@ -44,11 +50,12 @@ import javax.xml.bind.JAXBElement; -import java.util.ArrayList; -import java.util.List; +import java.util.*; +import static com.evolveum.midpoint.schema.constants.ExpressionConstants.VAR_OBJECT; import static com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyConstraintKindType.ASSIGNMENT_STATE; import static com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyConstraintKindType.OBJECT_STATE; +import static java.util.Collections.emptyList; /** * @author mederly @@ -67,6 +74,7 @@ public class StateConstraintEvaluator implements PolicyConstraintEvaluator EvaluatedPolicyRuleTrigger evaluate(JAXBElement constraint, @@ -90,34 +98,54 @@ private EvaluatedPolicyRuleTrigger evaluateForObject(St PolicyRuleEvaluationContext ctx, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException { - if (constraint.getFilter() == null && constraint.getExpression() == null) { - return null; // shouldn't occur + int count = + (constraint.getFilter() != null ? 1 : 0) + + (constraint.getExpression() != null ? 1 : 0) + + (constraint.getExecuteScript() != null ? 1 : 0); + + if (count != 1) { + throw new SchemaException("Exactly one of filter, expression, executeScript element must be present."); } PrismObject object = ctx.getObject(); if (object == null) { return null; } - boolean match = true; if (constraint.getFilter() != null) { ObjectFilter filter = QueryConvertor .parseFilter(constraint.getFilter(), object.asObjectable().getClass(), prismContext); if (!filter.match(object.getValue(), matchingRuleRegistry)) { - match = false; + return null; } } - if (match && constraint.getExecuteScript() != null) { - + if (constraint.getExecuteScript() != null) { + Map variables = new HashMap<>(); + variables.put(VAR_OBJECT.getLocalPart(), object); + variables.put("ruleEvaluationContext", ctx); + ExecutionContext resultingContext; + try { + resultingContext = scriptingExpressionEvaluator.evaluateExpression(constraint.getExecuteScript(), variables, ctx.task, result); + } catch (ScriptExecutionException e) { + throw new SystemException(e); // TODO + } + PipelineData output = resultingContext.getFinalOutput(); + LOGGER.trace("Scripting expression returned {} item(s); console output is:\n{}", + output != null ? output.getData().size() : null, resultingContext.getConsoleOutput()); + List items = output != null ? output.getData() : emptyList(); + if (items.isEmpty()) { + return null; + } + // TODO retrieve localization messages from output } - if (match && constraint.getExpression() != null) { - match = evaluatorHelper.evaluateBoolean(constraint.getExpression(), evaluatorHelper.createExpressionVariables(ctx), - "expression in object state constraint " + constraint.getName() + " (" + ctx.state + ")", ctx.task, result); + if (constraint.getExpression() != null) { + if (!evaluatorHelper.evaluateBoolean(constraint.getExpression(), evaluatorHelper.createExpressionVariables(ctx), + "expression in object state constraint " + constraint.getName() + " (" + ctx.state + ")", ctx.task, result)) { + return null; + } + // TODO retrieve localization messages from return (it should be Object then, not Boolean) } - if (match) { - return new EvaluatedStateTrigger(OBJECT_STATE, constraint, createMessage(OBJECT_CONSTRAINT_KEY_PREFIX, constraint, ctx, result)); - } - return null; + return new EvaluatedStateTrigger(OBJECT_STATE, constraint, createMessage(OBJECT_CONSTRAINT_KEY_PREFIX, constraint, ctx, result)); } private EvaluatedPolicyRuleTrigger evaluateForAssignment(StatePolicyConstraintType constraint, diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules2.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules2.java index 529585a05ca..f71ba11242d 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules2.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules2.java @@ -17,17 +17,21 @@ import com.evolveum.midpoint.model.api.context.EvaluatedPolicyRule; import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder; import com.evolveum.midpoint.prism.marshaller.QueryConvertor; import com.evolveum.midpoint.prism.query.ObjectFilter; +import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.schema.SearchResultList; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.internals.InternalMonitor; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.task.api.TaskCategory; import com.evolveum.midpoint.test.util.MidPointTestConstants; import com.evolveum.midpoint.test.util.TestUtil; import com.evolveum.midpoint.util.DebugUtil; @@ -360,6 +364,66 @@ public void test140JackNoChange() throws Exception { assertFocusTriggers(context, PolicyConstraintKindType.TRANSITION, 3); } + @Test + public void test142JackNoChangeButTaskExists() throws Exception { + final String TEST_NAME = "test142JackNoChangeButTaskExists"; + TestUtil.displayTestTitle(this, TEST_NAME); + + // GIVEN + Task task = taskManager.createTaskInstance(TestPolicyRules2.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + TaskType approvalTask = prismContext.createObjectable(TaskType.class) + .name("approval task") + .category(TaskCategory.WORKFLOW) + .executionStatus(TaskExecutionStatusType.WAITING) + .ownerRef(userAdministrator.getOid(), UserType.COMPLEX_TYPE) + .objectRef(USER_JACK_OID, UserType.COMPLEX_TYPE, SchemaConstants.ORG_DEFAULT); + String approvalTaskOid = taskManager.addTask(approvalTask.asPrismObject(), result); + System.out.println("Approval task OID = " + approvalTaskOid); + + ObjectQuery query = QueryBuilder.queryFor(TaskType.class, prismContext) + .item(TaskType.F_OBJECT_REF).ref(USER_JACK_OID) + .and().item(TaskType.F_CATEGORY).eq(TaskCategory.WORKFLOW) + .and().item(TaskType.F_EXECUTION_STATUS).eq(TaskExecutionStatusType.WAITING) + .build(); + SearchResultList> tasks = modelService + .searchObjects(TaskType.class, query, null, task, result); + display("Tasks for jack", tasks); + + LensContext context = createUserLensContext(); + fillContextWithUser(context, USER_JACK_OID, result); + display("Input context", context); + + assertFocusModificationSanity(context); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + + projector.project(context, ACTIVITY_DESCRIPTION, task, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + TestUtil.assertSuccess(result); + + dumpPolicyRules(context); + dumpPolicySituations(context); + + assertEvaluatedTargetPolicyRules(context, STUDENT_TARGET_RULES); + assertTargetTriggers(context, null, 1); + assertTargetTriggers(context, PolicyConstraintKindType.ASSIGNMENT_MODIFICATION, 0); + assertTargetTriggers(context, PolicyConstraintKindType.OBJECT_STATE, 1); + + assertEvaluatedFocusPolicyRules(context, STUDENT_FOCUS_RULES); + assertFocusTriggers(context, null, 10); + assertFocusTriggers(context, PolicyConstraintKindType.OBJECT_STATE, 2); + assertFocusTriggers(context, PolicyConstraintKindType.HAS_ASSIGNMENT, 4); + assertFocusTriggers(context, PolicyConstraintKindType.HAS_NO_ASSIGNMENT, 1); + assertFocusTriggers(context, PolicyConstraintKindType.TRANSITION, 3); + } + + @SuppressWarnings("unchecked") @Test public void test150FrankAttemptToAssignRoleStudentButDisabled() throws Exception { diff --git a/model/model-impl/src/test/resources/lens/policy/role-student.xml b/model/model-impl/src/test/resources/lens/policy/role-student.xml index ea3700cb350..be3aed6d005 100644 --- a/model/model-impl/src/test/resources/lens/policy/role-student.xml +++ b/model/model-impl/src/test/resources/lens/policy/role-student.xml @@ -439,32 +439,46 @@ no-task-for-this-object - task-for-this-object-exists + + + Approval task(s) related to this object exist(s) + + TaskType - - objectRef - - - - + + + objectRef + + + + + + executionStatus + waiting + + + category + Workflow + + - From 679d35f628934284a9981aab2134f8266f9b1bc4 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Wed, 20 Sep 2017 17:41:37 +0200 Subject: [PATCH 30/97] Fixed MID-4152: (show task) link to WF detail stopped working. Just another case of infinite recursion due to recently introduced recursive schemas. --- .../web/page/admin/server/PageTaskEdit.java | 14 ++++++++++---- model/model-impl/testng-unit.xml | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.java index b44d2c44236..55e08345c82 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.java @@ -58,9 +58,7 @@ import org.apache.wicket.request.mapper.parameter.PageParameters; import javax.xml.namespace.QName; -import java.util.Collection; -import java.util.Collections; -import java.util.List; +import java.util.*; /** * @author mederly @@ -428,13 +426,21 @@ protected boolean isEditable() { } private boolean isEditable(ItemDefinition definition) { + return isEditable(definition, new HashSet<>()); + } + + private boolean isEditable(ItemDefinition definition, Set> seen) { if (definition.canModify()) { return true; } else if (definition instanceof PrismContainerDefinition) { for (ItemDefinition subdef : ((PrismContainerDefinition) definition).getDefinitions()) { - if (isEditable(subdef)) { + if (seen.contains(subdef)) { + return false; + } + if (isEditable(subdef, seen)) { return true; } + seen.add(subdef); } } return false; diff --git a/model/model-impl/testng-unit.xml b/model/model-impl/testng-unit.xml index 237b4f6fad3..1e2d2b012fd 100644 --- a/model/model-impl/testng-unit.xml +++ b/model/model-impl/testng-unit.xml @@ -71,6 +71,7 @@ + From 476253a31db4b9c6996cc42d276154f6822f2153 Mon Sep 17 00:00:00 2001 From: kate Date: Thu, 21 Sep 2017 10:22:20 +0200 Subject: [PATCH 31/97] MID-4133 fixed --- .../assignment/UserSelectionButton.java | 7 +- .../page/self/PageAssignmentShoppingKart.html | 5 +- .../page/self/PageAssignmentShoppingKart.java | 111 +++++++----------- 3 files changed, 49 insertions(+), 74 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/UserSelectionButton.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/UserSelectionButton.java index ff8e9899187..5cb2f568bae 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/UserSelectionButton.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/UserSelectionButton.java @@ -18,6 +18,7 @@ import com.evolveum.midpoint.gui.api.component.BasePanel; import com.evolveum.midpoint.gui.api.component.ObjectBrowserPanel; import com.evolveum.midpoint.gui.api.page.PageBase; +import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import org.apache.wicket.ajax.AjaxRequestTarget; @@ -122,7 +123,7 @@ private void initUserSelectionPopup(AjaxRequestTarget target) { supportedTypes.add(pageBase.getPrismContext().getSchemaRegistry() .findObjectDefinitionByCompileTimeClass(UserType.class).getTypeName()); ObjectBrowserPanel focusBrowser = new ObjectBrowserPanel(pageBase.getMainPopupBodyId(), - UserType.class, supportedTypes, isMultiSelection, pageBase, null, getModelObject()) { + UserType.class, supportedTypes, isMultiSelection, pageBase, getUserQueryFilter(), getModelObject()) { @Override protected void onSelectPerformed(AjaxRequestTarget target, UserType object) { @@ -179,4 +180,8 @@ public int compare(UserType u1, UserType u2) { } return titleModel.getString(); } + + protected ObjectFilter getUserQueryFilter(){ + return null; + } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentShoppingKart.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentShoppingKart.html index 5da5f5ee60c..ceb59f2c8b9 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentShoppingKart.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentShoppingKart.html @@ -47,11 +47,8 @@
-
-
-
+
-
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentShoppingKart.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentShoppingKart.java index b9302a54f55..f832f70c40b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentShoppingKart.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentShoppingKart.java @@ -17,6 +17,7 @@ import com.evolveum.midpoint.gui.api.component.ObjectBrowserPanel; import com.evolveum.midpoint.gui.api.model.LoadableModel; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.model.api.ModelInteractionService; import com.evolveum.midpoint.model.api.RoleSelectionSpecification; import com.evolveum.midpoint.prism.PrismObject; @@ -89,8 +90,6 @@ public class PageAssignmentShoppingKart extends PageSelf { private static final String ID_NO_CATALOG_REF_DEFINED_LABEL = "noCatalogRefDefinedLabel"; private static final String ID_CATALOG_ITEMS_GRID_PANEL = "catalogItemsGridPanel"; private static final String ID_CONTENT_PANEL = "contentPanel"; - private static final String ID_CATALOG_ITEMS_PANEL_CONTAINER = "catalogItemsPanelContainer"; - private static final String ID_ASSIGNMENTS_OWNER_NAME = "assignmentsOwnerName"; private static final String ID_CART_BUTTON = "cartButton"; private static final String ID_CART_ITEMS_COUNT = "itemsCount"; private static final String ID_HEADER_PANEL = "headerPanel"; @@ -191,25 +190,6 @@ public Search load() { } private void initProvider() { - if (AssignmentViewType.USER_TYPE.equals(viewTypeModel.getObject())){ - UserType assignmentsOwner = getRoleCatalogStorage().getAssignmentsUserOwner(); - List listProviderData = new ArrayList<>(); - if (assignmentsOwner != null) { - List assignments = assignmentsOwner.getAssignment(); - for (AssignmentType assignment : assignments) { - if (!AssignmentsUtil.isPolicyRuleAssignment(assignment) && !AssignmentsUtil.isConsentAssignment(assignment) - && AssignmentsUtil.isAssignmentRelevant(assignment)) { - assignment.setId(null); - listProviderData.add(new AssignmentEditorDto(UserDtoStatus.MODIFY, assignment, PageAssignmentShoppingKart.this)); - } - } - Collections.sort(listProviderData); - } - provider = new ListDataProvider(this, Model.ofList(listProviderData)); - provider.setQuery(null); - provider.getAvailableData().clear(); - provider.getAvailableData().addAll(listProviderData); - } else { provider = new ObjectDataProvider(PageAssignmentShoppingKart.this, AbstractRoleType.class) { private static final long serialVersionUID = 1L; @@ -229,7 +209,6 @@ public ObjectQuery getQuery() { return createContentQuery(null); } }; - } } private void initHeaderPanel(Form mainForm){ @@ -289,31 +268,6 @@ public boolean isVisible(){ } private void initCatalogItemsPanel(WebMarkupContainer panelContainer){ - WebMarkupContainer catalogItemsPanelContainer = new WebMarkupContainer(ID_CATALOG_ITEMS_PANEL_CONTAINER); - catalogItemsPanelContainer.setOutputMarkupId(true); - catalogItemsPanelContainer.add(new VisibleEnableBehaviour(){ - private static final long serialVersionUID = 1L; - @Override - public boolean isVisible(){ - return !(AssignmentViewType.ROLE_CATALOG_VIEW.equals(viewTypeModel.getObject()) && - isCatalogOidEmpty()); - } - }); - panelContainer.add(catalogItemsPanelContainer); - - Label assignmentsOwnerLabel = new Label(ID_ASSIGNMENTS_OWNER_NAME, - createStringResource("AssignmentCatalogPanel.assignmentsOwner", - getRoleCatalogStorage().getAssignmentsUserOwner() != null ? - getRoleCatalogStorage().getAssignmentsUserOwner().getName().getOrig() : "").getString()); - assignmentsOwnerLabel.add(new VisibleEnableBehaviour(){ - private static final long serialVersionUID = 1L; - @Override - public boolean isVisible(){ - return AssignmentViewType.USER_TYPE.equals(viewTypeModel.getObject()); - } - }); - catalogItemsPanelContainer.add(assignmentsOwnerLabel); - GridViewComponent catalogItemsGrid = new GridViewComponent(ID_CATALOG_ITEMS_GRID_PANEL, new AbstractReadOnlyModel() { private static final long serialVersionUID = 1L; @@ -344,8 +298,16 @@ protected void assignmentAddedToShoppingCartPerformed(AjaxRequestTarget target){ }); } }; + catalogItemsGrid.add(new VisibleEnableBehaviour(){ + private static final long serialVersionUID = 1L; + @Override + public boolean isVisible(){ + return !(AssignmentViewType.ROLE_CATALOG_VIEW.equals(viewTypeModel.getObject()) && + isCatalogOidEmpty()); + } + }); catalogItemsGrid.setOutputMarkupId(true); - catalogItemsPanelContainer.add(catalogItemsGrid); + panelContainer.add(catalogItemsGrid); } private void selectTreeItemPerformed(SelectableBean selected, AjaxRequestTarget target) { @@ -410,6 +372,11 @@ public List getObject() { }, false, createStringResource("AssignmentCatalogPanel.selectSourceUser")){ private static final long serialVersionUID = 1L; + @Override + protected ObjectFilter getUserQueryFilter(){ + return getAssignableRolesFilter(); + } + @Override protected void singleUserSelectionPerformed(AjaxRequestTarget target, UserType user){ super.singleUserSelectionPerformed(target, user); @@ -417,9 +384,9 @@ protected void singleUserSelectionPerformed(AjaxRequestTarget target, UserType u getRoleCatalogStorage().setAssignmentsUserOwner(user); initProvider(); - //TODO don't remove component - getContentPanel().remove(ID_CATALOG_ITEMS_PANEL_CONTAINER); - initCatalogItemsPanel(getContentPanel()); +// TODO don't remove component +// getContentPanel().remove(ID_CATALOG_ITEMS_PANEL_CONTAINER); +// initCatalogItemsPanel(getContentPanel()); searchModel.reset(); target.add(getContentPanel()); @@ -439,9 +406,6 @@ protected void onDeleteSelectedUsersPerformed(AjaxRequestTarget target){ viewTypeModel.setObject(getRoleCatalogStorage().getShoppingCartConfigurationDto().getViewTypeList().get(0)); } initProvider(); - //TODO don't remove component - getContentPanel().remove(ID_CATALOG_ITEMS_PANEL_CONTAINER); - initCatalogItemsPanel(getContentPanel()); searchModel.reset(); target.add(getContentPanel()); @@ -490,12 +454,6 @@ public boolean isEnabled(){ private void initSearchPanel(WebMarkupContainer headerPanel) { final Form searchForm = new Form(ID_SEARCH_FORM); - searchForm.add(new VisibleEnableBehaviour() { - public boolean isVisible() { - return !(AssignmentViewType.ROLE_CATALOG_VIEW.equals(viewTypeModel.getObject()) && isCatalogOidEmpty()) - && !AssignmentViewType.USER_TYPE.equals(viewTypeModel.getObject()); - } - }); searchForm.setOutputMarkupId(true); SearchPanel search = new SearchPanel(ID_SEARCH, (IModel) searchModel, false) { @@ -507,7 +465,7 @@ public void searchPerformed(ObjectQuery query, AjaxRequestTarget target) { } }; searchForm.add(search); - headerPanel.addOrReplace(searchForm); + headerPanel.add(searchForm); } private void searchPerformed(ObjectQuery query, AjaxRequestTarget target) { @@ -524,7 +482,13 @@ protected ObjectQuery createContentQuery(ObjectQuery searchQuery) { } addOrgMembersFilter(oid, memberQuery); } - addAssignableRolesFilter(memberQuery); + if (AssignmentViewType.USER_TYPE.equals(viewTypeModel.getObject())) { + UserType assignmentsOwner = getRoleCatalogStorage().getAssignmentsUserOwner(); + List assignmentTargetObjectOidsList = collectTargetObjectOids(assignmentsOwner.getAssignment()); + ObjectFilter oidsFilter = InOidFilter.createInOid(assignmentTargetObjectOidsList); + memberQuery.addFilter(oidsFilter); + } + memberQuery.addFilter(getAssignableRolesFilter()); addViewTypeFilter(memberQuery); if (memberQuery == null) { memberQuery = new ObjectQuery(); @@ -555,7 +519,7 @@ private void addViewTypeFilter(ObjectQuery query) { } } - private void addAssignableRolesFilter(ObjectQuery query) { + private ObjectFilter getAssignableRolesFilter() { ObjectFilter filter = null; LOGGER.debug("Loading roles which the current user has right to assign"); OperationResult result = new OperationResult(OPERATION_LOAD_ASSIGNABLE_ROLES); @@ -573,10 +537,7 @@ private void addAssignableRolesFilter(ObjectQuery query) { if (!result.isSuccess() && !result.isHandledError()) { showResult(result); } - if (query == null) { - query = new ObjectQuery(); - } - query.addFilter(filter); + return filter; } private ObjectQuery addOrgMembersFilter(String oid, ObjectQuery query) { @@ -634,7 +595,7 @@ private boolean isCatalogOidEmpty(){ private WebMarkupContainer getCatalogItemsPanelContainer(){ - return (WebMarkupContainer)getContentPanel().get(ID_CATALOG_ITEMS_PANEL_CONTAINER); + return (WebMarkupContainer)getContentPanel().get(ID_CATALOG_ITEMS_GRID_PANEL); } private WebMarkupContainer getHeaderPanel(){ @@ -719,6 +680,18 @@ private String getSourceUserSelectionButtonLabel(UserType user){ } } - + private List collectTargetObjectOids(List assignments){ + List oidsList = new ArrayList<>(); + if (assignments == null){ + return oidsList; + } + for (AssignmentType assignment : assignments){ + if (assignment.getTargetRef() == null || assignment.getTargetRef().getOid() == null){ + continue; + } + oidsList.add(assignment.getTargetRef().getOid()); + } + return oidsList; + } } From 4c90010d730cb84d1588ddf508b8473319ce2e0a Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Thu, 21 Sep 2017 14:04:56 +0200 Subject: [PATCH 32/97] Preliminary support for case management related queries. --- .../midpoint/prism/query/ObjectPaging.java | 47 +++-- .../schema/constants/ObjectTypes.java | 4 +- .../common/common-case-management-3.xsd | 13 ++ .../controller/EmulatedSearchProvider.java | 162 ++++++++++++++++++ .../impl/controller/ModelController.java | 30 ++-- .../model/impl/misc/TestCaseManagement.java | 90 ++++++++++ .../src/test/resources/misc/case1.xml | 25 +++ .../src/test/resources/misc/case2.xml | 30 ++++ .../src/test/resources/misc/case3.xml | 21 +++ .../src/test/resources/misc/user1.xml | 21 +++ .../src/test/resources/misc/user2.xml | 21 +++ 11 files changed, 427 insertions(+), 37 deletions(-) create mode 100644 model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/EmulatedSearchProvider.java create mode 100644 model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/misc/TestCaseManagement.java create mode 100644 model/model-impl/src/test/resources/misc/case1.xml create mode 100644 model/model-impl/src/test/resources/misc/case2.xml create mode 100644 model/model-impl/src/test/resources/misc/case3.xml create mode 100644 model/model-impl/src/test/resources/misc/user1.xml create mode 100644 model/model-impl/src/test/resources/misc/user2.xml diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectPaging.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectPaging.java index 2a8b9e2d0f6..d189bdffa87 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectPaging.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectPaging.java @@ -19,6 +19,7 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.DebugUtil; +import org.jetbrains.annotations.NotNull; import javax.xml.namespace.QName; import java.io.Serializable; @@ -31,7 +32,7 @@ public class ObjectPaging implements DebugDumpable, Serializable { private Integer offset; private Integer maxSize; - private List ordering = new ArrayList<>(); + @NotNull private final List ordering = new ArrayList<>(); private String cookie; protected ObjectPaging() { @@ -108,11 +109,11 @@ public List getOrderingInstructions() { } public boolean hasOrdering() { - return ordering != null && !ordering.isEmpty(); // first is just for sure + return !ordering.isEmpty(); } public void setOrdering(ItemPath orderBy, OrderDirection direction) { - this.ordering = new ArrayList<>(); + this.ordering.clear(); addOrderingInstruction(orderBy, direction); } @@ -124,12 +125,19 @@ public void addOrderingInstruction(QName orderBy, OrderDirection direction) { addOrderingInstruction(new ItemPath(orderBy), direction); } + @SuppressWarnings("NullableProblems") public void setOrdering(ObjectOrdering... orderings) { - this.ordering = new ArrayList<>(Arrays.asList(orderings)); + this.ordering.clear(); + if (orderings != null) { + this.ordering.addAll(Arrays.asList(orderings)); + } } public void setOrdering(Collection orderings) { - this.ordering = orderings != null ? new ArrayList<>(orderings) : new ArrayList<>(); + this.ordering.clear(); + if (orderings != null) { + this.ordering.addAll(orderings); + } } public Integer getOffset() { @@ -187,11 +195,8 @@ public ObjectPaging clone() { protected void copyTo(ObjectPaging clone) { clone.offset = this.offset; clone.maxSize = this.maxSize; - if (this.ordering != null) { - clone.ordering = new ArrayList<>(this.ordering); - } else { - clone.ordering = null; - } + clone.ordering.clear(); + clone.ordering.addAll(this.ordering); clone.cookie = this.cookie; } @@ -231,10 +236,6 @@ public String debugDump(int indent) { public String toString() { StringBuilder sb = new StringBuilder(); sb.append("PAGING: "); - if (this == null){ - sb.append("null"); - return sb.toString(); - } if (getOffset() != null){ sb.append("O: "); sb.append(getOffset()); @@ -258,6 +259,7 @@ public String toString() { return sb.toString(); } + @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") @Override public boolean equals(Object o) { return equals(o, true); @@ -275,20 +277,15 @@ public boolean equals(Object o, boolean exact) { return false; if (maxSize != null ? !maxSize.equals(that.maxSize) : that.maxSize != null) return false; - if ((ordering != null && that.ordering == null) || (ordering == null && that.ordering != null)) { + if (ordering.size() != that.ordering.size()) { return false; } - if (ordering != null) { - if (ordering.size() != that.ordering.size()) { + for (int i = 0; i < ordering.size(); i++) { + ObjectOrdering oo1 = this.ordering.get(i); + ObjectOrdering oo2 = that.ordering.get(i); + if (!oo1.equals(oo2, exact)) { return false; } - for (int i = 0; i < ordering.size(); i++) { - ObjectOrdering oo1 = this.ordering.get(i); - ObjectOrdering oo2 = that.ordering.get(i); - if (!oo1.equals(oo2, exact)) { - return false; - } - } } return cookie != null ? cookie.equals(that.cookie) : that.cookie == null; } @@ -297,7 +294,7 @@ public boolean equals(Object o, boolean exact) { public int hashCode() { int result = offset != null ? offset.hashCode() : 0; result = 31 * result + (maxSize != null ? maxSize.hashCode() : 0); - result = 31 * result + (ordering != null ? ordering.hashCode() : 0); + result = 31 * result + ordering.hashCode(); result = 31 * result + (cookie != null ? cookie.hashCode() : 0); return result; } diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/ObjectTypes.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/ObjectTypes.java index aed1309f61d..e2b355f705b 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/ObjectTypes.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/ObjectTypes.java @@ -97,7 +97,7 @@ public enum ObjectTypes { SERVICE(ServiceType.COMPLEX_TYPE, SchemaConstantsGenerated.C_SERVICE, ServiceType.class, ObjectManager.MODEL, "services"), - CASE(CaseType.COMPLEX_TYPE, SchemaConstantsGenerated.C_CASE, CaseType.class, ObjectManager.MODEL, + CASE(CaseType.COMPLEX_TYPE, SchemaConstantsGenerated.C_CASE, CaseType.class, ObjectManager.EMULATED, "cases"), // this should be at end, because otherwise it presents itself as entry for all subtypes of ObjectType @@ -118,7 +118,7 @@ public ObjectTypes superType() { } public enum ObjectManager { - PROVISIONING, TASK_MANAGER, MODEL, WORKFLOW, REPOSITORY + PROVISIONING, TASK_MANAGER, MODEL, WORKFLOW, REPOSITORY, EMULATED } private QName type; diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-case-management-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-case-management-3.xsd index 3b75536686f..fd0096770bf 100644 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-case-management-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-case-management-3.xsd @@ -57,6 +57,19 @@ + + + + Object that the case is associated with. It might be e.g. resource, if the case + deals with creation of an account on that resource. + EXPERIMENTAL. May change in future. + + + 3.7 + true + + + diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/EmulatedSearchProvider.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/EmulatedSearchProvider.java new file mode 100644 index 00000000000..32e205bc9f2 --- /dev/null +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/EmulatedSearchProvider.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.model.impl.controller; + +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; +import com.evolveum.midpoint.prism.query.ObjectFilter; +import com.evolveum.midpoint.prism.query.ObjectOrdering; +import com.evolveum.midpoint.prism.query.ObjectPaging; +import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.util.CloneUtil; +import com.evolveum.midpoint.repo.api.RepositoryService; +import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.SearchResultList; +import com.evolveum.midpoint.schema.SelectorOptions; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CaseType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CaseWorkItemType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.function.Function; + +/** + * @author mederly + */ +@Component +public class EmulatedSearchProvider { + + @Autowired private MatchingRuleRegistry matchingRuleRegistry; + @Autowired + @Qualifier("cacheRepositoryService") + private transient RepositoryService cacheRepositoryService; + + public SearchResultList> searchObjects(Class type, ObjectQuery query, + Collection> options, + OperationResult result) throws SchemaException { + + SearchResultList> allObjects = cacheRepositoryService.searchObjects(type, null, options, result); + if (query == null) { + return allObjects; + } + + List> filtered = doFiltering(query, allObjects, (o) -> o.getValue()); + List> paged = doPaging(query, filtered, (o) -> o.getValue()); + return new SearchResultList<>(paged); + } + + public SearchResultList searchContainers(Class type, ObjectQuery query, + Collection> options, + OperationResult result) throws SchemaException { + if (!CaseWorkItemType.class.equals(type)) { + throw new UnsupportedOperationException("searchContainers is supported only for CaseWorkItemType, not for " + type); + } + + List allValues = new ArrayList<>(); + SearchResultList> cases = cacheRepositoryService + .searchObjects(CaseType.class, null, null, result); + for (PrismObject aCase : cases) { + allValues.addAll(CloneUtil.cloneCollectionMembers(aCase.asObjectable().getWorkItem())); + } + if (query == null) { + //noinspection unchecked + return (SearchResultList) new SearchResultList<>(allValues); + } + + List filtered = doFiltering(query, allValues, (v) -> v.asPrismContainerValue()); + List paged = doPaging(query, filtered, (v) -> v.asPrismContainerValue()); + //noinspection unchecked + return (SearchResultList) new SearchResultList<>(paged); + } + + private List doFiltering(ObjectQuery query, List allObjects, Function pcvExtractor) + throws SchemaException { + ObjectFilter filter = query.getFilter(); + if (filter == null) { + return allObjects; + } + List filtered = new ArrayList<>(); + for (T object : allObjects) { + if (filter.match(pcvExtractor.apply(object), matchingRuleRegistry)) { + filtered.add(object); + } + } + return filtered; + } + + + private List doPaging(ObjectQuery query, List allObjects, Function pcvExtractor) + throws SchemaException { + ObjectPaging paging = query.getPaging(); + if (paging == null) { + return allObjects; + } + if (!paging.getOrderingInstructions().isEmpty()) { + allObjects.sort((o1, o2) -> { + PrismContainerValue pcv1 = pcvExtractor.apply(o1); + PrismContainerValue pcv2 = pcvExtractor.apply(o2); + for (ObjectOrdering ordering : paging.getOrderingInstructions()) { + Comparable c1 = getComparable(pcv1.find(ordering.getOrderBy())); + Comparable c2 = getComparable(pcv2.find(ordering.getOrderBy())); + int result = c1 == null + ? (c2 == null ? 0 : 1) + : (c2 == null ? -1 : c1.compareTo(c2)); + if (result != 0) { + return result; + } + } + return 0; + }); + } + int start = paging.getOffset() != null ? paging.getOffset() : 0; + int end = paging.getMaxSize() != null ? Math.min(start + paging.getMaxSize(), allObjects.size()) : allObjects.size(); + if (start == 0 && end == allObjects.size()) { + return allObjects; + } else { + return allObjects.subList(start, end); + } + } + + @SuppressWarnings("unchecked") + private Comparable getComparable(Object o) { + if (o instanceof Item) { + Item item = (Item) o; + if (item.getValues().size() > 1) { + throw new IllegalStateException("Couldn't compare multivalued items"); + } else if (item.getValues().size() == 1) { + o = item.getValues().get(0); + } else { + return null; + } + } + if (o instanceof PrismValue) { + o = ((PrismValue) o).getRealValue(); + } + if (o instanceof Comparable) { + return (Comparable) o; + } + return null; + } + +} diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java index d787998cb50..a886c39bbc5 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java @@ -78,7 +78,6 @@ import com.evolveum.midpoint.xml.ns._public.model.scripting_3.ExecuteScriptType; import com.evolveum.midpoint.xml.ns._public.model.scripting_3.ScriptingExpressionType; import com.evolveum.prism.xml.ns._public.types_3.EvaluationTimeType; - import org.apache.commons.io.IOUtils; import org.apache.commons.lang.Validate; import org.jetbrains.annotations.NotNull; @@ -196,6 +195,9 @@ public class ModelController implements ModelService, TaskService, WorkflowServi @Autowired(required = true) private SystemObjectCache systemObjectCache; + @Autowired + private EmulatedSearchProvider emulatedSearchProvider; + public ModelObjectResolver getObjectResolver() { return objectResolver; } @@ -818,6 +820,7 @@ public SearchResultList> searchObjects(Cla QNameUtil.setTemporarilyTolerateUndeclaredPrefixes(true); } switch (searchProvider) { + case EMULATED: list = emulatedSearchProvider.searchObjects(type, query, options, result); break; case REPOSITORY: list = cacheRepositoryService.searchObjects(type, query, options, result); break; case PROVISIONING: list = provisioning.searchObjects(type, query, options, task, result); break; case TASK_MANAGER: @@ -874,25 +877,31 @@ public SearchResultList> searchObjects(Cla } private class ContainerOperationContext { - final boolean isCase; + final boolean isCertCase; + final boolean isCaseMgmtWorkItem; final boolean isWorkItem; final ObjectTypes.ObjectManager manager; final ObjectQuery refinedQuery; ContainerOperationContext(Class type, ObjectQuery query) throws SchemaException, SecurityViolationException { - isCase = AccessCertificationCaseType.class.equals(type); + isCertCase = AccessCertificationCaseType.class.equals(type); + isCaseMgmtWorkItem = CaseWorkItemType.class.equals(type); isWorkItem = WorkItemType.class.equals(type); - if (!isCase && !isWorkItem) { - throw new UnsupportedOperationException("searchContainers/countContainers methods are currently supported only for AccessCertificationCaseType and WorkItemType classes"); + if (!isCertCase && !isWorkItem && !isCaseMgmtWorkItem) { + throw new UnsupportedOperationException("searchContainers/countContainers methods are currently supported only for AccessCertificationCaseType, WorkItemType and CaseWorkItemType classes"); } - if (isCase) { - refinedQuery = preProcessSubobjectQuerySecurity(AccessCertificationCaseType.class, AccessCertificationCampaignType.class, query); + if (isCertCase) { + refinedQuery = preProcessSubobjectQuerySecurity(AccessCertificationCaseType.class, AccessCertificationCampaignType.class, query); manager = ObjectTypes.ObjectManager.REPOSITORY; } else if (isWorkItem) { refinedQuery = preProcessWorkItemSecurity(query); manager = ObjectTypes.ObjectManager.WORKFLOW; + } else //noinspection ConstantConditions + if (isCaseMgmtWorkItem) { + refinedQuery = query; // TODO + manager = ObjectTypes.ObjectManager.EMULATED; } else { throw new IllegalStateException(); } @@ -936,6 +945,7 @@ public SearchResultList searchContainers( QNameUtil.setTemporarilyTolerateUndeclaredPrefixes(true); } switch (ctx.manager) { + case EMULATED: list = emulatedSearchProvider.searchContainers(type, query, options, result); break; case REPOSITORY: list = cacheRepositoryService.searchContainers(type, query, options, result); break; case WORKFLOW: list = workflowManager.searchContainers(type, query, options, result); break; default: throw new IllegalStateException(); @@ -964,11 +974,11 @@ public SearchResultList searchContainers( RepositoryCache.exit(); } - if (ctx.isCase) { + if (ctx.isCertCase) { list = schemaTransformer.applySchemasAndSecurityToContainers(list, AccessCertificationCampaignType.class, AccessCertificationCampaignType.F_CASE, rootOptions, options, null, task, result); - } else if (ctx.isWorkItem) { - // TODO implement security post processing for WorkItems + } else if (ctx.isWorkItem || ctx.isCaseMgmtWorkItem) { + // TODO implement security post processing for WorkItems and CaseWorkItems } else { throw new IllegalStateException(); } diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/misc/TestCaseManagement.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/misc/TestCaseManagement.java new file mode 100644 index 00000000000..7b6ebc91fcf --- /dev/null +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/misc/TestCaseManagement.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.model.impl.misc; + +import com.evolveum.midpoint.model.impl.AbstractInternalModelIntegrationTest; +import com.evolveum.midpoint.model.impl.controller.ModelController; +import com.evolveum.midpoint.model.impl.lens.Clockwork; +import com.evolveum.midpoint.model.impl.lens.projector.Projector; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.schema.SearchResultList; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.task.api.TaskManager; +import com.evolveum.midpoint.test.util.MidPointTestConstants; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CaseType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CaseWorkItemType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.context.ContextConfiguration; +import org.testng.annotations.Test; + +import java.io.File; + +import static org.testng.AssertJUnit.assertEquals; + +/** + * @author mederly + * + */ +@ContextConfiguration(locations = {"classpath:ctx-model-test-main.xml"}) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) +public class TestCaseManagement extends AbstractInternalModelIntegrationTest { + + protected static final File TEST_DIR = new File(MidPointTestConstants.TEST_RESOURCES_DIR, "misc"); + protected static final File USER1_FILE = new File(TEST_DIR, "user1.xml"); + protected static final File USER2_FILE = new File(TEST_DIR, "user2.xml"); + protected static final File CASE1_FILE = new File(TEST_DIR, "case1.xml"); + protected static final File CASE2_FILE = new File(TEST_DIR, "case2.xml"); + protected static final File CASE3_FILE = new File(TEST_DIR, "case3.xml"); + + @Autowired protected ModelController controller; + @Autowired protected Projector projector; + @Autowired protected Clockwork clockwork; + @Autowired protected TaskManager taskManager; + + private PrismObject user1, user2; + private PrismObject case1, case2, case3; + + @Override + public void initSystem(Task initTask, OperationResult initResult) throws Exception { + super.initSystem(initTask, initResult); + user1 = repoAddObjectFromFile(USER1_FILE, initResult); + user2 = repoAddObjectFromFile(USER2_FILE, initResult); + case1 = repoAddObjectFromFile(CASE1_FILE, initResult); + case2 = repoAddObjectFromFile(CASE2_FILE, initResult); + case3 = repoAddObjectFromFile(CASE3_FILE, initResult); + } + + @Test + public void test100SearchCases() throws Exception { + final String TEST_NAME = "test100CreateCase"; + + Task task = taskManager.createTaskInstance(TEST_NAME); + OperationResult result = task.getResult(); + + login(userAdministrator); + + SearchResultList> cases = controller.searchObjects(CaseType.class, null, null, task, result); + assertEquals(3, cases.size()); + SearchResultList workItems = controller.searchContainers(CaseWorkItemType.class, null, null, task, result); + assertEquals(4, workItems.size()); + + } + +} diff --git a/model/model-impl/src/test/resources/misc/case1.xml b/model/model-impl/src/test/resources/misc/case1.xml new file mode 100644 index 00000000000..6dac9839a0d --- /dev/null +++ b/model/model-impl/src/test/resources/misc/case1.xml @@ -0,0 +1,25 @@ + + + + + case1 + + + + + \ No newline at end of file diff --git a/model/model-impl/src/test/resources/misc/case2.xml b/model/model-impl/src/test/resources/misc/case2.xml new file mode 100644 index 00000000000..ce3221a35b4 --- /dev/null +++ b/model/model-impl/src/test/resources/misc/case2.xml @@ -0,0 +1,30 @@ + + + + + case2 + + + + + + + + + + \ No newline at end of file diff --git a/model/model-impl/src/test/resources/misc/case3.xml b/model/model-impl/src/test/resources/misc/case3.xml new file mode 100644 index 00000000000..0317fe55406 --- /dev/null +++ b/model/model-impl/src/test/resources/misc/case3.xml @@ -0,0 +1,21 @@ + + + + + case3 + \ No newline at end of file diff --git a/model/model-impl/src/test/resources/misc/user1.xml b/model/model-impl/src/test/resources/misc/user1.xml new file mode 100644 index 00000000000..f2beecc1521 --- /dev/null +++ b/model/model-impl/src/test/resources/misc/user1.xml @@ -0,0 +1,21 @@ + + + + + user1 + \ No newline at end of file diff --git a/model/model-impl/src/test/resources/misc/user2.xml b/model/model-impl/src/test/resources/misc/user2.xml new file mode 100644 index 00000000000..30ee2ec2722 --- /dev/null +++ b/model/model-impl/src/test/resources/misc/user2.xml @@ -0,0 +1,21 @@ + + + + + user2 + \ No newline at end of file From 709686c27ddf18bce5fc8e48443313d6bf23a079 Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Thu, 21 Sep 2017 16:06:17 +0200 Subject: [PATCH 33/97] some fixes in prism forms --- .../AbstractAssignmentDetailsPanel.java | 4 +- .../objectdetails/FocusDetailsTabPanel.java | 1 + .../FocusProjectionsTabPanel.java | 3 +- .../prism/ContainerValueWrapper.java | 119 ++- .../web/component/prism/ContainerWrapper.java | 62 +- .../prism/ContainerWrapperFactory.java | 683 +++++++----------- .../web/component/prism/ObjectWrapper.java | 40 +- .../component/prism/ObjectWrapperFactory.java | 239 +++--- .../prism/PrismContainerValueHeaderPanel.java | 18 +- .../prism/PropertyOrReferenceWrapper.java | 9 +- .../web/component/prism/PropertyWrapper.java | 11 +- .../web/component/prism/ReferenceWrapper.java | 7 +- .../web/component/prism/ValueWrapper.java | 8 +- .../wizard/resource/ConfigurationStep.java | 1 + 14 files changed, 581 insertions(+), 624 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.java index 3bbb2a51f1f..fab2d6fd58f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.java @@ -165,11 +165,11 @@ private boolean getAssignmentBasicTabVisibity(ItemWrapper itemWrapper, ItemPath private boolean getActivationVisibileItems(ItemPath pathToCheck, ItemPath assignmentPath) { - if (assignmentPath.subPath(new ItemPath(AssignmentType.F_ACTIVATION, ActivationType.F_LOCKOUT_EXPIRATION_TIMESTAMP)).equivalent(pathToCheck)){ + if (assignmentPath.append(new ItemPath(AssignmentType.F_ACTIVATION, ActivationType.F_LOCKOUT_EXPIRATION_TIMESTAMP)).equivalent(pathToCheck)){ return false; } - if (assignmentPath.subPath(new ItemPath(AssignmentType.F_ACTIVATION, ActivationType.F_LOCKOUT_STATUS)).equivalent(pathToCheck)){ + if (assignmentPath.append(new ItemPath(AssignmentType.F_ACTIVATION, ActivationType.F_LOCKOUT_STATUS)).equivalent(pathToCheck)){ return false; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.java index 5b35e181a6b..33117fa6383 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.java @@ -42,6 +42,7 @@ import com.evolveum.midpoint.web.resource.img.ImgResources; import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; /** * @author semancik 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 3b03841fdd5..13293ebbee1 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 @@ -17,6 +17,7 @@ import java.io.Serializable; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import javax.xml.namespace.QName; @@ -129,7 +130,7 @@ protected void populateItem(final ListItem> item) packageRef = new PackageResourceReference(ImgResources.class, ImgResources.HDD_PRISM); shadowPanel = new PrismPanel(ID_SHADOW, - new ContainerWrapperListFromObjectWrapperModel<>(objectWrapperModel, null), packageRef, + new ContainerWrapperListFromObjectWrapperModel(objectWrapperModel, Arrays.asList(new ItemPath(ShadowType.F_ATTRIBUTES), SchemaConstants.PATH_ACTIVATION, SchemaConstants.PATH_PASSWORD)), packageRef, getMainForm(), null, getPageBase()); } else { shadowPanel = new SimpleErrorPanel(ID_SHADOW, item.getModel()) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java index d7cc2c29342..15247ccd1ce 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java @@ -28,6 +28,7 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; import org.apache.commons.lang.math.NumberUtils; +import org.apache.cxf.annotations.Logging; import org.jetbrains.annotations.Nullable; import com.evolveum.midpoint.gui.api.page.PageBase; @@ -41,6 +42,7 @@ import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismReferenceDefinition; import com.evolveum.midpoint.prism.PrismValue; +import com.evolveum.midpoint.prism.delta.ContainerDelta; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.ReferenceDelta; @@ -50,6 +52,7 @@ import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; @@ -78,35 +81,40 @@ public class ContainerValueWrapper extends PrismWrapper private List properties; private boolean readonly; - private boolean showInheritedObjectAttributes; +// private boolean showInheritedObjectAttributes; + // private PrismContainerDefinition containerDefinition; ContainerValueWrapper(ContainerWrapper containerWrapper, PrismContainerValue containerValue, ValueStatus status, ItemPath path) { Validate.notNull(status, "Container status must not be null."); + Validate.notNull(containerValue.getParent().getDefinition(), "container definition must not be null."); + Validate.notNull(status, "Container status must not be null."); this.containerWrapper = containerWrapper; this.containerValue = containerValue; this.status = status; this.path = path; - this.readonly = containerWrapper.isReadonly(); // [pm] this is quite questionable - this.showInheritedObjectAttributes = containerWrapper.isShowInheritedObjectAttributes(); +// this.readonly = containerWrapper.isReadonly(); // [pm] this is quite questionable +// this.showInheritedObjectAttributes = containerWrapper.isShowInheritedObjectAttributes(); + } - ContainerValueWrapper(PrismContainerValue container, ValueStatus status, ItemPath path, boolean readOnly, boolean showInheritedObjectAttributes) { + ContainerValueWrapper(PrismContainerValue containerValue, ValueStatus status, ItemPath path, boolean readOnly) { + this(null, containerValue, status, path); // super(null, container); - Validate.notNull(container, "container must not be null."); - Validate.notNull(container.getParent().getDefinition(), "container definition must not be null."); - Validate.notNull(status, "Container status must not be null."); - - this.containerValue = container; +// Validate.notNull(container, "container must not be null."); +// Validate.notNull(container.getParent().getDefinition(), "container definition must not be null."); +// Validate.notNull(status, "Container status must not be null."); +// +// this.containerValue = container; // this.containerDefinition = container.getParent().getDefinition(); - this.status = status; - this.path = path; +// this.status = status; +// this.path = path; this.readonly = readOnly; - this.showInheritedObjectAttributes = showInheritedObjectAttributes; +// this.showInheritedObjectAttributes = showInheritedObjectAttributes; } public PrismContainerDefinition getDefinition() { @@ -162,6 +170,13 @@ public List getItems() { } return properties; } + + + public void addEmptyProperties(List emptyProperties) { + emptyProperties.forEach(empty -> { + if (!properties.contains(empty)) properties.add(empty); + }); + } public void setProperties(List properties) { this.properties = properties; @@ -185,9 +200,9 @@ public void computeStripes() { } } - public boolean isShowInheritedObjectAttributes() { - return showInheritedObjectAttributes; - } +// public boolean isShowInheritedObjectAttributes() { +// return showInheritedObjectAttributes; +// } public boolean isMain() { return path==null || path.isEmpty(); @@ -346,8 +361,8 @@ public String debugDump(int indent) { sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "readonly", readonly, indent + 1); sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "showInheritedObjectAttributes", showInheritedObjectAttributes, indent + 1); - sb.append("\n"); +// DebugUtil.debugDumpWithLabel(sb, "showInheritedObjectAttributes", showInheritedObjectAttributes, indent + 1); +// sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "path", path == null ? null : path.toString(), indent + 1); sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "containerDefinition", getDefinition() == null ? null : getDefinition().toString(), indent + 1); @@ -359,6 +374,34 @@ public String debugDump(int indent) { DebugUtil.debugDump(sb, properties, indent + 2, false); return sb.toString(); } + + public PrismContainerValue createContainerValueAddDelta() { + if (!hasChanged()) { + return null; + } + + if (getStatus() != ValueStatus.ADDED) { + return null; + } + + PrismContainerValue newValue = containerValue.clone(); + + getItems().forEach(item -> { + + if (item instanceof ContainerWrapper) { + return; + } + + PropertyOrReferenceWrapper propOrRef = (PropertyOrReferenceWrapper) item; + try { + newValue.add(createItem(propOrRef, propOrRef.getItemDefinition())); + } catch (SchemaException e) { + LoggingUtils.logException(LOGGER, "Could not add item " + propOrRef.getItem(), e); + } + + }); + return newValue; + } public void collectModifications(ObjectDelta delta) throws SchemaException { // if (getItemDefinition().getName().equals(ShadowType.F_ASSOCIATION)) { @@ -389,7 +432,8 @@ public void collectModifications(ObjectDelta delta) th if (!hasChanged()) { return; } - + + for (ItemWrapper itemWrapper : getItems()) { if (!itemWrapper.hasChanged()) { continue; @@ -412,6 +456,8 @@ public void collectModifications(ObjectDelta delta) th if (!pDelta.isEmpty()) { delta.addModification(pDelta); } + } else if (itemWrapper instanceof ContainerWrapper) { + ((ContainerWrapper) itemWrapper).collectModifications(delta); } else { LOGGER.trace("Delta from wrapper: ignoring {}", itemWrapper); } @@ -421,7 +467,7 @@ public void collectModifications(ObjectDelta delta) th private ItemDelta computePropertyDeltas(PropertyWrapper propertyWrapper, ItemPath containerPath) { ItemDefinition itemDef = propertyWrapper.getItemDefinition(); - ItemDelta pDelta = itemDef.createEmptyDelta(propertyWrapper.getItem().getPath()); + ItemDelta pDelta = itemDef.createEmptyDelta(propertyWrapper.getPath()); addItemDelta(propertyWrapper, pDelta, itemDef, containerPath); return pDelta; } @@ -548,6 +594,37 @@ private void addItemDelta(PropertyOrReferenceWrapper itemWrapper, ItemDelta pDel } } + private Item createItem(PropertyOrReferenceWrapper itemWrapper, ItemDefinition propertyDef) { + List prismValues = new ArrayList<>(); + for (Object vWrapper : itemWrapper.getValues()) { + if (!(vWrapper instanceof ValueWrapper)) { + continue; + } + + ValueWrapper valueWrapper = (ValueWrapper) vWrapper; + + valueWrapper.normalize(propertyDef.getPrismContext()); + ValueStatus valueStatus = valueWrapper.getStatus(); + if (!valueWrapper.hasValueChanged() + && (ValueStatus.NOT_CHANGED.equals(valueStatus) || ValueStatus.ADDED.equals(valueStatus))) { + continue; + } + + prismValues.add(valueWrapper.getValue().clone()); + + } + + Item item = itemWrapper.getItem().clone(); + try { + item.addAll(prismValues); + } catch (SchemaException e) { + LoggingUtils.logException(LOGGER, "could not crate delta for " + itemWrapper.getItem(), e); + return null; + } + return item; + + } + //TODO: unify with other isVisibleMethods public boolean isVisible() { PrismContainerDefinition def = getDefinition(); @@ -591,11 +668,9 @@ private boolean emphasizedAndCanAdd(PrismContainerDefinition def) { @Override public void setShowEmpty(boolean showEmpty, boolean recursive) { super.setShowEmpty(showEmpty, recursive); - if (recursive) { - getItems().forEach(item -> { + getItems().forEach(item -> { item.setShowEmpty(showEmpty, recursive); }); - } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java index 7b37960e4ea..a43852910d2 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java @@ -73,28 +73,25 @@ public class ContainerWrapper extends PrismWrapper impl private List> values; private boolean readonly; - private boolean showInheritedObjectAttributes; - - +// private boolean showInheritedObjectAttributes; + + ContainerWrapper(PrismContainer container, ContainerStatus status, ItemPath path) { Validate.notNull(container, "container must not be null."); Validate.notNull(status, "Container status must not be null."); + Validate.notNull(container.getDefinition(), "container definition must not be null."); this.container = container; this.status = status; this.path = path; + } - ContainerWrapper(PrismContainer container, ContainerStatus status, ItemPath path, boolean readOnly, boolean showInheritedObjectAttributes) { - Validate.notNull(container, "container must not be null."); - Validate.notNull(container.getDefinition(), "container definition must not be null."); - Validate.notNull(status, "Container status must not be null."); - - this.container = container; - this.status = status; - this.path = path; - this.readonly = readOnly; - this.showInheritedObjectAttributes = showInheritedObjectAttributes; + ContainerWrapper(PrismContainer container, ContainerStatus status, ItemPath path, boolean readOnly) { + this(container, status, path); + this.readonly = readOnly; + +// this.showInheritedObjectAttributes = showInheritedObjectAttributes; } public void revive(PrismContext prismContext) throws SchemaException { @@ -196,9 +193,9 @@ public void computeStripes() { } } - public boolean isShowInheritedObjectAttributes() { - return showInheritedObjectAttributes; - } +// public boolean isShowInheritedObjectAttributes() { +// return showInheritedObjectAttributes; +// } @Override public String getDisplayName() { @@ -412,8 +409,8 @@ public String debugDump(int indent) { sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "readonly", readonly, indent + 1); sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "showInheritedObjectAttributes", showInheritedObjectAttributes, indent + 1); - sb.append("\n"); +// DebugUtil.debugDumpWithLabel(sb, "showInheritedObjectAttributes", showInheritedObjectAttributes, indent + 1); +// sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "path", path == null ? null : path.toString(), indent + 1); sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "containerDefinition", getItemDefinition() == null ? null : getItemDefinition().toString(), indent + 1); @@ -467,12 +464,31 @@ public void collectModifications(ObjectDelta delta) th return; } - for (ContainerValueWrapper itemWrapper : getValues()) { - if (!itemWrapper.hasChanged()) { - continue; - } + for (ContainerValueWrapper itemWrapper : getValues()) { + if (!itemWrapper.hasChanged()) { + continue; + } + + switch (itemWrapper.getStatus()) { + case ADDED: + PrismContainerValue valueToAdd = itemWrapper.createContainerValueAddDelta(); + if (getItemDefinition().isMultiValue()) { + delta.addModificationAddContainer(getPath(), valueToAdd); + break; + } + + delta.addModificationReplaceContainer(getPath(), valueToAdd); + break; + case NOT_CHANGED: + itemWrapper.collectModifications(delta); + break; + case DELETED: + delta.addModificationDeleteContainer(itemWrapper.getPath(), itemWrapper.getContainerValue().clone()); + break; + + } + - itemWrapper.collectModifications(delta); // ItemPath containerPath = getPath() != null ? getPath() : ItemPath.EMPTY_PATH; // // if (itemWrapper instanceof PropertyWrapper) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java index d6ca599f998..b38211afaad 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java @@ -99,18 +99,13 @@ public ContainerWrapper createContainerWrapper(Pris result = new OperationResult(CREATE_PROPERTIES); - ContainerWrapper cWrapper = new ContainerWrapper(container, status, path, readonly, false); + ContainerWrapper cWrapper = new ContainerWrapper(container, status, path, readonly); List> containerValues = createContainerValues(cWrapper, path); cWrapper.setProperties(containerValues); cWrapper.computeStripes(); - -// List properties = createProperties(cWrapper, result); -// cWrapper.setProperties(properties); -// -// cWrapper.computeStripes(); - + return cWrapper; } @@ -119,256 +114,90 @@ private List> createContainer PrismContainer container = cWrapper.getItem(); if (container.isEmpty()) { - PrismContainerValue newValue = container.createNewValue(); - ContainerValueWrapper containerValueWrapper = new ContainerValueWrapper<>(cWrapper, newValue, ValueStatus.ADDED, path); - - List properties = createProperties(containerValueWrapper, result); - containerValueWrapper.setProperties(properties); - containerValueWrappers.add(containerValueWrapper); - return containerValueWrappers; + PrismContainerValue pcv = container.createNewValue(); + ContainerValueWrapper containerValueWrapper = createContainerValueWrapper(cWrapper, pcv, ValueStatus.ADDED, cWrapper.getPath()); + + containerValueWrappers.add(containerValueWrapper); + return containerValueWrappers; } - for (PrismContainerValue containerValue : container.getValues()){ - ContainerValueWrapper containerValueWrapper = new ContainerValueWrapper<>(cWrapper, containerValue, ValueStatus.NOT_CHANGED, containerValue.getPath()); + container.getValues().forEach(pcv -> { + ContainerValueWrapper containerValueWrapper = createContainerValueWrapper(cWrapper, pcv, ValueStatus.NOT_CHANGED, pcv.getPath()); + containerValueWrappers.add(containerValueWrapper); + }); - List properties = createProperties(containerValueWrapper, result); - containerValueWrapper.setProperties(properties); - containerValueWrappers.add(containerValueWrapper); - } return containerValueWrappers; } + + private ContainerValueWrapper createContainerValueWrapper(ContainerWrapper cWrapper, PrismContainerValue value, ValueStatus status, ItemPath path){ + ContainerValueWrapper containerValueWrapper = new ContainerValueWrapper(cWrapper, value, status, path); + + List properties = createProperties(containerValueWrapper, false); + containerValueWrapper.setProperties(properties); + + return containerValueWrapper; + } - private List createProperties(ContainerValueWrapper cWrapper, OperationResult result) { - ContainerWrapper containerWrapper = cWrapper.getContainer(); -// PrismContainerValue containerValue = cWrapper.getContainerValue(); - PrismContainerDefinition definition = containerWrapper.getItemDefinition(); - - List properties = new ArrayList<>(); - -// PrismContainerDefinition definition = null; -// if (containerWrapper == null) { -// definition = containerDefinition; -// } else { -//// PrismObject parent = containerWrapper.getObject().getObject(); -// if (containerWrapper.isMain()) { -// -// -// Class clazz = ((PrismObject) containerWrapper.getItem()).getCompileTimeClass(); -// if (ShadowType.class.isAssignableFrom(clazz)) { -// try { -// createShadowContainer(containerDefinition, containerWrapper, definition); -// } catch (Exception ex) { -// LoggingUtils.logUnexpectedException(LOGGER, -// "Couldn't load definitions from refined schema for shadow", ex); -// result.recordFatalError( -// "Couldn't load definitions from refined schema for shadow, reason: " -// + ex.getMessage(), ex); -// -// return properties; -// } -// } else if (ResourceType.class.isAssignableFrom(clazz)) { -// if (containerDefinition != null) { -// definition = containerDefinition; -// } else { -// definition = containerWrapper.getItemDefinition(); -// } -// } else { -// definition = containerDefinition; -// } -// } else { -// definition = containerDefinition; -// } -// } + public List createProperties(ContainerValueWrapper cWrapper, boolean onlyEmpty) { + + result = new OperationResult(CREATE_PROPERTIES); + + ContainerWrapper containerWrapper = cWrapper.getContainer(); + PrismContainerDefinition definition = containerWrapper.getItemDefinition(); - if (definition == null) { - LOGGER.error("Couldn't get property list from null definition {}", - new Object[]{containerWrapper.getItem().getElementName()}); - return properties; - } + List properties = new ArrayList<>(); - // assignments are treated in a special way -- we display names of - // org.units and roles - // (but only if ObjectWrapper.isShowAssignments() is true; otherwise - // they are filtered out by ObjectWrapper) -// if (containerWrapper.getItem().getCompileTimeClass() != null -// && AssignmentType.class.isAssignableFrom(containerWrapper.getItem().getCompileTimeClass())) { -// -// for (Object o : container.getValues()) { -// PrismContainerValue pcv = (PrismContainerValue) o; -// -// AssignmentType assignmentType = pcv.asContainerable(); -// -// if (assignmentType.getTargetRef() == null) { -// continue; -// } -// -// // hack... we want to create a definition for Name -// // PrismPropertyDefinition def = ((PrismContainerValue) -// // pcv.getContainer().getParent()).getContainer().findProperty(ObjectType.F_NAME).getDefinition(); -// PrismPropertyDefinitionImpl def = new PrismPropertyDefinitionImpl(ObjectType.F_NAME, -// DOMUtil.XSD_STRING, pcv.getPrismContext()); -// -// if (OrgType.COMPLEX_TYPE.equals(assignmentType.getTargetRef().getType())) { -// def.setDisplayName("Org.Unit"); -// def.setDisplayOrder(100); -// } else if (RoleType.COMPLEX_TYPE.equals(assignmentType.getTargetRef().getType())) { -// def.setDisplayName("Role"); -// def.setDisplayOrder(200); -// } else { -// continue; -// } -// -// PrismProperty temp = def.instantiate(); -// -// String value = formatAssignmentBrief(assignmentType); -// -// temp.setValue(new PrismPropertyValue(value)); -// // TODO: do this.isReadOnly() - is that OK? (originally it was the default behavior for all cases) -// properties.add(new PropertyWrapper(cWrapper, temp, cWrapper.isReadonly(), ValueStatus.NOT_CHANGED)); -// } -// -// } else if (isShadowAssociation(cWrapper)) { -// -// // HACK: this should not be here. Find a better place. -// cWrapper.setDisplayName("prismContainer.shadow.associations"); -// -// PrismContext prismContext = containerWrapper.getObject().getPrismContext(); -// Map> assocMap = new HashMap<>(); -// PrismContainer associationContainer = cWrapper.getItem(); -// if (associationContainer != null && associationContainer.getValues() != null) { -// // Do NOT load shadows here. This will be huge overhead if there are many associations. -// // Load them on-demand (if necessary at all). -// List> associations = associationContainer.getValues(); -// if (associations != null) { -// for (PrismContainerValue cval : associations) { -// ShadowAssociationType associationType = cval.asContainerable(); -// QName assocName = associationType.getName(); -// PrismContainer fractionalContainer = assocMap.get(assocName); -// if (fractionalContainer == null) { -// fractionalContainer = new PrismContainer<>(ShadowType.F_ASSOCIATION, ShadowAssociationType.class, cval.getPrismContext()); -// fractionalContainer.setDefinition(cval.getParent().getDefinition()); -// // HACK: set the name of the association as the element name so wrapper.getName() will return correct data. -// fractionalContainer.setElementName(assocName); -// assocMap.put(assocName, fractionalContainer); -// } -// try { -// fractionalContainer.add(cval.clone()); -// } catch (SchemaException e) { -// // Should not happen -// throw new SystemException("Unexpected error: " + e.getMessage(), e); -// } -// } -// } -// } -// -// PrismReference resourceRef = containerWrapper.getObject().findReference(ShadowType.F_RESOURCE_REF); -// PrismObject resource = resourceRef.getValue().getObject(); -// -// // HACK. The revive should not be here. Revive is no good. The next use of the resource will -// // cause parsing of resource schema. We need some centralized place to maintain live cached copies -// // of resources. -// try { -// resource.revive(prismContext); -// } catch (SchemaException e) { -// throw new SystemException(e.getMessage(), e); -// } -// RefinedResourceSchema refinedSchema; -// CompositeRefinedObjectClassDefinition rOcDef; -// try { -// refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource); -// rOcDef = refinedSchema.determineCompositeObjectClassDefinition(containerWrapper.getObject()); -// } catch (SchemaException e) { -// throw new SystemException(e.getMessage(), e); -// } -// // Make sure even empty associations have their wrappers so they can be displayed and edited -// for (RefinedAssociationDefinition assocDef : rOcDef.getAssociationDefinitions()) { -// QName name = assocDef.getName(); -// if (!assocMap.containsKey(name)) { -// PrismContainer fractionalContainer = new PrismContainer<>(ShadowType.F_ASSOCIATION, ShadowAssociationType.class, prismContext); -// fractionalContainer.setDefinition(cWrapper.getItemDefinition()); -// // HACK: set the name of the association as the element name so wrapper.getName() will return correct data. -// fractionalContainer.setElementName(name); -// assocMap.put(name, fractionalContainer); -// } -// } -// -// for (Map.Entry> assocEntry : assocMap.entrySet()) { -// RefinedAssociationDefinition assocRDef = rOcDef.findAssociationDefinition(assocEntry.getKey()); -// AssociationWrapper assocWrapper = new AssociationWrapper(cWrapper, assocEntry.getValue(), -// cWrapper.isReadonly(), ValueStatus.NOT_CHANGED, assocRDef); -// properties.add(assocWrapper); -// } -// -// } else { // if not an assignment - - // there's no point in showing properties for non-single-valued - // parent containers, - // so we continue only if the parent is single-valued - - Collection propertyDefinitions = definition.getDefinitions(); - List propertyOrReferenceWrappers = new ArrayList<>(); - List> containerWrappers = new ArrayList<>(); - propertyDefinitions.forEach( itemDef -> { - - - if (itemDef.isIgnored() || skipProperty(itemDef)) { - LOGGER.info("Skipping creating wrapper for: {}", itemDef); - return; - } -// if (!cWrapper.isShowInheritedObjectAttributes() && INHERITED_OBJECT_ATTRIBUTES.contains(itemDef.getName())) { -// return; -// } - - - LOGGER.info("Creating wrapper for {}", itemDef); - createPropertyOrReferenceWrapper(itemDef, cWrapper, propertyOrReferenceWrappers); - createContainerWrapper(itemDef, cWrapper, containerWrappers); - - }); - - -// } + if (definition == null) { + LOGGER.error("Couldn't get property list from null definition {}", + new Object[] { containerWrapper.getItem().getElementName() }); + return properties; + } - Collections.sort(propertyOrReferenceWrappers, new ItemWrapperComparator()); - Collections.sort(containerWrappers, new ItemWrapperComparator()); - - properties.addAll(propertyOrReferenceWrappers); - properties.addAll(containerWrappers); + Collection propertyDefinitions = definition.getDefinitions(); + List propertyOrReferenceWrappers = new ArrayList<>(); + List> containerWrappers = new ArrayList<>(); + propertyDefinitions.forEach(itemDef -> { - result.recomputeStatus(); + if (itemDef.isIgnored() || skipProperty(itemDef)) { + LOGGER.info("Skipping creating wrapper for: {}", itemDef); + return; + } - return properties; - } + LOGGER.info("Creating wrapper for {}", itemDef); + createPropertyOrReferenceWrapper(itemDef, cWrapper, propertyOrReferenceWrappers, onlyEmpty, cWrapper.getPath()); + createContainerWrapper(itemDef, cWrapper, containerWrappers, onlyEmpty); + + }); + + Collections.sort(propertyOrReferenceWrappers, new ItemWrapperComparator()); + Collections.sort(containerWrappers, new ItemWrapperComparator()); + + properties.addAll(propertyOrReferenceWrappers); + properties.addAll(containerWrappers); + + result.recomputeStatus(); + + return properties; + } - private void createPropertyOrReferenceWrapper(ItemDefinition itemDef, ContainerValueWrapper cWrapper, List properties) { - -// if (itemDef.isIgnored() || skipProperty(itemDef)) { -// return; -// } -// if (!cWrapper.isShowInheritedObjectAttributes() && INHERITED_OBJECT_ATTRIBUTES.contains(itemDef.getName())) { -// return; -// } - -// PrismContainerValue containerValue = cWrapper.getContainerValue(); - - //TODO temporary decision to hide adminGuiConfiguration attribute (MID-3305) -// if (itemDef != null && itemDef.getName() != null && itemDef.getName().getLocalPart() != null && -// itemDef.getName().getLocalPart().equals("adminGuiConfiguration")){ -// continue; -// } + private void createPropertyOrReferenceWrapper(ItemDefinition itemDef, ContainerValueWrapper cWrapper, List properties, boolean onlyEmpty, ItemPath parentPath) { + PropertyOrReferenceWrapper propertyOrReferenceWrapper = null; if (itemDef instanceof PrismPropertyDefinition) { - - properties.add(createPropertyWrapper((PrismPropertyDefinition) itemDef, cWrapper)); + propertyOrReferenceWrapper = createPropertyWrapper((PrismPropertyDefinition) itemDef, cWrapper, onlyEmpty); + } else if (itemDef instanceof PrismReferenceDefinition) { - properties.add(createReferenceWrapper((PrismReferenceDefinition) itemDef, cWrapper)); + propertyOrReferenceWrapper = createReferenceWrapper((PrismReferenceDefinition) itemDef, cWrapper, onlyEmpty); } + if (propertyOrReferenceWrapper != null) { + properties.add(propertyOrReferenceWrapper); + } } - private void createContainerWrapper(ItemDefinition itemDef, ContainerValueWrapper cWrapper, List> properties) { + private void createContainerWrapper(ItemDefinition itemDef, ContainerValueWrapper cWrapper, List> properties, boolean onlyEmpty) { if (itemDef instanceof PrismContainerDefinition) { @@ -376,7 +205,7 @@ private void createContainerWrapper(ItemDefinition ite return; } - ContainerWrapper subContainerWrapper = createContainerWrapper((PrismContainerDefinition) itemDef, cWrapper); + ContainerWrapper subContainerWrapper = createContainerWrapper((PrismContainerDefinition) itemDef, cWrapper, onlyEmpty); if (subContainerWrapper == null) { @@ -392,70 +221,94 @@ private void createContainerWrapper(ItemDefinition ite } private PropertyWrapper createPropertyWrapper( - PrismPropertyDefinition def, ContainerValueWrapper cWrapper) { + PrismPropertyDefinition def, ContainerValueWrapper cWrapper, boolean onlyEmpty) { PrismContainerValue containerValue = cWrapper.getContainerValue(); PrismProperty property = containerValue.findProperty(def.getName()); boolean propertyIsReadOnly = isItemReadOnly(def, cWrapper); - // decision is based on parent object status, not this - // container's one (because container can be added also - // to an existing object) + + if (property != null && onlyEmpty) { + return null; + } if (property == null) { - return new PropertyWrapper(cWrapper, def.instantiate(), propertyIsReadOnly, ValueStatus.ADDED); + PrismProperty newProperty = def.instantiate(); +// try { +// newProperty = containerValue.createProperty(def); +// } catch (SchemaException e) { +// LoggingUtils.logException(LOGGER, "Failed to create new property " + def, e); +// return null; +// } + return new PropertyWrapper(cWrapper, newProperty, propertyIsReadOnly, ValueStatus.ADDED, cWrapper.getPath().append(newProperty.getPath())); } - return new PropertyWrapper(cWrapper, property, propertyIsReadOnly, ValueStatus.NOT_CHANGED); + return new PropertyWrapper(cWrapper, property, propertyIsReadOnly, ValueStatus.NOT_CHANGED, property.getPath()); } - private ReferenceWrapper createReferenceWrapper(PrismReferenceDefinition def, ContainerValueWrapper cWrapper) { + private ReferenceWrapper createReferenceWrapper(PrismReferenceDefinition def, ContainerValueWrapper cWrapper, boolean onlyEmpty) { PrismContainerValue containerValue = cWrapper.getContainerValue(); -// -// if (INHERITED_OBJECT_ATTRIBUTES.contains(def.getName())) { -// return null; -// } PrismReference reference = containerValue.findReference(def.getName()); boolean propertyIsReadOnly = isItemReadOnly(def, cWrapper); - // decision is based on parent object status, not this - // container's one (because container can be added also - // to an existing object) + if (reference != null && onlyEmpty) { + return null; + } + if (reference == null) { - return new ReferenceWrapper(cWrapper, def.instantiate(), propertyIsReadOnly, - ValueStatus.ADDED); + PrismReference newReference = def.instantiate(); +// try { +// containerValue.add(newReference); +// } catch (SchemaException e) { +// LoggingUtils.logException(LOGGER, "Failed to create new reference " + def, e); +// return null; +// } + return new ReferenceWrapper(cWrapper, newReference, propertyIsReadOnly, + ValueStatus.ADDED, cWrapper.getPath().append(newReference.getPath())); } return new ReferenceWrapper(cWrapper, reference, propertyIsReadOnly, - ValueStatus.NOT_CHANGED); + ValueStatus.NOT_CHANGED, reference.getPath()); } - private ContainerWrapper createContainerWrapper(PrismContainerDefinition def, ContainerValueWrapper cWrapper) { - + private ContainerWrapper createContainerWrapper(PrismContainerDefinition def, + ContainerValueWrapper cWrapper, boolean onlyEmpty) { + PrismContainerValue containerValue = cWrapper.getContainerValue(); PrismContainer container = containerValue.findContainer(def.getName()); - - //TODO: hack, temporary because of recurcive dependecies - if (container == null && - (PolicyConstraintPresentationType.COMPLEX_TYPE.equals(def.getTypeName()) || PolicyConstraintsType.COMPLEX_TYPE.equals(def.getTypeName()))) { - return null; - } - if (container == null) { - PrismContainer newContainer; + + // TODO: hack, temporary because of recurcive dependecies + if (PolicyConstraintsType.COMPLEX_TYPE.equals(def.getTypeName())) { + return createPolicyConstraintsContainer(container, def, cWrapper); + } + + if (container != null && onlyEmpty) { + return null; + } + + if (container == null) { + PrismContainer newContainer; try { newContainer = (PrismContainer) def.instantiate(); +// containerValue.add(newContainer); } catch (SchemaException e) { LoggingUtils.logException(LOGGER, "Cannot create container " + def.getName(), e); return null; } return createContainerWrapper(newContainer, ContainerStatus.ADDING, cWrapper.getPath().append(newContainer.getPath())); - } - return createContainerWrapper(container, ContainerStatus.MODIFYING, container.getPath()); -// List subContainerValues = createContainerValues(subContainerWrapper); -// subContainerWrapper.setProperties(subContainerValues); -// subContainerWrapper.computeStripes(); + } + return createContainerWrapper(container, ContainerStatus.MODIFYING, container.getPath()); + } + + private ContainerWrapper createPolicyConstraintsContainer(PrismContainer policyConstraintsContainer, PrismContainerDefinition def, ContainerValueWrapper parentContainer) { + if (policyConstraintsContainer != null) { + return createContainerWrapper(policyConstraintsContainer, ContainerStatus.MODIFYING, policyConstraintsContainer.getPath()); + } + + return null; + } private boolean isItemReadOnly(ItemDefinition def, ContainerValueWrapper cWrapper) { @@ -468,32 +321,32 @@ private boolean isItemReadOnly(ItemDefinition def, Con } -private void createShadowContainer(PrismContainerDefinition containerDefinition, ContainerWrapper containerWrapper, PrismContainerDefinition definition) throws SchemaException { - QName name = containerDefinition.getName(); - - if (ShadowType.F_ATTRIBUTES.equals(name)) { - definition = null;//containerWrapper.getObject().getRefinedAttributeDefinition(); - - if (definition == null) { - PrismReference resourceRef = containerWrapper.getItem().findReference(ShadowType.F_RESOURCE_REF); - PrismObject resource = resourceRef.getValue().getObject(); - -// definition = modelServiceLocator -// .getModelInteractionService() -// .getEditObjectClassDefinition((PrismObject) containerWrapper.getObject().getObject(), resource, -// AuthorizationPhaseType.REQUEST) -// .toResourceAttributeContainerDefinition(); - - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Refined account def:\n{}", definition.debugDump()); - } - } - - - } else { - definition = containerDefinition; - } -} +//private void createShadowContainer(PrismContainerDefinition containerDefinition, ContainerWrapper containerWrapper, PrismContainerDefinition definition) throws SchemaException { +// QName name = containerDefinition.getName(); +// +// if (ShadowType.F_ATTRIBUTES.equals(name)) { +// definition = null;//containerWrapper.getObject().getRefinedAttributeDefinition(); +// +// if (definition == null) { +// PrismReference resourceRef = containerWrapper.getItem().findReference(ShadowType.F_RESOURCE_REF); +// PrismObject resource = resourceRef.getValue().getObject(); +// +//// definition = modelServiceLocator +//// .getModelInteractionService() +//// .getEditObjectClassDefinition((PrismObject) containerWrapper.getObject().getObject(), resource, +//// AuthorizationPhaseType.REQUEST) +//// .toResourceAttributeContainerDefinition(); +// +// if (LOGGER.isTraceEnabled()) { +// LOGGER.trace("Refined account def:\n{}", definition.debugDump()); +// } +// } +// +// +// } else { +// definition = containerDefinition; +// } +//} // public ContainerWrapper createCustomContainerWrapper(C container, ContainerStatus status, ItemPath path, // boolean readonly, boolean showInheritedAttributes) { @@ -586,131 +439,131 @@ private void createShadowContainer(PrismContainerDefinition containerDefinition, // //} - private boolean isShadowAssociation(ContainerWrapper cWrapper) { -// ObjectWrapper oWrapper = cWrapper.getObject(); -// if (oWrapper == null) { -// return false; -// } - PrismContainer container = cWrapper.getItem(); +// private boolean isShadowAssociation(ContainerWrapper cWrapper) { +//// ObjectWrapper oWrapper = cWrapper.getObject(); +//// if (oWrapper == null) { +//// return false; +//// } +// PrismContainer container = cWrapper.getItem(); +//// +// if (!ShadowType.class.isAssignableFrom(container.getCompileTimeClass())) { +// return false; +// } // - if (!ShadowType.class.isAssignableFrom(container.getCompileTimeClass())) { - return false; - } - - if (!ShadowType.F_ASSOCIATION.equals(container.getElementName())) { - return false; - } - - return true; - } - - private boolean isShadowActivation(ContainerWrapper cWrapper) { -// ObjectWrapper oWrapper = cWrapper.getObject(); -// if (oWrapper == null) { -// return false; -// } - PrismContainer oWrapper = cWrapper.getItem(); - - if (!ShadowType.class.isAssignableFrom(oWrapper.getCompileTimeClass())) { - return false; - } - - if (!ShadowType.F_ACTIVATION.equals(oWrapper.getElementName())) { - return false; - } - - return true; - } - - private boolean hasActivationCapability(ContainerWrapper cWrapper, PrismPropertyDefinition def) { - PrismContainer oWrapper = cWrapper.getItem(); - if (!(oWrapper instanceof PrismObject)) { - return false; - } - ObjectType objectType = (ObjectType) ((PrismObject)oWrapper).asObjectable(); - if (!(objectType instanceof ShadowType)) { - return false; - } - - ShadowType shadow = (ShadowType) objectType; - ActivationCapabilityType cap = ResourceTypeUtil.getEffectiveCapability(shadow.getResource(), - ActivationCapabilityType.class); - - if (ActivationType.F_VALID_FROM.equals(def.getName()) && CapabilityUtil.getEffectiveActivationValidFrom(cap) == null) { - return false; - } - - if (ActivationType.F_VALID_TO.equals(def.getName()) && CapabilityUtil.getEffectiveActivationValidTo(cap) == null) { - return false; - } - - if (ActivationType.F_ADMINISTRATIVE_STATUS.equals(def.getName()) && CapabilityUtil.getEffectiveActivationStatus(cap) == null) { - return false; - } - - return true; - } +// if (!ShadowType.F_ASSOCIATION.equals(container.getElementName())) { +// return false; +// } +// +// return true; +// } +// +// private boolean isShadowActivation(ContainerWrapper cWrapper) { +//// ObjectWrapper oWrapper = cWrapper.getObject(); +//// if (oWrapper == null) { +//// return false; +//// } +// PrismContainer oWrapper = cWrapper.getItem(); +// +// if (!ShadowType.class.isAssignableFrom(oWrapper.getCompileTimeClass())) { +// return false; +// } +// +// if (!ShadowType.F_ACTIVATION.equals(oWrapper.getElementName())) { +// return false; +// } +// +// return true; +// } +// +// private boolean hasActivationCapability(ContainerWrapper cWrapper, PrismPropertyDefinition def) { +// PrismContainer oWrapper = cWrapper.getItem(); +// if (!(oWrapper instanceof PrismObject)) { +// return false; +// } +// ObjectType objectType = (ObjectType) ((PrismObject)oWrapper).asObjectable(); +// if (!(objectType instanceof ShadowType)) { +// return false; +// } +// +// ShadowType shadow = (ShadowType) objectType; +// ActivationCapabilityType cap = ResourceTypeUtil.getEffectiveCapability(shadow.getResource(), +// ActivationCapabilityType.class); +// +// if (ActivationType.F_VALID_FROM.equals(def.getName()) && CapabilityUtil.getEffectiveActivationValidFrom(cap) == null) { +// return false; +// } +// +// if (ActivationType.F_VALID_TO.equals(def.getName()) && CapabilityUtil.getEffectiveActivationValidTo(cap) == null) { +// return false; +// } +// +// if (ActivationType.F_ADMINISTRATIVE_STATUS.equals(def.getName()) && CapabilityUtil.getEffectiveActivationStatus(cap) == null) { +// return false; +// } +// +// return true; +// } // FIXME temporary - brutal hack - the following three methods are copied from // AddRoleAssignmentAspect - Pavol M. - private String formatAssignmentBrief(AssignmentType assignment) { - StringBuilder sb = new StringBuilder(); - if (assignment.getTarget() != null) { - sb.append(assignment.getTarget().getName()); - } else { - sb.append(assignment.getTargetRef().getOid()); - } - if (assignment.getActivation() != null - && (assignment.getActivation().getValidFrom() != null || assignment.getActivation() - .getValidTo() != null)) { - sb.append(" "); - sb.append("("); - sb.append(formatTimeIntervalBrief(assignment)); - sb.append(")"); - } - if (assignment.getActivation() != null) { - switch (assignment.getActivation().getEffectiveStatus()) { - case ARCHIVED: - sb.append(", archived"); - break; // TODO i18n - case ENABLED: - sb.append(", enabled"); - break; - case DISABLED: - sb.append(", disabled"); - break; - } - } - return sb.toString(); - } - - public static String formatTimeIntervalBrief(AssignmentType assignment) { - StringBuilder sb = new StringBuilder(); - if (assignment != null - && assignment.getActivation() != null - && (assignment.getActivation().getValidFrom() != null || assignment.getActivation() - .getValidTo() != null)) { - if (assignment.getActivation().getValidFrom() != null - && assignment.getActivation().getValidTo() != null) { - sb.append(formatTime(assignment.getActivation().getValidFrom())); - sb.append("-"); - sb.append(formatTime(assignment.getActivation().getValidTo())); - } else if (assignment.getActivation().getValidFrom() != null) { - sb.append("from "); - sb.append(formatTime(assignment.getActivation().getValidFrom())); - } else { - sb.append("to "); - sb.append(formatTime(assignment.getActivation().getValidTo())); - } - } - return sb.toString(); - } - - private static String formatTime(XMLGregorianCalendar time) { - DateFormat formatter = DateFormat.getDateInstance(); - return formatter.format(time.toGregorianCalendar().getTime()); - } +// private String formatAssignmentBrief(AssignmentType assignment) { +// StringBuilder sb = new StringBuilder(); +// if (assignment.getTarget() != null) { +// sb.append(assignment.getTarget().getName()); +// } else { +// sb.append(assignment.getTargetRef().getOid()); +// } +// if (assignment.getActivation() != null +// && (assignment.getActivation().getValidFrom() != null || assignment.getActivation() +// .getValidTo() != null)) { +// sb.append(" "); +// sb.append("("); +// sb.append(formatTimeIntervalBrief(assignment)); +// sb.append(")"); +// } +// if (assignment.getActivation() != null) { +// switch (assignment.getActivation().getEffectiveStatus()) { +// case ARCHIVED: +// sb.append(", archived"); +// break; // TODO i18n +// case ENABLED: +// sb.append(", enabled"); +// break; +// case DISABLED: +// sb.append(", disabled"); +// break; +// } +// } +// return sb.toString(); +// } +// +// public static String formatTimeIntervalBrief(AssignmentType assignment) { +// StringBuilder sb = new StringBuilder(); +// if (assignment != null +// && assignment.getActivation() != null +// && (assignment.getActivation().getValidFrom() != null || assignment.getActivation() +// .getValidTo() != null)) { +// if (assignment.getActivation().getValidFrom() != null +// && assignment.getActivation().getValidTo() != null) { +// sb.append(formatTime(assignment.getActivation().getValidFrom())); +// sb.append("-"); +// sb.append(formatTime(assignment.getActivation().getValidTo())); +// } else if (assignment.getActivation().getValidFrom() != null) { +// sb.append("from "); +// sb.append(formatTime(assignment.getActivation().getValidFrom())); +// } else { +// sb.append("to "); +// sb.append(formatTime(assignment.getActivation().getValidTo())); +// } +// } +// return sb.toString(); +// } +// +// private static String formatTime(XMLGregorianCalendar time) { +// DateFormat formatter = DateFormat.getDateInstance(); +// return formatter.format(time.toGregorianCalendar().getTime()); +// } /** * This methods check if we want to show property in form (e.g. diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java index 7493d2edc7e..3d1a52f7247 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java @@ -31,6 +31,7 @@ import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; @@ -64,6 +65,8 @@ public class ObjectWrapper extends PrismWrapper implements private String displayName; private String description; private List> containers; + + private ContainerWrapperFactory factory; // private boolean showEmpty; // private boolean minimalized; @@ -93,12 +96,12 @@ public class ObjectWrapper extends PrismWrapper implements // a refined definition of an resource object class that reflects its editability; applicable for shadows only private RefinedObjectClassDefinition objectClassDefinitionForEditing; - public ObjectWrapper(String displayName, String description, PrismObject object, ContainerStatus status) { - this(displayName, description, object, null, status); - } +// public ObjectWrapper(PrismObject object, ContainerStatus status, ContainerWrapperFactory factory) { +// this(object, null, status); +// } - public ObjectWrapper(String displayName, String description, PrismObject object, - RefinedObjectClassDefinition objectClassDefinitionForEditing, ContainerStatus status) { + public ObjectWrapper(String dispayName, String descritpion, PrismObject object, + ContainerStatus status) { Validate.notNull(object, "Object must not be null."); Validate.notNull(status, "Container status must not be null."); @@ -107,7 +110,8 @@ public ObjectWrapper(String displayName, String description, PrismObject object, this.object = object; this.objectOld = object.clone(); this.status = status; - this.objectClassDefinitionForEditing = objectClassDefinitionForEditing; + +// this.objectClassDefinitionForEditing = objectClassDefinitionForEditing; } // public void initializeContainers(PageBase pageBase) { @@ -232,14 +236,34 @@ public void setContainers(List> contai public ContainerWrapper findContainerWrapper(ItemPath path) { if (path == null || path.isEmpty()) { return (ContainerWrapper) findMainContainerWrapper(); +// ContainerWrapper mainContainer = (ContainerWrapper) findMainContainerWrapper(); +// if (mainContainer == null) { +// mainContainer = factory.createContainerWrapper(object, ContainerStatus.ADDING, ItemPath.EMPTY_PATH); +// containers.add(mainContainer); +// return mainContainer; +// } + } if (path.size() == 1) { - return (ContainerWrapper) getContainers().stream().filter(wrapper -> path.equivalent(wrapper.getPath())).findFirst().orElse(null); + return (ContainerWrapper) getContainers().stream().filter(wrapper -> path.equivalent(wrapper.getPath())).findFirst().orElse(null); +// ContainerWrapper containerWrapper = (ContainerWrapper) getContainers().stream().filter(wrapper -> path.equivalent(wrapper.getPath())).findFirst().orElse(null); +// if (containerWrapper == null) { +// PrismContainer container; +// try { +// container = object.findOrCreateContainer(path); +// } catch (SchemaException e) { +// LoggingUtils.logException(LOGGER, "Cannot create container " + path, e); +// return null; +// } +// containerWrapper = factory.createContainerWrapper(container, ContainerStatus.ADDING, path); +// containers.add(containerWrapper); +// return containerWrapper; +// } } - ContainerWrapper containerWrapper = findContainerWrapper(path.head()); + ContainerWrapper containerWrapper = findContainerWrapper(path.head()); if (containerWrapper == null) { return null; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java index c9cb7a1e5bf..296c0472e69 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java @@ -57,11 +57,6 @@ public class ObjectWrapperFactory { private static final String CREATE_CONTAINERS = DOT_CLASS + "createContainers"; private static final String CREATE_OBJECT_WRAPPER = DOT_CLASS + "createObjectWrapper"; - private static final List INHERITED_OBJECT_SUBCONTAINERS = Arrays.asList( -// ObjectType.F_METADATA, -// ObjectType.F_EXTENSION - ); - private static final List CONTAINERS_TO_IGNORE = Arrays.asList( SubjectedObjectSelectorType.COMPLEX_TYPE, TriggerType.COMPLEX_TYPE, @@ -96,7 +91,6 @@ public ObjectWrapper createObjectWrapper(String displa authorizationPhase = AuthorizationPhaseType.REQUEST; } try { -// Task task = modelServiceLocator.createSimpleTask(CREATE_OBJECT_WRAPPER); OperationResult result = task.getResult(); PrismObjectDefinition objectDefinitionForEditing = modelServiceLocator.getModelInteractionService() @@ -105,6 +99,9 @@ public ObjectWrapper createObjectWrapper(String displa LOGGER.trace("Edit definition for {}:\n{}", object, objectDefinitionForEditing.debugDump(1)); } + if (objectDefinitionForEditing != null) { + object.setDefinition(objectDefinitionForEditing); + } RefinedObjectClassDefinition objectClassDefinitionForEditing = null; if (isShadow(object)) { @@ -113,8 +110,11 @@ public ObjectWrapper createObjectWrapper(String displa Validate.notNull(resource, "No resource object in the resourceRef"); objectClassDefinitionForEditing = modelServiceLocator.getModelInteractionService().getEditObjectClassDefinition( (PrismObject) object, resource, authorizationPhase); + if (objectClassDefinitionForEditing != null) { + object.findContainer(ShadowType.F_ATTRIBUTES).applyDefinition((PrismContainerDefinition) objectClassDefinitionForEditing.toResourceAttributeContainerDefinition());; + } + } - return createObjectWrapper(displayName, description, object, objectDefinitionForEditing, objectClassDefinitionForEditing, status, result); } catch (SchemaException | ConfigurationException | ObjectNotFoundException ex) { @@ -140,12 +140,7 @@ private ObjectWrapper createObjectWrapper(String displ this.result = result; } - //replace default definition with the updated definition - limitation + security included - if (objectDefinitionForEditing != null) { - object.setDefinition(objectDefinitionForEditing); - } - - ObjectWrapper objectWrapper = new ObjectWrapper<>(displayName, description, object, objectClassDefinitionForEditing, + ObjectWrapper objectWrapper = new ObjectWrapper<>(displayName, description, object, status); List> containerWrappers = createContainerWrappers(objectWrapper, object, @@ -171,21 +166,21 @@ private List> c ContainerWrapperFactory cwf = new ContainerWrapperFactory(modelServiceLocator); try { - Class clazz = object.getCompileTimeClass(); - if (ShadowType.class.isAssignableFrom(clazz)) { - addShadowContainers(containerWrappers, oWrapper, object, objectDefinitionForEditing, cwf, cStatus, result); - } else if (ResourceType.class.isAssignableFrom(clazz)) { - addResourceContainers(containerWrappers, oWrapper, object, result); - } else if (ReportType.class.isAssignableFrom(clazz)) { - addReportContainers(containerWrappers, oWrapper, object, result); - } else { - ContainerWrapper mainContainerWrapper = cwf.createContainerWrapper(object, cStatus, ItemPath.EMPTY_PATH); +// Class clazz = object.getCompileTimeClass(); +// if (ShadowType.class.isAssignableFrom(clazz)) { +// addShadowContainers(containerWrappers, oWrapper, object, objectDefinitionForEditing, cwf, cStatus, result); +// } else if (ResourceType.class.isAssignableFrom(clazz)) { //TODO: is this even used??? +// addResourceContainers(containerWrappers, oWrapper, object, result); +// } else if (ReportType.class.isAssignableFrom(clazz)) { //TODO is this even used??? +// addReportContainers(containerWrappers, oWrapper, object, result); +// } else { + ContainerWrapper mainContainerWrapper = cwf.createContainerWrapper(object, cStatus, ItemPath.EMPTY_PATH); mainContainerWrapper.setDisplayName("prismContainer.mainPanelDisplayName"); result.addSubresult(cwf.getResult()); containerWrappers.add(mainContainerWrapper); addContainerWrappers(containerWrappers, oWrapper, object, null, result); - } +// } } catch (SchemaException | RuntimeException e) { //TODO: shouldn't be this exception thrown???? LoggingUtils.logUnexpectedException(LOGGER, "Error occurred during container wrapping", e); @@ -254,32 +249,9 @@ private void addContainerWrapper LOGGER.trace("ObjectWrapper.createContainerWrapper processing definition: {}", def); PrismContainerDefinition containerDef = (PrismContainerDefinition) def; - //todo this oWrapper.isShowAssignments() value is not set when initialization occurs (only default is there) [lazyman] -// if (!oWrapper.isShowAssignments() && AssignmentType.COMPLEX_TYPE.equals(containerDef.getTypeName())) { -// continue; -// } - //todo this oWrapper.isShowInheritedObjectAttributes() value is not set when initialization occurs (only default is there) [lazyman] -// if (!oWrapper.isShowInheritedObjectAttributes()) { -// boolean res = INHERITED_OBJECT_SUBCONTAINERS.contains(containerDef.getName()); -// LOGGER.info("checking " + containerDef.getName() + ", result = " + res); -// if (res) { -// continue; -// } -// } ItemPath newPath = createPropertyPath(parentPath, containerDef.getName()); - // [med] - // The following code fails to work when parent is multivalued or - // potentially multivalued. - // Therefore (as a brutal hack), for multivalued parents we simply - // skip it. -// if (parentContainer.size() <= 1) { - - // the same check as in getValue() implementation -// boolean isMultiValued = parentContainer.getDefinition() != null && !parentContainer.getDefinition().isDynamic(); -// && !parentContainer.getDefinition().isSingleValue(); -// if (!isMultiValued) { ContainerWrapperFactory cwf = new ContainerWrapperFactory(modelServiceLocator); if (AssignmentType.COMPLEX_TYPE.equals(parentContainer.getDefinition().getName())) { @@ -298,16 +270,7 @@ private void addContainerWrapper result.addSubresult(cwf.getResult()); containerWrappers.add(container); -// if (!AssignmentType.COMPLEX_TYPE.equals(containerDef.getTypeName()) -// || !ShadowType.F_ASSOCIATION.equals(parentContainer.getElementName())) { - // do not show internals of Assignments (e.g. activation) -// if (newPath.size() <= 1) { -// addContainerWrappers(containerWrappers, oWrapper, prismContainer, newPath, result); -// } -// } } -// } -// } } @@ -358,93 +321,89 @@ private void addResourceContainerWrapper( addContainerWrappers(containerWrappers, oWrapper, container, new ItemPath(ResourceType.F_CONNECTOR_CONFIGURATION), result); } - private void addShadowContainers( - List> containers, - ObjectWrapper oWrapper, PrismObject object, PrismObjectDefinition objectDefinitionForEditing, - ContainerWrapperFactory cwf, ContainerStatus cStatus, - OperationResult result) throws SchemaException { - - PrismContainer attributesContainer = object.findContainer(ShadowType.F_ATTRIBUTES); - ContainerStatus status = attributesContainer != null ? cStatus : ContainerStatus.ADDING; - if (attributesContainer == null) { - PrismContainerDefinition definition = object.getDefinition().findContainerDefinition( - ShadowType.F_ATTRIBUTES); - attributesContainer = definition.instantiate(); - } - - - - ContainerWrapper attributesContainerWrapper = cwf.createContainerWrapper(attributesContainer, status, - new ItemPath(ShadowType.F_ATTRIBUTES)); - result.addSubresult(cwf.getResult()); - -// attributesContainerWrapper.setMain(true); - attributesContainerWrapper.setDisplayName("prismContainer.shadow.mainPanelDisplayName"); - containers.add(attributesContainerWrapper); - - if (hasResourceCapability(((ShadowType) object.asObjectable()).getResource(), - ActivationCapabilityType.class)) { - containers - .addAll(createCustomContainerWrapper(oWrapper, object, objectDefinitionForEditing, ShadowType.F_ACTIVATION, result)); - } - if (hasResourceCapability(((ShadowType) object.asObjectable()).getResource(), - CredentialsCapabilityType.class)) { - containers - .addAll(createCustomContainerWrapper(oWrapper, object, objectDefinitionForEditing, ShadowType.F_CREDENTIALS, result)); - } - - PrismContainer associationContainer = object.findOrCreateContainer(ShadowType.F_ASSOCIATION); - attributesContainerWrapper = cwf.createContainerWrapper(associationContainer, ContainerStatus.MODIFYING, - new ItemPath(ShadowType.F_ASSOCIATION)); - result.addSubresult(cwf.getResult()); - containers.add(attributesContainerWrapper); -} - - private void addResourceContainers( - List> containers, - ObjectWrapper oWrapper, PrismObject object, - OperationResult result) throws SchemaException { - PrismObject connector = loadConnector(object); - if (connector != null) { - addResourceContainerWrapper(containers, oWrapper, object, connector, result); - } - } - - private void addReportContainers( - List> containers, - ObjectWrapper oWrapper, PrismObject object, - OperationResult result) throws SchemaException { - PrismContainer container = object.findContainer(ReportType.F_CONFIGURATION); - ContainerStatus status = container != null ? ContainerStatus.MODIFYING : ContainerStatus.ADDING; - - if (container == null) { - PrismSchema schema = ReportTypeUtil.parseReportConfigurationSchema( - (PrismObject) object, object.getPrismContext()); - PrismContainerDefinition definition = ReportTypeUtil.findReportConfigurationDefinition(schema); - if (definition == null) { - return; - } - container = definition.instantiate(); - } - ContainerWrapperFactory cwf = new ContainerWrapperFactory(modelServiceLocator); - ContainerWrapper wrapper = cwf.createContainerWrapper(container, status, new ItemPath(ReportType.F_CONFIGURATION)); - result.addSubresult(cwf.getResult()); - - containers.add(wrapper); - } - - private PrismObject loadConnector(PrismObject object) { - PrismReference connectorRef = object.findReference(ResourceType.F_CONNECTOR_REF); - return connectorRef != null ? (connectorRef.getValue() != null ? connectorRef.getValue().getObject() : null) : null; - // todo reimplement - } +// private void addShadowContainers( +// List> containers, +// ObjectWrapper oWrapper, PrismObject object, PrismObjectDefinition objectDefinitionForEditing, +// ContainerWrapperFactory cwf, ContainerStatus cStatus, +// OperationResult result) throws SchemaException { +// +// PrismContainer attributesContainer = object.findContainer(ShadowType.F_ATTRIBUTES); +// ContainerStatus status = attributesContainer != null ? cStatus : ContainerStatus.ADDING; +// if (attributesContainer == null) { +// PrismContainerDefinition definition = object.getDefinition().findContainerDefinition( +// ShadowType.F_ATTRIBUTES); +// attributesContainer = definition.instantiate(); +// } +// +// +// +// ContainerWrapper attributesContainerWrapper = cwf.createContainerWrapper(attributesContainer, status, +// new ItemPath(ShadowType.F_ATTRIBUTES)); +// result.addSubresult(cwf.getResult()); +// +//// attributesContainerWrapper.setMain(true); +// attributesContainerWrapper.setDisplayName("prismContainer.shadow.mainPanelDisplayName"); +// containers.add(attributesContainerWrapper); +// +// if (hasResourceCapability(((ShadowType) object.asObjectable()).getResource(), +// ActivationCapabilityType.class)) { +// containers +// .addAll(createCustomContainerWrapper(oWrapper, object, objectDefinitionForEditing, ShadowType.F_ACTIVATION, result)); +// } +// if (hasResourceCapability(((ShadowType) object.asObjectable()).getResource(), +// CredentialsCapabilityType.class)) { +// containers +// .addAll(createCustomContainerWrapper(oWrapper, object, objectDefinitionForEditing, ShadowType.F_CREDENTIALS, result)); +// } +// +// PrismContainer associationContainer = object.findOrCreateContainer(ShadowType.F_ASSOCIATION); +// attributesContainerWrapper = cwf.createContainerWrapper(associationContainer, ContainerStatus.MODIFYING, +// new ItemPath(ShadowType.F_ASSOCIATION)); +// result.addSubresult(cwf.getResult()); +// containers.add(attributesContainerWrapper); +//} + +// private void addResourceContainers( +// List> containers, +// ObjectWrapper oWrapper, PrismObject object, +// OperationResult result) throws SchemaException { +// PrismObject connector = loadConnector(object); +// if (connector != null) { +// addResourceContainerWrapper(containers, oWrapper, object, connector, result); +// } +// } +// +// private void addReportContainers( +// List> containers, +// ObjectWrapper oWrapper, PrismObject object, +// OperationResult result) throws SchemaException { +// PrismContainer container = object.findContainer(ReportType.F_CONFIGURATION); +// ContainerStatus status = container != null ? ContainerStatus.MODIFYING : ContainerStatus.ADDING; +// +// if (container == null) { +// PrismSchema schema = ReportTypeUtil.parseReportConfigurationSchema( +// (PrismObject) object, object.getPrismContext()); +// PrismContainerDefinition definition = ReportTypeUtil.findReportConfigurationDefinition(schema); +// if (definition == null) { +// return; +// } +// container = definition.instantiate(); +// } +// ContainerWrapperFactory cwf = new ContainerWrapperFactory(modelServiceLocator); +// ContainerWrapper wrapper = cwf.createContainerWrapper(container, status, new ItemPath(ReportType.F_CONFIGURATION)); +// result.addSubresult(cwf.getResult()); +// +// containers.add(wrapper); +// } +// +// private PrismObject loadConnector(PrismObject object) { +// PrismReference connectorRef = object.findReference(ResourceType.F_CONNECTOR_REF); +// return connectorRef != null ? (connectorRef.getValue() != null ? connectorRef.getValue().getObject() : null) : null; +// // todo reimplement +// } private ItemPath createPropertyPath(ItemPath path, QName element) { - List segments = new ArrayList<>(); - segments.addAll(path.getSegments()); - segments.add(new NameItemPathSegment(element)); - - return new ItemPath(segments); + return path.append(element); } private boolean isShadow(PrismObject object) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java index a820287c082..410e4e25200 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java @@ -1,5 +1,7 @@ package com.evolveum.midpoint.web.component.prism; +import java.util.List; + import org.apache.wicket.AttributeModifier; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.model.AbstractReadOnlyModel; @@ -81,12 +83,10 @@ public boolean isVisible() { @Override public void onClick(AjaxRequestTarget target) { - ContainerValueWrapper wrapper = PrismContainerValueHeaderPanel.this.getModelObject(); - wrapper.setShowEmpty(!wrapper.isShowEmpty(), true); - - onButtonClick(target); + onShowEmptyClick(target); } + @Override public boolean isOn() { return PrismContainerValueHeaderPanel.this.getModelObject().isShowEmpty(); @@ -124,5 +124,15 @@ public boolean isOn() { protected String getLabel() { return getModel().getObject().getDisplayName(); } + + private void onShowEmptyClick(AjaxRequestTarget target) { + + ContainerValueWrapper wrapper = PrismContainerValueHeaderPanel.this.getModelObject(); + wrapper.setShowEmpty(!wrapper.isShowEmpty(), false); + + onButtonClick(target); + + } + } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyOrReferenceWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyOrReferenceWrapper.java index 2b1e3660ed8..59a20620a25 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyOrReferenceWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PropertyOrReferenceWrapper.java @@ -49,8 +49,9 @@ public abstract class PropertyOrReferenceWrapper extends PropertyOrReferenceWrapper property, boolean readonly, ValueStatus status) { - super(container, property, readonly, status); + super(container, property, readonly, status, null); - if (container != null && SchemaConstants.PATH_PASSWORD.equivalent(container.getPath()) - && PasswordType.F_VALUE.equals(property.getElementName())) { - super.setDisplayName("prismPropertyPanel.name.credentials.password"); - } + values = createValues(); + } + + public PropertyWrapper(@Nullable ContainerValueWrapper container, PrismProperty property, boolean readonly, ValueStatus status, ItemPath path) { + super(container, property, readonly, status, path); values = createValues(); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ReferenceWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ReferenceWrapper.java index ce26cab0a05..474d490d678 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ReferenceWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ReferenceWrapper.java @@ -18,6 +18,7 @@ import com.evolveum.midpoint.prism.PrismReference; import com.evolveum.midpoint.prism.PrismReferenceDefinition; import com.evolveum.midpoint.prism.PrismReferenceValue; +import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.PrettyPrinter; @@ -30,7 +31,11 @@ public class ReferenceWrapper extends PropertyOrReferenceWrapper getValues() { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ValueWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ValueWrapper.java index e3d46de70c4..5ede2841065 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ValueWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ValueWrapper.java @@ -22,6 +22,7 @@ import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismPropertyValue; +import com.evolveum.midpoint.prism.PrismReferenceValue; import com.evolveum.midpoint.prism.PrismValue; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.util.CloneUtil; @@ -138,7 +139,12 @@ public void normalize(PrismContext prismContext) { } public boolean hasValueChanged() { - return oldValue != null ? !oldValue.equals(value) : value != null; + if (value instanceof PrismPropertyValue) { + return oldValue != null ? !oldValue.equals(value) : value != null; + } else { + return oldValue != null ? !oldValue.equals(value) : value != null && !value.isEmpty(); + } + } public boolean isReadonly() { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/ConfigurationStep.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/ConfigurationStep.java index 277f904c02a..7c593aa3f15 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/ConfigurationStep.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/ConfigurationStep.java @@ -142,6 +142,7 @@ private List createConfigContainerWrappers() throws SchemaExce } else { container = containerDef.instantiate(); containerWrapper = cwf.createContainerWrapper(container, ContainerStatus.ADDING, containerPath, parentPage.isReadOnly()); + containerWrapper.setShowEmpty(true, true); } containerWrappers.add(containerWrapper); } From d2492d9c33f08d3313a798f8ad999f4765cb61f7 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Thu, 21 Sep 2017 17:30:49 +0200 Subject: [PATCH 34/97] Support for fragmented extension schemas (split into multiple files). --- .../prism/ComplexTypeDefinitionImpl.java | 12 +- .../schema/DomToSchemaPostProcessor.java | 9 +- .../prism/schema/DomToSchemaProcessor.java | 4 +- .../midpoint/prism/schema/SchemaRegistry.java | 2 +- .../prism/schema/SchemaRegistryImpl.java | 108 +++++++++++++----- .../prism/schema/XmlEntityResolverImpl.java | 18 +-- .../midpoint/prism/TestExtraSchema.java | 7 +- .../src/test/resources/schema/extension2.xsd | 41 +++++++ 8 files changed, 155 insertions(+), 46 deletions(-) create mode 100644 infra/schema/src/test/resources/schema/extension2.xsd diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/ComplexTypeDefinitionImpl.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ComplexTypeDefinitionImpl.java index 36a849aadea..60b99925f14 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/ComplexTypeDefinitionImpl.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/ComplexTypeDefinitionImpl.java @@ -24,6 +24,8 @@ import com.evolveum.midpoint.prism.path.ParentPathSegment; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.PrettyPrinter; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; import org.jetbrains.annotations.NotNull; import com.evolveum.midpoint.util.QNameUtil; @@ -39,6 +41,8 @@ */ public class ComplexTypeDefinitionImpl extends TypeDefinitionImpl implements ComplexTypeDefinition { + private static final Trace LOGGER = TraceManager.getTrace(ComplexTypeDefinitionImpl.class); + private static final long serialVersionUID = 2655797837209175037L; @NotNull private final List itemDefinitions = new ArrayList<>(); private boolean containerMarker; @@ -245,7 +249,13 @@ public ID findNamedItemDefinition(@NotNull QName fir @Override public void merge(ComplexTypeDefinition otherComplexTypeDef) { for (ItemDefinition otherItemDef: otherComplexTypeDef.getDefinitions()) { - add(otherItemDef.clone()); + ItemDefinition existingItemDef = findItemDefinition(otherItemDef.getName()); + if (existingItemDef != null) { + LOGGER.warn("Overwriting existing definition {} by {} (in {})", existingItemDef, otherItemDef, this); + replaceDefinition(otherItemDef.getName(), otherItemDef.clone()); + } else { + add(otherItemDef.clone()); + } } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/DomToSchemaPostProcessor.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/DomToSchemaPostProcessor.java index edae5272b7a..6237d62f917 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/DomToSchemaPostProcessor.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/DomToSchemaPostProcessor.java @@ -29,7 +29,6 @@ import org.jetbrains.annotations.NotNull; import org.w3c.dom.Element; import org.w3c.dom.NodeList; -import org.xml.sax.EntityResolver; import javax.xml.bind.annotation.XmlEnumValue; import javax.xml.namespace.QName; @@ -58,17 +57,14 @@ class DomToSchemaPostProcessor { private static final Trace LOGGER = TraceManager.getTrace(DomToSchemaPostProcessor.class); private final XSSchemaSet xsSchemaSet; - private final EntityResolver entityResolver; private final PrismContext prismContext; private PrismSchemaImpl schema; private String shortDescription; private boolean isRuntime; private boolean allowDelayedItemDefinitions; - DomToSchemaPostProcessor(XSSchemaSet xsSchemaSet, EntityResolver entityResolver, - PrismContext prismContext) { + DomToSchemaPostProcessor(XSSchemaSet xsSchemaSet, PrismContext prismContext) { this.xsSchemaSet = xsSchemaSet; - this.entityResolver = entityResolver; this.prismContext = prismContext; } @@ -126,6 +122,7 @@ private void processComplexTypeDefinitions(XSSchemaSet set) throws SchemaExcepti while (iterator.hasNext()) { XSComplexType complexType = iterator.next(); if (complexType.getTargetNamespace().equals(schema.getNamespace())) { + LOGGER.trace("### processing CTD {} into {} [{}]", complexType, schema, shortDescription); processComplexTypeDefinition(complexType); } } @@ -260,6 +257,7 @@ private void processSimpleTypeDefinitions(XSSchemaSet set) throws SchemaExceptio while (iterator.hasNext()) { XSSimpleType simpleType = iterator.next(); if (simpleType.getTargetNamespace().equals(schema.getNamespace())) { + LOGGER.trace("### processing STD {} into {} [{}]", simpleType, schema, shortDescription); processSimpleTypeDefinition(simpleType); } } @@ -532,6 +530,7 @@ private void createDefinitionsFromElements(XSSchemaSet set) throws SchemaExcepti if (xsElementDecl.getTargetNamespace().equals(schema.getNamespace())) { QName elementName = new QName(xsElementDecl.getTargetNamespace(), xsElementDecl.getName()); + LOGGER.trace("### processing item {} into {} [{}]", elementName, schema, shortDescription); XSType xsType = xsElementDecl.getType(); if (xsType == null) { throw new SchemaException("Found element " + elementName + " without type definition"); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/DomToSchemaProcessor.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/DomToSchemaProcessor.java index 84d50ff95c9..5559223a50f 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/DomToSchemaProcessor.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/DomToSchemaProcessor.java @@ -73,7 +73,7 @@ void parseSchema(@NotNull PrismSchemaImpl prismSchema, @NotNull Element xsdSchem if (xsSchemaSet == null) { return; } - DomToSchemaPostProcessor postProcessor = new DomToSchemaPostProcessor(xsSchemaSet, entityResolver, prismContext); + DomToSchemaPostProcessor postProcessor = new DomToSchemaPostProcessor(xsSchemaSet, prismContext); postProcessor.postprocessSchema(prismSchema, isRuntime, allowDelayedItemDefinitions, shortDescription); } @@ -89,7 +89,7 @@ void parseSchemas(List schemaDescriptions, Element wrapper, return; } for (SchemaDescription schemaDescription : schemaDescriptions) { - DomToSchemaPostProcessor postProcessor = new DomToSchemaPostProcessor(xsSchemaSet, entityResolver, prismContext); + DomToSchemaPostProcessor postProcessor = new DomToSchemaPostProcessor(xsSchemaSet, prismContext); PrismSchemaImpl prismSchema = (PrismSchemaImpl) schemaDescription.getSchema(); boolean isRuntime = schemaDescription.getCompileTimeClassesPackage() == null; String schemaShortDescription = schemaDescription.getSourceDescription() + " in " + shortDescription; diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistry.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistry.java index b05762732fc..d849dafdf77 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistry.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistry.java @@ -48,7 +48,7 @@ public interface SchemaRegistry extends DebugDumpable, GlobalDefinitionsStore { javax.xml.validation.Schema getJavaxSchema(); - PrismSchema getSchema(String namespace); + PrismSchema getPrismSchema(String namespace); Collection getSchemas(); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistryImpl.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistryImpl.java index 7bd13cbf200..892b5fd1ffe 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistryImpl.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistryImpl.java @@ -45,6 +45,8 @@ import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.prism.xml.ns._public.types_3.ObjectType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; +import org.apache.commons.collections4.MultiValuedMap; +import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.apache.commons.lang.StringUtils; import org.apache.xml.resolver.Catalog; import org.apache.xml.resolver.CatalogManager; @@ -90,7 +92,9 @@ public class SchemaRegistryImpl implements DebugDumpable, SchemaRegistry { private javax.xml.validation.Schema javaxSchema; private EntityResolver builtinSchemaResolver; final private List schemaDescriptions = new ArrayList<>(); - final private Map parsedSchemas = new HashMap<>(); + // namespace -> schemas; in case of extension schemas there could be more of them with the same namespace! + final private MultiValuedMap parsedSchemas = new ArrayListValuedHashMap<>(); + // base type name -> CTD with (merged) extension definition final private Map extensionSchemas = new HashMap<>(); private boolean initialized = false; private DynamicNamespacePrefixMapper namespacePrefixMapper; @@ -125,7 +129,7 @@ public XmlEntityResolver getEntityResolver() { return entityResolver; } - public Map getParsedSchemas() { + public MultiValuedMap getParsedSchemas() { return parsedSchemas; } @@ -359,17 +363,26 @@ public void initialize() throws SAXException, IOException, SchemaException { throw new IllegalStateException("Namespace prefix mapper not set"); } try { - LOGGER.trace("initialize() starting"); // TODO remove (all of these) + LOGGER.info("initialize() starting"); + long start = System.currentTimeMillis(); + initResolver(); - LOGGER.trace("initResolver() done"); + long resolverDone = System.currentTimeMillis(); + LOGGER.info("initResolver() done in {} ms", resolverDone - start); + parsePrismSchemas(); - LOGGER.trace("parsePrismSchemas() done"); + long prismSchemasDone = System.currentTimeMillis(); + LOGGER.info("parsePrismSchemas() done in {} ms", prismSchemasDone - resolverDone); + parseJavaxSchema(); - LOGGER.trace("parseJavaxSchema() done"); + long javaxSchemasDone = System.currentTimeMillis(); + LOGGER.info("parseJavaxSchema() done in {} ms", javaxSchemasDone - prismSchemasDone); + compileCompileTimeClassList(); - LOGGER.trace("compileCompileTimeClassList() done"); - initialized = true; + long classesDone = System.currentTimeMillis(); + LOGGER.info("compileCompileTimeClassList() done in {} ms", classesDone - javaxSchemasDone); + initialized = true; } catch (SAXException ex) { if (ex instanceof SAXParseException) { SAXParseException sex = (SAXParseException)ex; @@ -400,6 +413,16 @@ private void parsePrismSchemas() throws SchemaException { resolveMissingTypeDefinitionsInGlobalItemDefinitions((PrismSchemaImpl) schemaDescription.getSchema()); } } + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("====================================== Dumping prism schemas ======================================\n"); + for (SchemaDescription schemaDescription : schemaDescriptions) { + LOGGER.trace("************************************************************* {} (in {})", + schemaDescription.getNamespace(), schemaDescription.getPath()); + if (schemaDescription.getSchema() != null) { + LOGGER.trace("{}", schemaDescription.getSchema().debugDump()); + } + } + } } // global item definitions may refer to types that are not yet available @@ -443,35 +466,59 @@ private void parsePrismSchemas(List schemaDescriptions, boole Element schemaElement = DOMUtil.createElement(DOMUtil.XSD_SCHEMA_ELEMENT); schemaElement.setAttribute("targetNamespace", "http://dummy/"); schemaElement.setAttribute("elementFormDefault", "qualified"); + + // These fragmented namespaces should not be included in wrapper XSD because they are defined in multiple XSD files. + // We have to process them one by one. + MultiValuedMap schemasByNamespace = new ArrayListValuedHashMap<>(); + prismSchemaDescriptions.forEach(sd -> schemasByNamespace.put(sd.getNamespace(), sd)); + List fragmentedNamespaces = schemasByNamespace.keySet().stream() + .filter(ns -> schemasByNamespace.get(ns).size() > 1) + .collect(Collectors.toList()); + LOGGER.trace("Fragmented namespaces: {}", fragmentedNamespaces); + + List wrappedDescriptions = new ArrayList<>(); for (SchemaDescription description : prismSchemaDescriptions) { - Element importElement = DOMUtil.createSubElement(schemaElement, DOMUtil.XSD_IMPORT_ELEMENT); - importElement.setAttribute(DOMUtil.XSD_ATTR_NAMESPACE.getLocalPart(), description.getNamespace()); - PrismSchemaImpl schemaImpl = new PrismSchemaImpl(prismContext); - description.setSchema(schemaImpl); + String namespace = description.getNamespace(); + if (!fragmentedNamespaces.contains(namespace)) { + Element importElement = DOMUtil.createSubElement(schemaElement, DOMUtil.XSD_IMPORT_ELEMENT); + importElement.setAttribute(DOMUtil.XSD_ATTR_NAMESPACE.getLocalPart(), namespace); + description.setSchema(new PrismSchemaImpl(prismContext)); + wrappedDescriptions.add(description); + } + } + if (LOGGER.isTraceEnabled()) { + String xml = DOMUtil.serializeDOMToString(schemaElement); + LOGGER.trace("Wrapper XSD:\n{}", xml); } - //String xml = DOMUtil.serializeDOMToString(schemaElement); - //System.out.println("Wrapper XSD:\n" + xml); long started = System.currentTimeMillis(); - LOGGER.trace("Parsing {} schemas", prismSchemaDescriptions.size()); + LOGGER.trace("Parsing {} schemas wrapped in single XSD", wrappedDescriptions.size()); PrismSchemaImpl.parseSchemas(schemaElement, entityResolver, - prismSchemaDescriptions, allowDelayedItemDefinitions, getPrismContext()); + wrappedDescriptions, allowDelayedItemDefinitions, getPrismContext()); LOGGER.trace("Parsed {} schemas in {} ms", - prismSchemaDescriptions.size(), System.currentTimeMillis()-started); + wrappedDescriptions.size(), System.currentTimeMillis()-started); - for (SchemaDescription description : prismSchemaDescriptions) { + for (SchemaDescription description : wrappedDescriptions) { detectExtensionSchema(description.getSchema()); } + + for (String namespace : fragmentedNamespaces) { + Collection fragments = schemasByNamespace.get(namespace); + LOGGER.trace("Parsing {} schemas for fragmented namespace {}", fragments.size(), namespace); + for (SchemaDescription schemaDescription : fragments) { + parsePrismSchema(schemaDescription, allowDelayedItemDefinitions); + } + } } private void detectExtensionSchema(PrismSchema schema) throws SchemaException { for (ComplexTypeDefinition def: schema.getDefinitions(ComplexTypeDefinition.class)) { QName extType = def.getExtensionForType(); if (extType != null) { + LOGGER.trace("Processing {} as an extension for {}", def, extType); if (extensionSchemas.containsKey(extType)) { ComplexTypeDefinition existingExtension = extensionSchemas.get(extType); existingExtension.merge(def); -// throw new SchemaException("Duplicate definition of extension for type "+extType+": "+def+" and "+extensionSchemas.get(extType)); } else { extensionSchemas.put(extType, def.clone()); } @@ -1173,17 +1220,26 @@ private List resolveGlobalItemDefinitionsWithout //region Finding schemas @Override - public PrismSchema getSchema(String namespace) { - return parsedSchemas.get(namespace).getSchema(); + public PrismSchema getPrismSchema(String namespace) { + List schemas = parsedSchemas.get(namespace).stream() + .filter(s -> s.getSchema() != null) + .map(s -> s.getSchema()) + .collect(Collectors.toList()); + if (schemas.size() > 1) { + throw new IllegalStateException("More than one prism schema for namespace " + namespace); + } else if (schemas.size() == 1) { + return schemas.get(0); + } else { + return null; + } } @Override public Collection getSchemas() { - Collection schemas = new ArrayList(); - for (Entry entry: parsedSchemas.entrySet()) { - schemas.add(entry.getValue().getSchema()); - } - return schemas; + return parsedSchemas.values().stream() + .filter(s -> s.getSchema() != null) + .map(s -> s.getSchema()) + .collect(Collectors.toList()); } @Override diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/XmlEntityResolverImpl.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/XmlEntityResolverImpl.java index fd16d6bb10e..8de4688e81d 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/XmlEntityResolverImpl.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/XmlEntityResolverImpl.java @@ -25,6 +25,7 @@ import org.xml.sax.SAXException; import java.io.*; +import java.util.Collection; /** * @author semancik @@ -91,10 +92,10 @@ public LSInput resolveResource(String type, String namespaceURI, String publicId inputSource = resolveResourceUsingBuiltinResolver(type, namespaceURI, publicId, systemId, baseURI); } if (inputSource == null) { - LOGGER.error("Unable to resolve resource of type {}, namespaceURI: {}, publicID: {}, systemID: {}, baseURI: {}",new Object[]{type, namespaceURI, publicId, systemId, baseURI}); + LOGGER.error("Unable to resolve resource of type {}, namespaceURI: {}, publicID: {}, systemID: {}, baseURI: {}", type, namespaceURI, publicId, systemId, baseURI); return null; } - LOGGER.trace("==> Resolved resource of type {}, namespaceURI: {}, publicID: {}, systemID: {}, baseURI: {} : {}",new Object[]{type, namespaceURI, publicId, systemId, baseURI, inputSource}); + LOGGER.trace("==> Resolved resource of type {}, namespaceURI: {}, publicID: {}, systemID: {}, baseURI: {} : {}", type, namespaceURI, publicId, systemId, baseURI, inputSource); return new Input(publicId, systemId, inputSource.getByteStream()); } @@ -112,8 +113,9 @@ private InputSource resolveResourceFromRegisteredSchemas(String publicId, String private InputSource resolveResourceFromRegisteredSchemasByNamespace(String namespaceURI) { if (namespaceURI != null) { - if (schemaRegistry.getParsedSchemas().containsKey(namespaceURI)) { - SchemaDescription schemaDescription = schemaRegistry.getParsedSchemas().get(namespaceURI); + Collection schemaDescriptions = schemaRegistry.getParsedSchemas().get(namespaceURI); + if (schemaDescriptions.size() == 1) { + SchemaDescription schemaDescription = schemaDescriptions.iterator().next(); InputStream inputStream; if (schemaDescription.canInputStream()) { inputStream = schemaDescription.openInputStream(); @@ -130,6 +132,8 @@ private InputSource resolveResourceFromRegisteredSchemasByNamespace(String names source.setSystemId(namespaceURI); source.setPublicId(namespaceURI); return source; + } else { + return null; // none or ambiguous namespace } } return null; @@ -137,7 +141,7 @@ private InputSource resolveResourceFromRegisteredSchemasByNamespace(String names public InputSource resolveResourceUsingBuiltinResolver(String type, String namespaceURI, String publicId, String systemId, String baseURI) { - InputSource inputSource = null; + InputSource inputSource; try { // we first try to use traditional pair of publicId + systemId // the use of namespaceUri can be misleading in case of schema fragments: @@ -151,11 +155,11 @@ public InputSource resolveResourceUsingBuiltinResolver(String type, String names LOGGER.trace("...... Result of using builtin resolver by namespaceURI + systemId: {}", inputSource); } } catch (SAXException e) { - LOGGER.error("XML parser error resolving reference of type {}, namespaceURI: {}, publicID: {}, systemID: {}, baseURI: {}: {}",new Object[]{type, namespaceURI, publicId, systemId, baseURI, e.getMessage(), e}); + LOGGER.error("XML parser error resolving reference of type {}, namespaceURI: {}, publicID: {}, systemID: {}, baseURI: {}: {}", type, namespaceURI, publicId, systemId, baseURI, e.getMessage(), e); // TODO: better error handling return null; } catch (IOException e) { - LOGGER.error("IO error resolving reference of type {}, namespaceURI: {}, publicID: {}, systemID: {}, baseURI: {}: {}",new Object[]{type, namespaceURI, publicId, systemId, baseURI, e.getMessage(), e}); + LOGGER.error("IO error resolving reference of type {}, namespaceURI: {}, publicID: {}, systemID: {}, baseURI: {}: {}", type, namespaceURI, publicId, systemId, baseURI, e.getMessage(), e); // TODO: better error handling return null; } diff --git a/infra/prism/src/test/java/com/evolveum/midpoint/prism/TestExtraSchema.java b/infra/prism/src/test/java/com/evolveum/midpoint/prism/TestExtraSchema.java index df26a2134c6..da46857b6c2 100644 --- a/infra/prism/src/test/java/com/evolveum/midpoint/prism/TestExtraSchema.java +++ b/infra/prism/src/test/java/com/evolveum/midpoint/prism/TestExtraSchema.java @@ -41,7 +41,6 @@ import com.evolveum.midpoint.prism.foo.UserType; import com.evolveum.midpoint.prism.schema.PrismSchema; -import com.evolveum.midpoint.prism.schema.SchemaRegistry; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.PrettyPrinter; @@ -97,13 +96,13 @@ public void testUserExtensionSchemaLoad() throws SAXException, IOException, Sche System.out.println(reg.debugDump()); // Try midpoint schemas by parsing a XML file - PrismSchema schema = reg.getSchema(NS_FOO); + PrismSchema schema = reg.getPrismSchema(NS_FOO); System.out.println("Parsed foo schema:"); System.out.println(schema.debugDump()); // TODO: assert user - schema = reg.getSchema(NS_USER_EXT); + schema = reg.getPrismSchema(NS_USER_EXT); System.out.println("Parsed user ext schema:"); System.out.println(schema.debugDump()); @@ -223,7 +222,7 @@ public void testTypeOverride() throws SAXException, IOException, SchemaException reg.registerPrismSchemasFromDirectory(EXTRA_SCHEMA_DIR); context.initialize(); - PrismSchema schema = reg.getSchema(NS_ROOT); + PrismSchema schema = reg.getPrismSchema(NS_ROOT); System.out.println("Parsed root schema:"); System.out.println(schema.debugDump()); diff --git a/infra/schema/src/test/resources/schema/extension2.xsd b/infra/schema/src/test/resources/schema/extension2.xsd new file mode 100644 index 00000000000..b489a0d8013 --- /dev/null +++ b/infra/schema/src/test/resources/schema/extension2.xsd @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + From 4160b5c28e1d787418e1c3621b414b8a1846d72e Mon Sep 17 00:00:00 2001 From: "jan.melnik" Date: Fri, 22 Sep 2017 16:09:07 +0200 Subject: [PATCH 35/97] MID-4149 (Shopping cart footer overflow fix - IE supported) --- gui/admin-gui/src/main/webapp/less/midpoint-theme.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/admin-gui/src/main/webapp/less/midpoint-theme.less b/gui/admin-gui/src/main/webapp/less/midpoint-theme.less index 30619fe0b15..2ef46eafb86 100644 --- a/gui/admin-gui/src/main/webapp/less/midpoint-theme.less +++ b/gui/admin-gui/src/main/webapp/less/midpoint-theme.less @@ -1164,7 +1164,7 @@ dd.stacktrace::before { color: rgba(255, 255, 255, 0.8); display: block; z-index: 10; - overflow-y: overlay; + overflow-y: auto; background: rgba(0, 0, 0, 0.1); .shopping-cart-item-button-details { From cb296a0d865e9df75714ec9da7b541eac3f90249 Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Fri, 22 Sep 2017 16:15:50 +0200 Subject: [PATCH 36/97] prism form fixes - fixed create and modify --- .../prism/ContainerValueWrapper.java | 67 ++++++++++++++----- .../web/component/prism/ContainerWrapper.java | 25 ++++++- .../prism/ContainerWrapperFactory.java | 4 +- .../web/component/prism/ObjectWrapper.java | 58 +++------------- .../component/prism/ObjectWrapperFactory.java | 2 +- .../midpoint/prism/PrismContainerValue.java | 12 ++-- 6 files changed, 97 insertions(+), 71 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java index 15247ccd1ce..e37b81e8c79 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java @@ -19,6 +19,7 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -36,9 +37,11 @@ import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.Item; import com.evolveum.midpoint.prism.ItemDefinition; +import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismContainerDefinition; import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismReferenceDefinition; import com.evolveum.midpoint.prism.PrismValue; @@ -52,6 +55,7 @@ import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.TunnelException; import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; @@ -375,7 +379,7 @@ public String debugDump(int indent) { return sb.toString(); } - public PrismContainerValue createContainerValueAddDelta() { + public PrismContainerValue createContainerValueAddDelta() throws SchemaException{ if (!hasChanged()) { return null; } @@ -385,24 +389,57 @@ public PrismContainerValue createContainerValueAddDelta() { } PrismContainerValue newValue = containerValue.clone(); + try { + newValue.addAllReplaceExisting((Collection) getUpdatedContainerValueItems(containerValue.getPrismContext())); + } catch (TunnelException e) { + throw new SchemaException(); + } - getItems().forEach(item -> { - - if (item instanceof ContainerWrapper) { - return; - } - - PropertyOrReferenceWrapper propOrRef = (PropertyOrReferenceWrapper) item; - try { - newValue.add(createItem(propOrRef, propOrRef.getItemDefinition())); - } catch (SchemaException e) { - LoggingUtils.logException(LOGGER, "Could not add item " + propOrRef.getItem(), e); - } - - }); return newValue; } + public Collection getUpdatedContainerValueItems(PrismContext prismContext) throws SchemaException{ + Collection updatedItems = new ArrayList<>(); + getItems().stream().forEach(item -> { + try { + if (!item.hasChanged()) { + return; + } + + if (item instanceof ContainerWrapper) { + PrismContainer containerToAdd = ((ContainerWrapper) item).createContainerAddDelta(); + updatedItems.add(containerToAdd); + } else { + + PropertyOrReferenceWrapper propOrRef = (PropertyOrReferenceWrapper) item; + Item updatedItem = propOrRef.getUpdatedItem(prismContext); + + if (item.getPath().containsName(ObjectType.F_EXTENSION)) { + PrismContainer extensionContainer; + try { + extensionContainer = containerValue.findOrCreateContainer(ObjectType.F_EXTENSION); + } catch (SchemaException e) { + LoggingUtils.logException(LOGGER, "Could not handle extension deltas item " + item.getItem(), e); + return; + } + if (extensionContainer == null) { + return; + } + extensionContainer.getValue().addReplaceExisting(updatedItem); + updatedItems.add(extensionContainer.clone()); + } else { + updatedItems.add(updatedItem); + } + + } + } catch (SchemaException ex) { + throw new TunnelException("Cannot create add delta for container value: " + containerValue); + } + } + ); + return updatedItems; + } + public void collectModifications(ObjectDelta delta) throws SchemaException { // if (getItemDefinition().getName().equals(ShadowType.F_ASSOCIATION)) { // //create ContainerDelta for association container diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java index a43852910d2..39dcd9d7371 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java @@ -34,6 +34,7 @@ import com.evolveum.midpoint.prism.PrismContainerDefinition; import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismReferenceDefinition; import com.evolveum.midpoint.prism.PrismValue; @@ -433,7 +434,29 @@ public boolean isStripe() { public void setStripe(boolean isStripe) { // Does not make much sense, but it is given by the interface } - + + public PrismContainer createContainerAddDelta() throws SchemaException { + + PrismContainer containerAdd = container.clone(); + + for (ContainerValueWrapper itemWrapper : getValues()) { + if (!itemWrapper.hasChanged()) { + continue; + } + + if (itemWrapper.isMain()) { + containerAdd.setValue(itemWrapper.createContainerValueAddDelta()); + continue; + } + +// PrismContainer childContainer = containerAdd.findOrCreateContainer(itemWrapper.getContainerValue().getPath()); + containerAdd.add(itemWrapper.createContainerValueAddDelta()); + } + + return containerAdd; + } + + public void collectModifications(ObjectDelta delta) throws SchemaException { // if (getItemDefinition().getName().equals(ShadowType.F_ASSOCIATION)) { // //create ContainerDelta for association container diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java index b38211afaad..d99fe267495 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapperFactory.java @@ -160,11 +160,11 @@ public List createP propertyDefinitions.forEach(itemDef -> { if (itemDef.isIgnored() || skipProperty(itemDef)) { - LOGGER.info("Skipping creating wrapper for: {}", itemDef); + LOGGER.trace("Skipping creating wrapper for: {}", itemDef); return; } - LOGGER.info("Creating wrapper for {}", itemDef); + LOGGER.trace("Creating wrapper for {}", itemDef); createPropertyOrReferenceWrapper(itemDef, cWrapper, propertyOrReferenceWrappers, onlyEmpty, cWrapper.getPath()); createContainerWrapper(itemDef, cWrapper, containerWrappers, onlyEmpty); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java index 3d1a52f7247..fc553acd2ea 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java @@ -426,55 +426,19 @@ private ObjectDelta createAddingObjectDelta() throws SchemaException { for (ContainerWrapper containerWrapper : getContainers()) { -// if (containerWrapper.getItemDefinition().getName().equals(ShadowType.F_ASSOCIATION)) { -// PrismContainer associationContainer = object.findOrCreateContainer(ShadowType.F_ASSOCIATION); -// List associationItemWrappers = (List) containerWrapper.getItems(); -// for (AssociationWrapper associationItemWrapper : associationItemWrappers) { -// List assocValueWrappers = associationItemWrapper.getValues(); -// for (ValueWrapper assocValueWrapper : assocValueWrappers) { -// PrismContainerValue assocValue = (PrismContainerValue) assocValueWrapper.getValue(); -// associationContainer.add(assocValue.clone()); -// } -// } -// continue; -// } - - if (!containerWrapper.hasChanged()) { + if (!containerWrapper.hasChanged()) { continue; } - - PrismContainer container = containerWrapper.getItem(); - ItemPath path = containerWrapper.getPath(); - if (containerWrapper.getPath() != null) { - container = container.clone(); - if (path.size() > 1) { - ItemPath parentPath = path.allExceptLast(); - PrismContainer parent = object.findOrCreateContainer(parentPath); - parent.add(container); - } else { - PrismContainer existing = object.findContainer(container.getElementName()); - if (existing == null) { - object.add(container); - } else { - continue; - } - } - } else { - container = object; - } - -// for (ContainerValueWrapper itemWrapper : (List) containerWrapper.getValues()) { -// if (!itemWrapper.hasChanged()) { -// continue; -// } -// if (container.findItem(itemWrapper.getName()) != null) { -// continue; -// } -// Item updatedItem = ((PropertyOrReferenceWrapper) itemWrapper).getUpdatedItem(object.getPrismContext()); -// if (!updatedItem.isEmpty()) { -// container.add(updatedItem); -// } -// } + + PrismContainer containerToAdd = containerWrapper.createContainerAddDelta(); + if (containerWrapper.isMain()) { + object = (PrismObject) containerToAdd; + continue; + } + + object.getValue().addReplaceExisting(containerToAdd); + + } // cleanup empty containers diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java index 296c0472e69..56d63c6b3fe 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapperFactory.java @@ -111,7 +111,7 @@ public ObjectWrapper createObjectWrapper(String displa objectClassDefinitionForEditing = modelServiceLocator.getModelInteractionService().getEditObjectClassDefinition( (PrismObject) object, resource, authorizationPhase); if (objectClassDefinitionForEditing != null) { - object.findContainer(ShadowType.F_ATTRIBUTES).applyDefinition((PrismContainerDefinition) objectClassDefinitionForEditing.toResourceAttributeContainerDefinition());; + object.findOrCreateContainer(ShadowType.F_ATTRIBUTES).applyDefinition((PrismContainerDefinition) objectClassDefinitionForEditing.toResourceAttributeContainerDefinition());; } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java index 8293d9db067..7980445d5f2 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java @@ -466,13 +466,15 @@ public void addAll(Collection> itemsToAdd) throws SchemaExce public void addAllReplaceExisting(Collection> itemsToAdd) throws SchemaException { checkMutability(); // Check for conflicts, remove conflicting values +// itemsToAdd.forEach(itemToAdd -> addReplaceExisting(itemToAdd)); for (Item item : itemsToAdd) { - Item existingItem = findItem(item.getElementName(), Item.class); - if (existingItem != null && items != null) { - items.remove(existingItem); - } + addReplaceExisting(item); +// Item existingItem = findItem(item.getElementName(), Item.class); +// if (existingItem != null && items != null) { +// items.remove(existingItem); +// } } - addAll(itemsToAdd); +// addAll(itemsToAdd); } public void replace(Item oldItem, Item newItem) throws SchemaException { From aba7b6646756bd6d46941e5455eb927f315494b4 Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Fri, 22 Sep 2017 16:16:22 +0200 Subject: [PATCH 37/97] fixing assignment details panel query for abstractRole + resource assignments --- .../assignment/AbstractRoleAssignmentPanel.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java index 4e4c2fb7001..b1af8b1b35f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java @@ -57,6 +57,7 @@ import com.evolveum.midpoint.web.session.UserProfileStorage; import com.evolveum.midpoint.web.session.UserProfileStorage.TableId; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ConstructionType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; @@ -278,8 +279,15 @@ protected int getItemsPerPage() { } protected ObjectQuery createObjectQuery() { - return QueryBuilder.queryFor(AssignmentType.class, getParentPage().getPrismContext()).item(new ItemPath(AssignmentType.F_TARGET_REF)) - .ref(getRelation()) + return QueryBuilder.queryFor(AssignmentType.class, getParentPage().getPrismContext()) + .block() + .not() + .item(new ItemPath(AssignmentType.F_CONSTRUCTION, ConstructionType.F_RESOURCE_REF)) + .isNull() + .endBlock() + .or() + .item(new ItemPath(AssignmentType.F_TARGET_REF)) + .ref(getRelation()) .build(); }; From c17ccd9cd25124e394356a8fc127680306d57eca Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Fri, 22 Sep 2017 16:40:14 +0200 Subject: [PATCH 38/97] removing unused lines of code --- .../prism/ContainerValueWrapper.java | 915 +++++++------- .../web/component/prism/ContainerWrapper.java | 872 +++++-------- .../web/component/prism/ObjectWrapper.java | 1074 ++++++++--------- 3 files changed, 1246 insertions(+), 1615 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java index e37b81e8c79..efcfca03ec4 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java @@ -29,7 +29,6 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; import org.apache.commons.lang.math.NumberUtils; -import org.apache.cxf.annotations.Logging; import org.jetbrains.annotations.Nullable; import com.evolveum.midpoint.gui.api.page.PageBase; @@ -41,11 +40,9 @@ import com.evolveum.midpoint.prism.PrismContainerDefinition; import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismReferenceDefinition; import com.evolveum.midpoint.prism.PrismValue; -import com.evolveum.midpoint.prism.delta.ContainerDelta; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.ReferenceDelta; @@ -69,6 +66,7 @@ /** * @author lazyman + * @author katkav */ public class ContainerValueWrapper extends PrismWrapper implements Serializable, DebugDumpable { @@ -76,430 +74,371 @@ public class ContainerValueWrapper extends PrismWrapper private static final Trace LOGGER = TraceManager.getTrace(ContainerValueWrapper.class); -// private String displayName; - private ContainerWrapper containerWrapper; - private PrismContainerValue containerValue; - private ValueStatus status; + private ContainerWrapper containerWrapper; + private PrismContainerValue containerValue; + private ValueStatus status; + private ItemPath path; + private List properties; + private boolean readonly; - private ItemPath path; - private List properties; - - private boolean readonly; -// private boolean showInheritedObjectAttributes; - - -// private PrismContainerDefinition containerDefinition; - - - ContainerValueWrapper(ContainerWrapper containerWrapper, PrismContainerValue containerValue, ValueStatus status, ItemPath path) { - Validate.notNull(status, "Container status must not be null."); - Validate.notNull(containerValue.getParent().getDefinition(), "container definition must not be null."); - Validate.notNull(status, "Container status must not be null."); + ContainerValueWrapper(ContainerWrapper containerWrapper, PrismContainerValue containerValue, ValueStatus status, + ItemPath path) { + Validate.notNull(status, "Container status must not be null."); + Validate.notNull(containerValue.getParent().getDefinition(), "container definition must not be null."); + Validate.notNull(status, "Container status must not be null."); this.containerWrapper = containerWrapper; this.containerValue = containerValue; this.status = status; this.path = path; -// this.readonly = containerWrapper.isReadonly(); // [pm] this is quite questionable -// this.showInheritedObjectAttributes = containerWrapper.isShowInheritedObjectAttributes(); - - } ContainerValueWrapper(PrismContainerValue containerValue, ValueStatus status, ItemPath path, boolean readOnly) { this(null, containerValue, status, path); -// super(null, container); -// Validate.notNull(container, "container must not be null."); -// Validate.notNull(container.getParent().getDefinition(), "container definition must not be null."); -// Validate.notNull(status, "Container status must not be null."); -// -// this.containerValue = container; -// this.containerDefinition = container.getParent().getDefinition(); -// this.status = status; -// this.path = path; - this.readonly = readOnly; -// this.showInheritedObjectAttributes = showInheritedObjectAttributes; - } - + this.readonly = readOnly; + } + public PrismContainerDefinition getDefinition() { return containerValue.getParent().getDefinition(); } - public void revive(PrismContext prismContext) throws SchemaException { - if (containerValue != null) { - containerValue.revive(prismContext); - } - if (getDefinition() != null) { - getDefinition().revive(prismContext); - } - if (properties != null) { - for (ItemWrapper itemWrapper : properties) { - itemWrapper.revive(prismContext); - } - } - } - -// @Override -// public PrismContainerDefinition getItemDefinition() { -// if (containerDefinition != null) { -// return containerDefinition; -// } -// if (main) { -// return containerWrapper.getItemDefinition(); -// } else { -// return containerWrapper.getItemDefinition().findContainerDefinition(path); -// } -// } - - @Nullable + public void revive(PrismContext prismContext) throws SchemaException { + if (containerValue != null) { + containerValue.revive(prismContext); + } + if (getDefinition() != null) { + getDefinition().revive(prismContext); + } + if (properties != null) { + for (ItemWrapper itemWrapper : properties) { + itemWrapper.revive(prismContext); + } + } + } + + @Nullable ContainerWrapper getContainer() { - return containerWrapper; - } - - public ValueStatus getStatus() { - return status; - } - - public ItemPath getPath() { - return path; - } - - public PrismContainerValue getContainerValue() { - return containerValue; - } - - public List getItems() { - if (properties == null) { - properties = new ArrayList<>(); - } - return properties; - } - - - public void addEmptyProperties(List emptyProperties) { - emptyProperties.forEach(empty -> { - if (!properties.contains(empty)) properties.add(empty); - }); - } - - public void setProperties(List properties) { - this.properties = properties; - } - - public void computeStripes() { - if (properties == null) { - return; - } - int visibleProperties = 0; - - for (ItemWrapper item: properties) { -// if (item.isVisible(isShowEmpty())) { - visibleProperties++; -// } - if (visibleProperties % 2 == 0) { - item.setStripe(true); - } else { - item.setStripe(false); - } - } - } - -// public boolean isShowInheritedObjectAttributes() { -// return showInheritedObjectAttributes; -// } - - public boolean isMain() { - return path==null || path.isEmpty(); - } - - static String getDisplayNameFromItem(Item item) { - Validate.notNull(item, "Item must not be null."); - - String displayName = item.getDisplayName(); - if (StringUtils.isEmpty(displayName)) { - QName name = item.getElementName(); - if (name != null) { - displayName = name.getLocalPart(); - } else { - displayName = item.getDefinition().getTypeName().getLocalPart(); - } - } - - return displayName; - } - - public boolean hasChanged() { - for (ItemWrapper item : getItems()) { - if (item.hasChanged()) { - return true; - } - } - - return false; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("ContainerWrapper("); -// builder.append(getDisplayNameFromItem(containerValue)); - builder.append(" ("); - builder.append(status); - builder.append(") "); - builder.append(getItems() == null ? null : getItems().size()); - builder.append(" items)"); - return builder.toString(); - } - - /** - * This methods check if we want to show property in form (e.g. - * failedLogins, fetchResult, lastFailedLoginTimestamp must be invisible) - * - * @return - * @deprecated will be implemented through annotations in schema - */ - @Deprecated - private boolean skipProperty(PrismPropertyDefinition def) { - final List names = new ArrayList(); - names.add(PasswordType.F_FAILED_LOGINS); - names.add(PasswordType.F_LAST_FAILED_LOGIN); - names.add(PasswordType.F_LAST_SUCCESSFUL_LOGIN); - names.add(PasswordType.F_PREVIOUS_SUCCESSFUL_LOGIN); - names.add(ObjectType.F_FETCH_RESULT); - // activation - names.add(ActivationType.F_EFFECTIVE_STATUS); - names.add(ActivationType.F_VALIDITY_STATUS); - // user - names.add(UserType.F_RESULT); - // org and roles - names.add(OrgType.F_APPROVAL_PROCESS); - names.add(OrgType.F_APPROVER_EXPRESSION); - names.add(OrgType.F_AUTOMATICALLY_APPROVED); - names.add(OrgType.F_CONDITION); - - - for (QName name : names) { - if (name.equals(def.getName())) { - return true; - } - } - - return false; - } - - public boolean isReadonly() { - // readonly flag in container is an override. Do not get the value from definition - // otherwise it will be propagated to items and overrides the item definition. - return readonly; - } - - public void setReadonly(boolean readonly) { - this.readonly = readonly; - } + return containerWrapper; + } + + public ValueStatus getStatus() { + return status; + } + + public ItemPath getPath() { + return path; + } + + public PrismContainerValue getContainerValue() { + return containerValue; + } + + public List getItems() { + if (properties == null) { + properties = new ArrayList<>(); + } + return properties; + } + + public void addEmptyProperties(List emptyProperties) { + emptyProperties.forEach(empty -> { + if (!properties.contains(empty)) + properties.add(empty); + }); + } + + public void setProperties(List properties) { + this.properties = properties; + } + + public void computeStripes() { + if (properties == null) { + return; + } + int visibleProperties = 0; + + for (ItemWrapper item : properties) { + if (item.isVisible()) { + visibleProperties++; + } + if (visibleProperties % 2 == 0) { + item.setStripe(true); + } else { + item.setStripe(false); + } + } + } + + public boolean isMain() { + return path == null || path.isEmpty(); + } + + static String getDisplayNameFromItem(Item item) { + Validate.notNull(item, "Item must not be null."); + + String displayName = item.getDisplayName(); + if (StringUtils.isEmpty(displayName)) { + QName name = item.getElementName(); + if (name != null) { + displayName = name.getLocalPart(); + } else { + displayName = item.getDefinition().getTypeName().getLocalPart(); + } + } + + return displayName; + } + + public boolean hasChanged() { + for (ItemWrapper item : getItems()) { + if (item.hasChanged()) { + return true; + } + } + return false; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("ContainerWrapper("); + // builder.append(getDisplayNameFromItem(containerValue)); + builder.append(" ("); + builder.append(status); + builder.append(") "); + builder.append(getItems() == null ? null : getItems().size()); + builder.append(" items)"); + return builder.toString(); + } + + /** + * This methods check if we want to show property in form (e.g. + * failedLogins, fetchResult, lastFailedLoginTimestamp must be invisible) + * + * @return + * @deprecated will be implemented through annotations in schema + */ + @Deprecated + private boolean skipProperty(PrismPropertyDefinition def) { + final List names = new ArrayList(); + names.add(PasswordType.F_FAILED_LOGINS); + names.add(PasswordType.F_LAST_FAILED_LOGIN); + names.add(PasswordType.F_LAST_SUCCESSFUL_LOGIN); + names.add(PasswordType.F_PREVIOUS_SUCCESSFUL_LOGIN); + names.add(ObjectType.F_FETCH_RESULT); + // activation + names.add(ActivationType.F_EFFECTIVE_STATUS); + names.add(ActivationType.F_VALIDITY_STATUS); + // user + names.add(UserType.F_RESULT); + // org and roles + names.add(OrgType.F_APPROVAL_PROCESS); + names.add(OrgType.F_APPROVER_EXPRESSION); + names.add(OrgType.F_AUTOMATICALLY_APPROVED); + names.add(OrgType.F_CONDITION); + + for (QName name : names) { + if (name.equals(def.getName())) { + return true; + } + } + + return false; + } + + public boolean isReadonly() { + // readonly flag in container is an override. Do not get the value from + // definition + // otherwise it will be propagated to items and overrides the item + // definition. + return readonly; + } + + public void setReadonly(boolean readonly) { + this.readonly = readonly; + } public void sort(final PageBase pageBase) { - if (containerWrapper.isSorted()){ - Collections.sort(properties, new Comparator(){ - @Override - public int compare(ItemWrapper pw1, ItemWrapper pw2) { - ItemDefinition id1 = pw1.getItemDefinition(); - ItemDefinition id2 = pw2.getItemDefinition(); - String str1 =(id1 != null ? (id1.getDisplayName() != null ? - (pageBase.createStringResource(id1.getDisplayName()) != null && - StringUtils.isNotEmpty(pageBase.createStringResource(id1.getDisplayName()).getString()) ? - pageBase.createStringResource(id1.getDisplayName()).getString() : id1.getDisplayName()): - (id1.getName() != null && id1.getName().getLocalPart() != null ? id1.getName().getLocalPart() : "")) : ""); - String str2 =(id2 != null ? (id2.getDisplayName() != null ? - (pageBase.createStringResource(id2.getDisplayName()) != null && - StringUtils.isNotEmpty(pageBase.createStringResource(id2.getDisplayName()).getString()) ? - pageBase.createStringResource(id2.getDisplayName()).getString() : id2.getDisplayName()): - (id2.getName() != null && id2.getName().getLocalPart() != null ? id2.getName().getLocalPart() : "")) : ""); - return str1.compareToIgnoreCase(str2); - } - }); - } - else { - final int[] maxOrderArray = new int[3]; - Collections.sort(properties, new Comparator(){ - @Override - public int compare(ItemWrapper pw1, ItemWrapper pw2) { - ItemDefinition id1 = pw1.getItemDefinition(); - ItemDefinition id2 = pw2.getItemDefinition(); - - //we need to find out the value of the biggest displayOrder to put - //properties with null display order to the end of the list - int displayOrder1 = (id1 != null && id1.getDisplayOrder() != null) ? id1.getDisplayOrder() : 0; - int displayOrder2 = (id2 != null && id2.getDisplayOrder() != null) ? id2.getDisplayOrder() : 0; - if (maxOrderArray[0] == 0){ - maxOrderArray[0] = displayOrder1 > displayOrder2 ? displayOrder1 + 1 : displayOrder2 + 1; - } - maxOrderArray[1] = displayOrder1; - maxOrderArray[2] = displayOrder2; - - int maxDisplayOrder = NumberUtils.max(maxOrderArray); - maxOrderArray[0] = maxDisplayOrder + 1; - - return Integer.compare(id1 != null && id1.getDisplayOrder() != null ? id1.getDisplayOrder() : maxDisplayOrder, - id2 != null && id2.getDisplayOrder() != null ? id2.getDisplayOrder() : maxDisplayOrder); - } - }); - } - } - - @Override - public String debugDump() { - return debugDump(0); - } - - @Override - public String debugDump(int indent) { - StringBuilder sb = new StringBuilder(); - DebugUtil.indentDebugDump(sb, indent); - sb.append("ContainervalueWrapper: ");//.append(PrettyPrinter.prettyPrint(getName())).append("\n"); - DebugUtil.debugDumpWithLabel(sb, "displayName", getDisplayName(), indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "status", status == null ? null : status.toString(), indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "main", isMain(), indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "readonly", readonly, indent + 1); - sb.append("\n"); -// DebugUtil.debugDumpWithLabel(sb, "showInheritedObjectAttributes", showInheritedObjectAttributes, indent + 1); -// sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "path", path == null ? null : path.toString(), indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "containerDefinition", getDefinition() == null ? null : getDefinition().toString(), indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "container", containerValue == null ? null : containerValue.toString(), indent + 1); - sb.append("\n"); - DebugUtil.debugDumpLabel(sb, "properties", indent + 1); - sb.append("\n"); - DebugUtil.debugDump(sb, properties, indent + 2, false); - return sb.toString(); - } - - public PrismContainerValue createContainerValueAddDelta() throws SchemaException{ - if (!hasChanged()) { - return null; - } - - if (getStatus() != ValueStatus.ADDED) { - return null; - } - - PrismContainerValue newValue = containerValue.clone(); - try { + if (containerWrapper.isSorted()) { + Collections.sort(properties, new Comparator() { + @Override + public int compare(ItemWrapper pw1, ItemWrapper pw2) { + ItemDefinition id1 = pw1.getItemDefinition(); + ItemDefinition id2 = pw2.getItemDefinition(); + String str1 = (id1 != null ? (id1.getDisplayName() != null + ? (pageBase.createStringResource(id1.getDisplayName()) != null + && StringUtils.isNotEmpty(pageBase.createStringResource(id1.getDisplayName()).getString()) + ? pageBase.createStringResource(id1.getDisplayName()).getString() + : id1.getDisplayName()) + : (id1.getName() != null && id1.getName().getLocalPart() != null ? id1.getName().getLocalPart() : "")) + : ""); + String str2 = (id2 != null ? (id2.getDisplayName() != null + ? (pageBase.createStringResource(id2.getDisplayName()) != null + && StringUtils.isNotEmpty(pageBase.createStringResource(id2.getDisplayName()).getString()) + ? pageBase.createStringResource(id2.getDisplayName()).getString() + : id2.getDisplayName()) + : (id2.getName() != null && id2.getName().getLocalPart() != null ? id2.getName().getLocalPart() : "")) + : ""); + return str1.compareToIgnoreCase(str2); + } + }); + } else { + final int[] maxOrderArray = new int[3]; + Collections.sort(properties, new Comparator() { + @Override + public int compare(ItemWrapper pw1, ItemWrapper pw2) { + ItemDefinition id1 = pw1.getItemDefinition(); + ItemDefinition id2 = pw2.getItemDefinition(); + + // we need to find out the value of the biggest displayOrder + // to put + // properties with null display order to the end of the list + int displayOrder1 = (id1 != null && id1.getDisplayOrder() != null) ? id1.getDisplayOrder() : 0; + int displayOrder2 = (id2 != null && id2.getDisplayOrder() != null) ? id2.getDisplayOrder() : 0; + if (maxOrderArray[0] == 0) { + maxOrderArray[0] = displayOrder1 > displayOrder2 ? displayOrder1 + 1 : displayOrder2 + 1; + } + maxOrderArray[1] = displayOrder1; + maxOrderArray[2] = displayOrder2; + + int maxDisplayOrder = NumberUtils.max(maxOrderArray); + maxOrderArray[0] = maxDisplayOrder + 1; + + return Integer.compare(id1 != null && id1.getDisplayOrder() != null ? id1.getDisplayOrder() : maxDisplayOrder, + id2 != null && id2.getDisplayOrder() != null ? id2.getDisplayOrder() : maxDisplayOrder); + } + }); + } + } + + @Override + public String debugDump() { + return debugDump(0); + } + + @Override + public String debugDump(int indent) { + StringBuilder sb = new StringBuilder(); + DebugUtil.indentDebugDump(sb, indent); + sb.append("ContainervalueWrapper: ");// .append(PrettyPrinter.prettyPrint(getName())).append("\n"); + DebugUtil.debugDumpWithLabel(sb, "displayName", getDisplayName(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "status", status == null ? null : status.toString(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "main", isMain(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "readonly", readonly, indent + 1); + sb.append("\n"); + // DebugUtil.debugDumpWithLabel(sb, "showInheritedObjectAttributes", + // showInheritedObjectAttributes, indent + 1); + // sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "path", path == null ? null : path.toString(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "containerDefinition", getDefinition() == null ? null : getDefinition().toString(), + indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "container", containerValue == null ? null : containerValue.toString(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpLabel(sb, "properties", indent + 1); + sb.append("\n"); + DebugUtil.debugDump(sb, properties, indent + 2, false); + return sb.toString(); + } + + public PrismContainerValue createContainerValueAddDelta() throws SchemaException { + if (!hasChanged()) { + return null; + } + + if (getStatus() != ValueStatus.ADDED) { + return null; + } + + PrismContainerValue newValue = containerValue.clone(); + try { newValue.addAllReplaceExisting((Collection) getUpdatedContainerValueItems(containerValue.getPrismContext())); } catch (TunnelException e) { throw new SchemaException(); } - - return newValue; - } - public Collection getUpdatedContainerValueItems(PrismContext prismContext) throws SchemaException{ - Collection updatedItems = new ArrayList<>(); + return newValue; + } + + public Collection getUpdatedContainerValueItems(PrismContext prismContext) throws SchemaException { + Collection updatedItems = new ArrayList<>(); getItems().stream().forEach(item -> { try { - if (!item.hasChanged()) { - return; - } + if (!item.hasChanged()) { + return; + } - if (item instanceof ContainerWrapper) { - PrismContainer containerToAdd = ((ContainerWrapper) item).createContainerAddDelta(); - updatedItems.add(containerToAdd); - } else { + if (item instanceof ContainerWrapper) { + PrismContainer containerToAdd = ((ContainerWrapper) item).createContainerAddDelta(); + updatedItems.add(containerToAdd); + } else { - PropertyOrReferenceWrapper propOrRef = (PropertyOrReferenceWrapper) item; - Item updatedItem = propOrRef.getUpdatedItem(prismContext); + PropertyOrReferenceWrapper propOrRef = (PropertyOrReferenceWrapper) item; + Item updatedItem = propOrRef.getUpdatedItem(prismContext); - if (item.getPath().containsName(ObjectType.F_EXTENSION)) { - PrismContainer extensionContainer; - try { - extensionContainer = containerValue.findOrCreateContainer(ObjectType.F_EXTENSION); - } catch (SchemaException e) { - LoggingUtils.logException(LOGGER, "Could not handle extension deltas item " + item.getItem(), e); - return; - } - if (extensionContainer == null) { - return; + if (item.getPath().containsName(ObjectType.F_EXTENSION)) { + PrismContainer extensionContainer; + try { + extensionContainer = containerValue.findOrCreateContainer(ObjectType.F_EXTENSION); + } catch (SchemaException e) { + LoggingUtils.logException(LOGGER, "Could not handle extension deltas item " + item.getItem(), e); + return; + } + if (extensionContainer == null) { + return; + } + extensionContainer.getValue().addReplaceExisting(updatedItem); + updatedItems.add(extensionContainer.clone()); + } else { + updatedItems.add(updatedItem); } - extensionContainer.getValue().addReplaceExisting(updatedItem); - updatedItems.add(extensionContainer.clone()); - } else { - updatedItems.add(updatedItem); - } - } + } } catch (SchemaException ex) { throw new TunnelException("Cannot create add delta for container value: " + containerValue); } - } - ); - return updatedItems; - } - + }); + return updatedItems; + } + public void collectModifications(ObjectDelta delta) throws SchemaException { -// if (getItemDefinition().getName().equals(ShadowType.F_ASSOCIATION)) { -// //create ContainerDelta for association container -// //HACK HACK HACK create correct procession for association container data -// //according to its structure -// ContainerDelta associationDelta = -// ContainerDelta.createDelta(ShadowType.F_ASSOCIATION, -// (PrismContainerDefinition) getItemDefinition()); -// for (ItemWrapper itemWrapper : getItems()) { -// AssociationWrapper associationItemWrapper = (AssociationWrapper) itemWrapper; -// List assocValueWrappers = associationItemWrapper.getValues(); -// for (ValueWrapper assocValueWrapper : assocValueWrappers) { -// PrismContainerValue assocValue = (PrismContainerValue) assocValueWrapper.getValue(); -// if (!assocValue.isEmpty()) { -// if (assocValueWrapper.getStatus() == ValueStatus.DELETED) { -// associationDelta.addValueToDelete(assocValue.clone()); -// } else if (assocValueWrapper.getStatus().equals(ValueStatus.ADDED)) { -// associationDelta.addValueToAdd(assocValue.clone()); -// } -// } -// } -// } -// if (!associationDelta.isEmpty()) { -// delta.addModification(associationDelta); -// } -// } else { - if (!hasChanged()) { - return; + if (!hasChanged()) { + return; + } + + for (ItemWrapper itemWrapper : getItems()) { + if (!itemWrapper.hasChanged()) { + continue; } - - - for (ItemWrapper itemWrapper : getItems()) { - if (!itemWrapper.hasChanged()) { - continue; - } - ItemPath containerPath = getPath() != null ? getPath() : ItemPath.EMPTY_PATH; - if (itemWrapper instanceof PropertyWrapper) { - ItemDelta pDelta = computePropertyDeltas((PropertyWrapper) itemWrapper, containerPath); - if (!pDelta.isEmpty()) { - //HACK to remove a password replace delta is to be created - if (getContainer().getName().equals(CredentialsType.F_PASSWORD)) { - if (pDelta.getValuesToDelete() != null){ - pDelta.resetValuesToDelete(); - pDelta.setValuesToReplace(new ArrayList()); - } + ItemPath containerPath = getPath() != null ? getPath() : ItemPath.EMPTY_PATH; + if (itemWrapper instanceof PropertyWrapper) { + ItemDelta pDelta = computePropertyDeltas((PropertyWrapper) itemWrapper, containerPath); + if (!pDelta.isEmpty()) { + // HACK to remove a password replace delta is to be created + if (getContainer().getName().equals(CredentialsType.F_PASSWORD)) { + if (pDelta.getValuesToDelete() != null) { + pDelta.resetValuesToDelete(); + pDelta.setValuesToReplace(new ArrayList()); } - delta.addModification(pDelta); - } - } else if (itemWrapper instanceof ReferenceWrapper) { - ReferenceDelta pDelta = computeReferenceDeltas((ReferenceWrapper) itemWrapper, containerPath); - if (!pDelta.isEmpty()) { - delta.addModification(pDelta); } - } else if (itemWrapper instanceof ContainerWrapper) { - ((ContainerWrapper) itemWrapper).collectModifications(delta); - } else { - LOGGER.trace("Delta from wrapper: ignoring {}", itemWrapper); + delta.addModification(pDelta); } + } else if (itemWrapper instanceof ReferenceWrapper) { + ReferenceDelta pDelta = computeReferenceDeltas((ReferenceWrapper) itemWrapper, containerPath); + if (!pDelta.isEmpty()) { + delta.addModification(pDelta); + } + } else if (itemWrapper instanceof ContainerWrapper) { + ((ContainerWrapper) itemWrapper).collectModifications(delta); + } else { + LOGGER.trace("Delta from wrapper: ignoring {}", itemWrapper); } -// } + } } private ItemDelta computePropertyDeltas(PropertyWrapper propertyWrapper, ItemPath containerPath) { @@ -522,10 +461,10 @@ private void addItemDelta(PropertyOrReferenceWrapper itemWrapper, ItemDelta pDel for (Object vWrapper : itemWrapper.getValues()) { if (!(vWrapper instanceof ValueWrapper)) { continue; - } - + } + ValueWrapper valueWrapper = (ValueWrapper) vWrapper; - + valueWrapper.normalize(propertyDef.getPrismContext()); ValueStatus valueStatus = valueWrapper.getStatus(); if (!valueWrapper.hasValueChanged() @@ -533,24 +472,6 @@ private void addItemDelta(PropertyOrReferenceWrapper itemWrapper, ItemDelta pDel continue; } - // TODO: need to check if the resource has defined - // capabilities - // todo this is bad hack because now we have not tri-state - // checkbox -// if (SchemaConstants.PATH_ACTIVATION.equivalent(containerPath) && getContainer().getObject() != null) { -// -// PrismObject object = getContainer().getObject().getObject(); -// if (object.asObjectable() instanceof ShadowType -// && (((ShadowType) object.asObjectable()).getActivation() == null || ((ShadowType) object -// .asObjectable()).getActivation().getAdministrativeStatus() == null)) { -// -// if (!getContainer().getObject().hasResourceCapability(((ShadowType) object.asObjectable()).getResource(), -// ActivationCapabilityType.class)) { -// continue; -// } -// } -// } - PrismValue newValCloned = ObjectWrapper.clone(valueWrapper.getValue()); PrismValue oldValCloned = ObjectWrapper.clone(valueWrapper.getOldValue()); switch (valueWrapper.getStatus()) { @@ -560,7 +481,8 @@ private void addItemDelta(PropertyOrReferenceWrapper itemWrapper, ItemDelta pDel // password change will always look like add, // therefore we push replace if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Delta from wrapper: {} (password) ADD -> replace {}", pDelta.getPath(), newValCloned); + LOGGER.trace("Delta from wrapper: {} (password) ADD -> replace {}", pDelta.getPath(), + newValCloned); } pDelta.setValuesToReplace(Arrays.asList(newValCloned)); } else if (propertyDef.isSingleValue()) { @@ -570,7 +492,8 @@ private void addItemDelta(PropertyOrReferenceWrapper itemWrapper, ItemDelta pDel // summarizing deltas for // unreachable resources if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Delta from wrapper: {} (single,new) ADD -> replace {}", pDelta.getPath(), newValCloned); + LOGGER.trace("Delta from wrapper: {} (single,new) ADD -> replace {}", pDelta.getPath(), + newValCloned); } pDelta.setValueToReplace(newValCloned); } else { @@ -601,13 +524,15 @@ private void addItemDelta(PropertyOrReferenceWrapper itemWrapper, ItemDelta pDel // newValCloned.isEmpty() if (newValCloned != null && !newValCloned.isEmpty()) { if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Delta from wrapper: {} (single,new) NOT_CHANGED -> replace {}", pDelta.getPath(), newValCloned); + LOGGER.trace("Delta from wrapper: {} (single,new) NOT_CHANGED -> replace {}", pDelta.getPath(), + newValCloned); } pDelta.setValuesToReplace(Arrays.asList(newValCloned)); } else { if (oldValCloned != null) { if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Delta from wrapper: {} (single,old) NOT_CHANGED -> delete {}", pDelta.getPath(), oldValCloned); + LOGGER.trace("Delta from wrapper: {} (single,old) NOT_CHANGED -> delete {}", pDelta.getPath(), + oldValCloned); } pDelta.addValueToDelete(oldValCloned); } @@ -615,13 +540,15 @@ private void addItemDelta(PropertyOrReferenceWrapper itemWrapper, ItemDelta pDel } else { if (newValCloned != null && !newValCloned.isEmpty()) { if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Delta from wrapper: {} (multi,new) NOT_CHANGED -> add {}", pDelta.getPath(), newValCloned); + LOGGER.trace("Delta from wrapper: {} (multi,new) NOT_CHANGED -> add {}", pDelta.getPath(), + newValCloned); } pDelta.addValueToAdd(newValCloned); } if (oldValCloned != null) { if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Delta from wrapper: {} (multi,old) NOT_CHANGED -> delete {}", pDelta.getPath(), oldValCloned); + LOGGER.trace("Delta from wrapper: {} (multi,old) NOT_CHANGED -> delete {}", pDelta.getPath(), + oldValCloned); } pDelta.addValueToDelete(oldValCloned); } @@ -630,27 +557,27 @@ private void addItemDelta(PropertyOrReferenceWrapper itemWrapper, ItemDelta pDel } } } - + private Item createItem(PropertyOrReferenceWrapper itemWrapper, ItemDefinition propertyDef) { List prismValues = new ArrayList<>(); for (Object vWrapper : itemWrapper.getValues()) { if (!(vWrapper instanceof ValueWrapper)) { continue; - } - + } + ValueWrapper valueWrapper = (ValueWrapper) vWrapper; - + valueWrapper.normalize(propertyDef.getPrismContext()); ValueStatus valueStatus = valueWrapper.getStatus(); if (!valueWrapper.hasValueChanged() && (ValueStatus.NOT_CHANGED.equals(valueStatus) || ValueStatus.ADDED.equals(valueStatus))) { continue; } - + prismValues.add(valueWrapper.getValue().clone()); - + } - + Item item = itemWrapper.getItem().clone(); try { item.addAll(prismValues); @@ -659,36 +586,36 @@ private Item createItem(PropertyOrReferenceWrapper itemWrapper, ItemDefinition p return null; } return item; - + } - - //TODO: unify with other isVisibleMethods + + // TODO: unify with other isVisibleMethods public boolean isVisible() { PrismContainerDefinition def = getDefinition(); - + if (def.isIgnored() || (def.isOperational() && !def.getTypeName().equals(MetadataType.COMPLEX_TYPE))) { return false; } - + if (def.getTypeName().equals(MetadataType.COMPLEX_TYPE)) { return isShowMetadata(); } - - //TODO: emphasized + + // TODO: emphasized switch (status) { - case NOT_CHANGED : - return isNotEmptyAndCanReadAndModify(def) || showEmptyCanReadAndModify(def); - case ADDED : + case NOT_CHANGED: + return isNotEmptyAndCanReadAndModify(def) || showEmptyCanReadAndModify(def); + case ADDED: return emphasizedAndCanAdd(def) || showEmptyAndCanAdd(def); } - + return false; } - + private boolean isNotEmptyAndCanReadAndModify(PrismContainerDefinition def) { return def.canRead() && def.canModify(); } - + private boolean showEmptyCanReadAndModify(PrismContainerDefinition def) { return def.canRead() && def.canModify() && isShowEmpty(); } @@ -696,21 +623,20 @@ private boolean showEmptyCanReadAndModify(PrismContainerDefinition def) { private boolean showEmptyAndCanAdd(PrismContainerDefinition def) { return def.canAdd(); } - + private boolean emphasizedAndCanAdd(PrismContainerDefinition def) { return def.canAdd() && def.isEmphasized(); } - - + @Override public void setShowEmpty(boolean showEmpty, boolean recursive) { super.setShowEmpty(showEmpty, recursive); - getItems().forEach(item -> { - item.setShowEmpty(showEmpty, recursive); - }); - + getItems().forEach(item -> { + item.setShowEmpty(showEmpty, recursive); + }); + } - + @Override public void setShowMetadata(boolean showMetadata) { super.setShowMetadata(showMetadata); @@ -721,10 +647,9 @@ public void setShowMetadata(boolean showMetadata) { }); } - -// @Override + // @Override public boolean checkRequired(PageBase pageBase) { - boolean rv = true; + boolean rv = true; for (ItemWrapper itemWrapper : getItems()) { if (!itemWrapper.checkRequired(pageBase)) { rv = false; @@ -732,71 +657,61 @@ public boolean checkRequired(PageBase pageBase) { } return rv; } - - public PropertyOrReferenceWrapper findPropertyWrapper(QName name) { - Validate.notNull(name, "QName must not be null."); - for (ItemWrapper wrapper : getItems()) { - if (wrapper instanceof ContainerWrapper) { - continue; - } - if (QNameUtil.match(name, wrapper.getItem().getElementName())) { - return (PropertyOrReferenceWrapper) wrapper; - } - } - return null; - } - + + public PropertyOrReferenceWrapper findPropertyWrapper(QName name) { + Validate.notNull(name, "QName must not be null."); + for (ItemWrapper wrapper : getItems()) { + if (wrapper instanceof ContainerWrapper) { + continue; + } + if (QNameUtil.match(name, wrapper.getItem().getElementName())) { + return (PropertyOrReferenceWrapper) wrapper; + } + } + return null; + } + public ContainerWrapper findContainerWrapper(ItemPath path) { - Validate.notNull(path, "QName must not be null."); - for (ItemWrapper wrapper : getItems()) { - if (!(wrapper instanceof ContainerWrapper)) { - continue; - } - ContainerWrapper containerWrapper = (ContainerWrapper) wrapper; - if (containerWrapper.getPath().equivalent(path)) { - return containerWrapper; - } - -// return ((ContainerWrapper)wrapper).findContainerWrapper(path); - - } - return null; - } - + Validate.notNull(path, "QName must not be null."); + for (ItemWrapper wrapper : getItems()) { + if (!(wrapper instanceof ContainerWrapper)) { + continue; + } + ContainerWrapper containerWrapper = (ContainerWrapper) wrapper; + if (containerWrapper.getPath().equivalent(path)) { + return containerWrapper; + } + } + return null; + } + public ContainerValueWrapper findContainerValueWrapper(ItemPath path) { - Validate.notNull(path, "QName must not be null."); - for (ItemWrapper wrapper : getItems()) { - if (!(wrapper instanceof ContainerValueWrapper)) { - continue; - } - return ((ContainerValueWrapper)wrapper).findContainerValueWrapper(path); - - } - return null; - } - + Validate.notNull(path, "QName must not be null."); + for (ItemWrapper wrapper : getItems()) { + if (!(wrapper instanceof ContainerValueWrapper)) { + continue; + } + return ((ContainerValueWrapper) wrapper).findContainerValueWrapper(path); + + } + return null; + } + public String getDisplayName() { - if (getContainer().isMain()){ + if (getContainer().isMain()) { return "prismContainer.mainPanelDisplayName"; } - + if (getDefinition() == null) { return WebComponentUtil.getDisplayName(containerValue); } - + if (getDefinition().isSingleValue()) { - + return ContainerWrapper.getDisplayNameFromItem(getContainerValue().getContainer()); - } + } return WebComponentUtil.getDisplayName(containerValue); - -// return containerValue.toHumanReadableString(); - } -// -// @Override -// public boolean isEnforceRequiredFields() { -// return containerWrapper != null && containerWrapper.isEnforceRequiredFields(); -// } + } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java index 39dcd9d7371..4bcc8cac1ea 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java @@ -18,7 +18,6 @@ import java.io.Serializable; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import javax.xml.namespace.QName; @@ -29,20 +28,13 @@ import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.Item; -import com.evolveum.midpoint.prism.ItemDefinition; import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismContainerDefinition; import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismReferenceDefinition; -import com.evolveum.midpoint.prism.PrismValue; -import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; -import com.evolveum.midpoint.prism.delta.ReferenceDelta; import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.PrettyPrinter; @@ -60,23 +52,22 @@ * @author lazyman * @author katkav */ -public class ContainerWrapper extends PrismWrapper implements ItemWrapper, PrismContainerDefinition, ContainerValueWrapper>, Serializable, DebugDumpable { +public class ContainerWrapper extends PrismWrapper implements + ItemWrapper, PrismContainerDefinition, ContainerValueWrapper>, Serializable, DebugDumpable { private static final long serialVersionUID = 1L; private static final Trace LOGGER = TraceManager.getTrace(ContainerWrapper.class); private String displayName; - private PrismContainer container; - private ContainerStatus status; + private PrismContainer container; + private ContainerStatus status; - private ItemPath path; - private List> values; + private ItemPath path; + private List> values; + + private boolean readonly; - private boolean readonly; -// private boolean showInheritedObjectAttributes; - - ContainerWrapper(PrismContainer container, ContainerStatus status, ItemPath path) { Validate.notNull(container, "container must not be null."); Validate.notNull(status, "Container status must not be null."); @@ -85,344 +76,267 @@ public class ContainerWrapper extends PrismWrapper impl this.container = container; this.status = status; this.path = path; - + } ContainerWrapper(PrismContainer container, ContainerStatus status, ItemPath path, boolean readOnly) { - this(container, status, path); + this(container, status, path); this.readonly = readOnly; - -// this.showInheritedObjectAttributes = showInheritedObjectAttributes; - } - - public void revive(PrismContext prismContext) throws SchemaException { - if (container != null) { - container.revive(prismContext); - } - if (getItemDefinition() != null) { - getItemDefinition().revive(prismContext); - } - if (values != null) { - for (ContainerValueWrapper itemWrapper : values) { - itemWrapper.revive(prismContext); - } - } - } - - @Override - public PrismContainerDefinition getItemDefinition() { - return container.getDefinition(); - } - - public ContainerStatus getStatus() { - return status; - } - - public ItemPath getPath() { - return path; - } - - @Override - public PrismContainer getItem() { - return container; - } - - - @Override - public List> getValues() { - if (values == null) { - values = new ArrayList<>(); - } - return values; - - } - - public void setProperties(List> properties) { - this.values = properties; - } - - public PropertyOrReferenceWrapper findPropertyWrapper(QName name) { - Validate.notNull(name, "QName must not be null."); - for (ContainerValueWrapper wrapper : getValues()) { - PropertyOrReferenceWrapper propertyWrapper = wrapper.findPropertyWrapper(name); - if (propertyWrapper != null) { - return propertyWrapper; - } - } - return null; - } - - public ContainerWrapper findContainerWrapper(ItemPath path) { - Validate.notNull(path, "QName must not be null."); - for (ContainerValueWrapper wrapper : getValues()) { - ContainerWrapper containerWrapper = wrapper.findContainerWrapper(path); - if (containerWrapper != null) { - return containerWrapper; - } - } - return null; - } - - public ContainerValueWrapper findContainerValueWrapper(ItemPath path) { - Validate.notNull(path, "QName must not be null."); - for (ContainerValueWrapper wrapper : getValues()) { - - if (path.equivalent(wrapper.getPath())) { - return wrapper; - } - - ContainerValueWrapper containerWrapper = wrapper.findContainerValueWrapper(path); - if (containerWrapper != null) { - return containerWrapper; - } - } - return null; - } - - public void computeStripes() { - int visibleProperties = 0; - for (ContainerValueWrapper item: values) { - item.computeStripes(); -// if (item.isVisible()) { -// visibleProperties++; -// } -// if (visibleProperties % 2 == 0) { -// item.setStripe(true); -// } else { -// item.setStripe(false); -// } - } - } - -// public boolean isShowInheritedObjectAttributes() { -// return showInheritedObjectAttributes; -// } - - @Override - public String getDisplayName() { - if (StringUtils.isNotEmpty(displayName)) { - return displayName; - } - return getDisplayNameFromItem(container); - } - - @Override - public void setDisplayName(String name) { - this.displayName = name; - } - - @Override - public QName getName() { - return getItem().getElementName(); - } - - public boolean isMain() { - return path == null || path.isEmpty(); - } - - - static String getDisplayNameFromItem(Item item) { - Validate.notNull(item, "Item must not be null."); - - String displayName = item.getDisplayName(); - if (StringUtils.isEmpty(displayName)) { - QName name = item.getElementName(); - if (name != null) { - displayName = name.getLocalPart(); - } else { - displayName = item.getDefinition().getTypeName().getLocalPart(); - } - } - - return displayName; - } - - public boolean hasChanged() { - for (ContainerValueWrapper item : getValues()) { - if (item.hasChanged()) { - return true; - } - } - - return false; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("ContainerWrapper("); - builder.append(getDisplayNameFromItem(container)); - builder.append(" ("); - builder.append(status); - builder.append(") "); - builder.append(getValues() == null ? null : getValues().size()); - builder.append(" items)"); - return builder.toString(); - } - - /** - * This methods check if we want to show property in form (e.g. - * failedLogins, fetchResult, lastFailedLoginTimestamp must be invisible) - * - * @return - * @deprecated will be implemented through annotations in schema - */ - @Deprecated - private boolean skipProperty(PrismPropertyDefinition def) { - final List names = new ArrayList(); - names.add(PasswordType.F_FAILED_LOGINS); - names.add(PasswordType.F_LAST_FAILED_LOGIN); - names.add(PasswordType.F_LAST_SUCCESSFUL_LOGIN); - names.add(PasswordType.F_PREVIOUS_SUCCESSFUL_LOGIN); - names.add(ObjectType.F_FETCH_RESULT); - // activation - names.add(ActivationType.F_EFFECTIVE_STATUS); - names.add(ActivationType.F_VALIDITY_STATUS); - // user - names.add(UserType.F_RESULT); - // org and roles - names.add(OrgType.F_APPROVAL_PROCESS); - names.add(OrgType.F_APPROVER_EXPRESSION); - names.add(OrgType.F_AUTOMATICALLY_APPROVED); - names.add(OrgType.F_CONDITION); - - - for (QName name : names) { - if (name.equals(def.getName())) { - return true; - } - } - - return false; - } - - public boolean isReadonly() { - // readonly flag in container is an override. Do not get the value from definition - // otherwise it will be propagated to items and overrides the item definition. - return readonly; - } - - public void setReadonly(boolean readonly) { - this.readonly = readonly; - } - -// @Override -// public List getValues() { -// // TODO Auto-generated method stub -// return null; -// } -// - - - @Override - public boolean isEmpty() { - return getItem().isEmpty(); - } - -// PrismContainer getContainer() { -// // TODO Auto-generated method stub -// return container -// } - - - //TODO add new PrismContainerValue to association container - public void addValue(boolean showEmpty) { - getValues().add(createItem(showEmpty)); - } - - public ContainerValueWrapper createItem(boolean showEmpty) { - PrismContainerValue pcv = container.createNewValue(); - ContainerValueWrapper wrapper = new ContainerValueWrapper(this, pcv, ValueStatus.ADDED, pcv.getPath()); - wrapper.setShowEmpty(showEmpty, true); - return wrapper; - } - - public void sort(final PageBase pageBase) { - for (ContainerValueWrapper valueWrapper : getValues()) { - valueWrapper.sort(pageBase); - } - } - -// public void sort(final PageBase pageBase) { -// if (objectWrapper.isSorted()){ -// Collections.sort(values, new Comparator(){ -// @Override -// public int compare(ItemWrapper pw1, ItemWrapper pw2) { -// ItemDefinition id1 = pw1.getItemDefinition(); -// ItemDefinition id2 = pw2.getItemDefinition(); -// String str1 =(id1 != null ? (id1.getDisplayName() != null ? -// (pageBase.createStringResource(id1.getDisplayName()) != null && -// StringUtils.isNotEmpty(pageBase.createStringResource(id1.getDisplayName()).getString()) ? -// pageBase.createStringResource(id1.getDisplayName()).getString() : id1.getDisplayName()): -// (id1.getName() != null && id1.getName().getLocalPart() != null ? id1.getName().getLocalPart() : "")) : ""); -// String str2 =(id2 != null ? (id2.getDisplayName() != null ? -// (pageBase.createStringResource(id2.getDisplayName()) != null && -// StringUtils.isNotEmpty(pageBase.createStringResource(id2.getDisplayName()).getString()) ? -// pageBase.createStringResource(id2.getDisplayName()).getString() : id2.getDisplayName()): -// (id2.getName() != null && id2.getName().getLocalPart() != null ? id2.getName().getLocalPart() : "")) : ""); -// return str1.compareToIgnoreCase(str2); -// } -// }); -// } -// else { -// final int[] maxOrderArray = new int[3]; -// Collections.sort(values, new Comparator(){ -// @Override -// public int compare(ItemWrapper pw1, ItemWrapper pw2) { -// ItemDefinition id1 = pw1.getItemDefinition(); -// ItemDefinition id2 = pw2.getItemDefinition(); -// -// //we need to find out the value of the biggest displayOrder to put -// //properties with null display order to the end of the list -// int displayOrder1 = (id1 != null && id1.getDisplayOrder() != null) ? id1.getDisplayOrder() : 0; -// int displayOrder2 = (id2 != null && id2.getDisplayOrder() != null) ? id2.getDisplayOrder() : 0; -// if (maxOrderArray[0] == 0){ -// maxOrderArray[0] = displayOrder1 > displayOrder2 ? displayOrder1 + 1 : displayOrder2 + 1; -// } -// maxOrderArray[1] = displayOrder1; -// maxOrderArray[2] = displayOrder2; -// -// int maxDisplayOrder = NumberUtils.max(maxOrderArray); -// maxOrderArray[0] = maxDisplayOrder + 1; -// -// return Integer.compare(id1 != null && id1.getDisplayOrder() != null ? id1.getDisplayOrder() : maxDisplayOrder, -// id2 != null && id2.getDisplayOrder() != null ? id2.getDisplayOrder() : maxDisplayOrder); -// } -// }); -// } -// } - - @Override - public String debugDump() { - return debugDump(0); - } - - @Override - public String debugDump(int indent) { - StringBuilder sb = new StringBuilder(); - DebugUtil.indentDebugDump(sb, indent); - sb.append("ContainerWrapper: ").append(PrettyPrinter.prettyPrint(getName())).append("\n"); - DebugUtil.debugDumpWithLabel(sb, "displayName", displayName, indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "status", status == null ? null : status.toString(), indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "main", isMain(), indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "readonly", readonly, indent + 1); - sb.append("\n"); -// DebugUtil.debugDumpWithLabel(sb, "showInheritedObjectAttributes", showInheritedObjectAttributes, indent + 1); -// sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "path", path == null ? null : path.toString(), indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "containerDefinition", getItemDefinition() == null ? null : getItemDefinition().toString(), indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "container", container == null ? null : container.toString(), indent + 1); - sb.append("\n"); - DebugUtil.debugDumpLabel(sb, "properties", indent + 1); - sb.append("\n"); - DebugUtil.debugDump(sb, values, indent + 2, false); - return sb.toString(); - } + } + + public void revive(PrismContext prismContext) throws SchemaException { + if (container != null) { + container.revive(prismContext); + } + if (getItemDefinition() != null) { + getItemDefinition().revive(prismContext); + } + if (values != null) { + for (ContainerValueWrapper itemWrapper : values) { + itemWrapper.revive(prismContext); + } + } + } + + @Override + public PrismContainerDefinition getItemDefinition() { + return container.getDefinition(); + } + + public ContainerStatus getStatus() { + return status; + } + + public ItemPath getPath() { + return path; + } + + @Override + public PrismContainer getItem() { + return container; + } + + @Override + public List> getValues() { + if (values == null) { + values = new ArrayList<>(); + } + return values; + + } + + public void setProperties(List> properties) { + this.values = properties; + } + + public PropertyOrReferenceWrapper findPropertyWrapper(QName name) { + Validate.notNull(name, "QName must not be null."); + for (ContainerValueWrapper wrapper : getValues()) { + PropertyOrReferenceWrapper propertyWrapper = wrapper.findPropertyWrapper(name); + if (propertyWrapper != null) { + return propertyWrapper; + } + } + return null; + } + + public ContainerWrapper findContainerWrapper(ItemPath path) { + Validate.notNull(path, "QName must not be null."); + for (ContainerValueWrapper wrapper : getValues()) { + ContainerWrapper containerWrapper = wrapper.findContainerWrapper(path); + if (containerWrapper != null) { + return containerWrapper; + } + } + return null; + } + + public ContainerValueWrapper findContainerValueWrapper(ItemPath path) { + Validate.notNull(path, "QName must not be null."); + for (ContainerValueWrapper wrapper : getValues()) { + + if (path.equivalent(wrapper.getPath())) { + return wrapper; + } + + ContainerValueWrapper containerWrapper = wrapper.findContainerValueWrapper(path); + if (containerWrapper != null) { + return containerWrapper; + } + } + return null; + } + + public void computeStripes() { + int visibleProperties = 0; + for (ContainerValueWrapper item : values) { + item.computeStripes(); + } + } + + @Override + public String getDisplayName() { + if (StringUtils.isNotEmpty(displayName)) { + return displayName; + } + return getDisplayNameFromItem(container); + } + + @Override + public void setDisplayName(String name) { + this.displayName = name; + } + + @Override + public QName getName() { + return getItem().getElementName(); + } + + public boolean isMain() { + return path == null || path.isEmpty(); + } + + static String getDisplayNameFromItem(Item item) { + Validate.notNull(item, "Item must not be null."); + + String displayName = item.getDisplayName(); + if (StringUtils.isEmpty(displayName)) { + QName name = item.getElementName(); + if (name != null) { + displayName = name.getLocalPart(); + } else { + displayName = item.getDefinition().getTypeName().getLocalPart(); + } + } + + return displayName; + } + + public boolean hasChanged() { + for (ContainerValueWrapper item : getValues()) { + if (item.hasChanged()) { + return true; + } + } + + return false; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("ContainerWrapper("); + builder.append(getDisplayNameFromItem(container)); + builder.append(" ("); + builder.append(status); + builder.append(") "); + builder.append(getValues() == null ? null : getValues().size()); + builder.append(" items)"); + return builder.toString(); + } + + /** + * This methods check if we want to show property in form (e.g. + * failedLogins, fetchResult, lastFailedLoginTimestamp must be invisible) + * + * @return + * @deprecated will be implemented through annotations in schema + */ + @Deprecated + private boolean skipProperty(PrismPropertyDefinition def) { + final List names = new ArrayList(); + names.add(PasswordType.F_FAILED_LOGINS); + names.add(PasswordType.F_LAST_FAILED_LOGIN); + names.add(PasswordType.F_LAST_SUCCESSFUL_LOGIN); + names.add(PasswordType.F_PREVIOUS_SUCCESSFUL_LOGIN); + names.add(ObjectType.F_FETCH_RESULT); + // activation + names.add(ActivationType.F_EFFECTIVE_STATUS); + names.add(ActivationType.F_VALIDITY_STATUS); + // user + names.add(UserType.F_RESULT); + // org and roles + names.add(OrgType.F_APPROVAL_PROCESS); + names.add(OrgType.F_APPROVER_EXPRESSION); + names.add(OrgType.F_AUTOMATICALLY_APPROVED); + names.add(OrgType.F_CONDITION); + + for (QName name : names) { + if (name.equals(def.getName())) { + return true; + } + } + + return false; + } + + public boolean isReadonly() { + // readonly flag in container is an override. Do not get the value from + // definition + // otherwise it will be propagated to items and overrides the item + // definition. + return readonly; + } + + public void setReadonly(boolean readonly) { + this.readonly = readonly; + } + + @Override + public boolean isEmpty() { + return getItem().isEmpty(); + } + + public void addValue(boolean showEmpty) { + getValues().add(createItem(showEmpty)); + } + + public ContainerValueWrapper createItem(boolean showEmpty) { + PrismContainerValue pcv = container.createNewValue(); + ContainerValueWrapper wrapper = new ContainerValueWrapper(this, pcv, ValueStatus.ADDED, pcv.getPath()); + wrapper.setShowEmpty(showEmpty, true); + return wrapper; + } + + public void sort(final PageBase pageBase) { + for (ContainerValueWrapper valueWrapper : getValues()) { + valueWrapper.sort(pageBase); + } + } + + @Override + public String debugDump() { + return debugDump(0); + } + + @Override + public String debugDump(int indent) { + StringBuilder sb = new StringBuilder(); + DebugUtil.indentDebugDump(sb, indent); + sb.append("ContainerWrapper: ").append(PrettyPrinter.prettyPrint(getName())).append("\n"); + DebugUtil.debugDumpWithLabel(sb, "displayName", displayName, indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "status", status == null ? null : status.toString(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "main", isMain(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "readonly", readonly, indent + 1); + sb.append("\n"); + // DebugUtil.debugDumpWithLabel(sb, "showInheritedObjectAttributes", + // showInheritedObjectAttributes, indent + 1); + // sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "path", path == null ? null : path.toString(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "containerDefinition", + getItemDefinition() == null ? null : getItemDefinition().toString(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "container", container == null ? null : container.toString(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpLabel(sb, "properties", indent + 1); + sb.append("\n"); + DebugUtil.debugDump(sb, values, indent + 2, false); + return sb.toString(); + } @Override public boolean isStripe() { @@ -434,58 +348,29 @@ public boolean isStripe() { public void setStripe(boolean isStripe) { // Does not make much sense, but it is given by the interface } - + public PrismContainer createContainerAddDelta() throws SchemaException { - - PrismContainer containerAdd = container.clone(); - - for (ContainerValueWrapper itemWrapper : getValues()) { - if (!itemWrapper.hasChanged()) { - continue; - } - - if (itemWrapper.isMain()) { - containerAdd.setValue(itemWrapper.createContainerValueAddDelta()); - continue; - } - -// PrismContainer childContainer = containerAdd.findOrCreateContainer(itemWrapper.getContainerValue().getPath()); - containerAdd.add(itemWrapper.createContainerValueAddDelta()); - } - - return containerAdd; - } - - - public void collectModifications(ObjectDelta delta) throws SchemaException { -// if (getItemDefinition().getName().equals(ShadowType.F_ASSOCIATION)) { -// //create ContainerDelta for association container -// //HACK HACK HACK create correct procession for association container data -// //according to its structure -// ContainerDelta associationDelta = -// ContainerDelta.createDelta(ShadowType.F_ASSOCIATION, -// (PrismContainerDefinition) getItemDefinition()); -// for (ItemWrapper itemWrapper : getValues()) { -// AssociationWrapper associationItemWrapper = (AssociationWrapper) itemWrapper; -// List assocValueWrappers = associationItemWrapper.getValues(); -// for (ValueWrapper assocValueWrapper : assocValueWrappers) { -// PrismContainerValue assocValue = (PrismContainerValue) assocValueWrapper.getValue(); -// if (!assocValue.isEmpty()) { -// if (assocValueWrapper.getStatus() == ValueStatus.DELETED) { -// associationDelta.addValueToDelete(assocValue.clone()); -// } else if (assocValueWrapper.getStatus().equals(ValueStatus.ADDED)) { -// associationDelta.addValueToAdd(assocValue.clone()); -// } -// } -// } -// } -// if (!associationDelta.isEmpty()) { -// delta.addModification(associationDelta); -// } -// } else { - if (!hasChanged()) { - return; + + PrismContainer containerAdd = container.clone(); + + for (ContainerValueWrapper itemWrapper : getValues()) { + if (!itemWrapper.hasChanged()) { + continue; + } + if (itemWrapper.isMain()) { + containerAdd.setValue(itemWrapper.createContainerValueAddDelta()); + continue; } + containerAdd.add(itemWrapper.createContainerValueAddDelta()); + } + return containerAdd; + } + + public void collectModifications(ObjectDelta delta) throws SchemaException { + + if (!hasChanged()) { + return; + } for (ContainerValueWrapper itemWrapper : getValues()) { if (!itemWrapper.hasChanged()) { @@ -499,7 +384,6 @@ public void collectModifications(ObjectDelta delta) th delta.addModificationAddContainer(getPath(), valueToAdd); break; } - delta.addModificationReplaceContainer(getPath(), valueToAdd); break; case NOT_CHANGED: @@ -508,162 +392,13 @@ public void collectModifications(ObjectDelta delta) th case DELETED: delta.addModificationDeleteContainer(itemWrapper.getPath(), itemWrapper.getContainerValue().clone()); break; - - } - - -// ItemPath containerPath = getPath() != null ? getPath() : ItemPath.EMPTY_PATH; -// -// if (itemWrapper instanceof PropertyWrapper) { -// ItemDelta pDelta = computePropertyDeltas((PropertyWrapper) itemWrapper, containerPath); -// if (!pDelta.isEmpty()) { -// //HACK to remove a password replace delta is to be created -// if (getName().equals(CredentialsType.F_PASSWORD)) { -// if (pDelta.getValuesToDelete() != null){ -// pDelta.resetValuesToDelete(); -// pDelta.setValuesToReplace(new ArrayList()); -// } -// } -// delta.addModification(pDelta); -// } -// } else if (itemWrapper instanceof ReferenceWrapper) { -// ReferenceDelta pDelta = computeReferenceDeltas((ReferenceWrapper) itemWrapper, containerPath); -// if (!pDelta.isEmpty()) { -// delta.addModification(pDelta); -// } -// } else { -// LOGGER.trace("Delta from wrapper: ignoring {}", itemWrapper); -// } } -// } - } - -// private ItemDelta computePropertyDeltas(PropertyWrapper propertyWrapper, ItemPath containerPath) { -// ItemDefinition itemDef = propertyWrapper.getItemDefinition(); -// ItemDelta pDelta = itemDef.createEmptyDelta(containerPath.subPath(itemDef.getName())); -// addItemDelta(propertyWrapper, pDelta, itemDef, containerPath); -// return pDelta; -// } -// -// private ReferenceDelta computeReferenceDeltas(ReferenceWrapper referenceWrapper, ItemPath containerPath) { -// PrismReferenceDefinition propertyDef = referenceWrapper.getItemDefinition(); -// ReferenceDelta pDelta = new ReferenceDelta(containerPath, propertyDef.getName(), propertyDef, -// propertyDef.getPrismContext()); -// addItemDelta(referenceWrapper, pDelta, propertyDef, containerPath.subPath(propertyDef.getName())); -// return pDelta; -// } -// -// private void addItemDelta(ItemWrapper itemWrapper, ItemDelta pDelta, ItemDefinition propertyDef, -// ItemPath containerPath) { -// for (ValueWrapper valueWrapper : itemWrapper.getValues()) { -// valueWrapper.normalize(propertyDef.getPrismContext()); -// ValueStatus valueStatus = valueWrapper.getStatus(); -// if (!valueWrapper.hasValueChanged() -// && (ValueStatus.NOT_CHANGED.equals(valueStatus) || ValueStatus.ADDED.equals(valueStatus))) { -// continue; -// } -// -// // TODO: need to check if the resource has defined -// // capabilities -// // todo this is bad hack because now we have not tri-state -// // checkbox -//// if (SchemaConstants.PATH_ACTIVATION.equivalent(containerPath) && getObject() != null) { -//// -//// PrismObject object = getObject().getObject(); -//// if (object.asObjectable() instanceof ShadowType -//// && (((ShadowType) object.asObjectable()).getActivation() == null || ((ShadowType) object -//// .asObjectable()).getActivation().getAdministrativeStatus() == null)) { -//// -//// if (!getObject().hasResourceCapability(((ShadowType) object.asObjectable()).getResource(), -//// ActivationCapabilityType.class)) { -//// continue; -//// } -//// } -//// } -// -// PrismValue newValCloned = ObjectWrapper.clone(valueWrapper.getValue()); -// PrismValue oldValCloned = ObjectWrapper.clone(valueWrapper.getOldValue()); -// switch (valueWrapper.getStatus()) { -// case ADDED: -// if (newValCloned != null) { -// if (SchemaConstants.PATH_PASSWORD.equivalent(containerPath)) { -// // password change will always look like add, -// // therefore we push replace -// if (LOGGER.isTraceEnabled()) { -// LOGGER.trace("Delta from wrapper: {} (password) ADD -> replace {}", pDelta.getPath(), newValCloned); -// } -// pDelta.setValuesToReplace(Arrays.asList(newValCloned)); -// } else if (propertyDef.isSingleValue()) { -// // values for single-valued properties -// // should be pushed via replace -// // in order to prevent problems e.g. with -// // summarizing deltas for -// // unreachable resources -// if (LOGGER.isTraceEnabled()) { -// LOGGER.trace("Delta from wrapper: {} (single,new) ADD -> replace {}", pDelta.getPath(), newValCloned); -// } -// pDelta.setValueToReplace(newValCloned); -// } else { -// if (LOGGER.isTraceEnabled()) { -// LOGGER.trace("Delta from wrapper: {} (multi,new) ADD -> add {}", pDelta.getPath(), newValCloned); -// } -// pDelta.addValueToAdd(newValCloned); -// } -// } -// break; -// case DELETED: -// if (newValCloned != null) { -// if (LOGGER.isTraceEnabled()) { -// LOGGER.trace("Delta from wrapper: {} (new) DELETE -> delete {}", pDelta.getPath(), newValCloned); -// } -// pDelta.addValueToDelete(newValCloned); -// } -// if (oldValCloned != null) { -// if (LOGGER.isTraceEnabled()) { -// LOGGER.trace("Delta from wrapper: {} (old) DELETE -> delete {}", pDelta.getPath(), oldValCloned); -// } -// pDelta.addValueToDelete(oldValCloned); -// } -// break; -// case NOT_CHANGED: -// // this is modify... -// if (propertyDef.isSingleValue()) { -// // newValCloned.isEmpty() -// if (newValCloned != null && !newValCloned.isEmpty()) { -// if (LOGGER.isTraceEnabled()) { -// LOGGER.trace("Delta from wrapper: {} (single,new) NOT_CHANGED -> replace {}", pDelta.getPath(), newValCloned); -// } -// pDelta.setValuesToReplace(Arrays.asList(newValCloned)); -// } else { -// if (oldValCloned != null) { -// if (LOGGER.isTraceEnabled()) { -// LOGGER.trace("Delta from wrapper: {} (single,old) NOT_CHANGED -> delete {}", pDelta.getPath(), oldValCloned); -// } -// pDelta.addValueToDelete(oldValCloned); -// } -// } -// } else { -// if (newValCloned != null && !newValCloned.isEmpty()) { -// if (LOGGER.isTraceEnabled()) { -// LOGGER.trace("Delta from wrapper: {} (multi,new) NOT_CHANGED -> add {}", pDelta.getPath(), newValCloned); -// } -// pDelta.addValueToAdd(newValCloned); -// } -// if (oldValCloned != null) { -// if (LOGGER.isTraceEnabled()) { -// LOGGER.trace("Delta from wrapper: {} (multi,old) NOT_CHANGED -> delete {}", pDelta.getPath(), oldValCloned); -// } -// pDelta.addValueToDelete(oldValCloned); -// } -// } -// break; -// } -// } -// } + } + } @Override public boolean checkRequired(PageBase pageBase) { - boolean rv = true; + boolean rv = true; for (ContainerValueWrapper itemWrapper : getValues()) { if (!itemWrapper.checkRequired(pageBase)) { rv = false; @@ -671,16 +406,16 @@ public boolean checkRequired(PageBase pageBase) { } return rv; } - + @Override public void setShowEmpty(boolean showEmpty, boolean recursive) { super.setShowEmpty(showEmpty, recursive); if (recursive) { getValues().forEach(value -> value.setShowEmpty(showEmpty, recursive)); } - + } - + @Override public void setShowMetadata(boolean showMetadata) { super.setShowMetadata(showMetadata); @@ -689,7 +424,8 @@ public void setShowMetadata(boolean showMetadata) { @Override public boolean isEnforceRequiredFields() { - return true;//objectWrapper != null && objectWrapper.isEnforceRequiredFields(); + return true;// objectWrapper != null && + // objectWrapper.isEnforceRequiredFields(); } @Override @@ -701,25 +437,25 @@ public ContainerWrapper getParent() { @Override public boolean isVisible() { PrismContainerDefinition def = getItemDefinition(); - + if (def.isIgnored() || (def.isOperational()) && (!def.getTypeName().equals(MetadataType.COMPLEX_TYPE))) { return false; } - + switch (status) { - case MODIFYING : - return isNotEmptyAndCanReadAndModify(def) || showEmptyCanReadAndModify(def); - case ADDING : + case MODIFYING: + return isNotEmptyAndCanReadAndModify(def) || showEmptyCanReadAndModify(def); + case ADDING: return emphasizedAndCanAdd(def) || showEmptyAndCanAdd(def); } - + return false; } - + private boolean isNotEmptyAndCanReadAndModify(PrismContainerDefinition def) { return def.canRead() && def.canModify(); } - + private boolean showEmptyCanReadAndModify(PrismContainerDefinition def) { return def.canRead() && def.canModify() && isShowEmpty(); } @@ -727,9 +463,9 @@ private boolean showEmptyCanReadAndModify(PrismContainerDefinition def) { private boolean showEmptyAndCanAdd(PrismContainerDefinition def) { return def.canAdd() && isShowEmpty(); } - + private boolean emphasizedAndCanAdd(PrismContainerDefinition def) { return def.canAdd() && def.isEmphasized(); } - + } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java index fc553acd2ea..ef79556f453 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java @@ -16,11 +16,36 @@ package com.evolveum.midpoint.web.component.prism; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; + import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; -import com.evolveum.midpoint.prism.*; -import com.evolveum.midpoint.prism.delta.*; +import com.evolveum.midpoint.prism.ConsistencyCheckScope; +import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.prism.Item; +import com.evolveum.midpoint.prism.OriginType; +import com.evolveum.midpoint.prism.PrismContainer; +import com.evolveum.midpoint.prism.PrismContainerDefinition; +import com.evolveum.midpoint.prism.PrismContainerValue; +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismProperty; +import com.evolveum.midpoint.prism.PrismPropertyValue; +import com.evolveum.midpoint.prism.PrismReferenceValue; +import com.evolveum.midpoint.prism.PrismValue; +import com.evolveum.midpoint.prism.Revivable; +import com.evolveum.midpoint.prism.delta.ChangeType; +import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.schema.GetOperationOptions; @@ -31,132 +56,115 @@ import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CapabilityType; import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.Validate; - -import java.io.Serializable; -import java.util.*; - /** * @author lazyman + * @author katkav */ public class ObjectWrapper extends PrismWrapper implements Serializable, Revivable, DebugDumpable { private static final long serialVersionUID = 1L; public static final String F_DISPLAY_NAME = "displayName"; - public static final String F_SELECTED = "selected"; + public static final String F_SELECTED = "selected"; - private static final Trace LOGGER = TraceManager.getTrace(ObjectWrapper.class); + private static final Trace LOGGER = TraceManager.getTrace(ObjectWrapper.class); public static final String PROPERTY_CONTAINERS = "containers"; - private PrismObject object; - private PrismObject objectOld; - private ObjectDelta oldDelta; - private ContainerStatus status; - private HeaderStatus headerStatus; - private String displayName; - private String description; - private List> containers; - - private ContainerWrapperFactory factory; - -// private boolean showEmpty; -// private boolean minimalized; -// private boolean sorted; -// private boolean showMetadata = false; - private boolean selectable; - private boolean selected; - - private boolean showAssignments = false; - // whether to show name and description properties and metadata container - private boolean showInheritedObjectAttributes = true; - - // readonly flag is an override. false means "do not override" - private boolean readonly = false; - - // whether to make wicket enforce that required fields are filled-in (if set to false, this check has to be done explicitly) - private boolean enforceRequiredFields = true; - - private Collection> loadOptions; - private OperationResult result; - - private Collection> parentOrgs = new ArrayList<>(); - - private OperationResult fetchResult; - // a "static" (non-refined) definition that reflects editability of the object in terms of midPoint schema limitations and security -// private PrismContainerDefinition objectDefinitionForEditing; - // a refined definition of an resource object class that reflects its editability; applicable for shadows only - private RefinedObjectClassDefinition objectClassDefinitionForEditing; - -// public ObjectWrapper(PrismObject object, ContainerStatus status, ContainerWrapperFactory factory) { -// this(object, null, status); -// } - - public ObjectWrapper(String dispayName, String descritpion, PrismObject object, - ContainerStatus status) { - Validate.notNull(object, "Object must not be null."); - Validate.notNull(status, "Container status must not be null."); - - this.displayName = displayName; - this.description = description; - this.object = object; - this.objectOld = object.clone(); - this.status = status; - -// this.objectClassDefinitionForEditing = objectClassDefinitionForEditing; - } - -// public void initializeContainers(PageBase pageBase) { -// //todo remove -// } - - public void revive(PrismContext prismContext) throws SchemaException { - if (object != null) { - object.revive(prismContext); - } - if (oldDelta != null) { - oldDelta.revive(prismContext); - } - if (containers != null) { - for (ContainerWrapper containerWrapper : containers) { - containerWrapper.revive(prismContext); - } - } - } - - public Collection> getParentOrgs() { - return parentOrgs; - } - - public OperationResult getFetchResult() { - return fetchResult; - } - - public void setFetchResult(OperationResult fetchResult) { - this.fetchResult = fetchResult; - } - - void setResult(OperationResult result) { - this.result = result; - } - - public OperationResult getResult() { - return result; - } - - public void clearResult() { - result = null; - } - - public Collection> getLoadOptions() { + private PrismObject object; + private PrismObject objectOld; + private ObjectDelta oldDelta; + private ContainerStatus status; + private HeaderStatus headerStatus; + private String displayName; + private String description; + private List> containers; + + private boolean selectable; + private boolean selected; + + private boolean showAssignments = false; + // whether to show name and description properties and metadata container + private boolean showInheritedObjectAttributes = true; + + // readonly flag is an override. false means "do not override" + private boolean readonly = false; + + // whether to make wicket enforce that required fields are filled-in (if set + // to false, this check has to be done explicitly) + private boolean enforceRequiredFields = true; + + private Collection> loadOptions; + private OperationResult result; + + private Collection> parentOrgs = new ArrayList<>(); + + private OperationResult fetchResult; + // a "static" (non-refined) definition that reflects editability of the + // object in terms of midPoint schema limitations and security + // private PrismContainerDefinition objectDefinitionForEditing; + // a refined definition of an resource object class that reflects its + // editability; applicable for shadows only + private RefinedObjectClassDefinition objectClassDefinitionForEditing; + + public ObjectWrapper(String dispayName, String descritpion, PrismObject object, ContainerStatus status) { + Validate.notNull(object, "Object must not be null."); + Validate.notNull(status, "Container status must not be null."); + + this.displayName = displayName; + this.description = description; + this.object = object; + this.objectOld = object.clone(); + this.status = status; + } + + public void revive(PrismContext prismContext) throws SchemaException { + if (object != null) { + object.revive(prismContext); + } + if (oldDelta != null) { + oldDelta.revive(prismContext); + } + if (containers != null) { + for (ContainerWrapper containerWrapper : containers) { + containerWrapper.revive(prismContext); + } + } + } + + public Collection> getParentOrgs() { + return parentOrgs; + } + + public OperationResult getFetchResult() { + return fetchResult; + } + + public void setFetchResult(OperationResult fetchResult) { + this.fetchResult = fetchResult; + } + + void setResult(OperationResult result) { + this.result = result; + } + + public OperationResult getResult() { + return result; + } + + public void clearResult() { + result = null; + } + + public Collection> getLoadOptions() { return loadOptions; } @@ -165,407 +173,379 @@ public void setLoadOptions(Collection> load } public HeaderStatus getHeaderStatus() { - if (headerStatus == null) { - headerStatus = HeaderStatus.NORMAL; - } - return headerStatus; - } - - public ObjectDelta getOldDelta() { - return oldDelta; - } - - public void setOldDelta(ObjectDelta oldDelta) { - this.oldDelta = oldDelta; - } - - public void setHeaderStatus(HeaderStatus headerStatus) { - this.headerStatus = headerStatus; - } - - public PrismObject getObject() { - return object; - } - - public PrismObject getObjectOld() { - return objectOld; - } - - public String getDisplayName() { - if (displayName == null) { - return WebComponentUtil.getName(object); - } - return displayName; - } - - public ContainerStatus getStatus() { - return status; - } - - public String getDescription() { - return description; - } - - public boolean isSelectable() { - return selectable; - } - - public void setSelectable(boolean selectable) { - this.selectable = selectable; - } - - public boolean isSelected() { - return selected; - } - - public void setSelected(boolean selected) { - this.selected = selected; - } - - public List> getContainers() { - if (containers == null) { - containers = new ArrayList<>(); - } - return containers; - } - - public void setContainers(List> containers) { - this.containers = containers; - } - - public ContainerWrapper findContainerWrapper(ItemPath path) { - if (path == null || path.isEmpty()) { - return (ContainerWrapper) findMainContainerWrapper(); -// ContainerWrapper mainContainer = (ContainerWrapper) findMainContainerWrapper(); -// if (mainContainer == null) { -// mainContainer = factory.createContainerWrapper(object, ContainerStatus.ADDING, ItemPath.EMPTY_PATH); -// containers.add(mainContainer); -// return mainContainer; -// } - - } - - if (path.size() == 1) { - return (ContainerWrapper) getContainers().stream().filter(wrapper -> path.equivalent(wrapper.getPath())).findFirst().orElse(null); -// ContainerWrapper containerWrapper = (ContainerWrapper) getContainers().stream().filter(wrapper -> path.equivalent(wrapper.getPath())).findFirst().orElse(null); -// if (containerWrapper == null) { -// PrismContainer container; -// try { -// container = object.findOrCreateContainer(path); -// } catch (SchemaException e) { -// LoggingUtils.logException(LOGGER, "Cannot create container " + path, e); -// return null; -// } -// containerWrapper = factory.createContainerWrapper(container, ContainerStatus.ADDING, path); -// containers.add(containerWrapper); -// return containerWrapper; -// } - } - - - ContainerWrapper containerWrapper = findContainerWrapper(path.head()); - if (containerWrapper == null) { - return null; - } - - return containerWrapper.findContainerWrapper(path); - - } - - public ContainerValueWrapper findContainerValueWrapper(ItemPath path) { - if (path == null || path.isEmpty()) { - ContainerWrapper mainContainer = (ContainerWrapper) findMainContainerWrapper(); - if (mainContainer == null) { - return null; - } - return mainContainer.getValues().iterator().next(); - } - - ContainerWrapper containerWrapper = findContainerWrapper(path.head()); - if (containerWrapper == null) { - return null; - } - - return containerWrapper.findContainerValueWrapper(path); - - } - - public ContainerWrapper findMainContainerWrapper() { - for (ContainerWrapper wrapper : getContainers()) { - if (wrapper.isMain()) { - return wrapper; - } - } - return null; - } - - public IW findPropertyWrapper(ItemPath path) { - ContainerWrapper containerWrapper; - ItemPath propertyPath; - if (path.size() == 1) { - containerWrapper = findMainContainerWrapper(); - propertyPath = path; - } else { - containerWrapper = findContainerWrapper(path.head()); - propertyPath = path.tail(); - } - if (containerWrapper == null) { - return null; - } - return (IW) containerWrapper.findPropertyWrapper(ItemPath.getFirstName(propertyPath)); - } - - public void normalize() throws SchemaException { - ObjectDelta delta = getObjectDelta(); - if (ChangeType.ADD.equals(delta.getChangeType())) { - object = delta.getObjectToAdd(); - } else { - delta.applyTo(object); - } - } - - public void sort(PageBase pageBase) { - ContainerWrapper main = findMainContainerWrapper(); - if (main != null) { - main.sort(pageBase); - } - computeStripes(); - } - -// @Override -// public void setShowEmpty(boolean showEmpty) { -// super.setShowEmpty(showEmpty); -// getContainers().forEach(c -> c.setShowEmpty(showEmpty)); -// } - - @Override - public void computeStripes() { + if (headerStatus == null) { + headerStatus = HeaderStatus.NORMAL; + } + return headerStatus; + } + + public ObjectDelta getOldDelta() { + return oldDelta; + } + + public void setOldDelta(ObjectDelta oldDelta) { + this.oldDelta = oldDelta; + } + + public void setHeaderStatus(HeaderStatus headerStatus) { + this.headerStatus = headerStatus; + } + + public PrismObject getObject() { + return object; + } + + public PrismObject getObjectOld() { + return objectOld; + } + + public String getDisplayName() { + if (displayName == null) { + return WebComponentUtil.getName(object); + } + return displayName; + } + + public ContainerStatus getStatus() { + return status; + } + + public String getDescription() { + return description; + } + + public boolean isSelectable() { + return selectable; + } + + public void setSelectable(boolean selectable) { + this.selectable = selectable; + } + + public boolean isSelected() { + return selected; + } + + public void setSelected(boolean selected) { + this.selected = selected; + } + + public List> getContainers() { + if (containers == null) { + containers = new ArrayList<>(); + } + return containers; + } + + public void setContainers(List> containers) { + this.containers = containers; + } + + public ContainerWrapper findContainerWrapper(ItemPath path) { + if (path == null || path.isEmpty()) { + return (ContainerWrapper) findMainContainerWrapper(); + + } + + if (path.size() == 1) { + return (ContainerWrapper) getContainers().stream().filter(wrapper -> path.equivalent(wrapper.getPath())) + .findFirst().orElse(null); + } + + ContainerWrapper containerWrapper = findContainerWrapper(path.head()); + if (containerWrapper == null) { + return null; + } + + return containerWrapper.findContainerWrapper(path); + + } + + public ContainerValueWrapper findContainerValueWrapper(ItemPath path) { + if (path == null || path.isEmpty()) { + ContainerWrapper mainContainer = (ContainerWrapper) findMainContainerWrapper(); + if (mainContainer == null) { + return null; + } + return mainContainer.getValues().iterator().next(); + } + + ContainerWrapper containerWrapper = findContainerWrapper(path.head()); + if (containerWrapper == null) { + return null; + } + + return containerWrapper.findContainerValueWrapper(path); + + } + + public ContainerWrapper findMainContainerWrapper() { + for (ContainerWrapper wrapper : getContainers()) { + if (wrapper.isMain()) { + return wrapper; + } + } + return null; + } + + public IW findPropertyWrapper(ItemPath path) { + ContainerWrapper containerWrapper; + ItemPath propertyPath; + if (path.size() == 1) { + containerWrapper = findMainContainerWrapper(); + propertyPath = path; + } else { + containerWrapper = findContainerWrapper(path.head()); + propertyPath = path.tail(); + } + if (containerWrapper == null) { + return null; + } + return (IW) containerWrapper.findPropertyWrapper(ItemPath.getFirstName(propertyPath)); + } + + public void normalize() throws SchemaException { + ObjectDelta delta = getObjectDelta(); + if (ChangeType.ADD.equals(delta.getChangeType())) { + object = delta.getObjectToAdd(); + } else { + delta.applyTo(object); + } + } + + public void sort(PageBase pageBase) { + ContainerWrapper main = findMainContainerWrapper(); + if (main != null) { + main.sort(pageBase); + } + computeStripes(); + } + + @Override + public void computeStripes() { getContainers().forEach(c -> c.computeStripes()); } public ObjectDelta getObjectDelta() throws SchemaException { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Wrapper before creating delta:\n{}", this.debugDump()); - } + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Wrapper before creating delta:\n{}", this.debugDump()); + } - if (ContainerStatus.ADDING.equals(getStatus())) { - return createAddingObjectDelta(); - } + if (ContainerStatus.ADDING.equals(getStatus())) { + return createAddingObjectDelta(); + } - ObjectDelta delta = new ObjectDelta(object.getCompileTimeClass(), ChangeType.MODIFY, - object.getPrismContext()); - delta.setOid(object.getOid()); + ObjectDelta delta = new ObjectDelta(object.getCompileTimeClass(), ChangeType.MODIFY, object.getPrismContext()); + delta.setOid(object.getOid()); - List> containers = getContainers(); - // sort containers by path size - Collections.sort(containers, new PathSizeComparator()); + List> containers = getContainers(); + // sort containers by path size + Collections.sort(containers, new PathSizeComparator()); - for (ContainerWrapper containerWrapper : getContainers()) { + for (ContainerWrapper containerWrapper : getContainers()) { containerWrapper.collectModifications(delta); } - // returning container to previous order - Collections.sort(containers, new ItemWrapperComparator()); - - if (object.getPrismContext() != null) { - // Make sure we have all the definitions - object.getPrismContext().adopt(delta); - } - - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Creating delta from wrapper {}: existing object, creating delta:\n{}", this, delta.debugDump()); - } - - return delta; - } - - // TODO move to appropriate place! - public static PrismValue clone(PrismValue value) { - if (value == null) { - return null; - } - PrismValue cloned = value.clone(); - cloned.setOriginType(OriginType.USER_ACTION); - if (value instanceof PrismPropertyValue) { - PrismPropertyValue ppValue = (PrismPropertyValue) value; - if (ppValue.getValue() instanceof ProtectedStringType) { - ((PrismPropertyValue) cloned).setValue(((ProtectedStringType) ppValue.getValue()).clone()); - } - if (ppValue.getValue() instanceof PolyString) { - PolyString poly = (PolyString) ppValue.getValue(); - if (StringUtils.isEmpty(poly.getOrig())) { - return null; - } - ((PrismPropertyValue) cloned).setValue(new PolyString(poly.getOrig(), poly.getNorm())); - } - } else if (value instanceof PrismReferenceValue) { - if (cloned == null) { - return null; - } - if (cloned.isEmpty()) { - return null; - } - } - - return cloned; - } - - protected boolean hasResourceCapability(ResourceType resource, - Class capabilityClass) { - if (resource == null) { - return false; - } - return ResourceTypeUtil.hasEffectiveCapability(resource, capabilityClass); - } - - private ObjectDelta createAddingObjectDelta() throws SchemaException { - PrismObject object = this.object.clone(); - - List> containers = getContainers(); - // sort containers by path size - Collections.sort(containers, new PathSizeComparator()); - - for (ContainerWrapper containerWrapper : getContainers()) { - - if (!containerWrapper.hasChanged()) { - continue; - } - - PrismContainer containerToAdd = containerWrapper.createContainerAddDelta(); - if (containerWrapper.isMain()) { - object = (PrismObject) containerToAdd; - continue; - } - - object.getValue().addReplaceExisting(containerToAdd); - - - } - - // cleanup empty containers - cleanupEmptyContainers(object); - - ObjectDelta delta = ObjectDelta.createAddDelta(object); - - // returning container to previous order - Collections.sort(containers, new ItemWrapperComparator()); - - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Creating delta from wrapper {}: adding object, creating complete ADD delta:\n{}", this, delta.debugDump()); - } - - if (InternalsConfig.consistencyChecks) { - delta.checkConsistence(true, true, true, ConsistencyCheckScope.THOROUGH); - } - - return delta; - } - - private void cleanupEmptyContainers(PrismContainer container) { - List values = container.getValues(); - List valuesToBeRemoved = new ArrayList(); - for (PrismContainerValue value : values) { - List items = value.getItems(); - if (items != null) { - Iterator iterator = items.iterator(); - while (iterator.hasNext()) { - Item item = iterator.next(); - - if (item instanceof PrismContainer) { - cleanupEmptyContainers((PrismContainer) item); - - if (item.isEmpty()) { - iterator.remove(); - } - } - } - } - - if (items == null || value.isEmpty()) { - valuesToBeRemoved.add(value); - } - } - - container.removeAll(valuesToBeRemoved); - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("ObjectWrapper("); - builder.append(ContainerWrapper.getDisplayNameFromItem(object)); - builder.append(" ("); - builder.append(status); - builder.append(") "); - builder.append(getContainers() == null ? null : getContainers().size()); - builder.append(" containers)"); - return builder.toString(); - } - - public boolean isProtectedAccount() { - if (object == null || !(ShadowType.class.isAssignableFrom(object.getCompileTimeClass()))) { - return false; - } - - PrismProperty protectedObject = object.findProperty(ShadowType.F_PROTECTED_OBJECT); - if (protectedObject == null) { - return false; - } - - return protectedObject.getRealValue() != null ? protectedObject.getRealValue() : false; - } - - private static class PathSizeComparator implements Comparator { - - @Override - public int compare(ContainerWrapper c1, ContainerWrapper c2) { - int size1 = c1.getPath() != null ? c1.getPath().size() : 0; - int size2 = c2.getPath() != null ? c2.getPath().size() : 0; - - return size1 - size2; - } - } + // returning container to previous order + Collections.sort(containers, new ItemWrapperComparator()); + + if (object.getPrismContext() != null) { + // Make sure we have all the definitions + object.getPrismContext().adopt(delta); + } + + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Creating delta from wrapper {}: existing object, creating delta:\n{}", this, delta.debugDump()); + } + + return delta; + } + + // TODO move to appropriate place! + public static PrismValue clone(PrismValue value) { + if (value == null) { + return null; + } + PrismValue cloned = value.clone(); + cloned.setOriginType(OriginType.USER_ACTION); + if (value instanceof PrismPropertyValue) { + PrismPropertyValue ppValue = (PrismPropertyValue) value; + if (ppValue.getValue() instanceof ProtectedStringType) { + ((PrismPropertyValue) cloned).setValue(((ProtectedStringType) ppValue.getValue()).clone()); + } + if (ppValue.getValue() instanceof PolyString) { + PolyString poly = (PolyString) ppValue.getValue(); + if (StringUtils.isEmpty(poly.getOrig())) { + return null; + } + ((PrismPropertyValue) cloned).setValue(new PolyString(poly.getOrig(), poly.getNorm())); + } + } else if (value instanceof PrismReferenceValue) { + if (cloned == null) { + return null; + } + if (cloned.isEmpty()) { + return null; + } + } + + return cloned; + } + + protected boolean hasResourceCapability(ResourceType resource, Class capabilityClass) { + if (resource == null) { + return false; + } + return ResourceTypeUtil.hasEffectiveCapability(resource, capabilityClass); + } + + private ObjectDelta createAddingObjectDelta() throws SchemaException { + PrismObject object = this.object.clone(); + + List> containers = getContainers(); + // sort containers by path size + Collections.sort(containers, new PathSizeComparator()); + + for (ContainerWrapper containerWrapper : getContainers()) { + + if (!containerWrapper.hasChanged()) { + continue; + } + + PrismContainer containerToAdd = containerWrapper.createContainerAddDelta(); + if (containerWrapper.isMain()) { + object = (PrismObject) containerToAdd; + continue; + } + + object.getValue().addReplaceExisting(containerToAdd); + + } + + // cleanup empty containers + cleanupEmptyContainers(object); + + ObjectDelta delta = ObjectDelta.createAddDelta(object); + + // returning container to previous order + Collections.sort(containers, new ItemWrapperComparator()); + + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Creating delta from wrapper {}: adding object, creating complete ADD delta:\n{}", this, + delta.debugDump()); + } + + if (InternalsConfig.consistencyChecks) { + delta.checkConsistence(true, true, true, ConsistencyCheckScope.THOROUGH); + } + + return delta; + } + + private void cleanupEmptyContainers(PrismContainer container) { + List values = container.getValues(); + List valuesToBeRemoved = new ArrayList(); + for (PrismContainerValue value : values) { + List items = value.getItems(); + if (items != null) { + Iterator iterator = items.iterator(); + while (iterator.hasNext()) { + Item item = iterator.next(); + + if (item instanceof PrismContainer) { + cleanupEmptyContainers((PrismContainer) item); + + if (item.isEmpty()) { + iterator.remove(); + } + } + } + } + + if (items == null || value.isEmpty()) { + valuesToBeRemoved.add(value); + } + } + + container.removeAll(valuesToBeRemoved); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("ObjectWrapper("); + builder.append(ContainerWrapper.getDisplayNameFromItem(object)); + builder.append(" ("); + builder.append(status); + builder.append(") "); + builder.append(getContainers() == null ? null : getContainers().size()); + builder.append(" containers)"); + return builder.toString(); + } + + public boolean isProtectedAccount() { + if (object == null || !(ShadowType.class.isAssignableFrom(object.getCompileTimeClass()))) { + return false; + } + + PrismProperty protectedObject = object.findProperty(ShadowType.F_PROTECTED_OBJECT); + if (protectedObject == null) { + return false; + } + + return protectedObject.getRealValue() != null ? protectedObject.getRealValue() : false; + } + + private static class PathSizeComparator implements Comparator { + + @Override + public int compare(ContainerWrapper c1, ContainerWrapper c2) { + int size1 = c1.getPath() != null ? c1.getPath().size() : 0; + int size2 = c2.getPath() != null ? c2.getPath().size() : 0; + + return size1 - size2; + } + } public String getOid() { return object.getOid(); } - public boolean isShowAssignments() { - return showAssignments; - } - - public void setShowAssignments(boolean showAssignments) { - this.showAssignments = showAssignments; - } - - @Override - public void setShowEmpty(boolean showEmpty, boolean recursive) { - super.setShowEmpty(showEmpty, recursive); - } - - - public void setShowEmpty(boolean showEmpty) { - super.setShowEmpty(showEmpty, false); - getContainers().forEach(container -> container.setShowEmpty(showEmpty, true)); - } - - public boolean isReadonly() { - if (isProtectedAccount()) { - return true; - } - return readonly; - } - - public void setReadonly(boolean readonly) { - this.readonly = readonly; - } - - public boolean isShowInheritedObjectAttributes() { - return showInheritedObjectAttributes; - } - - public void setShowInheritedObjectAttributes(boolean showInheritedObjectAttributes) { - this.showInheritedObjectAttributes = showInheritedObjectAttributes; - } + public boolean isShowAssignments() { + return showAssignments; + } + + public void setShowAssignments(boolean showAssignments) { + this.showAssignments = showAssignments; + } + + @Override + public void setShowEmpty(boolean showEmpty, boolean recursive) { + super.setShowEmpty(showEmpty, recursive); + } + + public void setShowEmpty(boolean showEmpty) { + super.setShowEmpty(showEmpty, false); + getContainers().forEach(container -> container.setShowEmpty(showEmpty, true)); + } + + public boolean isReadonly() { + if (isProtectedAccount()) { + return true; + } + return readonly; + } + + public void setReadonly(boolean readonly) { + this.readonly = readonly; + } + + public boolean isShowInheritedObjectAttributes() { + return showInheritedObjectAttributes; + } + + public void setShowInheritedObjectAttributes(boolean showInheritedObjectAttributes) { + this.showInheritedObjectAttributes = showInheritedObjectAttributes; + } public boolean isEnforceRequiredFields() { return enforceRequiredFields; @@ -576,22 +556,19 @@ public void setEnforceRequiredFields(boolean enforceRequiredFields) { } public PrismContainerDefinition getDefinition() { -// if (objectDefinitionForEditing != null) { -// return objectDefinitionForEditing; -// } - return object.getDefinition(); - } - - public PrismContainerDefinition getRefinedAttributeDefinition() { - if (objectClassDefinitionForEditing != null) { - return objectClassDefinitionForEditing.toResourceAttributeContainerDefinition(); - } - return null; - } + return object.getDefinition(); + } + + public PrismContainerDefinition getRefinedAttributeDefinition() { + if (objectClassDefinitionForEditing != null) { + return objectClassDefinitionForEditing.toResourceAttributeContainerDefinition(); + } + return null; + } public void copyRuntimeStateTo(ObjectWrapper newWrapper) { newWrapper.setMinimalized(this.isMinimalized()); -// newWrapper.setShowEmpty(this.isShowEmpty()); + // newWrapper.setShowEmpty(this.isShowEmpty()); newWrapper.setSorted(this.isSorted()); newWrapper.setSelectable(this.isSelectable()); newWrapper.setSelected(this.isSelected()); @@ -601,48 +578,51 @@ public void copyRuntimeStateTo(ObjectWrapper newWrapper) { } // returns true if everything is OK - // to be used when enforceRequiredFields is false, so we want to check them only when really needed - // (e.g. MID-3876: when rejecting a work item, fields marked as required need not be present) + // to be used when enforceRequiredFields is false, so we want to check them + // only when really needed + // (e.g. MID-3876: when rejecting a work item, fields marked as required + // need not be present) public boolean checkRequiredFields(PageBase pageBase) { - boolean rv = true; + boolean rv = true; for (ContainerWrapper container : containers) { if (!container.checkRequired(pageBase)) { - rv = false; // continuing to display messages for all missing fields + rv = false; // continuing to display messages for all missing + // fields } } return rv; } - @Override - public String debugDump() { - return debugDump(0); - } - - @Override - public String debugDump(int indent) { - StringBuilder sb = new StringBuilder(); - DebugUtil.indentDebugDump(sb, indent); - sb.append("ObjectWrapper(\n"); - DebugUtil.debugDumpWithLabel(sb, "displayName", displayName, indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "description", description, indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "object", object == null ? null : object.toString(), indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "objectOld", objectOld == null ? null : objectOld.toString(), indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "oldDelta", oldDelta, indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "status", status == null ? null : status.toString(), indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "headerStatus", headerStatus == null ? null : headerStatus.toString(), indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "containers", containers, indent + 1); - sb.append("\n"); - DebugUtil.debugDumpWithLabel(sb, "loadOptions", loadOptions, indent + 1); - sb.append("\n"); - DebugUtil.indentDebugDump(sb, indent); - sb.append(")"); - return sb.toString(); - } + @Override + public String debugDump() { + return debugDump(0); + } + + @Override + public String debugDump(int indent) { + StringBuilder sb = new StringBuilder(); + DebugUtil.indentDebugDump(sb, indent); + sb.append("ObjectWrapper(\n"); + DebugUtil.debugDumpWithLabel(sb, "displayName", displayName, indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "description", description, indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "object", object == null ? null : object.toString(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "objectOld", objectOld == null ? null : objectOld.toString(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "oldDelta", oldDelta, indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "status", status == null ? null : status.toString(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "headerStatus", headerStatus == null ? null : headerStatus.toString(), indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "containers", containers, indent + 1); + sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "loadOptions", loadOptions, indent + 1); + sb.append("\n"); + DebugUtil.indentDebugDump(sb, indent); + sb.append(")"); + return sb.toString(); + } } From d0481eeb3d6bd4b72a05b03c62bcf609de8cae08 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Fri, 22 Sep 2017 16:44:55 +0200 Subject: [PATCH 39/97] No longer allowing putting multiple values into single-valued item. --- .../com/evolveum/midpoint/prism/Item.java | 8 +- .../midpoint/schema/TestMiscellaneous.java | 76 +++++++++++++++++++ infra/schema/testng-unit.xml | 1 + 3 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 infra/schema/src/test/java/com/evolveum/midpoint/schema/TestMiscellaneous.java diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/Item.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/Item.java index 0fe6c53bc15..2ec49b934ce 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/Item.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/Item.java @@ -429,8 +429,12 @@ public boolean add(@NotNull V newValue, boolean checkUniqueness) throws SchemaEx if (checkUniqueness && containsEquivalentValue(newValue)) { return false; } - if (getDefinition() != null) { - newValue.applyDefinition(getDefinition(), false); + D definition = getDefinition(); + if (definition != null) { + if (!isEmpty() && definition.isSingleValue()) { + throw new SchemaException("Attempt to put more than one value to single-valued item " + this + "; newly added value: " + newValue); + } + newValue.applyDefinition(definition, false); } return values.add(newValue); } diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestMiscellaneous.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestMiscellaneous.java new file mode 100644 index 00000000000..24b7b00e1c1 --- /dev/null +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestMiscellaneous.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.schema; + +import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.prism.PrismContainer; +import com.evolveum.midpoint.prism.PrismContainerValue; +import com.evolveum.midpoint.prism.util.PrismTestUtil; +import com.evolveum.midpoint.schema.constants.MidPointConstants; +import com.evolveum.midpoint.util.PrettyPrinter; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; +import org.xml.sax.SAXException; + +import java.io.IOException; + +import static com.evolveum.midpoint.prism.util.PrismTestUtil.getPrismContext; +import static org.testng.AssertJUnit.fail; + +/** + * @author mederly + * + */ +public class TestMiscellaneous { + + @BeforeSuite + public void setup() throws SchemaException, SAXException, IOException { + PrettyPrinter.setDefaultNamespacePrefix(MidPointConstants.NS_MIDPOINT_PUBLIC_PREFIX); + PrismTestUtil.resetPrismContext(MidPointPrismContextFactory.FACTORY); + } + + @Test + public void singleValuedItems() throws Exception { + System.out.println("===[ singleValuedItems ]==="); + + UserType userBean = getPrismContext().createObjectable(UserType.class) + .beginAssignment() + .id(1L) + .targetRef(new ObjectReferenceType().oid("123456").type(RoleType.COMPLEX_TYPE)) + .end(); + + //noinspection unchecked + PrismContainerValue assignmentPcv = userBean.getAssignment().get(0).asPrismContainerValue(); + PrismContainer limitContentPc = assignmentPcv + .findOrCreateContainer(AssignmentType.F_LIMIT_TARGET_CONTENT); + PrismContainerValue val1 = limitContentPc.createNewValue(); + val1.setId(1L); + PrismContainerValue val2 = val1.clone(); + val2.setId(2L); + try { + limitContentPc.add(val2); + fail("unexpected success"); + } catch (SchemaException e) { + System.out.println("Got expected exception: " + e); + } + } + +} diff --git a/infra/schema/testng-unit.xml b/infra/schema/testng-unit.xml index a601d8a8d68..3d8e7c61e35 100644 --- a/infra/schema/testng-unit.xml +++ b/infra/schema/testng-unit.xml @@ -135,6 +135,7 @@ + From c1db27f597cc7005edcc038814080b39ee19c808 Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Fri, 22 Sep 2017 17:01:56 +0200 Subject: [PATCH 40/97] sorting for container values --- .../web/component/prism/ContainerValueWrapper.java | 2 +- .../midpoint/web/component/prism/ObjectWrapper.java | 9 +++++---- .../component/prism/PrismContainerValueHeaderPanel.java | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java index efcfca03ec4..1c70de9ca07 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java @@ -260,7 +260,7 @@ public void setReadonly(boolean readonly) { } public void sort(final PageBase pageBase) { - if (containerWrapper.isSorted()) { + if (isSorted()) { Collections.sort(properties, new Comparator() { @Override public int compare(ItemWrapper pw1, ItemWrapper pw2) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java index ef79556f453..65473318f01 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java @@ -314,10 +314,11 @@ public void normalize() throws SchemaException { } public void sort(PageBase pageBase) { - ContainerWrapper main = findMainContainerWrapper(); - if (main != null) { - main.sort(pageBase); - } + getContainers().forEach(ContainerWrapper -> ContainerWrapper.sort(pageBase)); +// ContainerWrapper main = findMainContainerWrapper(); +// if (main != null) { +// main.sort(pageBase); +// } computeStripes(); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java index 410e4e25200..ab5dfc2efa9 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismContainerValueHeaderPanel.java @@ -103,9 +103,9 @@ public boolean isOn() { @Override public void onClick(AjaxRequestTarget target) { - PrismWrapper objectWrapper = PrismContainerValueHeaderPanel.this.getModelObject(); - objectWrapper.setSorted(!objectWrapper.isSorted()); -// objectWrapper.sort((PageBase)getPage()); + ContainerValueWrapper containerValueWrapper = PrismContainerValueHeaderPanel.this.getModelObject(); + containerValueWrapper.setSorted(!containerValueWrapper.isSorted()); + containerValueWrapper.sort(getPageBase()); onButtonClick(target); } From a22b447b7509aa975d613dc6cf19bf5b877adf96 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Fri, 22 Sep 2017 17:23:45 +0200 Subject: [PATCH 41/97] Privileged mode for bulk actions (to be used for constraint evaluation). --- .../policy/evaluators/StateConstraintEvaluator.java | 2 +- .../model/impl/scripting/ExecutionContext.java | 9 +++++++++ .../impl/scripting/ScriptingExpressionEvaluator.java | 10 ++++++++++ .../impl/scripting/actions/BaseActionExecutor.java | 6 +++++- .../model/impl/scripting/actions/NotifyExecutor.java | 2 +- .../model/impl/scripting/actions/ScriptExecutor.java | 2 +- 6 files changed, 27 insertions(+), 4 deletions(-) diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/StateConstraintEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/StateConstraintEvaluator.java index 8dac51dd762..1be7257be81 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/StateConstraintEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/StateConstraintEvaluator.java @@ -124,7 +124,7 @@ private EvaluatedPolicyRuleTrigger evaluateForObject(St variables.put("ruleEvaluationContext", ctx); ExecutionContext resultingContext; try { - resultingContext = scriptingExpressionEvaluator.evaluateExpression(constraint.getExecuteScript(), variables, ctx.task, result); + resultingContext = scriptingExpressionEvaluator.evaluateExpressionPrivileged(constraint.getExecuteScript(), variables, ctx.task, result); } catch (ScriptExecutionException e) { throw new SystemException(e); // TODO } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java index d76ae51be53..d00c56ef2f9 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java @@ -38,6 +38,7 @@ public class ExecutionContext { private static final Trace LOGGER = TraceManager.getTrace(ExecutionContext.class); + private boolean privileged; private final ScriptingExpressionEvaluationOptionsType options; private final Task task; private final ScriptingExpressionEvaluator scriptingExpressionEvaluator; @@ -138,4 +139,12 @@ public ModelService getModelService() { public PrismContext getPrismContext() { return scriptingExpressionEvaluator.getPrismContext(); } + + public boolean isPrivileged() { + return privileged; + } + + public void setPrivileged(boolean privileged) { + this.privileged = privileged; + } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java index c34fc099f08..97c4d86ff13 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java @@ -160,6 +160,16 @@ public ExecutionContext evaluateExpression(@NotNull ExecuteScriptType executeScr return context; } + // VERY TEMPORARY! + public ExecutionContext evaluateExpressionPrivileged(@NotNull ExecuteScriptType executeScript, @NotNull Map initialVariables, Task task, OperationResult result) throws ScriptExecutionException { + Validate.notNull(executeScript.getScriptingExpression(), "Scripting expression must be present"); + ExecutionContext context = evaluateExpression(executeScript.getScriptingExpression().getValue(), + PipelineData.parseFrom(executeScript.getInput(), initialVariables, prismContext), executeScript.getOptions(), initialVariables, task, result); + context.setPrivileged(true); + context.computeResults(); + return context; + } + // main entry point from the outside private ExecutionContext evaluateExpression(ScriptingExpressionType expression, PipelineData data, ScriptingExpressionEvaluationOptionsType options, Map initialVariables, diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/BaseActionExecutor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/BaseActionExecutor.java index a4a33b6a952..a3c0002d3d7 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/BaseActionExecutor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/BaseActionExecutor.java @@ -133,7 +133,11 @@ protected Throwable processActionException(Throwable e, String actionName, Prism } } - protected void checkRootAuthorization(OperationResult globalResult, String actionName) throws ScriptExecutionException { + protected void checkRootAuthorization(ExecutionContext context, + OperationResult globalResult, String actionName) throws ScriptExecutionException { + if (context.isPrivileged()) { + return; + } try { securityEnforcer.authorize(AuthorizationConstants.AUTZ_ALL_URL, null, null, null, null, null, globalResult); } catch (SecurityViolationException |SchemaException e) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/NotifyExecutor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/NotifyExecutor.java index 896a01f4e4e..8bbe0851f69 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/NotifyExecutor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/NotifyExecutor.java @@ -76,7 +76,7 @@ public PipelineData execute(ActionExpressionType expression, PipelineData input, boolean forWholeInput = expressionHelper.getArgumentAsBoolean(expression.getParameter(), PARAM_FOR_WHOLE_INPUT, input, context, false, PARAM_FOR_WHOLE_INPUT, globalResult); if (handler != null) { - checkRootAuthorization(globalResult, NAME); // TODO explain that the reason is that handler is not null + checkRootAuthorization(context, globalResult, NAME); // TODO explain that the reason is that handler is not null } if (status == null) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/ScriptExecutor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/ScriptExecutor.java index fcc59cbaf67..d5061df292a 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/ScriptExecutor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/ScriptExecutor.java @@ -70,7 +70,7 @@ public void init() { @Override public PipelineData execute(ActionExpressionType expression, PipelineData input, ExecutionContext context, OperationResult globalResult) throws ScriptExecutionException { - checkRootAuthorization(globalResult, NAME); + checkRootAuthorization(context, globalResult, NAME); ScriptExpressionEvaluatorType script = expressionHelper.getSingleArgumentValue(expression.getParameter(), PARAM_SCRIPT, true, true, NAME, input, context, ScriptExpressionEvaluatorType.class, globalResult); From d625c749762bcbc866633a5f31aa46180924c3e7 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Sat, 23 Sep 2017 05:38:00 +0200 Subject: [PATCH 42/97] Interim commit. --- .../xml/ns/public/common/common-core-3.xsd | 82 ++++++++++++---- .../public/common/common-model-context-3.xsd | 80 ++++++++++++++- .../xml/ns/public/common/common-policy-3.xsd | 97 ++++++++++--------- .../complex/system-configuration.xml | 41 +++++++- .../model/impl/lens/ChangeExecutor.java | 48 +++------ .../model/impl/lens/LensElementContext.java | 20 ++++ .../impl/lens/LensProjectionContext.java | 2 +- .../impl/lens/projector/FocusProcessor.java | 4 +- ...AssignmentPolicyRuleEvaluationContext.java | 16 +-- .../ObjectPolicyRuleEvaluationContext.java | 13 ++- .../policy/PolicyRuleEvaluationContext.java | 13 +-- .../projector/policy/PolicyRuleProcessor.java | 42 ++++++-- .../policy/PolicySituationUpdater.java | 9 ++ .../policy/RulesEvaluationContext.java | 31 ++++++ 14 files changed, 357 insertions(+), 141 deletions(-) create mode 100644 model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/RulesEvaluationContext.java 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 3cc847b530d..43e25402934 100644 --- 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 @@ -362,8 +362,50 @@ - - + + + + + The policy situation(s) of this object. The situations are result of + evaluation of the policy rules. This property is recorded for each object + and can be used for reporting, diagnostics, target selection in certification + campaigns, etc. + + + 3.5 + true + + + + + + + + Triggered policy rules for this assignment. (Not necessarily complete; subject to specified storage strategy.) + This is EXPERIMENTAL functionality. It is possibly to change in the near future. + + + 3.7 + true + + + + + + + + Recorded exception from a policy rule. The exceptions that are approved are + recoded here to avoid re-evaluating and re-approving them all the time. + This is EXPERIMENTAL functionality. It is likely to change in the near future. + + + 3.5 + true + + + + + @@ -2399,22 +2441,7 @@ - - - - The policy situation(s) of this object. The situations are result of - evaluation of the policy rules. This property is recorded for each object - and can be used for reporting, diagnostics, target selection in certification - campaigns, etc. - - - 3.5 - true - - - - - + @@ -3492,12 +3519,25 @@ - Fired policy rule triggers for this assignment. (Some fields of the triggers might be zeroed out - in order to save space. This is yet to be decided.) - This is EXPERIMENTAL functionality. It is likely to change in the near future. + DEPRECATED. DO NOT USE. 3.6 + true + 3.7 + true + + + + + + + + Triggered policy rules for this assignment. (Not necessarily complete; subject to specified storage strategy.) + This is EXPERIMENTAL functionality. It is possibly to change in the near future. + + + 3.7 true diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-model-context-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-model-context-3.xsd index b9aecb7f036..0e306f80e99 100644 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-model-context-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-model-context-3.xsd @@ -506,10 +506,40 @@ - - - - + + + + DEPRECATED. Moved to EvaluatedPolicyRuleType. DO NOT USE. + + + true + 3.7 + + + + + + + DEPRECATED. Moved to EvaluatedPolicyRuleType. DO NOT USE. + + + true + 3.7 + + + + + + + DEPRECATED. Moved to EvaluatedPolicyRuleType. DO NOT USE. + + + true + 3.7 + + + + @@ -637,7 +667,47 @@ - + + + + TODO + + + 3.7 + + + + + + + TODO + + + 3.7 + + + + + + + TODO + + + 3.7 + + + + + + + TODO + + + 3.7 + + + + diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd index 185dfa04f07..534cb7687dd 100644 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd @@ -300,43 +300,6 @@ - - - - Policy situation that is the result when this constraint is triggered. - TODO specify the relation to policySituation defined at the level of policy rule. - - - 3.7 - true - - - - - - - How is this constraint to be used? E.g. also for reporting or for certification? This determines - if its triggers and/or related policy situation should be stored into repository. - EXPERIMENTAL - - - 3.7 - true - - - - - - - If triggers are to be stored, what level of details should be preserved? - EXPERIMENTAL - - - 3.7 - true - - - @@ -449,7 +412,7 @@ - + If triggers are to be stored, what level of details should be preserved? @@ -461,33 +424,33 @@ - + - Only message and short message will be stored. + Triggers will not be stored. - + - + - Whole triggers will be stored. (But only those that are directly marked with expectedUse property.) + Only message and short message for each trigger will be stored. Hidden and final presentation settings are respected. - + - + - Whole triggers will be stored, including subtriggers. + The triggers for the rule will be stored (including subtriggers). Hidden and final presentation settings are respected. - + @@ -1051,6 +1014,14 @@ + + + + Record action. The operation will proceed. Policy situation will be recorded for + given object or assignment. It can be reported on or certified later on. + + + @@ -1404,6 +1375,38 @@ + + + + TODO + + + + 3.7 + true + + + + + + + + + How should be triggers stored? + EXPERIMENTAL + + + 3.7 + true + + + + + + + + + diff --git a/model/certification-impl/src/test/resources/complex/system-configuration.xml b/model/certification-impl/src/test/resources/complex/system-configuration.xml index ca588c142d4..8c8cd007d65 100644 --- a/model/certification-impl/src/test/resources/complex/system-configuration.xml +++ b/model/certification-impl/src/test/resources/complex/system-configuration.xml @@ -223,9 +223,6 @@ true - http://sample.org/situations#active-role-with-no-identifier - certification - fullReport role-active @@ -240,8 +237,6 @@ true - http://sample.org/situations#incomplete-role-c1-to-c4 - fullReport c1-no-risk-level @@ -389,6 +384,42 @@ RoleType + + re1-report-draft-roles-violating-c1-c4 + RE1: See all draft roles that do not meet constraints C1-C4. + + + incomplete-role-c1-to-c4 + + + http://sample.org/situations#incomplete-role-c1-to-c4 + + + full + + + + RoleType + + + + re2-report-active-roles-violating-c5 + RE2: See all active roles that do not meet constraint C5. + + + active-role-with-no-identifier + + + http://sample.org/situations#active-role-with-no-identifier + + + none + + + + RoleType + + test-primary 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 834c11784d6..6fc341b5c85 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 @@ -110,38 +110,17 @@ public class ChangeExecutor { private static final String OPERATION_UPDATE_SITUATION_ACCOUNT = ChangeExecutor.class.getName() + ".updateSituationInShadow"; - @Autowired - private transient TaskManager taskManager; - - @Autowired - @Qualifier("cacheRepositoryService") - private transient RepositoryService cacheRepositoryService; - - @Autowired - private ProvisioningService provisioning; - - @Autowired - private PrismContext prismContext; - - @Autowired - private ExpressionFactory expressionFactory; - - @Autowired - private SecurityEnforcer securityEnforcer; - - @Autowired - private Clock clock; - - @Autowired - private ModelObjectResolver objectResolver; - - @Autowired - private OperationalDataManager metadataManager; - - @Autowired - private PolicySituationUpdater policySituationUpdater; - @Autowired - private CredentialsProcessor credentialsProcessor; + @Autowired private transient TaskManager taskManager; + @Autowired @Qualifier("cacheRepositoryService") private transient RepositoryService cacheRepositoryService; + @Autowired private ProvisioningService provisioning; + @Autowired private PrismContext prismContext; + @Autowired private ExpressionFactory expressionFactory; + @Autowired private SecurityEnforcer securityEnforcer; + @Autowired private Clock clock; + @Autowired private ModelObjectResolver objectResolver; + @Autowired private OperationalDataManager metadataManager; + @Autowired private PolicySituationUpdater policySituationUpdater; + @Autowired private CredentialsProcessor credentialsProcessor; private PrismObjectDefinition userDefinition = null; private PrismObjectDefinition shadowDefinition = null; @@ -171,6 +150,11 @@ public boolean executeChanges(LensContext context, Tas if (focusContext != null) { ObjectDelta focusDelta = focusContext.getWaveExecutableDelta(context.getExecutionWave()); + for (ItemDelta itemDelta : focusContext.getPendingPolicySituationModifications()) { + focusContext.swallowToSecondaryDelta(itemDelta); + } + focusContext.clearPendingPolicySituationModifications(); + if (!focusContext.isDelete()) { focusDelta = policySituationUpdater.applyAssignmentSituation(context, focusDelta); policySituationUpdater.storeFocusPolicySituation(context); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java index abb553d18db..fee71efd96c 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java @@ -73,6 +73,14 @@ public abstract class LensElementContext implements ModelE private int iteration; private String iterationToken; + /** + * These are policy situation modifications that should be applied regardless of how the clockwork is exited + * (e.g. in primary state, in final state, with an exception). + * + * Currently implemented only for focus, not for projections. + */ + @NotNull private transient final List> pendingPolicySituationModifications = new ArrayList<>(); + /** * Initial intent regarding the account. It indicated what the initiator of the operation WANTS TO DO with the * context. @@ -250,6 +258,18 @@ public void swallowToPrimaryDelta(ItemDelta itemDelta) throws SchemaExcepti public abstract void swallowToSecondaryDelta(ItemDelta itemDelta) throws SchemaException; + public List> getPendingPolicySituationModifications() { + return pendingPolicySituationModifications; + } + + public void clearPendingPolicySituationModifications() { + pendingPolicySituationModifications.clear(); + } + + public void addToPendingPolicySituationModifications(ItemDelta modification) { + pendingPolicySituationModifications.add(modification); + } + public boolean isAdd() { if (ObjectDelta.isAdd(getPrimaryDelta())) { return true; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java index 12b4b59fdf7..c85343d4eba 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java @@ -243,7 +243,7 @@ public void addSecondaryDelta(ObjectDelta delta) throws SchemaExcept @Override public void swallowToSecondaryDelta(ItemDelta itemDelta) throws SchemaException { if (secondaryDelta == null) { - secondaryDelta = new ObjectDelta(getObjectTypeClass(), ChangeType.MODIFY, getPrismContext()); + secondaryDelta = new ObjectDelta<>(getObjectTypeClass(), ChangeType.MODIFY, getPrismContext()); secondaryDelta.setOid(getOid()); } secondaryDelta.swallow(itemDelta); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java index 2416410aede..a72191f2adc 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java @@ -260,7 +260,9 @@ private void processFocusFocus(LensContext context, Str // ASSIGNMENTS - LensUtil.partialExecute("assignments", + focusContext.clearPendingPolicySituationModifications(); + + LensUtil.partialExecute("assignments", () -> assignmentProcessor.processAssignmentsProjections(context, now, task, result), partialProcessingOptions::getAssignments); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/AssignmentPolicyRuleEvaluationContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/AssignmentPolicyRuleEvaluationContext.java index 734839749c2..93dae8057c0 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/AssignmentPolicyRuleEvaluationContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/AssignmentPolicyRuleEvaluationContext.java @@ -43,15 +43,18 @@ public class AssignmentPolicyRuleEvaluationContext extends public AssignmentPolicyRuleEvaluationContext(@NotNull EvaluatedPolicyRule policyRule, @NotNull EvaluatedAssignmentImpl evaluatedAssignment, boolean inPlus, boolean inZero, boolean inMinus, boolean isDirect, LensContext context, - DeltaSetTriple> evaluatedAssignmentTriple, Task task) { - this(policyRule, evaluatedAssignment, inPlus, inZero, inMinus, isDirect, context, evaluatedAssignmentTriple, task, ObjectState.AFTER); + DeltaSetTriple> evaluatedAssignmentTriple, Task task, + RulesEvaluationContext globalCtx) { + this(policyRule, evaluatedAssignment, inPlus, inZero, inMinus, isDirect, context, evaluatedAssignmentTriple, + task, ObjectState.AFTER, globalCtx); } public AssignmentPolicyRuleEvaluationContext(@NotNull EvaluatedPolicyRule policyRule, @NotNull EvaluatedAssignmentImpl evaluatedAssignment, boolean inPlus, boolean inZero, boolean inMinus, boolean isDirect, LensContext context, - DeltaSetTriple> evaluatedAssignmentTriple, Task task, ObjectState state) { - super(policyRule, context, task, state); + DeltaSetTriple> evaluatedAssignmentTriple, Task task, ObjectState state, + RulesEvaluationContext globalCtx) { + super(policyRule, context, task, globalCtx, state); this.evaluatedAssignment = evaluatedAssignment; this.inPlus = inPlus; this.inZero = inZero; @@ -62,7 +65,8 @@ public AssignmentPolicyRuleEvaluationContext(@NotNull EvaluatedPolicyRule policy @Override public AssignmentPolicyRuleEvaluationContext cloneWithStateConstraints(ObjectState state) { - return new AssignmentPolicyRuleEvaluationContext<>(policyRule, evaluatedAssignment, inPlus, inZero, inMinus, isDirect, lensContext, evaluatedAssignmentTriple, task, state); + return new AssignmentPolicyRuleEvaluationContext<>(policyRule, evaluatedAssignment, inPlus, inZero, inMinus, isDirect, lensContext, evaluatedAssignmentTriple, task, state, + globalCtx); } @Override @@ -98,6 +102,6 @@ public String getShortDescription() { @Override public AssignmentPolicyRuleEvaluationContext clone() { return new AssignmentPolicyRuleEvaluationContext<>(policyRule, evaluatedAssignment, inPlus, inZero, inMinus, - isDirect, lensContext, evaluatedAssignmentTriple, task); + isDirect, lensContext, evaluatedAssignmentTriple, task, globalCtx); } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/ObjectPolicyRuleEvaluationContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/ObjectPolicyRuleEvaluationContext.java index 43957ddd5fb..19da2f325c5 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/ObjectPolicyRuleEvaluationContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/ObjectPolicyRuleEvaluationContext.java @@ -31,18 +31,18 @@ */ public class ObjectPolicyRuleEvaluationContext extends PolicyRuleEvaluationContext { - public ObjectPolicyRuleEvaluationContext(@NotNull EvaluatedPolicyRule policyRule, LensContext context, Task task) { - this(policyRule, context, task, ObjectState.AFTER); + public ObjectPolicyRuleEvaluationContext(@NotNull EvaluatedPolicyRule policyRule, RulesEvaluationContext globalCtx, LensContext context, Task task) { + this(policyRule, globalCtx, context, task, ObjectState.AFTER); } - public ObjectPolicyRuleEvaluationContext(@NotNull EvaluatedPolicyRule policyRule, LensContext context, Task task, + public ObjectPolicyRuleEvaluationContext(@NotNull EvaluatedPolicyRule policyRule, RulesEvaluationContext globalCtx, LensContext context, Task task, ObjectState state) { - super(policyRule, context, task, state); + super(policyRule, context, task, globalCtx, state); } @Override public PolicyRuleEvaluationContext cloneWithStateConstraints(ObjectState state) { - return new ObjectPolicyRuleEvaluationContext<>(policyRule, lensContext, task, state); + return new ObjectPolicyRuleEvaluationContext<>(policyRule, globalCtx, lensContext, task, state); } @Override @@ -58,7 +58,6 @@ public String getShortDescription() { @SuppressWarnings({ "CloneDoesntDeclareCloneNotSupportedException", "MethodDoesntCallSuperMethod" }) @Override public ObjectPolicyRuleEvaluationContext clone() { - return new ObjectPolicyRuleEvaluationContext<>(policyRule, lensContext, task); + return new ObjectPolicyRuleEvaluationContext<>(policyRule, globalCtx, lensContext, task); } - } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleEvaluationContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleEvaluationContext.java index 2442c2cb190..8e8b87a3caf 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleEvaluationContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleEvaluationContext.java @@ -37,18 +37,15 @@ public abstract class PolicyRuleEvaluationContext implement @NotNull public final LensFocusContext focusContext; @NotNull public final Task task; @NotNull public final ObjectState state; + @NotNull public final RulesEvaluationContext globalCtx; public PolicyRuleEvaluationContext(@NotNull EvaluatedPolicyRule policyRule, @NotNull LensContext context, - @NotNull Task task) { - this(policyRule, context, task, null); - } - - public PolicyRuleEvaluationContext(@NotNull EvaluatedPolicyRule policyRule, @NotNull LensContext context, - @NotNull Task task, @NotNull ObjectState state) { + @NotNull Task task, @NotNull RulesEvaluationContext globalCtx, @NotNull ObjectState state) { this.policyRule = policyRule; this.lensContext = context; this.focusContext = context.getFocusContext(); this.task = task; + this.globalCtx = globalCtx; if (focusContext == null) { throw new IllegalStateException("No focus context"); } @@ -72,4 +69,8 @@ public boolean isApplicableToState() { } public abstract String getShortDescription(); + + public void record() { + globalCtx.rulesToRecord.add(policyRule); + } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java index f53e12fed3e..a04d3df97f0 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java @@ -25,7 +25,6 @@ import com.evolveum.midpoint.prism.delta.ContainerDelta; import com.evolveum.midpoint.prism.delta.DeltaSetTriple; import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; -import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.repo.common.expression.ExpressionUtil; import com.evolveum.midpoint.repo.common.expression.ObjectDeltaObject; @@ -70,7 +69,7 @@ public class PolicyRuleProcessor { @Autowired @Qualifier("cacheRepositoryService") private RepositoryService repositoryService; @Autowired private MappingFactory mappingFactory; @Autowired private MappingEvaluator mappingEvaluator; - @Autowired private MatchingRuleRegistry matchingRuleRegistry; + @Autowired private PolicySituationUpdater situationUpdater; @Autowired private AssignmentConstraintEvaluator assignmentConstraintEvaluator; @Autowired private HasAssignmentConstraintEvaluator hasAssignmentConstraintEvaluator; @@ -98,6 +97,8 @@ public void evaluateAssignmentPolicyRules(LensContext c throws PolicyViolationException, SchemaException, ExpressionEvaluationException, ObjectNotFoundException { for (EvaluatedAssignmentImpl evaluatedAssignment : evaluatedAssignmentTriple.union()) { + RulesEvaluationContext globalCtx = new RulesEvaluationContext(); + boolean inPlus = evaluatedAssignmentTriple.presentInPlusSet(evaluatedAssignment); boolean inMinus = evaluatedAssignmentTriple.presentInMinusSet(evaluatedAssignment); boolean inZero = evaluatedAssignmentTriple.presentInZeroSet(evaluatedAssignment); @@ -116,7 +117,8 @@ public void evaluateAssignmentPolicyRules(LensContext c if (!hasSituationConstraint(policyRule)) { if (checkApplicabilityToAssignment(policyRule)) { evaluateRule(new AssignmentPolicyRuleEvaluationContext<>(policyRule, - evaluatedAssignment, inPlus, inZero, inMinus, true, context, evaluatedAssignmentTriple, task), result); + evaluatedAssignment, inPlus, inZero, inMinus, true, context, + evaluatedAssignmentTriple, task, globalCtx), result); } } } @@ -124,7 +126,8 @@ public void evaluateAssignmentPolicyRules(LensContext c if (!hasSituationConstraint(policyRule)) { if (checkApplicabilityToAssignment(policyRule)) { evaluateRule(new AssignmentPolicyRuleEvaluationContext<>(policyRule, - evaluatedAssignment, inPlus, inZero, inMinus, false, context, evaluatedAssignmentTriple, task), result); + evaluatedAssignment, inPlus, inZero, inMinus, false, context, + evaluatedAssignmentTriple, task, globalCtx), result); } } } @@ -132,7 +135,8 @@ public void evaluateAssignmentPolicyRules(LensContext c if (hasSituationConstraint(policyRule)) { if (checkApplicabilityToAssignment(policyRule)) { evaluateRule(new AssignmentPolicyRuleEvaluationContext<>(policyRule, - evaluatedAssignment, inPlus, inZero, inMinus, true, context, evaluatedAssignmentTriple, task), result); + evaluatedAssignment, inPlus, inZero, inMinus, true, context, + evaluatedAssignmentTriple, task, globalCtx), result); } } } @@ -140,10 +144,12 @@ public void evaluateAssignmentPolicyRules(LensContext c if (hasSituationConstraint(policyRule)) { if (checkApplicabilityToAssignment(policyRule)) { evaluateRule(new AssignmentPolicyRuleEvaluationContext<>(policyRule, - evaluatedAssignment, inPlus, inZero, inMinus, false, context, evaluatedAssignmentTriple, task), result); + evaluatedAssignment, inPlus, inZero, inMinus, false, context, + evaluatedAssignmentTriple, task, globalCtx), result); } } } + situationUpdater.applyAssignmentSituation(context, evaluatedAssignment, globalCtx.rulesToRecord); } exclusionConstraintEvaluator.checkExclusionsLegacy(context, evaluatedAssignmentTriple.getPlusSet(), @@ -176,6 +182,8 @@ public void evaluateObjectPolicyRules(LensContext conte return; } + RulesEvaluationContext globalCtx = new RulesEvaluationContext(); + List rules = new ArrayList<>(); collectFocusRulesFromAssignments(rules, context); collectGlobalObjectRules(rules, context, task, result); @@ -201,11 +209,12 @@ public void evaluateObjectPolicyRules(LensContext conte } for (EvaluatedPolicyRule rule : nonSituationRules) { - evaluateFocusRule(rule, context, task, result); + evaluateFocusRule(rule, context, globalCtx, task, result); } for (EvaluatedPolicyRule rule : situationRules) { - evaluateFocusRule(rule, context, task, result); + evaluateFocusRule(rule, context, globalCtx, task, result); } + situationUpdater.applyObjectSituation(context, globalCtx.rulesToRecord); } private Collection getAllGlobalRules(LensContext context) { @@ -214,9 +223,10 @@ private Collection getAllGlobalR : Collections.emptyList(); } - private void evaluateFocusRule(EvaluatedPolicyRule rule, LensContext context, Task task, OperationResult result) + private void evaluateFocusRule(EvaluatedPolicyRule rule, LensContext context, + RulesEvaluationContext globalCtx, Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException { - evaluateRule(new ObjectPolicyRuleEvaluationContext<>(rule, context, task), result); + evaluateRule(new ObjectPolicyRuleEvaluationContext<>(rule, globalCtx, context, task), result); } private void collectFocusRulesFromAssignments(List rules, LensContext context) { @@ -309,9 +319,21 @@ private void evaluateRule(PolicyRuleEvaluationContext c } ctx.triggerRule(triggers); } + if (ctx.policyRule.getActions() != null && ctx.policyRule.getActions().getRecordSituation() != null) { + ctx.record(); + } traceRuleEvaluationResult(ctx.policyRule, ctx); } +// private void prepareSituationDeltas(PolicyRuleEvaluationContext ctx, +// RecordSituationPolicyActionType recordAction) { +// if (ctx instanceof AssignmentPolicyRuleEvaluationContext) { +// situationUpdater.prepareAssignmentSituationDeltas(); +// } else { +// situationUpdater.prepareObjectSituationDeltas(ctx.lensContext, recordAction); +// } +// } + // returns non-empty list if the constraints evaluated to true (if allMustApply, all of the constraints must apply; otherwise, at least one must apply) @SuppressWarnings("unchecked") @NotNull diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicySituationUpdater.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicySituationUpdater.java index 5102a1869eb..ea46eb3e4be 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicySituationUpdater.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicySituationUpdater.java @@ -276,4 +276,13 @@ private PropertyDelta createTriggerDelta(ItemPat return triggersDelta; } + public void applyAssignmentSituation(LensContext context, + EvaluatedAssignmentImpl evaluatedAssignment, + List rulesToRecord) { + // TODO + } + + public void applyObjectSituation(LensContext context, List rulesToRecord) { + + } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/RulesEvaluationContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/RulesEvaluationContext.java new file mode 100644 index 00000000000..0ca6dc92085 --- /dev/null +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/RulesEvaluationContext.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.model.impl.lens.projector.policy; + +import com.evolveum.midpoint.model.api.context.EvaluatedPolicyRule; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author mederly + */ +public class RulesEvaluationContext { + + @NotNull final List rulesToRecord = new ArrayList<>(); // not private because it's final +} From ec64808010d070c5a4871aeab5df64fe604ad419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Ga=C5=A1par=C3=ADk?= Date: Sat, 23 Sep 2017 11:00:51 +0200 Subject: [PATCH 43/97] Translation WIP --- .../localization/Midpoint_cs.properties | 16 +- .../localization/Midpoint_de.properties | 16 +- .../localization/Midpoint_en.properties | 8 +- .../localization/Midpoint_es.properties | 16 +- .../localization/Midpoint_et.properties | 24 +- .../localization/Midpoint_fi.properties | 16 +- .../localization/Midpoint_hu.properties | 16 +- .../localization/Midpoint_pl.properties | 16 +- .../localization/Midpoint_pt_BR.properties | 16 +- .../localization/Midpoint_ru.properties | 16 +- .../localization/Midpoint_sk.properties | 442 +++++++++--------- .../localization/Midpoint_tr.properties | 16 +- .../localization/Midpoint_zh_CN.properties | 16 +- .../localization/schema_cs.properties | 4 +- .../localization/schema_sk.properties | 72 +-- 15 files changed, 393 insertions(+), 317 deletions(-) diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_cs.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_cs.properties index d2ad9f20957..ece0f20f6f8 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_cs.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_cs.properties @@ -1083,6 +1083,7 @@ PageAdmin.menu.top.users.org=Org. struktura PageAdmin.menu.top.users.org.tree=Organizační strom PageAdmin.menu.top.users=Uživatelé PageAdmin.menu.top.valuePolicies.list= Seznam politik hodnot +PageAdmin.menu.top.valuePolicies.new = Nová politika hodnot PageAdmin.menu.top.valuePolicies= Politika hodnot PageAdmin.menu.top.workItems.listClaimable=Úkoly nárokované na mě PageAdmin.menu.top.workItems.list=Moje úkoly @@ -2265,6 +2266,7 @@ MultipleAssignmentSelector.orgUnit=Org. jednotka pageValuePolicies.table.description=Popis pageValuePolicies.button.delete=Smazat PageValuePolicies.title=Seznam politik hodnot +PageValuePolicy.title = Politika hodnot pageWorkItem.accordionLabel.additionalData=Související údaje (technické informace) pageWorkItem.accordionLabel.objectNew=Objekt po navrhované změně (technické informace) pageWorkItem.accordionLabel.objectOld=Objekt před změnou (technické informace) @@ -2325,6 +2327,7 @@ TaskWfParentPanel.requestsHelp=Zde jsou zobrazeny všechny procesy schvalování workItemPanel.otherWorkItems=Další pracovní položky pro tuto žádost workItemPanel.requests=Žádosti workItemPanel.relatedRequests=Příbuzné žádosti +workItemPanel.reasons=Zdůvodnění pro schvalovací proces workItemPanel.approverComment=Komentář schvalovatele workItemPanel.approverInstruction=Instrukce schvalovatele pageWorkItems.button.approve=Schválit @@ -2853,7 +2856,6 @@ SystemConfigPanel.deploymentInformation.logoImageUrl = Adresa URL pro logo SystemConfigPanel.deploymentInformation.logoCssClass = CSS třída ikonek SystemConfigPanel.deploymentInformation.customerUrl = Zákaznická adresa SystemConfigPanel.deploymentInformation.partnerName = Jméno partnera -SystemConfigPanel.deploymentInformation.skin = Šablona vzhledu SystemConfigPanel.deploymentInformation.subscriptionIdentifier = Identifikátor podpory SystemConfigPanel.deprecated.objectPolicy=Tato část konfigurace je zastaralá. Je zde použita pro udržení zpětné kompatibility. Pro definici objektových politik použijte komponenty níže. SystemConfigPanel.mail.config.placeholder=Nová konfigurace @@ -2883,7 +2885,7 @@ SystemConfigPanel.title.passwordPolicy=Globální politika hesel SystemConfigPanel.title.securityPolicy=Globální bezpečnostní politika SystemConfigPanel.title.userTemplate=Výhozí šablona uživatele SystemConfigPanel.tooltip.duration=Formát: P[n][p], n-číslo, p-perioda (d - dny, m - měsíce, ...), příklad: P3M - vyčištění každé 3 měsíce -SystemConfigPanel.tooltip.color = Šestnáctkový formát (hex), například 3e934a pro tmavě zelenou (dark green) +SystemConfigPanel.tooltip.color =Šestnáctkový formát (hex), například 3c8dbc pro světle modrou barvu (blue-light) SystemInfoPanel.cpuUsage=Využití CPU SystemInfoPanel.heapMemory=Paměť typu heap (využitá/přidělená/max) SystemInfoPanel.nonHeapMemory=Paměť typu non-heap (využitá/přidělená/max) @@ -3457,7 +3459,7 @@ operation.com.evolveum.midpoint.web.page.admin.certification.PageCertDefinitions SceneDto.unnamed=(nepojmenováno) LockoutStatusPanel.undoButtonLabel=Vrátit zpět LockoutStatusPanel.unlockButtonLabel=Nastavit na "Normální" -LockoutStatusPanel.changesSaving=(bude uplantněno po kliknutí na tlačítko Uložit) +LockoutStatusPanel.changesSaving=(bude uplatněno po kliknutí na tlačítko Uložit) operation.com.evolveum.midpoint.web.page.admin.server.PageTaskEdit.saveTask=Uložit úlohu (GUI) operation.com.evolveum.midpoint.web.page.admin.users.PageUsers.unlockUsers=Odemknout uživatele operation.com.evolveum.midpoint.web.page.admin.workflow.PageProcessInstances.stopProcessInstance=Zastavit instanci procesu @@ -3528,10 +3530,12 @@ PageAssignmentConflicts.title=Přiřazení jsou v konfliktu s PageAssignmentConflicts.back=Zpět PageAssignmentConflicts.submit=Odeslat AssignmentCatalogPanel.selectTargetUser=Vybrat cílového uživatele +AssignmentCatalogPanel.selectSourceUser=Vybrat zdrojového uživatele přiřazení +AssignmentCatalogPanel.sourceUserSelected=Zdrojový uživatel přiřazení: {0} AssignmentCatalogPanel.selectAssignmentsUserOwner=Vybrat vlastníka přiřazení uživatele AssignmentCatalogPanel.requestForMe=Cílový uživatel: já -AssignmentCatalogPanel.requestFor=Cílový uživatel: -AssignmentCatalogPanel.requestForMultiple=vybráno {0} uživatelů +AssignmentCatalogPanel.requestFor=Cílový uživatel: {0} +AssignmentCatalogPanel.requestForMultiple=vybráno {0} cílových uživatelů AssignmentCatalogPanel.assignmentsOwner=Přiřazení identity {0} MultiButtonPanel.plusIconTitle=Přidat položku do nákupního košíku MultiButtonPanel.assignmentDetailsPopupTitle=Podrobnosti přiřazení @@ -3748,4 +3752,6 @@ AbstractPolicyConstraintType.enforcement=Vynucení ExclusionPolicyConstraintType.targetRef=Cíl ExclusionPolicyConstraintType.policy=Politika ExclusionPolicyConstraintPanel.exclusionTitle=Výlučnost +ValuePolicyBasicPanel.valuePolicy.name=Název +ValuePolicyBasicPanel.valuePolicy.description=Popis comboInput.nullValid=Vyberte jedno z diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_de.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_de.properties index ce10bac3283..b5b897b178a 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_de.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_de.properties @@ -1083,6 +1083,7 @@ PageAdmin.menu.top.users.org=Organisationsstruktur PageAdmin.menu.top.users.org.tree=hierarchischer Organisationsaufbau PageAdmin.menu.top.users=Benutzer PageAdmin.menu.top.valuePolicies.list= List value policies +PageAdmin.menu.top.valuePolicies.new = New value policy PageAdmin.menu.top.valuePolicies= Value policies PageAdmin.menu.top.workItems.listClaimable=Durch mich beanspruchte Elemente PageAdmin.menu.top.workItems.list=Meine Elemente @@ -2265,6 +2266,7 @@ MultipleAssignmentSelector.orgUnit=Organisationseinheit pageValuePolicies.table.description=Description pageValuePolicies.button.delete=Delete PageValuePolicies.title=List value policies +PageValuePolicy.title = Value policy pageWorkItem.accordionLabel.additionalData=Verwandte Daten (Technische Informationen) pageWorkItem.accordionLabel.objectNew=Objekt nach geplanter Veränderung (Technische Information) pageWorkItem.accordionLabel.objectOld=Objekt vor der Veränderung (Technische Information) @@ -2325,6 +2327,7 @@ TaskWfParentPanel.requestsHelp=All approval processes for changes displayed here workItemPanel.otherWorkItems=Andere Arbeitselemente für diese Anfrage workItemPanel.requests=Anträge workItemPanel.relatedRequests=zugehörige Anträge +workItemPanel.reasons=Reasons for the approval process workItemPanel.approverComment=Kommentar Genehmiger workItemPanel.approverInstruction=Genehmiger Instruktionen pageWorkItems.button.approve=Genehmigen @@ -2853,7 +2856,6 @@ SystemConfigPanel.deploymentInformation.logoImageUrl = Logo URL SystemConfigPanel.deploymentInformation.logoCssClass = Icon CSS Klasse SystemConfigPanel.deploymentInformation.customerUrl = Kunden URL SystemConfigPanel.deploymentInformation.partnerName = Partner Name -SystemConfigPanel.deploymentInformation.skin = Vorlage Verkleidung (skin) SystemConfigPanel.deploymentInformation.subscriptionIdentifier = Abonnementskennung SystemConfigPanel.deprecated.objectPolicy=This part of configuration is deprecated. It is kept here for compatibility purposes. Please, use the component below to define object policies. SystemConfigPanel.mail.config.placeholder=New Configuration @@ -2883,7 +2885,7 @@ SystemConfigPanel.title.passwordPolicy=Globale Passwort-Richtlinie SystemConfigPanel.title.securityPolicy=Globale Sicherheits-Richtlinie SystemConfigPanel.title.userTemplate=Standard Benutzervorlage SystemConfigPanel.tooltip.duration=Format: P{n][p], n-Nummer, p-Periode (d - Tage, m - Monate, ...), P3M - Säuberung alle drei Monate -SystemConfigPanel.tooltip.color = HEX Format, z.B. #3E934A für "dunkelgrün" +SystemConfigPanel.tooltip.color =Hex format, e.g. #3c8dbc for the default "blue-light" color SystemInfoPanel.cpuUsage=CPU Usage SystemInfoPanel.heapMemory=Heap memory (used/committed/max) SystemInfoPanel.nonHeapMemory=Non heap memory (used/committed/max) @@ -3157,7 +3159,7 @@ ChangePasswordPanel.helpInfo=

This portion of the credentials dialog controls ChangePasswordPanel.helpPopupTitle=Hilfe für die Passwort Propagierung PageBase.button.tooltip.clearSearch=leeren mainForm.uploadTooLarge = Upload muss kleiner sein als ${maxSize}. -mainForm.uploadFailed = Datei konnte nicht hochgeladen werden: ${exception.localizedMessage}PageSelfCredentials.couldntResolve=Couldn't resolve resource. +mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage} PageSelfCredentials.couldntResolve=Ressource konnte nicht aufgelöst werden. roleMemberPanel.type=Type: roleMemberPanel.tenant=Besitzer: @@ -3528,10 +3530,12 @@ PageAssignmentConflicts.title=Zuweisungskonflikte PageAssignmentConflicts.back=Zurück PageAssignmentConflicts.submit=Absenden AssignmentCatalogPanel.selectTargetUser=Wähle Zielbenutzer +AssignmentCatalogPanel.selectSourceUser=Select assignments source user +AssignmentCatalogPanel.sourceUserSelected=Assignments source user: {0} AssignmentCatalogPanel.selectAssignmentsUserOwner=Selektiere Besitzer der Benutzerzuweisungen AssignmentCatalogPanel.requestForMe=Zielbenutzer: Ich -AssignmentCatalogPanel.requestFor=Ziel Benutzer: -AssignmentCatalogPanel.requestForMultiple={} Benutzer ausgewählt +AssignmentCatalogPanel.requestFor=Target user: {0} +AssignmentCatalogPanel.requestForMultiple={0} target users selected AssignmentCatalogPanel.assignmentsOwner={0} Zuweisungen MultiButtonPanel.plusIconTitle=Objekt in den Einkaufswagen legen MultiButtonPanel.assignmentDetailsPopupTitle=Zuweisungsdetails @@ -3748,4 +3752,6 @@ AbstractPolicyConstraintType.enforcement=Zwang ExclusionPolicyConstraintType.targetRef=Zielreferenz ExclusionPolicyConstraintType.policy=Richtlinie ExclusionPolicyConstraintPanel.exclusionTitle=Ausschluss +ValuePolicyBasicPanel.valuePolicy.name=Name +ValuePolicyBasicPanel.valuePolicy.description=Description comboInput.nullValid=Choose one diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties index f866a257d50..946893c001c 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties @@ -1083,6 +1083,7 @@ PageAdmin.menu.top.users.org=Org. structure PageAdmin.menu.top.users.org.tree=Organization tree PageAdmin.menu.top.users=Users PageAdmin.menu.top.valuePolicies.list= List value policies +PageAdmin.menu.top.valuePolicies.new = New value policy PageAdmin.menu.top.valuePolicies= Value policies PageAdmin.menu.top.workItems.listClaimable=Items claimable by me PageAdmin.menu.top.workItems.list=My items @@ -2265,6 +2266,7 @@ MultipleAssignmentSelector.orgUnit=Org. unit pageValuePolicies.table.description=Description pageValuePolicies.button.delete=Delete PageValuePolicies.title=List value policies +PageValuePolicy.title = Value policy pageWorkItem.accordionLabel.additionalData=Related data (technical information) pageWorkItem.accordionLabel.objectNew=Object after proposed change (technical information) pageWorkItem.accordionLabel.objectOld=Object before change (technical information) @@ -2325,6 +2327,7 @@ TaskWfParentPanel.requestsHelp=All approval processes for changes displayed here workItemPanel.otherWorkItems=Other work items for this request workItemPanel.requests=Requests workItemPanel.relatedRequests=Related requests +workItemPanel.reasons=Reasons for the approval process workItemPanel.approverComment=Approver comment workItemPanel.approverInstruction=Approver instruction pageWorkItems.button.approve=Approve @@ -2853,7 +2856,6 @@ SystemConfigPanel.deploymentInformation.logoImageUrl = Logo image URL SystemConfigPanel.deploymentInformation.logoCssClass = Icon css class SystemConfigPanel.deploymentInformation.customerUrl = Customer url SystemConfigPanel.deploymentInformation.partnerName = Partner name -SystemConfigPanel.deploymentInformation.skin = Template skin SystemConfigPanel.deploymentInformation.subscriptionIdentifier = Subscription identifier SystemConfigPanel.deprecated.objectPolicy=This part of configuration is deprecated. It is kept here for compatibility purposes. Please, use the component below to define object policies. SystemConfigPanel.mail.config.placeholder=New Configuration @@ -3157,7 +3159,7 @@ ChangePasswordPanel.helpInfo=

This portion of the credentials dialog controls ChangePasswordPanel.helpPopupTitle=Password propagation help PageBase.button.tooltip.clearSearch=Clear mainForm.uploadTooLarge = Upload must be less than ${maxSize}. -mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage}PageSelfCredentials.couldntResolve=Couldn't resolve resource. +mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage} PageSelfCredentials.couldntResolve=Couldn't resolve resource. roleMemberPanel.type=Type: roleMemberPanel.tenant=Tenant: @@ -3750,4 +3752,6 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Policy ExclusionPolicyConstraintPanel.exclusionTitle=Exclusion +ValuePolicyBasicPanel.valuePolicy.name=Name +ValuePolicyBasicPanel.valuePolicy.description=Description comboInput.nullValid=Choose one diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_es.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_es.properties index a16660a4083..6de3191ee6d 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_es.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_es.properties @@ -1083,6 +1083,7 @@ PageAdmin.menu.top.users.org=Estructura organizativa PageAdmin.menu.top.users.org.tree=Árbol organizacional PageAdmin.menu.top.users=Usuario PageAdmin.menu.top.valuePolicies.list= List value policies +PageAdmin.menu.top.valuePolicies.new = New value policy PageAdmin.menu.top.valuePolicies= Value policies PageAdmin.menu.top.workItems.listClaimable=Artículos reclamados por mí PageAdmin.menu.top.workItems.list=Mis artículos @@ -2265,6 +2266,7 @@ MultipleAssignmentSelector.orgUnit=Unidad Org. pageValuePolicies.table.description=Description pageValuePolicies.button.delete=Delete PageValuePolicies.title=List value policies +PageValuePolicy.title = Value policy pageWorkItem.accordionLabel.additionalData=Datos vinculados (información técnica) pageWorkItem.accordionLabel.objectNew=Objeto después de cambio propuesto (información técnica) pageWorkItem.accordionLabel.objectOld=Objeto antes del cambio(información técnica) @@ -2325,6 +2327,7 @@ TaskWfParentPanel.requestsHelp=All approval processes for changes displayed here workItemPanel.otherWorkItems=Other work items for this request workItemPanel.requests=Requests workItemPanel.relatedRequests=Related requests +workItemPanel.reasons=Reasons for the approval process workItemPanel.approverComment=Approver comment workItemPanel.approverInstruction=Approver instruction pageWorkItems.button.approve=Aprobar @@ -2853,7 +2856,6 @@ SystemConfigPanel.deploymentInformation.logoImageUrl = Logo image URL SystemConfigPanel.deploymentInformation.logoCssClass = Icon css class SystemConfigPanel.deploymentInformation.customerUrl = Customer url SystemConfigPanel.deploymentInformation.partnerName = Partner name -SystemConfigPanel.deploymentInformation.skin = Template skin SystemConfigPanel.deploymentInformation.subscriptionIdentifier = Subscription identifier SystemConfigPanel.deprecated.objectPolicy=This part of configuration is deprecated. It is kept here for compatibility purposes. Please, use the component below to define object policies. SystemConfigPanel.mail.config.placeholder=New Configuration @@ -2883,7 +2885,7 @@ SystemConfigPanel.title.passwordPolicy=Política Global de contraseñas SystemConfigPanel.title.securityPolicy=Global security policy SystemConfigPanel.title.userTemplate=Plantilla por defecto de usuario SystemConfigPanel.tooltip.duration=Format: P[n][p], n-number, p-period (d - days, m - months, ...), P3M - cleanup every 3 months -SystemConfigPanel.tooltip.color = Hex format, e.g. #3e934a for a "dark green" +SystemConfigPanel.tooltip.color =Hex format, e.g. #3c8dbc for the default "blue-light" color SystemInfoPanel.cpuUsage=CPU Usage SystemInfoPanel.heapMemory=Heap memory (used/committed/max) SystemInfoPanel.nonHeapMemory=Non heap memory (used/committed/max) @@ -3157,7 +3159,7 @@ ChangePasswordPanel.helpInfo=

This portion of the credentials dialog controls ChangePasswordPanel.helpPopupTitle=Password propagation help PageBase.button.tooltip.clearSearch=Limpiar mainForm.uploadTooLarge = Upload must be less than ${maxSize}. -mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage}PageSelfCredentials.couldntResolve=Couldn't resolve resource. +mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage} PageSelfCredentials.couldntResolve=No se puede determinar recurso. roleMemberPanel.type=Tipo: roleMemberPanel.tenant=Tenant: @@ -3528,10 +3530,12 @@ PageAssignmentConflicts.title=Assignments conflicts PageAssignmentConflicts.back=Back PageAssignmentConflicts.submit=Submit AssignmentCatalogPanel.selectTargetUser=Select target user +AssignmentCatalogPanel.selectSourceUser=Select assignments source user +AssignmentCatalogPanel.sourceUserSelected=Assignments source user: {0} AssignmentCatalogPanel.selectAssignmentsUserOwner=Select assignments user owner AssignmentCatalogPanel.requestForMe=Target user: me -AssignmentCatalogPanel.requestFor=Target user: -AssignmentCatalogPanel.requestForMultiple={0} users selected +AssignmentCatalogPanel.requestFor=Target user: {0} +AssignmentCatalogPanel.requestForMultiple={0} target users selected AssignmentCatalogPanel.assignmentsOwner={0}'s assignments MultiButtonPanel.plusIconTitle=Add item to shopping cart MultiButtonPanel.assignmentDetailsPopupTitle=Assignment details @@ -3748,4 +3752,6 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Policy ExclusionPolicyConstraintPanel.exclusionTitle=Exclusion +ValuePolicyBasicPanel.valuePolicy.name=Name +ValuePolicyBasicPanel.valuePolicy.description=Description comboInput.nullValid=Choose one diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_et.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_et.properties index e0567deaf43..1467a0f325e 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_et.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_et.properties @@ -1083,6 +1083,7 @@ PageAdmin.menu.top.users.org=Org. struktuur PageAdmin.menu.top.users.org.tree=Organisatsioonipuu PageAdmin.menu.top.users=Kasutajad PageAdmin.menu.top.valuePolicies.list= List value policies +PageAdmin.menu.top.valuePolicies.new = Uus väärtuspoliitika PageAdmin.menu.top.valuePolicies= Väärtuspoliitikad PageAdmin.menu.top.workItems.listClaimable=Üksused, mida saan endale võtta PageAdmin.menu.top.workItems.list=Minu üksused @@ -2265,6 +2266,7 @@ MultipleAssignmentSelector.orgUnit=Org. üksus pageValuePolicies.table.description=Kirjeldus pageValuePolicies.button.delete=Kustuta PageValuePolicies.title=List value policies +PageValuePolicy.title = Väärtuspoliitika pageWorkItem.accordionLabel.additionalData=Seonduvad andmed (tehniline teave) pageWorkItem.accordionLabel.objectNew=Objekt peale väljapakutud muudatust (tehniline teave) pageWorkItem.accordionLabel.objectOld=Objekt enne muudatust (tehniline teave) @@ -2325,6 +2327,7 @@ TaskWfParentPanel.requestsHelp=Kõik kinnitamisprotsessid siin näha olevate muu workItemPanel.otherWorkItems=Selle taotluse teised tööüksused workItemPanel.requests=Taotlused workItemPanel.relatedRequests=Seonduvad taotlused +workItemPanel.reasons=Kinnitamisprotsessi põhjused workItemPanel.approverComment=Kinnitaja kommentaar workItemPanel.approverInstruction=Kinnitaja juhis pageWorkItems.button.approve=Kinnita @@ -2849,11 +2852,10 @@ SystemConfigPanel.deploymentInformation.description= Deployment description SystemConfigPanel.deploymentInformation.name = Deployment name SystemConfigPanel.deploymentInformation.headerColor = Päise värv SystemConfigPanel.deploymentInformation.skin = Template skin -SystemConfigPanel.deploymentInformation.logoImageUrl = Logo image URL -SystemConfigPanel.deploymentInformation.logoCssClass = Icon css class -SystemConfigPanel.deploymentInformation.customerUrl = Customer url +SystemConfigPanel.deploymentInformation.logoImageUrl = Logo pildi URL +SystemConfigPanel.deploymentInformation.logoCssClass = Ikooni css klass +SystemConfigPanel.deploymentInformation.customerUrl = Kliendi url SystemConfigPanel.deploymentInformation.partnerName = Partneri nimi -SystemConfigPanel.deploymentInformation.skin = Template skin SystemConfigPanel.deploymentInformation.subscriptionIdentifier = Subscription identifier SystemConfigPanel.deprecated.objectPolicy=See konfiguratsiooni osa on aegunud. Seda hoitakse siin ühilduvuse eesmärgil. Palun kasuta allpool olevat komponenti, et defineerida objekti poliitikad. SystemConfigPanel.mail.config.placeholder=Uus konfiguratsioon @@ -2883,7 +2885,7 @@ SystemConfigPanel.title.passwordPolicy=Üldine paroolipoliitika SystemConfigPanel.title.securityPolicy=Üldine turbepoliitika SystemConfigPanel.title.userTemplate=Vaikimisi kasutaja mall SystemConfigPanel.tooltip.duration=Vorming: P[n][p], n-arv, p-periood (d - päevad, m - kuud, ...), P3M - puhastamine iga 3 kuu tagant -SystemConfigPanel.tooltip.color = Hex format, e.g. #3e934a for a "dark green" +SystemConfigPanel.tooltip.color =Hex format, e.g. #3c8dbc for the default "blue-light" color SystemInfoPanel.cpuUsage=Protsessori hõivatus SystemInfoPanel.heapMemory=Kuhja mälu (kasutusel/seotud/max) SystemInfoPanel.nonHeapMemory=Mitte-kuhja mälu (kasutusel/seotud/max) @@ -3157,7 +3159,7 @@ ChangePasswordPanel.helpInfo=

See osa identimisteabe dialoogist kontrollib sed ChangePasswordPanel.helpPopupTitle=Parooli levimise abi PageBase.button.tooltip.clearSearch=Tühjenda mainForm.uploadTooLarge = Üleslaadimise suurus peab olema väiksem kui ${maxSize}. -mainForm.uploadFailed = Faili ei õnnestunus üles laadida: ${exception.localizedMessage}PageSelfCredentials.couldntResolve=Ei õnnestunud ressurssi lahendada. +mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage} PageSelfCredentials.couldntResolve=Ei saanud ressurssi lahendada. roleMemberPanel.type=Tüüp: roleMemberPanel.tenant=Rentnik: @@ -3528,10 +3530,12 @@ PageAssignmentConflicts.title=Omistuste konfliktid PageAssignmentConflicts.back=Tagasi PageAssignmentConflicts.submit=Edasta AssignmentCatalogPanel.selectTargetUser=Vali sihtkasutaja +AssignmentCatalogPanel.selectSourceUser=Vali omistuste allik-kasutaja +AssignmentCatalogPanel.sourceUserSelected=Omistuste allik-kasutaja: {0} AssignmentCatalogPanel.selectAssignmentsUserOwner=Vali kasutajaomistuste omanik AssignmentCatalogPanel.requestForMe=Sihtkasutaja: mina -AssignmentCatalogPanel.requestFor=Sihtkasutaja: -AssignmentCatalogPanel.requestForMultiple=Valitud on {0} kasutajat +AssignmentCatalogPanel.requestFor=Target user: {0} +AssignmentCatalogPanel.requestForMultiple={0} target users selected AssignmentCatalogPanel.assignmentsOwner={0} omistused MultiButtonPanel.plusIconTitle=Lisa objekt ostukorvi MultiButtonPanel.assignmentDetailsPopupTitle=Omistuse üksikasjad @@ -3748,4 +3752,6 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Poliitika ExclusionPolicyConstraintPanel.exclusionTitle=Välistus -comboInput.nullValid=Choose one +ValuePolicyBasicPanel.valuePolicy.name=Nimi +ValuePolicyBasicPanel.valuePolicy.description=Kirjeldus +comboInput.nullValid=Vali üks diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_fi.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_fi.properties index 43c67be6ae9..3e34c957ab7 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_fi.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_fi.properties @@ -1083,6 +1083,7 @@ PageAdmin.menu.top.users.org=Org. rakenne PageAdmin.menu.top.users.org.tree=Organisaatiopuu PageAdmin.menu.top.users=Käyttäjät PageAdmin.menu.top.valuePolicies.list= Luettele arvolinjaukset +PageAdmin.menu.top.valuePolicies.new = New value policy PageAdmin.menu.top.valuePolicies= Arvolinjaukset PageAdmin.menu.top.workItems.listClaimable=tehtävät jotka voin ottaa itselleni PageAdmin.menu.top.workItems.list=minun tehtäväni @@ -2265,6 +2266,7 @@ MultipleAssignmentSelector.orgUnit=Org. yksikkö pageValuePolicies.table.description=Kuvaus pageValuePolicies.button.delete=Poista PageValuePolicies.title=Luettele arvolinjaukset +PageValuePolicy.title = Value policy pageWorkItem.accordionLabel.additionalData=Liittyvä data (Tekniset tiedot) pageWorkItem.accordionLabel.objectNew=Objekti ehdotetun muutoksen jälkeen (Tekniset tiedot) pageWorkItem.accordionLabel.objectOld=Objekti ennen muutosta (Tekniset tiedot) @@ -2325,6 +2327,7 @@ TaskWfParentPanel.requestsHelp=Kaikki muutosten hyväksyntäprosessit näytetä workItemPanel.otherWorkItems=Muut työtehtävät tässä pyyynnössä workItemPanel.requests=Pyynnöt workItemPanel.relatedRequests=Liittyvät pyynnöt +workItemPanel.reasons=Reasons for the approval process workItemPanel.approverComment=Hyväksyjän kommentti workItemPanel.approverInstruction=Hyväksyjän ohjeistus pageWorkItems.button.approve=Hyväksy @@ -2853,7 +2856,6 @@ SystemConfigPanel.deploymentInformation.logoImageUrl = Logokuva URL SystemConfigPanel.deploymentInformation.logoCssClass = Ikoni css luokka SystemConfigPanel.deploymentInformation.customerUrl = Asiakas url SystemConfigPanel.deploymentInformation.partnerName = Partnerin nimi -SystemConfigPanel.deploymentInformation.skin = Malli ulkonäkö SystemConfigPanel.deploymentInformation.subscriptionIdentifier = Tilauksen tunnistaja SystemConfigPanel.deprecated.objectPolicy=Tämä osa asetuksista on vanhentunut. Sitä säilytetään täällä yhteensopivuus syistä. Käytä alla olevaa komponenttia objektilinjausten määrittämiseen. SystemConfigPanel.mail.config.placeholder=Uudet asetukset @@ -2883,7 +2885,7 @@ SystemConfigPanel.title.passwordPolicy=Globaali salasanalinjaus SystemConfigPanel.title.securityPolicy=Globaali turvallisuuslinjaus SystemConfigPanel.title.userTemplate=oletus käyttäjämalli SystemConfigPanel.tooltip.duration=Formaatti: P[n][p], n-numero, p-kausi (d - päivät, m - kuukaudet, ...), P3M - puhdistus joka 3. kuukausi -SystemConfigPanel.tooltip.color = Hex formaatti, esim. #3e934a saadaksesi "dark green" +SystemConfigPanel.tooltip.color =Hex format, e.g. #3c8dbc for the default "blue-light" color SystemInfoPanel.cpuUsage=CPU Käyttö SystemInfoPanel.heapMemory=Muistikeko (käytetty/sidottu/max) SystemInfoPanel.nonHeapMemory=Muistikeon ulkopuolinen (käytetty/sidottu/max) @@ -3157,7 +3159,7 @@ ChangePasswordPanel.helpInfo=

Tämä osa tunnusdialogia kontrolloi kuinka sala ChangePasswordPanel.helpPopupTitle=Salasana leviäminen avustus PageBase.button.tooltip.clearSearch=Tyhjennä mainForm.uploadTooLarge = Lähetyksen pitää olla alle ${maxSize}. -mainForm.uploadFailed = Tiedoston lähettäminen ei onnistunut ${exception.localizedMessage}SivuOmaTunnukset.EiPystyttyRatkaisemaan=Resunssin ratkaiseminen ei onnistunut. +mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage} PageSelfCredentials.couldntResolve=Resurssin ratkaisu ei onnistunut. roleMemberPanel.type=Tyyppi: roleMemberPanel.tenant=Haltija: @@ -3528,10 +3530,12 @@ PageAssignmentConflicts.title=Toimeksiantojen ristiriidat PageAssignmentConflicts.back=Takaisin PageAssignmentConflicts.submit=Kirjaa AssignmentCatalogPanel.selectTargetUser=Valitse kohteen käyttäjä +AssignmentCatalogPanel.selectSourceUser=Select assignments source user +AssignmentCatalogPanel.sourceUserSelected=Assignments source user: {0} AssignmentCatalogPanel.selectAssignmentsUserOwner=Valitse toimeksiantojen käyttäjän omistaja AssignmentCatalogPanel.requestForMe=Kohteen käyttäjä: minä -AssignmentCatalogPanel.requestFor=Kohteen käyttäjä: -AssignmentCatalogPanel.requestForMultiple={0} käyttäjää valittuina +AssignmentCatalogPanel.requestFor=Target user: {0} +AssignmentCatalogPanel.requestForMultiple={0} target users selected AssignmentCatalogPanel.assignmentsOwner={0}n toimeksiannot MultiButtonPanel.plusIconTitle=Lisää tavara ostoskoriin MultiButtonPanel.assignmentDetailsPopupTitle=Toimeksiannon yksityiskohdat @@ -3748,4 +3752,6 @@ AbstractPolicyConstraintType.enforcement=Valvonta ExclusionPolicyConstraintType.targetRef=Kohde viittaus ExclusionPolicyConstraintType.policy=Linjaus ExclusionPolicyConstraintPanel.exclusionTitle=Poissulku +ValuePolicyBasicPanel.valuePolicy.name=Name +ValuePolicyBasicPanel.valuePolicy.description=Description comboInput.nullValid=Choose one diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_hu.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_hu.properties index 14b724c7248..d837f1d0bf1 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_hu.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_hu.properties @@ -1083,6 +1083,7 @@ PageAdmin.menu.top.users.org=Org. structure PageAdmin.menu.top.users.org.tree=Organization tree PageAdmin.menu.top.users=Felhasználók PageAdmin.menu.top.valuePolicies.list= List value policies +PageAdmin.menu.top.valuePolicies.new = New value policy PageAdmin.menu.top.valuePolicies= Value policies PageAdmin.menu.top.workItems.listClaimable=Items claimable by me PageAdmin.menu.top.workItems.list=My items @@ -2265,6 +2266,7 @@ MultipleAssignmentSelector.orgUnit=Org. unit pageValuePolicies.table.description=Description pageValuePolicies.button.delete=Delete PageValuePolicies.title=List value policies +PageValuePolicy.title = Value policy pageWorkItem.accordionLabel.additionalData=Related data (technical information) pageWorkItem.accordionLabel.objectNew=Object after proposed change (technical information) pageWorkItem.accordionLabel.objectOld=Object before change (technical information) @@ -2325,6 +2327,7 @@ TaskWfParentPanel.requestsHelp=All approval processes for changes displayed here workItemPanel.otherWorkItems=Other work items for this request workItemPanel.requests=Requests workItemPanel.relatedRequests=Related requests +workItemPanel.reasons=Reasons for the approval process workItemPanel.approverComment=Approver comment workItemPanel.approverInstruction=Approver instruction pageWorkItems.button.approve=Approve @@ -2853,7 +2856,6 @@ SystemConfigPanel.deploymentInformation.logoImageUrl = Logo image URL SystemConfigPanel.deploymentInformation.logoCssClass = Icon css class SystemConfigPanel.deploymentInformation.customerUrl = Customer url SystemConfigPanel.deploymentInformation.partnerName = Partner name -SystemConfigPanel.deploymentInformation.skin = Template skin SystemConfigPanel.deploymentInformation.subscriptionIdentifier = Subscription identifier SystemConfigPanel.deprecated.objectPolicy=This part of configuration is deprecated. It is kept here for compatibility purposes. Please, use the component below to define object policies. SystemConfigPanel.mail.config.placeholder=New Configuration @@ -2883,7 +2885,7 @@ SystemConfigPanel.title.passwordPolicy=Globális jelszó házirend SystemConfigPanel.title.securityPolicy=Global security policy SystemConfigPanel.title.userTemplate=Default user template SystemConfigPanel.tooltip.duration=Format: P[n][p], n-number, p-period (d - days, m - months, ...), P3M - cleanup every 3 months -SystemConfigPanel.tooltip.color = Hex format, e.g. #3e934a for a "dark green" +SystemConfigPanel.tooltip.color =Hex format, e.g. #3c8dbc for the default "blue-light" color SystemInfoPanel.cpuUsage=CPU Usage SystemInfoPanel.heapMemory=Heap memory (used/committed/max) SystemInfoPanel.nonHeapMemory=Non heap memory (used/committed/max) @@ -3157,7 +3159,7 @@ ChangePasswordPanel.helpInfo=

This portion of the credentials dialog controls ChangePasswordPanel.helpPopupTitle=Password propagation help PageBase.button.tooltip.clearSearch=Clear mainForm.uploadTooLarge = Upload must be less than ${maxSize}. -mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage}PageSelfCredentials.couldntResolve=Couldn't resolve resource. +mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage} PageSelfCredentials.couldntResolve=Couldn't resolve resource. roleMemberPanel.type=Type: roleMemberPanel.tenant=Tenant: @@ -3528,10 +3530,12 @@ PageAssignmentConflicts.title=Assignments conflicts PageAssignmentConflicts.back=Back PageAssignmentConflicts.submit=Submit AssignmentCatalogPanel.selectTargetUser=Select target user +AssignmentCatalogPanel.selectSourceUser=Select assignments source user +AssignmentCatalogPanel.sourceUserSelected=Assignments source user: {0} AssignmentCatalogPanel.selectAssignmentsUserOwner=Select assignments user owner AssignmentCatalogPanel.requestForMe=Target user: me -AssignmentCatalogPanel.requestFor=Target user: -AssignmentCatalogPanel.requestForMultiple={0} users selected +AssignmentCatalogPanel.requestFor=Target user: {0} +AssignmentCatalogPanel.requestForMultiple={0} target users selected AssignmentCatalogPanel.assignmentsOwner={0}'s assignments MultiButtonPanel.plusIconTitle=Add item to shopping cart MultiButtonPanel.assignmentDetailsPopupTitle=Assignment details @@ -3748,4 +3752,6 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Policy ExclusionPolicyConstraintPanel.exclusionTitle=Exclusion +ValuePolicyBasicPanel.valuePolicy.name=Name +ValuePolicyBasicPanel.valuePolicy.description=Description comboInput.nullValid=Choose one diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_pl.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_pl.properties index 6e99ea9ed72..6df555aae17 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_pl.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_pl.properties @@ -1083,6 +1083,7 @@ PageAdmin.menu.top.users.org=Struktura org. PageAdmin.menu.top.users.org.tree=Drzewo struktury org. PageAdmin.menu.top.users=Użytkownicy PageAdmin.menu.top.valuePolicies.list= Lista polityk wartości +PageAdmin.menu.top.valuePolicies.new = Nowa polityka wartości PageAdmin.menu.top.valuePolicies= Polityki wartości PageAdmin.menu.top.workItems.listClaimable=Pozycje które mogę wykonać PageAdmin.menu.top.workItems.list=Moje zadania @@ -2265,6 +2266,7 @@ MultipleAssignmentSelector.orgUnit=Jednostka organizacyjna pageValuePolicies.table.description=Opis pageValuePolicies.button.delete=Usuń PageValuePolicies.title=Lista polityki wartości +PageValuePolicy.title = Polityka wartości pageWorkItem.accordionLabel.additionalData=Powiązane dane (informacje techniczne) pageWorkItem.accordionLabel.objectNew=Obiekt po zaproponowanej zmianie (informacje techniczne) pageWorkItem.accordionLabel.objectOld=Obiekt przed zmianą (informacje techniczne) @@ -2325,6 +2327,7 @@ TaskWfParentPanel.requestsHelp=Wszystkie procesy akceptacji zmian wyświetlone t workItemPanel.otherWorkItems=Inne zadania dotyczące tego wniosku workItemPanel.requests=Wnioski workItemPanel.relatedRequests=Powiązane wnioski +workItemPanel.reasons=Uzasadnienie procesu zatwierdzania workItemPanel.approverComment=Komentarz od zatwierdzającego workItemPanel.approverInstruction=Instrukcje zatwierdzającego pageWorkItems.button.approve=Zatwierdź @@ -2853,7 +2856,6 @@ SystemConfigPanel.deploymentInformation.logoImageUrl = URL obrazka z logiem SystemConfigPanel.deploymentInformation.logoCssClass = Klasa css ikony SystemConfigPanel.deploymentInformation.customerUrl = URL klienta SystemConfigPanel.deploymentInformation.partnerName = Nazwa partnera -SystemConfigPanel.deploymentInformation.skin = Skórka SystemConfigPanel.deploymentInformation.subscriptionIdentifier = Identyfikator subskrypcji SystemConfigPanel.deprecated.objectPolicy=Ta część konfiguracji jest przestarzała i trzymana wyłącznie z powodu kompatybilności. Proszę używać komponentu poniżej do określenia polityk obiektów. SystemConfigPanel.mail.config.placeholder=Nowa konfiguracja @@ -2883,7 +2885,7 @@ SystemConfigPanel.title.passwordPolicy=Globalna polityka hasła SystemConfigPanel.title.securityPolicy=Globalna polityka bezpieczeństwa SystemConfigPanel.title.userTemplate=Domyślny szablon użytkownika SystemConfigPanel.tooltip.duration=Format: P[n][p], n-liczba, p-okres (d - dni, m - miesiące, ...), P3M - czyszczenie co 3 miesiące -SystemConfigPanel.tooltip.color = Format szesnastkowy, np. #3e934a to "ciemnozielony" +SystemConfigPanel.tooltip.color =Format szesnastkowy, np. #3c8dbc to domyślny kolor "jasnoniebieski" SystemInfoPanel.cpuUsage=Użycie procesora SystemInfoPanel.heapMemory=Pamięć typu heap (użyta/przydzielona/maks) SystemInfoPanel.nonHeapMemory=Pamięć typu non-heap (użyta/przydzielona/maks) @@ -3157,7 +3159,7 @@ ChangePasswordPanel.helpInfo=

Ta część okna dialogowego zmiany hasła odpow ChangePasswordPanel.helpPopupTitle=Pomoc dotycząca propagacji hasła PageBase.button.tooltip.clearSearch=Wyczyść mainForm.uploadTooLarge = Wielkość pliku musi być mniejsza niż ${maxSize}. -mainForm.uploadFailed = Nie można wczytać pliku: ${exception.localizedMessage}PageSelfCredentials.couldntResolve=Nie można nawiązać kontaktu z systemem. +mainForm.uploadFailed = Błąd wczytywania pliku: ${exception.localizedMessage} PageSelfCredentials.couldntResolve=Nie można rozwiązać systemu. roleMemberPanel.type=Typ: roleMemberPanel.tenant=Podmiot: @@ -3528,10 +3530,12 @@ PageAssignmentConflicts.title=Konflikty przypisań PageAssignmentConflicts.back=Wstecz PageAssignmentConflicts.submit=Prześlij AssignmentCatalogPanel.selectTargetUser=Wybierz docelowego użytkownika +AssignmentCatalogPanel.selectSourceUser=Wybierz przypisania źródłowego użytkownika +AssignmentCatalogPanel.sourceUserSelected=Przypisania źródłowego użytkownika: {0} AssignmentCatalogPanel.selectAssignmentsUserOwner=Wybierz właściciela przypisań użytkownika AssignmentCatalogPanel.requestForMe=Docelowy użytkownik: ja -AssignmentCatalogPanel.requestFor=Docelowy użytkownik: -AssignmentCatalogPanel.requestForMultiple=Wybrano {0} użytkowników +AssignmentCatalogPanel.requestFor=Docelowy użytkownik: {0} +AssignmentCatalogPanel.requestForMultiple=Wybrano {0} docelowych użytkowników AssignmentCatalogPanel.assignmentsOwner=przypisania {0} MultiButtonPanel.plusIconTitle=Dodaj pozycję do koszyka MultiButtonPanel.assignmentDetailsPopupTitle=Szczegóły przypisania @@ -3748,4 +3752,6 @@ AbstractPolicyConstraintType.enforcement=Wymuszenie ExclusionPolicyConstraintType.targetRef=Odniesienie do celu ExclusionPolicyConstraintType.policy=Polityka ExclusionPolicyConstraintPanel.exclusionTitle=Wykluczenie +ValuePolicyBasicPanel.valuePolicy.name=Nazwa +ValuePolicyBasicPanel.valuePolicy.description=Opis comboInput.nullValid=Wybierz diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_pt_BR.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_pt_BR.properties index 1a742449737..69cc359381e 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_pt_BR.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_pt_BR.properties @@ -1083,6 +1083,7 @@ PageAdmin.menu.top.users.org=Estrutura org. PageAdmin.menu.top.users.org.tree=Árvore da org. PageAdmin.menu.top.users=Usuários PageAdmin.menu.top.valuePolicies.list= List value policies +PageAdmin.menu.top.valuePolicies.new = New value policy PageAdmin.menu.top.valuePolicies= Value policies PageAdmin.menu.top.workItems.listClaimable=Itens reivindicáveis por mim PageAdmin.menu.top.workItems.list=Meus itens @@ -2265,6 +2266,7 @@ MultipleAssignmentSelector.orgUnit=Unid. org. pageValuePolicies.table.description=Description pageValuePolicies.button.delete=Delete PageValuePolicies.title=List value policies +PageValuePolicy.title = Value policy pageWorkItem.accordionLabel.additionalData=Dados relac. (informação técnica) pageWorkItem.accordionLabel.objectNew=Objeto após alteração proposta (informação téc.) pageWorkItem.accordionLabel.objectOld=Objeto antes da alteração (informação téc.) @@ -2325,6 +2327,7 @@ TaskWfParentPanel.requestsHelp=Todos os processos de aprovação para mudanças workItemPanel.otherWorkItems=Outros itens de trabalho para esta solicitação workItemPanel.requests=Solicitações workItemPanel.relatedRequests=Solicitações relacionadas +workItemPanel.reasons=Reasons for the approval process workItemPanel.approverComment=Comentário do aprovador workItemPanel.approverInstruction=Instrução de aprovação pageWorkItems.button.approve=Aprovar @@ -2853,7 +2856,6 @@ SystemConfigPanel.deploymentInformation.logoImageUrl = Logo image URL SystemConfigPanel.deploymentInformation.logoCssClass = Icon css class SystemConfigPanel.deploymentInformation.customerUrl = Customer url SystemConfigPanel.deploymentInformation.partnerName = Partner name -SystemConfigPanel.deploymentInformation.skin = Template skin SystemConfigPanel.deploymentInformation.subscriptionIdentifier = Subscription identifier SystemConfigPanel.deprecated.objectPolicy=Esta parte da configuração está em desuso. Ela é mantida aqui por razões de compatibilidade. Favor utilizar o componente abaixo para definir políticas de objeto. SystemConfigPanel.mail.config.placeholder=Nova configuração @@ -2883,7 +2885,7 @@ SystemConfigPanel.title.passwordPolicy=Pólitica de senha global SystemConfigPanel.title.securityPolicy=Política de segurança global SystemConfigPanel.title.userTemplate=Modelo de usuário default SystemConfigPanel.tooltip.duration=Formato: P [n] [p], n-número, p-período (d - dias, m - meses, ...), P3M - limpeza a cada 3 meses -SystemConfigPanel.tooltip.color = Hex format, e.g. #3e934a for a "dark green" +SystemConfigPanel.tooltip.color =Hex format, e.g. #3c8dbc for the default "blue-light" color SystemInfoPanel.cpuUsage=Uso de CPU SystemInfoPanel.heapMemory=Memória heap (utiliz./comprometida/máx) SystemInfoPanel.nonHeapMemory=Memória non-heap (utiliz./comprometida/máx) @@ -3157,7 +3159,7 @@ ChangePasswordPanel.helpInfo=

Esta parte da caixa de diálogo de credenciais c ChangePasswordPanel.helpPopupTitle=Ajuda de propagação de senha PageBase.button.tooltip.clearSearch=Limpar mainForm.uploadTooLarge = Carga deve ser menor que ${maxSize}. -mainForm.uploadFailed = Falha ao carregar arquivo: ${exception.localizedMessage}PageSelfCredentials.couldntResolve=Não foi possível resolver recurso. +mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage} PageSelfCredentials.couldntResolve=Não foi possível resolver recurso. roleMemberPanel.type=Tipo: roleMemberPanel.tenant=Inquilino @@ -3528,10 +3530,12 @@ PageAssignmentConflicts.title=Conflitos entre atribuições PageAssignmentConflicts.back=Voltar PageAssignmentConflicts.submit=Enviar AssignmentCatalogPanel.selectTargetUser=Selecionar usuário alvo +AssignmentCatalogPanel.selectSourceUser=Select assignments source user +AssignmentCatalogPanel.sourceUserSelected=Assignments source user: {0} AssignmentCatalogPanel.selectAssignmentsUserOwner=Selecionar atribuições do usuário proprietário AssignmentCatalogPanel.requestForMe=Usuário alvo: eu -AssignmentCatalogPanel.requestFor=Usuário alvo: -AssignmentCatalogPanel.requestForMultiple={0} usuários selecionados +AssignmentCatalogPanel.requestFor=Target user: {0} +AssignmentCatalogPanel.requestForMultiple={0} target users selected AssignmentCatalogPanel.assignmentsOwner={0}'s atribuições MultiButtonPanel.plusIconTitle=Incluir item para carrinho de compras MultiButtonPanel.assignmentDetailsPopupTitle=Detalhes de atribuição @@ -3748,4 +3752,6 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Policy ExclusionPolicyConstraintPanel.exclusionTitle=Exclusion +ValuePolicyBasicPanel.valuePolicy.name=Name +ValuePolicyBasicPanel.valuePolicy.description=Description comboInput.nullValid=Choose one diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_ru.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_ru.properties index e11aad2dac6..d24426a323c 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_ru.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_ru.properties @@ -1083,6 +1083,7 @@ PageAdmin.menu.top.users.org=Оргструктура PageAdmin.menu.top.users.org.tree=Дерево организаций PageAdmin.menu.top.users=Пользователи PageAdmin.menu.top.valuePolicies.list= List value policies +PageAdmin.menu.top.valuePolicies.new = New value policy PageAdmin.menu.top.valuePolicies= Value policies PageAdmin.menu.top.workItems.listClaimable=Задания, запрошенные мной PageAdmin.menu.top.workItems.list=Мои задания @@ -2265,6 +2266,7 @@ MultipleAssignmentSelector.orgUnit=Организационное подразд pageValuePolicies.table.description=Description pageValuePolicies.button.delete=Delete PageValuePolicies.title=List value policies +PageValuePolicy.title = Value policy pageWorkItem.accordionLabel.additionalData=Связанные данные (техническая информация) pageWorkItem.accordionLabel.objectNew=Объект после предложенного изменения (техническая информация) pageWorkItem.accordionLabel.objectOld=Объект до изменения (техническая информация) @@ -2325,6 +2327,7 @@ TaskWfParentPanel.requestsHelp=Все процессы утверждения и workItemPanel.otherWorkItems=Другие задания для этого запроса workItemPanel.requests=Заявки workItemPanel.relatedRequests=Связанные запросы +workItemPanel.reasons=Reasons for the approval process workItemPanel.approverComment=Комментарий workItemPanel.approverInstruction=Инструкция согласующего pageWorkItems.button.approve=Согласовать @@ -2853,7 +2856,6 @@ SystemConfigPanel.deploymentInformation.logoImageUrl = Logo image URL SystemConfigPanel.deploymentInformation.logoCssClass = Icon css class SystemConfigPanel.deploymentInformation.customerUrl = Customer url SystemConfigPanel.deploymentInformation.partnerName = Partner name -SystemConfigPanel.deploymentInformation.skin = Template skin SystemConfigPanel.deploymentInformation.subscriptionIdentifier = Subscription identifier SystemConfigPanel.deprecated.objectPolicy=Это часть процесса синхронизации недопустима. Пожалуйста, определите объекты политик с помощью компонентов ниже. SystemConfigPanel.mail.config.placeholder=Новая конфигурация @@ -2883,7 +2885,7 @@ SystemConfigPanel.title.passwordPolicy=Глобальная парольная SystemConfigPanel.title.securityPolicy=Глобальная политика безопасности SystemConfigPanel.title.userTemplate=Пользовательский шаблон по умолчанию SystemConfigPanel.tooltip.duration=Format: P[n][p], n-number, p-period (d - days, m - months, ...), P3M - cleanup every 3 months -SystemConfigPanel.tooltip.color = Hex format, e.g. #3e934a for a "dark green" +SystemConfigPanel.tooltip.color =Hex format, e.g. #3c8dbc for the default "blue-light" color SystemInfoPanel.cpuUsage=Использование ЦПУ SystemInfoPanel.heapMemory=Использование памяти heap (используется/выделено/максимум) SystemInfoPanel.nonHeapMemory=Использование других областей памяти (используется/выделено/максимум) @@ -3157,7 +3159,7 @@ ChangePasswordPanel.helpInfo=

Эта часть диалогового окн ChangePasswordPanel.helpPopupTitle=Справка по передаче пароля PageBase.button.tooltip.clearSearch=Очистить mainForm.uploadTooLarge = Загружаемый файл должен быть меньше ${maxSize}. -mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage}PageSelfCredentials.couldntResolve=Couldn't resolve resource. +mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage} PageSelfCredentials.couldntResolve=Невозможно определить ресурс roleMemberPanel.type=Тип roleMemberPanel.tenant=Первичный: @@ -3528,10 +3530,12 @@ PageAssignmentConflicts.title=Конфликты назначений PageAssignmentConflicts.back=Назад PageAssignmentConflicts.submit=Подтвердить AssignmentCatalogPanel.selectTargetUser=Выберите целевого пользователя +AssignmentCatalogPanel.selectSourceUser=Select assignments source user +AssignmentCatalogPanel.sourceUserSelected=Assignments source user: {0} AssignmentCatalogPanel.selectAssignmentsUserOwner=Выберите владельца назначения AssignmentCatalogPanel.requestForMe=Запрос для себя -AssignmentCatalogPanel.requestFor=Запрос для: -AssignmentCatalogPanel.requestForMultiple={0} пользователей выбрано +AssignmentCatalogPanel.requestFor=Target user: {0} +AssignmentCatalogPanel.requestForMultiple={0} target users selected AssignmentCatalogPanel.assignmentsOwner=Назначения {0} MultiButtonPanel.plusIconTitle=Добавить элемент в Корзину MultiButtonPanel.assignmentDetailsPopupTitle=Сведения о назначении @@ -3748,4 +3752,6 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Policy ExclusionPolicyConstraintPanel.exclusionTitle=Exclusion +ValuePolicyBasicPanel.valuePolicy.name=Name +ValuePolicyBasicPanel.valuePolicy.description=Description comboInput.nullValid=Choose one diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_sk.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_sk.properties index c1d0229f6db..8d7b44fe00b 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_sk.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_sk.properties @@ -22,7 +22,7 @@ addCapabilityDialog.button.Add=Pridať addCapabilityDialog.button.cancel=Zrušiť addCapabilityDialog.column.name=Meno addCapabilityDialog.title=Zvoľte možnosti pridať -admStatusFetchStrategy.nullValid=Vyberte jednu +admStatusFetchStrategy.nullValid=Vyberte hodnotu AEPlevel.FULL=Úplný AEPlevel.LEGALIZE=Relatívny AEPlevel.MARK=Značka @@ -36,7 +36,7 @@ assignablePopupContent.displayName=Zobraziť meno assignablePopupContent.message.errorLoadingRoleTypes=Nebolo možné načítať dostupné typy rolí pre účely vyhľadávania. assignablePopupContent.message.noOrgStructureDefined=Žiadna org. štruktúra nebola definovaná. assignablePopupContent.name=Názov -assignablePopupContent.role.type=Typ role +assignablePopupContent.role.type=Typ roly AssignmentEditorPanel.attributes=Atribúty AssignmentEditorPanel.browser.title=Prehliadač AssignmentEditorPanel.description=Popis @@ -100,7 +100,7 @@ AssignmentPreviewDialog.label=Zobraziť priame & nepriame priradenia AssignmentPreviewDialog.delegationPreviewLabel=Limit privileges AssignmentPreviewDialog.type.direct=Priame AssignmentPreviewDialog.type.indirect=Nepriame -AssignmentTablePanel.menu.assign=Priradiť účet +AssignmentTablePanel.menu.assign=Priradiť AssignmentTablePanel.menu.assignOrg=Priradiť org. AssignmentTablePanel.menu.assignOrg.noorgs=No organization structure defined. AssignmentTablePanel.menu.assignRole=Priradiť rolu @@ -117,7 +117,7 @@ AssignmentTablePanel.modal.message.deleteDelegation=Do you really want to delete AssignmentTablePanel.modal.message.noDelegationWarning=User doesn't have any delegable item AssignmentTablePanel.modal.title.confirmDeletion=Potvrďte zmazanie AssignmentTablePanel.modal.title.selectAssignment=Vyberte objekt(y) -associationAttribute.nullValid=Vyberte jednu +associationAttribute.nullValid=Vyberte hodnotu AsyncDashboardPanel.loading=Načítavam dáta AuditPopulPanel.exportType.label=Exportovať súbor typu AuditPopupPanel.auditEventType=Typ udalosti @@ -139,11 +139,11 @@ capabilityActivationPanel.label.ignoreAttribute=Ignorovať atribút capabilityActivationPanel.label.returnedByDefault=Vrátené v predvolenom nastavení capabilityActivationPanel.label.status.message=Rovnako ako povolený/zakázaný capabilityActivationPanel.label.status=Stav -capabilityActivationPanel.label.lockout=Lockout +capabilityActivationPanel.label.lockout=Zamknutý capabilityActivationPanel.label.validFrom=Platný od capabilityActivationPanel.label.validTo=Platný do capabilityActivationPanel.list.placeholder=Vložiť hodnotu -capabilityCredentialsPanel.label=Konfigurácia nastavení +capabilityCredentialsPanel.label=Konfigurácia hesiel capabilityCredentialsPanel.label.enabled=Povolený capabilityCredentialsPanel.label.password=Heslo capabilityCredentialsPanel.label.returned=Vrátené v predvolenom nastavení @@ -154,7 +154,7 @@ capabilityScriptPanel.label.onResource=V koncovom systéme capabilityScriptPanel.label=Konfigurácia skriptu CapabilityStep.capabilities=Možnosti CapabilityStep.addCapabilities=Add capabilities -CapabilityStep.disabled=(disabled) +CapabilityStep.disabled=(zakázané) CapabilityStep.activation.tooltip.attributeName=Meno atribútu, ktorý obsahuje hodnotu pre simulovaný administrativeStatus. To je zvyčajne atribút, ktorý obsahuje nejaký druh povolenej/ zakázanej informácie. Typickými príkladmi sú atribúty, ako je "povolený", "ds-pwp-account-disabled", "accountStatus", etc. CapabilityStep.activation.tooltip.disableList=Zoznam hodnôt atribútov, ktoré predstavujú "zakázaný" stav. Ak niektorá z týchto hodnôt je prítomná v atribúte, potom bude objekt považovaný za zakázaný. Typické hodnoty sú "nepravda", "zakázaný", "0" alebo prázdne hodnoty. CapabilityStep.activation.tooltip.enabled=Pravda je, pokiaľ táto možnosť je aktívna. Nepravda je, ak je to zakázané. Zakázaný pôsobí rovnakým spôsobom, ako keby tam nebola. Možnosti možno vypnúť napr. chybou konektora, koncový systém len na čítanie, atď. @@ -202,10 +202,10 @@ CertDefinitionPage.message.cantSaveEmptyName=Can't save definition with empty na Channel.discovery=Objav Channel.import=Import Channel.liveSync=Živá synchronizácia -Channel.null=Vyberte jednu -channel.nullValid=Vyberte jednu -Channel.reconciliation=Schválenie -Channel.recompute=Recompute +Channel.null=Vyberte hodnotu +channel.nullValid=Vyberte hodnotu +Channel.reconciliation=Rekonciliácia +Channel.recompute=Prepočítanie Channel.user=Používateľ Channel.webService=Webová služba CheckTableHeader.label.error=Chyba @@ -254,18 +254,18 @@ DecisionsPanel.when=Keď DecisionsPanel.escalation=Esc. level DefinitionScopeObjectType.FocusType=Users, roles, orgs and services DefinitionScopeObjectType.AbstractRoleType=Roles, orgs and services -DefinitionScopeObjectType.RoleType=Role +DefinitionScopeObjectType.RoleType=Roly DefinitionScopeObjectType.UserType=Používatelia -DefinitionScopeObjectType.OrgType=Orgs -DefinitionScopeObjectType.ServiceType=Services +DefinitionScopeObjectType.OrgType=Organizácie +DefinitionScopeObjectType.ServiceType=Služby deleteAllDialog.label.accountShadowsDelete=Account shadows to delete: {0} deleteAllDialog.label.nonAccountShadowsDelete=Non-Account shadows to delete: {0} deleteAllDialog.label.org=Org. jednotka -deleteAllDialog.label.orgUnitsDelete=Org. units to delete: {0} +deleteAllDialog.label.orgUnitsDelete=Org. jednotky na zmazanie: {0} deleteAllDialog.label.shadow.account=Sledovaný účet deleteAllDialog.label.shadow.nonAccount=Nesledovaný účet deleteAllDialog.label.shadow.org=Org. jednotku sledovať -deleteAllDialog.label.shadow.role=Sledované role +deleteAllDialog.label.shadow.role=Sledované roly deleteAllDialog.label.totalToDelete=Total objects to delete: {0} deleteAllDialog.label.usersDelete=Users to delete: {0} (User 'Administrator' will not be deleted) deleteAllDialog.label.users=Používatelia @@ -276,10 +276,10 @@ DeltaPanel.label.changeType=Change type: DeltaPanel.label.modifications=Modifications: DeltaPanel.label.objectToAdd=Object to add: DeltaPanel.label.oid=object with oid: -direction.nullvalid=Vyberte jednu +direction.nullvalid=Vyberte hodnotu DoubleButtonPanel.button.default=Vykonať DoubleButtonPanel.download=Stiahnuť -DropDownChoicePanel.empty=Vyberte jednu +DropDownChoicePanel.empty=Vyberte hodnotu DropDownChoicePanel.notDefined=Nedefinovaný EmptyProcessDetailsPanel.message=Detaily procesu nie sú k dispozícii. ExecuteChangeOptionsPanel.label.executeAfterAllApprovals=Vykonať po ukončení všetkých schvaľovaní @@ -287,8 +287,8 @@ ExecuteChangeOptionsPanel.label.force=Vynútiť ExecuteChangeOptionsPanel.label.keepDisplayingResults=Ponechať výsledky zobrazené ExecuteChangeOptionsPanel.label.reconcileAffected=Vykonať rekonciliáciu dotknutých objektov ExecuteChangeOptionsPanel.label.reconcile=Vykonať rekonciliáciu -ExecuteChangeOptionsPanel.options=Voľby -existenceFetchStrategy.nullValid=Vyberte jednu +ExecuteChangeOptionsPanel.options=Možnosti +existenceFetchStrategy.nullValid=Vyberte hodnotu ExportType.CSV=CSV ExportType.DOCX=DOCX ExportType.HTML=HTML @@ -313,8 +313,8 @@ ExpressionEditorPanel.message.cantSerialize=Could not create JAXBElement from ExpressionEditorPanel.message.expressionSuccess=Výraz bol úspešne aktualizovaný. ExpressionEvaluatorType.AS_IS=Ako je ExpressionEvaluatorType.GENERATE=Generovať -ExpressionEvaluatorType.LITERAL=Literál -ExpressionEvaluatorType.null=Vyberte jednu +ExpressionEvaluatorType.LITERAL=Konštanta +ExpressionEvaluatorType.null=Vyberte hodnotu ExpressionEvaluatorType.PATH=Cesta ExpressionEvaluatorType.SCRIPT=Skript ExpressionReturnMultiplicityType.MULTI=Viac @@ -355,7 +355,7 @@ feedbackMessagePanel.param=Param: feedbackMessagePanel.showStack=[ Zobraziť chybový výpis ] feedbackMessagePanel.times=krát feedtempMessagePanelbackMessagePanel.message.info=Informácia -fetchStrategy.nullValid=Vyberte jednu +fetchStrategy.nullValid=Vyberte hodnotu filter.duplicate=Filter s menom '{0}' je už definovaný. filter.emptyFilter=Filter nesmie byť prázdny. H3Header.label.error=Chyba @@ -376,19 +376,19 @@ HandlerUriActions.ACTION_MODIFY_USER=Modify user (deprecated) HandlerUriActions.ACTION_SYNCHRONIZE=Synchronize (deprecated) HandlerUriActions.ACTION_UNLINK_ACCOUNT=Unlink account (deprecated) HandlerUriActions.ACTION_UNLINK=Odpojiť -HoursValidator.range=Pole '${label}' musí byť medzi ${minimum} a ${maximum}. -ImportOptionsPanel.errorCount=Chybný účet +HoursValidator.range=Položka '${label}' musí byť medzi ${minimum} a ${maximum}. +ImportOptionsPanel.errorCount=Počet chýb importOptionsPanel.fetchResourceSchema=Načítať schému koncového systému -importOptionsPanel.keepOid=Podržať OID -ImportOptionsPanel.options=Voľby +importOptionsPanel.keepOid=Zachovať OID +ImportOptionsPanel.options=Možnosti importOptionsPanel.overwriteExistingObject=Prepísať existujúci objekt -importOptionsPanel.protectedByEncryption=Chránené šifrovaním +importOptionsPanel.protectedByEncryption=Ochrániť šifrovaním importOptionsPanel.referentialIntegrity=Referenčná integrita -importOptionsPanel.stopAfter=Zastaviť po prekročení chýb +importOptionsPanel.stopAfter=Zastaviť po prekročení limitu chýb importOptionsPanel.summarizeErrors=Summarizovať chyby importOptionsPanel.summarizeSuccesses=Summarizovať úspechy importOptionsPanel.validateDynamicSchema=Validovať dynamickú schému -importOptionsPanel.validateStaticSchema=Validate static schema (XML only) +importOptionsPanel.validateStaticSchema=Validovať dynamickú schému (iba XML) ItemApprovalPanel.approvalSchema=Schválenie schémy ItemApprovalPanel.currentWorkItems=Aktuálne pracovné položky ItemApprovalPanel.nextStages=Following stages @@ -424,7 +424,7 @@ JasperReportParameterProperties.targetType=Target type JasperReportParameterProperties.multivalue=Multivalue JasperReportParameterProperties.config=Properties configuration JasperReportParameterProperties.title=Configure -kind.nullValid=Vyberte jednu +kind.nullValid=Vyberte hodnotu Language.GROOVY=Groovy (predvolené) Language.JAVASCRIPT=Javascript Language.XPATH=XPath @@ -502,7 +502,7 @@ lower.ActivationStatusType.DISABLED=zakázaný lower.ActivationStatusType.ENABLED=povolený lower.ActivationStatusType.null=nedefinovaný mainForm.category.null=Všetky -mainForm.mailServer.nullValid=Vyberte jednu +mainForm.mailServer.nullValid=Vyberte hodnotu mainForm.state.null=Všetky mainForm.tabPanel.panel.aepChooser.null=Relatívny (Predvolený) MappingEditorDialog.button.cancel=Zrušiť @@ -535,7 +535,7 @@ MappingsStatistics.MinTime=Min MappingsStatistics.Object=Obsahuje objekt MappingsStatistics.TotalTime=Celkový čas MappingType.label.placeholder=Vytvoriť nové mapovanie -matchingRule.nullValid=Vyberte jednu +matchingRule.nullValid=Vyberte hodnotu message.emptyLevel=Level nesmie byť prázdny. message.emptyString=Vstupný panel nesmie byť prázdny. message.error=Prosím ešte raz @@ -573,7 +573,7 @@ MyAssignmentsPanel.type.user=Používateľ MyAssignmentsPanel.type.policyRule=Policy rule NameStep.arrowToTurotialText=Každý krok sprievodcu má tlačidlo nápovedy. Stlačte toto tlačidlo na získanie informácií o ciele konkrétneho kroku konfigurácie. NameStep.connectorBundle=Balík -NameStep.connectorHost=Konektor hostiteľa +NameStep.connectorHost=Hostiteľ konektorov NameStep.connectorInformation=Informácia NameStep.connectorName=Meno konektora NameStep.connectorNotSelected=Konektor nebol vybraný. @@ -602,7 +602,7 @@ NotificationsStatistics.MaxTime=Max NotificationsStatistics.MinTime=Min NotificationsStatistics.TotalTime=Celkový čas NotificationsStatistics.Transport=Transport -nullValid=Vyberte jednu +nullValid=Vyberte hodnotu objectPolicyConfigurationEditor.button.edit=Upraviť objectPolicyConfigurationEditor.label=Object policies objectPolicyConfigurationEditor.name.placeholder=Vložiť politiku objektu @@ -617,16 +617,16 @@ ObjectPolicyDialog.property.placeholder=Vložte cestu k vlastnosti ObjectPolicyDialog.subtype=Object subtype ObjectPolicyDialog.template=Šablóna objektu ObjectPolicyDialog.type=Object type -objectSyncConfig.editorFocus.nullValid=Vyberte jednu -objectSyncConfig.editorKind.nullValid=Vyberte jednu -objectSyncConfig.editorObjectTemplate.nullValid=Vyberte jednu -objectTemplateRef.nullValid=Vyberte jednu +objectSyncConfig.editorFocus.nullValid=Vyberte hodnotu +objectSyncConfig.editorKind.nullValid=Vyberte hodnotu +objectSyncConfig.editorObjectTemplate.nullValid=Vyberte hodnotu +objectTemplateRef.nullValid=Vyberte hodnotu ObjectTypeGuiDescriptor.abstractRole=Abstraktná rola ObjectTypeGuiDescriptor.accessCertificationCampaign=Prístup k certifikačnej kampani ObjectTypeGuiDescriptor.accessCertificationDefinition=Prístup k certifikačnej definícii ObjectTypeGuiDescriptor.account=Účet ObjectTypeGuiDescriptor.connector=Konektor -ObjectTypeGuiDescriptor.connectorHost=Konektor hostiteľa +ObjectTypeGuiDescriptor.connectorHost=Hostiteľ konektorov ObjectTypeGuiDescriptor.focus=Focus ObjectTypeGuiDescriptor.form=Form ObjectTypeGuiDescriptor.genericObject=Generický objekt @@ -776,7 +776,7 @@ operation.com.evolveum.midpoint.task.api.TaskManager.switchToBackground=Prepnú operation.com.evolveum.midpoint.task.quartzimpl.cluster.ClusterManager.stopClusterManagerThread=Zastaviť ClusterManager thread (Úloha) operation.com.evolveum.midpoint.task.quartzimpl.cluster.NodeRegistrar.deleteNode=Zmazať uzol (Úloha) operation.com.evolveum.midpoint.task.quartzimpl.execution.ExecutionManager.addNodeAndTaskInformation=Pridať uzol a informácie o úlohách (Úloha) -operation.com.evolveum.midpoint.task.quartzimpl.execution.ExecutionManager.getClusterStatusInformation=Načítať informácie o statuse clustera (Úloha) +operation.com.evolveum.midpoint.task.quartzimpl.execution.ExecutionManager.getClusterStatusInformation=Načítať informácie o statuse klastra (Úloha) operation.com.evolveum.midpoint.task.quartzimpl.execution.ExecutionManager.scheduleTaskNow=Naplánovať úlohu teraz (Úloha) operation.com.evolveum.midpoint.task.quartzimpl.execution.ExecutionManager.startScheduler=Spustiť plánovač (Úloha) operation.com.evolveum.midpoint.task.quartzimpl.execution.ExecutionManager.stopAllTasksOnThisNodeAndWait=Zastaviť všetky úlohy v tomto uzle a čakať na ich dokončenie (Úloha) @@ -842,7 +842,7 @@ operation.com.evolveum.midpoint.web.page.admin.resources.PageResources.syncStatu operation.com.evolveum.midpoint.web.page.admin.resources.PageResources.testResource=Test koncového systému (Gui) operation.com.evolveum.midpoint.web.page.admin.roles.PageRole.loadRole=Načítať rolu (Gui) operation.com.evolveum.midpoint.web.page.admin.roles.PageRole.saveRole=Uložiť rolu (Gui) -operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.deleteRoles=Zmazať role (Gui) +operation.com.evolveum.midpoint.web.page.admin.roles.PageRoles.deleteRoles=Zmazať roly (Gui) operation.com.evolveum.midpoint.web.page.admin.server.dto.NodeDtoProvider.countNodes=Spočítať uzly (Gui) operation.com.evolveum.midpoint.web.page.admin.server.dto.NodeDtoProvider.listNodes=Zoznam uzlov (Gui) operation.com.evolveum.midpoint.web.page.admin.server.dto.TaskDtoProvider.countTasks=Spočítať úlohy (Gui) @@ -954,8 +954,8 @@ OrgUnitBrowser.createRoot=Vytvoriť koreň OrgUnitBrowser.message.queryError=Nastala chyba pri prekladaní dotazu na filter do databázy. OrgUnitBrowser.search=Vyhľadať OrgUnitBrowser.title=Vybrať nového rodiča pre org. jednotku -PageAbout.allRightsReserved=©2014 Evolveum. -PageAbout.button.testProvisioning=Auto - test provizií +PageAbout.allRightsReserved=©2017 Evolveum. +PageAbout.button.testProvisioning=Auto - test provisioningu PageAbout.button.cleanupActivitiProcesses=Clean-up Activiti processes PageAbout.button.testRepositoryCheckOrgClosure=Skontrolovať a opraviť konzistenciu PageAbout.button.reindexRepositoryObjects=Reindex repository objects @@ -969,16 +969,16 @@ PageAbout.midPointVersion=${pom.version} PageAbout.midPointVersionTitle=Verzia PageAbout.repoDiag.additionalDetails.name=Meno PageAbout.repoDiag.additionalDetails.value=Hodnota -PageAbout.repoDiag.driverShortName=Driver skratka -PageAbout.repoDiag.driverVersion=Driver verzia +PageAbout.repoDiag.driverShortName=Krátke meno ovládača +PageAbout.repoDiag.driverVersion=Verzia ovládača PageAbout.repoDiag.implementationDescription=Popis implementácie PageAbout.repoDiag.implementationShortName=Názov implementácie PageAbout.repoDiag.isEmbedded=Vložený PageAbout.repoDiag.repositoryUrl=Repozitár URL -PageAbout.title=About this system -PageAbout.title.basic=Základný +PageAbout.title=O tomto systéme +PageAbout.title.basic=Základné PageAbout.title.jvmProperties=JVM vlastnosti -PageAbout.title.provisioning=Provízie +PageAbout.title.provisioning=Provisioning PageAbout.title.repository.additional=Ďalšie detaily PageAbout.title.repository=Repozitár PageAbout.title.systemProperties=Systémové vlastnosti @@ -1038,7 +1038,7 @@ PageAdmin.menu.top.certification.decisions=My work items PageAdmin.menu.top.certification.definitions=Definície kampane PageAdmin.menu.top.certification.newDefinition=Definícia novej kampane PageAdmin.menu.top.certification.viewDefinition=View campaign definition -PageAdmin.menu.top.configuration.about=O +PageAdmin.menu.top.configuration.about=O systéme PageAdmin.menu.top.configuration.basic=Systém PageAdmin.menu.top.configuration.bulkActions=Bulk akcie PageAdmin.menu.top.configuration.repoQuery=Query playground @@ -1046,13 +1046,13 @@ PageAdmin.menu.top.configuration.evaluateMapping=Mapping playground PageAdmin.menu.top.configuration=Konfigurácia PageAdmin.menu.top.configuration.configuration=Konfigurácia PageAdmin.menu.top.configuration.development=Vývoj -PageAdmin.menu.top.configuration.expressionEvaluator=Ohodnotenie výrazu +PageAdmin.menu.top.configuration.expressionEvaluator=Vyhodnotenie výrazu PageAdmin.menu.top.configuration.importObject=Importovať objekt PageAdmin.menu.top.configuration.internals=Vnútorná konfigurácia PageAdmin.menu.top.configuration.logging=Logovanie PageAdmin.menu.top.configuration.notifications=Notifikácie PageAdmin.menu.top.configuration.profiling=Profilovanie -PageAdmin.menu.top.configuration.adminGui=Admin GUI +PageAdmin.menu.top.configuration.adminGui=Administrátorské rozhranie PageAdmin.menu.top.configuration.repositoryObjects=Objekty repozitára PageAdmin.menu.top.configuration.repositoryObjectsList=List objects PageAdmin.menu.top.configuration.security=Zabezpečenie @@ -1063,15 +1063,15 @@ PageAdmin.menu.top.reports.list=Zoznam reportov PageAdmin.menu.top.reports.new=Importovať definíciu reportu PageAdmin.menu.top.reports=Reporty PageAdmin.menu.top.resources.import=Importovať definíciu systému -PageAdmin.menu.top.resources.list=Zoznam systémov -PageAdmin.menu.top.resources.new=Nový systém -PageAdmin.menu.top.resources.view=View resource -PageAdmin.menu.top.resources.edit=Editovať systém -PageAdmin.menu.top.resources=Systémy -PageAdmin.menu.top.connectorHosts.list=List connector hosts +PageAdmin.menu.top.resources.list=Zoznam koncových systémov +PageAdmin.menu.top.resources.new=Nový koncový systém +PageAdmin.menu.top.resources.view=Zobraziť koncový systém +PageAdmin.menu.top.resources.edit=Editovať koncový systém +PageAdmin.menu.top.resources=Koncové systémy +PageAdmin.menu.top.connectorHosts.list=Zoznam hostiteľov konektorov PageAdmin.menu.top.roles.list=Zoznam rolí PageAdmin.menu.top.roles.new=Nová rola -PageAdmin.menu.top.roles=Role +PageAdmin.menu.top.roles=Roly PageAdmin.menu.top.serverTasks.list=Zoznam úloh PageAdmin.menu.top.serverTasks.new=Nová úloha PageAdmin.menu.top.serverTasks=Serverové úlohy @@ -1083,6 +1083,7 @@ PageAdmin.menu.top.users.org=Org. štruktúra PageAdmin.menu.top.users.org.tree=Org. strom PageAdmin.menu.top.users=Používatelia PageAdmin.menu.top.valuePolicies.list= List value policies +PageAdmin.menu.top.valuePolicies.new = New value policy PageAdmin.menu.top.valuePolicies= Value policies PageAdmin.menu.top.workItems.listClaimable=Pracovné položky nárokovateľné mnou PageAdmin.menu.top.workItems.list=Moje pracovné položky @@ -1103,7 +1104,7 @@ PageAdminObjectDetails.title.newRoleType=Vytvoriť novú rolu PageAdminObjectDetails.title.editOrgType=Upraviť organizáciu '{0}' PageAdminObjectDetails.title.newOrgType=Vytvoriť novú organizáciu PageAdminObjectDetails.noChangesSave=Neboli vykonané žiadne zmeny, ktoré by sa dali uložiť. -PageAdminObjectDetails.noChangesPreview=There are no changes to be previewed. +PageAdminObjectDetails.noChangesPreview=Neboli vykonané žiadne zmeny, ktoré by sa dali zobraziť v náhľade. pageAdminFocus.basic=Základné pageAdminFocus.message.cantEditFocus=Unknown error occurred, can't edit focus object. pageAdminFocus.message.cantNewFocus=Unknown error occurred, can't create new focus object. @@ -1140,11 +1141,11 @@ pageAdminFocus.message.unlocked=Account '{0}' was marked to be unlocked. Apply b pageAdminFocus.message.noAccountSelected=Nebola vybraná projekcia. pageAdminFocus.message.noAssignmentSelected=Nebolo vybraté priradenie. pageAdminFocus.title.selectResource=Vybraté koncové systém(y) -pageAdminFocus.title.selectAssignable=Vyberte objekt(y) +pageAdminFocus.title.selectAssignable=Vyberte objekt(y) pageAdminFocus.task.name=Meno úlohy pageAdminFocus.task.category=Kategória: -pageAdminFocus.task.descriptionHasTasks=Active tasks related to this object: -pageAdminFocus.task.descriptionNoTasks=There are no active tasks related to this object. +pageAdminFocus.task.descriptionHasTasks=Aktívne úlohy pre tento objekt: +pageAdminFocus.task.descriptionNoTasks=Pre tento objekt neexistujú žiadne aktívne úlohy. pageAdminFocus.task.execution=Stav spracovania pageAdminFocus.task.status=Stav pageAdminFocus.tasks=Úlohy @@ -1152,7 +1153,7 @@ pageAdminFocus.button.save=Uložiť pageAdminFocus.button.previewChanges=Náhľad zmien pageAdminFocus.button.abort=Skončiť pageAdminFocus.button.back=Späť -pageAdminFocus.button.continueEditing=Continue editing +pageAdminFocus.button.continueEditing=Pokračovať v úpravách pageAdminFocus.title.confirmDelete=Potvrďte zmazanie pageAdminFocus.message.deleteAccountConfirm=Naozaj chcete zmazať {0} projekciu(e)? pageAdminFocus.message.deleteAssignmentConfirm=Naozaj chcete zmazať {0} vybraných priradení? @@ -1167,7 +1168,7 @@ pageAdminResources.message.cantLoadResource=Nepodarilo sa načítať detaily kon pageAdminResources.newResource=Nový systém pageAdmin.resources=Systémy pageAdmin.roles.description=Konfigurácia rolí -pageAdmin.roles=Role +pageAdmin.roles=Roly pageAdmin.serverTasks.description=Bežiace úlohy pageAdmin.serverTasks=Serverové úlohy pageAdmin.users.description=Používatelia v databáze @@ -1194,7 +1195,7 @@ PageBase.demoSubscriptionMessage=Demo subscription. PageBulkAction.async=Asynchrónny PageBulkAction.button.start=Štart PageBulkAction.message.emptyString=Vložená bulk akcia je prázdna. Prosím vložte neprázdny skript. -PageBulkAction.options=Voľby +PageBulkAction.options=Možnosti PageBulkAction.title=Používateľská bulk akcia PageRepositoryQuery.title=Repository query PageRepositoryQuery.button.translateAndExecute=Translate and execute @@ -1243,7 +1244,7 @@ PageCertCampaign.menu.delegate=Postúpiť PageCertCampaign.menu.noResponse=Bez odozvy PageCertCampaign.menu.notDecided=Nerozhodnuté PageCertCampaign.menu.reduce=Redukovať -PageCertCampaign.menu.revoke=Odňať +PageCertCampaign.menu.revoke=Odobrať PageCertCampaign.name=Názov PageCertCampaign.numberOfStages=Počet etáp PageCertCampaign.owner=Vlastník @@ -1378,7 +1379,7 @@ PageCertDefinition.scopeAssignmentsInducements=Include assignments or inducement PageCertDefinition.scopeIncludeAssignments=Priradenia PageCertDefinition.scopeIncludeInducements=Stimuly PageCertDefinition.scopeIncludeTargetTypes=Include target types -PageCertDefinition.scopeIncludeRoles=Role +PageCertDefinition.scopeIncludeRoles=Roly PageCertDefinition.scopeIncludeOrgs=Orgs PageCertDefinition.scopeIncludeServices=Services PageCertDefinition.scopeIncludeResources=Systémy @@ -1441,7 +1442,7 @@ pageContentAccounts.menu.changeOwner=Zmeniť vlastníka pageContentAccounts.menu.deleteAccount=Zmazať pageContentAccounts.menu.disableAccount=Zakázať pageContentAccounts.menu.enableAccount=Povoliť -pageContentAccounts.menu.importAccount=Import +pageContentAccounts.menu.importAccount=Importovať pageContentAccounts.menu.removeOwner=Odstrániť vlastníka pageContentAccounts.menu.deleteAccounts=Zmazať vybrané pageContentAccounts.menu.disableAccounts=Disable selected @@ -1492,33 +1493,33 @@ PageDashboard.activeTasks=Aktívne úlohy PageDashboard.activeUsers=Aktívni používatelia PageDashboard.assignments=Moje priradenia PageDashboard.personalInfo=Osobné údaje -PageDashboard.serverLoad=Server Load +PageDashboard.serverLoad=Záťaž serveru PageDashboard.systemInfo=Stav systému -PageDashboard.title=Vitajte +PageDashboard.title=Prehľad PageDashboard.usedRam=Použitá RAM PageDashboard.workItems=Moje pracovné položky PageDashboard.infobox.users.label=Používatelia -PageDashboard.infobox.users.number=povolený -PageDashboard.infobox.users.total=total -PageDashboard.infobox.users.archived=archivovaný -PageDashboard.infobox.orgs.label=Organizational units -PageDashboard.infobox.orgs.number=povolený -PageDashboard.infobox.orgs.total=total -PageDashboard.infobox.orgs.archived=archivovaný -PageDashboard.infobox.roles.label=Role -PageDashboard.infobox.roles.number=povolený -PageDashboard.infobox.roles.total=total -PageDashboard.infobox.roles.archived=archivovaný -PageDashboard.infobox.services.label=Services -PageDashboard.infobox.services.number=povolený -PageDashboard.infobox.services.total=total -PageDashboard.infobox.services.archived=archivovaný -PageDashboard.infobox.resources.label=Systémy -PageDashboard.infobox.resources.number=up -PageDashboard.infobox.resources.total=total +PageDashboard.infobox.users.number=povolených +PageDashboard.infobox.users.total=celkovo +PageDashboard.infobox.users.archived=archivovaných +PageDashboard.infobox.orgs.label=Organizačné jednotky +PageDashboard.infobox.orgs.number=povolených +PageDashboard.infobox.orgs.total=celkovo +PageDashboard.infobox.orgs.archived=archivovaných +PageDashboard.infobox.roles.label=Roly +PageDashboard.infobox.roles.number=povolených +PageDashboard.infobox.roles.total=celkovo +PageDashboard.infobox.roles.archived=archivovaných +PageDashboard.infobox.services.label=Služby +PageDashboard.infobox.services.number=povolených +PageDashboard.infobox.services.total=celkovo +PageDashboard.infobox.services.archived=archivovaných +PageDashboard.infobox.resources.label=Koncové systémy +PageDashboard.infobox.resources.number=funkčných +PageDashboard.infobox.resources.total=celkovo PageDashboard.infobox.tasks.label=Úlohy -PageDashboard.infobox.tasks.number=active -PageDashboard.infobox.tasks.total=total +PageDashboard.infobox.tasks.number=aktívnych +PageDashboard.infobox.tasks.total=celkovo pageDebugList.button.clear=Vymazať pageDebugList.button.search=Vyhľadať pageDebugList.description=Popis @@ -1550,7 +1551,7 @@ pageDebugList.messsage.deleteAllShadowsStarted=Úloha mažúca všetky obrazy sy pageDebugList.name=Meno pageDebugList.oid=Oid pageDebugList.objectType=Typy objektu -pageDebugList.options=Voľby +pageDebugList.options=Možnosti pageDebugList.resourceName=Meno systému pageDebugList.resource=Systém pageDebugList.resourceType=Typ systému @@ -1563,7 +1564,7 @@ pageDebugView.edit=Editovať pageDebugView.encrypt=Chránené šifrovaním pageDebugView.message.cantSaveEmpty=Nie je možné uložit prázdne xml. pageDebugView.message.oidNotDefined=OID objektu nie je definované. -pageDebugView.options=Voľby +pageDebugView.options=Možnosti pageDebugView.reevaluateSearchFilters=Prehodnotiť filter na vyhľadávanie pageDebugView.saveAsRaw=Uložiť v surovom stave pageDebugView.switchToPlainText=Prepnúť na čistý text @@ -1592,7 +1593,7 @@ PageImportObject.embeddedEditor=Vstavaný editor PageImportObject.file=Súbor PageImportObject.getObjectsFrom=Načítať objekty z pageImportObject.message.emptyXml=Nie je možné uložit prázdne xml. -PageImportObject.message.help=Choose XML, JSON or YAML file for import. +PageImportObject.message.help=Vyberte súbor vo formáte XML, JSON alebo YAML na import. pageImportObject.message.nullFile=Posielaný súbor je null. PageImportObject.title=Importovať objekty PageInternals.button.changeTime=Zmeniť čas @@ -1781,7 +1782,7 @@ PageReports.message.unknownReport=Neznámy report. PageReports.report.auditDescription=Report bol vyrobený z auditných záznamov. PageReports.report.auditName=Auditné logy PageReports.report.reconciliationDescription=Schvaľujúci report pre vybrané systémy. -PageReports.report.reconciliationName=Schválenie +PageReports.report.reconciliationName=Rekonciliácia PageReports.report.usersDescription=Users listed in Identity Manager. PageReports.report.usersName=Users in Identity Manager PageReports.search.showSubreports=Zobraziť subreporty @@ -1829,7 +1830,7 @@ pageResource.conSchema=Schéma konektora pageResource.deleteSyncToken=Zmazať synch. token pageResourceEdit.edit=Upraviť pageResourceEdit.message.emptyXml=Nie je možné uložiť prázdne xml ako koncový systém. -pageResourceEdit.options=Voľby +pageResourceEdit.options=Možnosti pageResource.editResource=Editovať koncový systém PageResourceEdit.title=Nový koncový systém pageResource.import=Import @@ -1852,7 +1853,7 @@ pageResources.button.discoveryRemote=Discovery pageResources.button.editAsXml=Editovať XML pageResources.button.search=Vyhľadať pageResources.connector.hostname=Meno host-u -pageResources.connectorHosts=Konektor host-u +pageResources.connectorHosts=Hostitelia konektorov pageResources.connector.name=Meno pageResources.connector.port=Port pageResources.connector.protectConnection=Chránený @@ -1875,7 +1876,7 @@ pageResources.resources=Systémy pageResources.searchText.placeholder=Názov pageResources.status=Posledný stav pageResource.status=Stav -PageResources.title=Resources List +PageResources.title=Zoznam koncových systémov pageResources.version=Verzia pageResource.sync=Synchronizácia PageResource.title=Detaily koncového systému @@ -1965,7 +1966,7 @@ pageTask.category.ImportFromFile=Import zo súboru pageTask.category.ImportingAccounts=Importovať účty pageTask.category.LiveSynchronization=Živá synchronizácia pageTask.category.Recomputation=Prepočet -pageTask.category.Reconciliation=Schválenie +pageTask.category.Reconciliation=Rekonciliácia pageTask.category.UserRecomputation=Používateľský prepočet pageTask.category.Workflow=Workflow pageTask.createSuspended=Vytvoriť v stave SUSPENDED @@ -1974,14 +1975,14 @@ pageTask.cronHelpLink=Pre viac informácii prosím pozrite pageTask.cronHelpLinkTutorial=tutoriál pageTask.cronSpec=Naplánovať podľa cron-like špecifikácie pageTask.dryRun=Skúšobný beh -pageTask.focusType=Applicable to type -pageTaskEdit.basic=Základný +pageTask.focusType=Aplikovateľné pre typ +pageTaskEdit.basic=Základné pageTaskEdit.work=Work to do pageTaskEdit.boundHelp=Tesne previazané úlohy sú použité na spustenie krátkych akcií, ktoré sa pomerne často opakujú (napríklad v intervale kratšom než 1 minúta). Typickým príkladom je živá synchronizácia. Cron-like špecifikácia nie je podporovaná pre tieto úlohy; musíte zadať časový interval. pageTaskEdit.bound=Tesne zviazané (použiť v prípade ak opakujúca sa úloha beží často) pageTaskEdit.binding=Binding pageTaskEdit.button.back=Späť -pageTaskEdit.button.cancelEditing=Cancel editing +pageTaskEdit.button.cancelEditing=Zrušiť úpravy pageTaskEdit.button.edit=Upraviť pageTaskEdit.button.resume=Záver pageTaskEdit.button.runNow=Spustiť teraz @@ -2026,7 +2027,7 @@ pageTaskEdit.opResult.message=Správa pageTaskEdit.opResult.operation=Operácia pageTaskEdit.opResult.status=Stav pageTaskEdit.opResult.token=Token -pageTaskEdit.options=Voľby +pageTaskEdit.options=Možnosti pageTaskEdit.parent=Rodičovská úloha pageTaskEdit.owner=Task owner pageTaskEdit.recurring=Opakujúca sa úloha @@ -2039,10 +2040,10 @@ pageTaskEdit.approvals=Approvals pageTaskEdit.operation=Operation context pageTaskEdit.performance=Environmental performance pageTaskEdit.progress=Aktuálny status -pageTaskEdit.subtasksAndThreads=Subtasks and threads -pageTaskEdit.statesAndActions=States and actions +pageTaskEdit.subtasksAndThreads=Subtasky a vlákna +pageTaskEdit.statesAndActions=Stavy a akcie pageTaskEdit.result=Výsledok -pageTaskEdit.errors=Errors +pageTaskEdit.errors=Chyby pageTaskEdit.subtasksLabel=Subtasky pageTaskEdit.suspendReq=Skôr ako je možné editovať úlohu, je potrebné ju pozastaviť. pageTaskEdit.taskState=Stav úlohy @@ -2073,7 +2074,7 @@ pageTask.notStartBefore.error1='Nezačať pred' je neskor ako 'Nezačať po' pageTask.now=Teraz pageTask.objectClass=Trieda objektu pageTask.objectRef=Referencia na konc. systém -pageTask.options=Voľby +pageTask.options=Možnosti pageTask.recurring=Opakujúca sa úloha pageTask.runUntilNodeDown.error1=Compatible data for 'Thread stop action' are: Close, Suspend pageTask.runUntilNodeDown.error2=Compatible data for 'Thread stop action' are: Restart, Reschedule @@ -2105,7 +2106,7 @@ pageTasks.category.ImportingAccounts=Importovať účty pageTasks.category.LiveSynchronization=Živá synchronizácia pageTasks.category.null=(nedefinovaný) pageTasks.category.Recomputation=Prepočet -pageTasks.category.Reconciliation=Schválenie +pageTasks.category.Reconciliation=Rekonciliácia pageTasks.category.Report=Report pageTasks.category.System=Systém pageTasks.category.UserRecomputation=Používateľský prepočet @@ -2126,7 +2127,7 @@ pageTasks.message.confirmationMessageForSingleTaskObject=Do you really want to { pageTasks.message.confirmationMessageForMultipleTaskObject=Do you really want to {0} selected {1} task(s)? pageTasks.message.confirmationMessageForSingleNodeObject=Do you really want to {0} node '{1}'? pageTasks.message.confirmationMessageForMultipleNodeObject=Do you really want to {0} selected {1} node(s)? -pageTask.scheduleHelp=U jednorazových úloh, nezadávajte ani plánovaný interval ani cron-like špecifikáciu. U opakovaných úloh, zadajte presne jedno z toho. +pageTask.scheduleHelp=U jednorazových úloh, nezadávajte plánovaný interval ani cron-like špecifikáciu. U opakovaných úloh, zadajte presne jedno z toho. pageTask.scheduleInterval=Plánovaný interval (sekundy) pageTask.scheduleTitle=Plánovanie pageTask.scheduleValidation.bothIntervalAndCron='Schedule Interval' a 'Cron-like špecifikácie' nesmú byť prítomné zároveň. @@ -2146,24 +2147,24 @@ pageTasks.message.deleteAllClosedTasksConfirm=Do you really want to delete all c pageTasks.message.deleteTasksConfirm=Naozaj chcete zmazať {0} úlohy? pageTasks.message.noNodeSelected=Nebol vybraný žiadny uzol. pageTasks.message.noTaskSelected=Nebola vybraná žiadna úloha. -pageTasks.node.clustered=Clustered +pageTasks.node.clustered=V klastri pageTasks.node.executionStatus=Stav -pageTasks.node.lastCheckInTime=Posledný čas check-in -pageTasks.node.managementPort=Management port +pageTasks.node.lastCheckInTime=Posledný čas kontroly +pageTasks.node.managementPort=Port na správu pageTasks.node.name=Meno pageTasks.nodes=Uzly pageTasks.node.statusMessage=Stavová správa pageTasks.nowForNotRunningTasks=(teraz) pageTasks.now=teraz pageTasks.runsContinually=beží nepretržite -pageTasks.stalledSince=POZASTAVENÁ v {0} o {1} +pageTasks.stalledSince=POZASTAVENÁ od {0} o {1} pageTasks.state=Stav: pageTasks.subtasks=Zobraziť subtasky: pageTasks.task.category=Kategória pageTasks.task.currentRunTime=Aktuálny čas spustenia pageTasks.task.detail=Detail -pageTasks.task.executingAt=Spracované v -pageTasks.task.execution=Spracovanie +pageTasks.task.executingAt=Vykonáva sa na +pageTasks.task.execution=Stav behu pageTasks.task.name=Meno pageTasks.task.objectRef=Referencia na objekt pageTasks.task.progress=Progres @@ -2243,7 +2244,7 @@ pageUsers.message.deleteAction=zmazať pageUsers.message.confirmActionPopupTitle=Potvrdiť akciu pageUsers.message.nothingSelected=Nebol vybraný žiaden používateľ. pageUsers.message.queryError=Nastala chyba pri preklade dopytu pre vyhľadávanie. -PageUsers.title=User List +PageUsers.title=Zoznam používateľov pageUser.task.category=Kategória pageUser.task.execution=Stav spracovania pageUser.task.name=Meno úlohy @@ -2256,15 +2257,16 @@ pageUser.title.newUser=Vytvoriť pageUser.title.selectAssignable=Vyberte objekt(y) pageUser.title.selectResource=Vybraté koncové systém(y) pageUser.userDetails=Detaily používateľa -MultipleAssignmentSelectorPanel.availableRoles=Available roles -MultipleAssignmentSelectorPanel.parameters=Parameters -MultipleAssignmentSelectorPanel.currentRoles=Current roles -MultipleAssignmentSelector.filterByUser=Filter by user +MultipleAssignmentSelectorPanel.availableRoles=Dostupné roly +MultipleAssignmentSelectorPanel.parameters=Parametre +MultipleAssignmentSelectorPanel.currentRoles=Priradené roly +MultipleAssignmentSelector.filterByUser=Filtrovať podľa používateľa MultipleAssignmentSelector.tenant=Tenant MultipleAssignmentSelector.orgUnit=Org. jednotka pageValuePolicies.table.description=Description pageValuePolicies.button.delete=Delete PageValuePolicies.title=List value policies +PageValuePolicy.title = Value policy pageWorkItem.accordionLabel.additionalData=Súvisiace dáta (technické informácie) pageWorkItem.accordionLabel.objectNew=Objekt po navrhovanej zmene (technické informácie) pageWorkItem.accordionLabel.objectOld=Objekt pred zmenou (technické informácie) @@ -2284,7 +2286,7 @@ pageWorkItem.label.showTechnicalInformation=Zobraziť technické informácie pageWorkItem.mainInfo=Základné informácie pageWorkItem.objectNew.description=Objekt po navrhovanej zmene pageWorkItem.objectOld.description=Objekt pred zmenou -pageWorkItem.options=Voľby +pageWorkItem.options=Možnosti pageWorkItem.requestCommon.description=Všeobecné informácie o žiadosti pageWorkItem.requestedBy=Requested by: pageWorkItem.requestedOn=Requested on: @@ -2298,7 +2300,7 @@ workItemPanel.escalationLevel=Escalation level: workItemPanel.requesterComment=Requester comment: workItemPanel.delta=Delta bude schválená workItemPanel.mainInfo=Základné informácie -workItemPanel.options=Voľby +workItemPanel.options=Možnosti workItemPanel.requestedBy=Requested by: workItemPanel.requestedOn=Requested on: workItemPanel.workItemCreatedOn=This work item created on: @@ -2325,6 +2327,7 @@ TaskWfParentPanel.requestsHelp=All approval processes for changes displayed here workItemPanel.otherWorkItems=Other work items for this request workItemPanel.requests=Requests workItemPanel.relatedRequests=Related requests +workItemPanel.reasons=Reasons for the approval process workItemPanel.approverComment=Approver comment workItemPanel.approverInstruction=Approver instruction pageWorkItems.button.approve=Schváliť @@ -2354,16 +2357,16 @@ past.ChangeType.ADD=Pridané past.ChangeType.DELETE=Zmazané past.ChangeType.MODIFY=Zmenené PersonalInfoPanel.lastFail.date=Dátum -PersonalInfoPanel.lastFail.from=Od +PersonalInfoPanel.lastFail.from=Adresa PersonalInfoPanel.lastFail=Posledné neúspešné prihlásenie PersonalInfoPanel.lastLogin.date=Dátum -PersonalInfoPanel.lastLogin.from=Od +PersonalInfoPanel.lastLogin.from=Adresa PersonalInfoPanel.lastLogin=Posledné prihlásenie PersonalInfoPanel.never=Nikdy -PersonalInfoPanel.other=Iný +PersonalInfoPanel.other=Ostatné PersonalInfoPanel.passwordExp=Dátum expirácie účtu PersonalInfoPanel.undefined=Nedefinovaný -policyRef.nullValid=Vyberte jednu +policyRef.nullValid=Vyberte hodnotu prismContainer.mainPanelDisplayName=Vlastnosti prismContainer.shadow.associations=Asociácie prismContainer.shadow.mainPanelDisplayName=Atribúty @@ -2438,7 +2441,7 @@ ReconciliationPopupPanel.exportFileType=Typ exportu DownloadButtonPanel.download=Stiahnuť ReconciliationPopupPanel.resource=Systém ReconciliationPopupPanel.title.basic=Základná konfigurácia pre schvaľujúci report -repeater.input.nullValid=Vyberte jednu +repeater.input.nullValid=Vyberte hodnotu ReportConfigurationPanel.title.basic=Základný ReportConfigurationPanel.title.advanced=Rozšírené Requestable.ALL=Všetky @@ -2593,7 +2596,7 @@ SchemaHandlingStep.association.tooltip.associationLocalPart=TODO: SchemaHandling SchemaHandlingStep.association.tooltip.associationNamespace=TODO: SchemaHandlingStep.association.tooltip.associationNamespace SchemaHandlingStep.association.tooltip.direction=Defines the direction of the association. Object-to-subject: Object (e.g. group) has an attribute that contains identifier of the subject (e.g. account); Subject-to-object: Subject (e.g. account) has an attribute that contains identifier of the object (e.g. group). SchemaHandlingStep.association.tooltip.explicitRefIntegrity=Explicit referential integrity. If set to false then system assumes that the resource implements referential integrity. E.g. system assumes that the resource automatically updates the association identifiers if an account is renamed and system does not need to do anything. If set to true then system will do referential integrity explicitly. In this case system will explicitly update the association attributes if an account is renamed. -SchemaHandlingStep.association.tooltip.intent=Účel asociácie cieľového typu objektu. Určiť druh a účelne identifikovať typ objektu, ktorým je cielená asociácia, napr skupina, oprávnenie, role, atď. +SchemaHandlingStep.association.tooltip.intent=Účel asociácie cieľového typu objektu. Určiť druh a účelne identifikovať typ objektu, ktorým je cielená asociácia, napr skupina, oprávnenie, roly, atď. SchemaHandlingStep.association.tooltip.kind=Druh asociácie cieľového typu objektu. To je zvyčajne "nárok". Určiť druh a účelne identifikovať typ objektu, ktorým je cielená asociácia, napr skupina, oprávnenie, role, atď. SchemaHandlingStep.association.tooltip.valueAttribute=Názov atribútu, ktorý je zdrojom hodnoty pre asociáciu. Hodnota tohto atribútu bude prijatá a uložená do atribútu asociácie pri jej vzniku. To je zvyčajne atribút, ktorý obsahuje identifikátor alebo názov, napríklad "uid", "id", "name", etc. V subjekt k objektu asociáciách to je atribút objektu (napr. skupina). V objekte k subjektu asociácii je atribútom subjektu (napr účet). SchemaHandlingStep.attribute.label.attributeName=Meno atribútu @@ -2731,8 +2734,8 @@ SearchType.NAME=Meno simpleErrorPanel.label.showMore=Zobraziť viac simpleErrorPanel.message.error=Účet do systému '{0}' nebol načítaný. SimpleRoleSelector.reset=Resetnúť -MultipleAssignmentSelector.reset=Reset the list -situation.nullValid=Vyberte jednu +MultipleAssignmentSelector.reset=Nastaviť zoznam na pôvodné hodnoty +situation.nullValid=Vyberte hodnotu StandardLoggerType.CHANGE_EXECUTOR=Zmaniť vykonávateľa (c.e.m.model.lens.ChangeExecutor) StandardLoggerType.CLOCKWORK=Clockwork (c.e.m.model.lens.Clockwork) StandardLoggerType.EXPRESSION=Výraz (c.e.m.common.expression.Expression) @@ -2828,7 +2831,7 @@ SynchronizationStep.reaction.tooltip.reconcile=If set to true then the reconcili SynchronizationStep.reaction.tooltip.situation=Synchronizačná situácia. Ak sa udalosť zhoduje s udalosťou, ktorá je tu špecifikovaná, potom táto reakcia bude spracovaná. Inak bude ignorovaná. SynchronizationStep.reaction.tooltip.synchronize=Ak je nastavená na hodnotu pravda, potom bude použitý obvyklý synchronizačný algoritmus (a.k.a. clockwork and projector), okrem explicitných činností uvedených nižšie. Toto je obvyklý prípad. Ak je nastavená na hodnotu nepravda, potom bude synchronizačný algoritmyus preskočený a iba explicitná akcia bude vykonaná. SynchronizationStep.title=Synchronizácia -SynchronizationStep.tooltip.condition=Nastavenie synchronizácie sa použije iba pokiaľ táto podmienka vráti PRAVDA. Podmienka sa používa väčšinou na zotriedenie objektov rovnakého druhu. Napr. podmienka môže rozhodnúť, či užívateľské meno začína "T". Môže zotriediť účty podľa účelu "test", ale ak to tak nie je, potom účet bude mať predvolený účel. +SynchronizationStep.tooltip.condition=Nastavenie synchronizácie sa použije iba pokiaľ táto podmienka vráti PRAVDA. Podmienka sa používa väčšinou na zotriedenie objektov rovnakého druhu. Napr. podmienka môže rozhodnúť, či používateľské meno začína "T". Môže zotriediť účty podľa účelu "test", ale ak to tak nie je, potom účet bude mať predvolený účel. SynchronizationStep.tooltip.confirmation=Potvrdenie výrazu. Každý výsledok korelačného výrazu bude odovzdaný do potvrdzovacieho výrazu. Ak potvrdzovací výraz vráti hodnotu PRAVDA, potom budú objekty prepojené. Ak nie je zadaný potvrdzovací výraz, potom všetky objekty vrátené z korelačného dotazu sú štandardne akceptované. Potvrdenie výrazu môže byť primerane náročné na prostriedky, pretože bude vykonané iba pre objekty, ktoré sú vrátené z korelačného dotazu. SynchronizationStep.tooltip.correlation=Korelačný výraz. Korelačný výraz sa používa na prepojenie ústredných objektov (napr používateľ) a obrazov (napr účtu), ktoré patria k sebe. Korelačný výraz má za následok vyhľadávací filter, ktorý je vykonaný cez ústredné objekty (zvyčajne používateli). Dotaz vráti kandidátov na spojenie. Korelačný výraz musí byť veľmi efektívny inak výkon synchronizácie utrpí. SynchronizationStep.tooltip.enabled=Je nastavená na hodnotu PRAVDA ak je povolené toto nastavenie. Toto je predvolené. Toto nastavenie je možné použiť na dočasné zakázanie nastavenia synchronizácie. @@ -2853,7 +2856,6 @@ SystemConfigPanel.deploymentInformation.logoImageUrl = Logo image URL SystemConfigPanel.deploymentInformation.logoCssClass = Icon css class SystemConfigPanel.deploymentInformation.customerUrl = Customer url SystemConfigPanel.deploymentInformation.partnerName = Partner name -SystemConfigPanel.deploymentInformation.skin = Template skin SystemConfigPanel.deploymentInformation.subscriptionIdentifier = Subscription identifier SystemConfigPanel.deprecated.objectPolicy=Táto časť konfigurácia je zastaralá. Je tu archivovaná pre účely kompatibility. Prosím, použite nižšie uvedený komponent na definovanie pravidiel. SystemConfigPanel.mail.config.placeholder=Nová konfigurácia @@ -2883,7 +2885,7 @@ SystemConfigPanel.title.passwordPolicy=Globálne pravidlá tvorby hesla SystemConfigPanel.title.securityPolicy=Global security policy SystemConfigPanel.title.userTemplate=Predvolená šablóna používateľa SystemConfigPanel.tooltip.duration=Format: P[n][p], n-number, p-period (d - days, m - months, ...), P3M - cleanup every 3 months -SystemConfigPanel.tooltip.color = Hex format, e.g. #3e934a for a "dark green" +SystemConfigPanel.tooltip.color =Hex format, e.g. #3c8dbc for the default "blue-light" color SystemInfoPanel.cpuUsage=CPU Usage SystemInfoPanel.heapMemory=Heap memory (used/committed/max) SystemInfoPanel.nonHeapMemory=Non heap memory (used/committed/max) @@ -2972,7 +2974,7 @@ Title.MappingsStatistics=Informácia o ohodnotení mapovania Title.NotificationsStatistics=Notifikačná informácia Title.ProvisioningStatistics=Informácie o províznych operáciách Title.Source=Source: -TreeTablePanel.childOrg=Org. jednotky potomkov +TreeTablePanel.childOrg=Podriadené org. jednotky TreeTablePanel.collapseAll=Zbaliť všetky TreeTablePanel.deleteRoot=Zmazať koreň TreeTablePanel.dialog.title.confirmDelete=Potvrďte zmazanie @@ -3006,23 +3008,23 @@ TreeTablePanel.search.scope.one=Jedna úroveň TreeTablePanel.search.scope.subtree=Podstrom TreeTablePanel.fullName.displayName=Celé meno/Zobrazované meno TreeTablePanel.identifier.description=Identifikátor/Popis -TreeTablePanel.warning.childrenExist=Organization which is going to be deleted has members. Do you really want to delete it? +TreeTablePanel.warning.childrenExist=Organizácia, ktorá sa má vymazať, má členov. Chcete ju naozaj vymazať? Type.AUDIT=Auditný -type.nullValid=Vyberte jednu -Type.RECONCILIATION=Schválenie -typeSelect.null=Všetky role +type.nullValid=Vyberte hodnotu +Type.RECONCILIATION=Rekonciliácia +typeSelect.null=Všetky roly Type.USERS=Používateľ UploadPanel.delete.tooltip=Odstrániť súbor UploadPanel.message.help=Vybrať súbor na import. UploadPanel.message.removeError=Súbor bol odstránený. -UploadPanel.message.removeSuccess=Súbor bol odstráený. -UploadPanel.message.uploadError=Odovzdanie súboru zlyhalo. Prosím skúste ešte raz. -UploadPanel.message.uploadSuccess=Odovzdanie súboru zlyhalo. Prosím skúste ešte raz. -UploadPanel.upload.tooltip=Poslať súbor -UploadPanel.download.tooltip=Download file +UploadPanel.message.removeSuccess=Súbor bol odstránený. +UploadPanel.message.uploadError=Nahrávanie súboru zlyhalo. Prosím skúste ešte raz. +UploadPanel.message.uploadSuccess=Nahrávanie súboru bolo úspešné. Pokračujte v úpravách a až skončíte, stlačte ULOŽIŤ. +UploadPanel.upload.tooltip=Nahrať súbor +UploadPanel.download.tooltip=Stiahnúť súbor userBrowserDialog.button.cancelButton=Zrušiť userBrowserDialog.button.addButton=Pridať -userBrowserDialog.button.selectButton=Select +userBrowserDialog.button.selectButton=Vybrať userBrowserDialog.button.searchButton=Vyhľadať userBrowserDialog.email=E-mail userBrowserDialog.familyName=Priezvisko @@ -3033,10 +3035,10 @@ userBrowserDialog.name=Meno userBrowserDialog.title=Vyberte používateľa userBrowserDialog.type=Typ User.disabled=Zakázaný -UserMenuPanel.editPasswordQuestions=Znulovať bezpečnostné otázky +UserMenuPanel.editPasswordQuestions=Bezpečnostné otázky UserMenuPanel.editProfile=Upraviť profil UserMenuPanel.logout=Odhlásiť -UserMenuPanel.resetPasswords=Znulovať heslá +UserMenuPanel.resetPasswords=Reset hesla UserOrgReferenceChoosePanel.type.org=Org. jednotka UserOrgReferenceChoosePanel.type=Typ vlastníka UserOrgReferenceChoosePanel.type.user=Používateľ @@ -3050,9 +3052,9 @@ user.superuser=Privilegovaný používateľ user.orgManager=Manažér user.orgMember=Člen user.noOrgs=Žiadne organizácie -validFromFetchStrategy.nullValid=Vyberte jednu -validToFetchStrategy.nullValid=Vyberte jednu -valueAttribute.nullValid=Vyberte jednu +validFromFetchStrategy.nullValid=Vyberte hodnotu +validToFetchStrategy.nullValid=Vyberte hodnotu +valueAttribute.nullValid=Vyberte hodnotu WebModelUtils.couldntLoadObject=Nepodarilo sa načítať objekt. WebModelUtils.couldntSaveObject=Couldn't save object. WebModelUtils.couldntSearchObjects=Couldn't search objects. @@ -3060,14 +3062,14 @@ WebModelUtils.couldntDeleteObject=Couldn't delete object. WebModelUtils.couldntCountObjects=Couldn't count objects. web.security.provider.access.denied=Prístup zamietnutý. Nemáte právo na prístup, kontaktujte prosím správcov systému. web.security.provider.denied=Prístup zamietnutý. -web.security.provider.disabled=Používateľ je zablokovaný. -web.security.provider.invalid=Nesprávne použ. meno a/alebo heslo. -web.security.provider.invalid.link=Invalid link -web.security.provider.locked=Používateľ je zablokovaný, prosím počkajte. +web.security.provider.disabled=Používateľ je zakázaný. +web.security.provider.invalid=Nesprávne používateľské meno a/alebo heslo. +web.security.provider.invalid.link=Neplatný odkaz +web.security.provider.locked=Používateľ je zamknutý, prosím počkajte. web.security.provider.password.bad=Používateľ nemá definované heslo. web.security.provider.password.encoding=Nie je možné prihlásenie používateľa, dôvod: nemožno zašifrovať heslo. web.security.provider.unavailable=Momentálne nie je možné spracovať Vašu požiadavku. Skúste prosím neskôr. -web.security.ldap.access.denied=Access denied. You don't have permission to access, please contact Identity Manager's administrators. +web.security.ldap.access.denied=Prístup zamietnutý. Nemáte právo na prístup, kontaktujte prosím správcov systému. web.security.ldap.denied=Permission denied. web.security.ldap.disabled=User is disabled. web.security.ldap.invalid=Invalid username and/or password. @@ -3097,7 +3099,7 @@ WorkItemsPanel.started=Process started WorkItemsPanel.created=Vytvorený WorkItemsPanel.deadline=Deadline WorkItemsPanel.escalationLevel=Esc. level -PageAdmin.menu.dashboard=Vitajte +PageAdmin.menu.dashboard=Prehľad PageAdmin.menu.selfDashboard=Domov PageAdmin.menu.selfService=SAMOOBSLUHA PageAdmin.menu.mainNavigation=ADMINISTRÁCIA @@ -3152,12 +3154,12 @@ ChangePasswordPanel.enabled=Účet povolený ChangePasswordPanel.legendMessage.selected= - Heslo bude zmenené ChangePasswordPanel.legendMessage.propagated= - Automatická propagácia hesla (heslo môže byť zmenené v závislosti od nastavenia koncového systému) ChangePasswordPanel.legendMessage.deselected= - Heslo nebude zmenené -ChangePasswordPanel.legendMessage.no.password.capability= - Správa hesiel nie je na tomto systéme podporovaná +ChangePasswordPanel.legendMessage.no.password.capability= - Správa hesiel nie je v tomto koncovom systéme podporovaná ChangePasswordPanel.helpInfo=

Táto časť dialógu na zmenu hesla riadi propagáciu hesla do jednotlivých koncových systémov. Prvý riadok definuje, či sa heslo zmení v správcovi identít. Ostatné riadky reprezentujú jednotlivé koncové systémy, kde sa má heslo zmeniť. Propagácia hesla sa ovláda nasledovnými ikonami:

  • Heslo bude zmenené. Heslo pre tento systém sa nastaví na hodnotu určenú v dialógu pre zmenu hesla.
  • Automatická propagácia hesla. Heslo môže byť zmenené. Závisí to od politík nastavených správcom identít. Zvyčajne to znamená, že heslo bude zmenené, pokiaľ to v danej situácii a pri daných nastaveniach má zmysel. Toto je rozumné predvolené nastavenie.
  • Heslo nebude v tomto systéme zmenené.
  • Tento systém nepodporuje zmenu hesla. Preto v tomto systéme nedôjde k zmene hesla.

Nastavenia propagácie hesla môžete zmeniť kliknutím na ikony, čím určíte, ako sa má heslo propagovať do jednotlivých systémov.

ChangePasswordPanel.helpPopupTitle=Pomoc pre propagáciu hesla PageBase.button.tooltip.clearSearch=Vymazať mainForm.uploadTooLarge = Nahrávaný súbor musí byť menší ako ${maxSize}. -mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage}PageSelfCredentials.couldntResolve=Couldn't resolve resource. +mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage} PageSelfCredentials.couldntResolve=Nepodarilo sa získať informácie o koncovom systéme. roleMemberPanel.type=Typ: roleMemberPanel.tenant=Tenant: @@ -3208,7 +3210,7 @@ operation.com.evolveum.midpoint.model.impl.lens.ChangeExecutor.execute.focus.Use operation.com.evolveum.midpoint.model.impl.lens.ChangeExecutor.executeDelta=Vykonať delta (Model) operation.com.evolveum.midpoint.task.api.Task.listSubtasksDeeply=List subtasks deeply (Task) operation.com.evolveum.midpoint.task.api.Task.listSubtasksRaw=List subtasks raw (Task) -operation.com.evolveum.midpoint.web.page.self.PageSelfCredentials.savePassword=Change password (GUI) +operation.com.evolveum.midpoint.web.page.self.PageSelfCredentials.savePassword=Zmena hesla (GUI) operation.com.evolveum.midpoint.web.page.self.PageRequestRole.save=Changes were successfully saved operation.com.evolveum.midpoint.web.page.self.PageRequestRole.taskCreated=The process of assigning a role is waiting for the approval. PageError.button.home=Domov @@ -3223,24 +3225,24 @@ PageResource.tab.content.tasks=Defined Tasks ResourceContentTabPanel.searchType.repository=Repozitár ResourceContentTabPanel.searchType.resource=Koncový systém ResourceContentTabPanel.searchType=Search In: -PagePreviewChanges.primaryChangesOne=Primary changes: {0} object -PagePreviewChanges.primaryChangesMore=Primary changes: {0} objects -PagePreviewChanges.secondaryChangesOne=Secondary changes: {0} object -PagePreviewChanges.secondaryChangesMore=Secondary changes: {0} objects +PagePreviewChanges.primaryChangesOne=Primárne zmeny: {0} objekt +PagePreviewChanges.primaryChangesMore=Primárne zmeny: {0} objektov +PagePreviewChanges.secondaryChangesOne=Odvodené zmeny: {0} objekt +PagePreviewChanges.secondaryChangesMore=Odvodené zmeny: {0} objektov PagePreviewChanges.policyViolationMessages=Policy violation messages -PagePreviewChanges.approvalsRequired=Approvals required -PagePreviewChanges.button.continueEditing=Continue editing +PagePreviewChanges.approvalsRequired=Vyžaduje sa schválenie +PagePreviewChanges.button.continueEditing=Pokračovať v úpravách PagePreviewChanges.button.save=Uložiť -ScenePanel.object={0} object -ScenePanel.objects={0} objects -ScenePanel.item=Item -ScenePanel.oldValue=Old value -ScenePanel.newValue=New value +ScenePanel.object={0} objekt +ScenePanel.objects={0} objektov +ScenePanel.item=Položka +ScenePanel.oldValue=Stará hodnota +ScenePanel.newValue=Nová hodnota ScenePanel.value=Hodnota -SceneItemLinePanel.removedValue=Removed value -SceneItemLinePanel.addedValue=Added value -SceneItemLinePanel.unchangedValue=Unchanged value -SceneItemLinePanel.unknownLabel=(unknown) +SceneItemLinePanel.removedValue=Odobraná hodnota +SceneItemLinePanel.addedValue=Pridaná hodnota +SceneItemLinePanel.unchangedValue=Nezmenená hodnota +SceneItemLinePanel.unknownLabel=(neznáma) operation.com.evolveum.midpoint.web.page.admin.resources.ResourceContentTabPanel.changeOwner=Change owner (GUI) TaskSummaryPanel.progressWithTotalKnown=Progress: {0} out of {1} TaskSummaryPanel.progressWithTotalUnknown=Progress: {0} @@ -3256,20 +3258,20 @@ SearchPanel.basic=Základné SearchPanel.search=Vyhľadať SearchPanel.debug=DEBUG ResourceContentResourcePanel.realSearch=(In fact) Searching by: -typedAssignablePanel.selectedOrgs=Orgs: -typedAssignablePanel.selectedResources=Resources: -typedAssignablePanel.selectedRoles=Roles: -typedAssignablePanel.selectedServices=Services: -SearchPanel.insertFilterXml=Insert filter xml (SearchFilterType) +typedAssignablePanel.selectedOrgs=Organizácie: +typedAssignablePanel.selectedResources=Koncové systémy: +typedAssignablePanel.selectedRoles=Roly: +typedAssignablePanel.selectedServices=Služby: +SearchPanel.insertFilterXml=Vložiť filter v XML formáte (SearchFilterType) autoRefreshPanel.refreshNow=Refresh now autoRefreshPanel.resumeRefreshing=Resume refreshing autoRefreshPanel.pauseRefreshing=Pause refreshing autoRefreshPanel.refreshingEach=Refreshing each {0} sec autoRefreshPanel.noRefreshing=(no refreshing) -PageAdmin.menu.top.services=Services -PageAdmin.menu.top.services.list=List services -PageAdmin.menu.top.services.new=New service -PageAdmin.menu.top.services.edit=Edit service +PageAdmin.menu.top.services=Služby +PageAdmin.menu.top.services.list=Zoznam služieb +PageAdmin.menu.top.services.new=Nová služba +PageAdmin.menu.top.services.edit=Upraviť službu taskShowAdvancedFeaturesPanel.label=Show advanced features taskWfParentPanel.changesNotRequiringApproval=Changes not requiring approval taskOtherChangesPanel.label.state=State: @@ -3314,30 +3316,30 @@ PageResources.inlineMenuItem.test=Testovať spojenie PageRequestRole.title=Žiadať o rolu MainObjectListPanel.refresh=Aktualizovať MainObjectListPanel.newObject=Nový -MainObjectListPanel.import=Import -MainObjectListPanel.export=Export +MainObjectListPanel.import=Importovať +MainObjectListPanel.export=Exportovať MainObjectListPanel.exportFileName=export -TreeTablePanel.menu.createMember=Create member -TreeTablePanel.menu.createManager=Create manager -TreeTablePanel.menu.addMembers=Assign members -TreeTablePanel.menu.addManagers=Assign managers -TreeTablePanel.menu.unassignMembersSelected=Unassign selected members -TreeTablePanel.menu.unassignMembersAll=Unassign all members -TreeTablePanel.menu.removeManagersAll=Unassign all managers -TreeTablePanel.menu.recomputeMembersSelected=Recompute selected members -TreeTablePanel.menu.recomputeMembersAll=Recompute all members -TreeTablePanel.menu.recomputeMembersAllDirect=Recompute direct members -TreeTablePanel.menu.recomputeManagersAll=Recompute all managers -TreeTablePanel.menu.deleteManagersAll=Delete all managers -TreeTablePanel.menu.deleteManager.confirm=Are you sure you want to delete selected manager from system? This change is permanent. -TreeTablePanel.menu.deleteManagersAll.confirm=All defined managers will be permanently removed from system. Are you sure to perform this action? +TreeTablePanel.menu.createMember=Vytvoriť člena +TreeTablePanel.menu.createManager=Vytvoriť manažéra +TreeTablePanel.menu.addMembers=Priradiť členov +TreeTablePanel.menu.addManagers=Priradiť manažérov +TreeTablePanel.menu.unassignMembersSelected=Odobrať vybraných členov +TreeTablePanel.menu.unassignMembersAll=Odobrať všetkých členov +TreeTablePanel.menu.removeManagersAll=Odobrať všetkých manažérov +TreeTablePanel.menu.recomputeMembersSelected=Prepočítať vybraných členov +TreeTablePanel.menu.recomputeMembersAll=Prepočítať všetkých členov +TreeTablePanel.menu.recomputeMembersAllDirect=Prepočítať priamych členov +TreeTablePanel.menu.recomputeManagersAll=Prepočítať všetkých manažérov +TreeTablePanel.menu.deleteManagersAll=Zmazať všetkých manažérov +TreeTablePanel.menu.deleteManager.confirm=Naozaj chcete zmazať vybraného manažéra zo systému? Táto zmena je trvalá. +TreeTablePanel.menu.deleteManagersAll.confirm=Všetci definovaní manažéri budú natrvalo zmazaní zo systému. Naozaj chcete vykonať túto akciu? TreeTablePanel.move=Presunúť TreeTablePanel.makeRoot=Make root TreeTablePanel.delete=Zmazať TreeTablePanel.recompute=Prepočítať TreeTablePanel.edit=Editovať -TreeTablePanel.viewDetails=View details -TreeTablePanel.createChild=Create child +TreeTablePanel.viewDetails=Zobraziť podrobnosti +TreeTablePanel.createChild=Vytvoriť podriadenú organizačnú jednotku WorkItemSummaryPanel.allocated=Allocated WorkItemSummaryPanel.notAllocated=Not allocated WorkItemPanel.showRequest=Show the approval request. @@ -3385,17 +3387,17 @@ PageResourceWizard.readOnlyNote=Resource is in read-only mode. PageResourceWizard.readOnlySwitch=Click here to enable editing. operation.com.evolveum.midpoint.web.page.admin.users.component.TreeTablePanel.recompute=Recompute (GUI) Button.ok=OK -Button.assign=Priradiť účet -Note=Note +Button.assign=Priradiť +Note=Poznámka Warning=Varovanie ProfilingConfigPanel.profilingMustBeEnabled=In order to use profiling, the 'profilingEnabled' system configuration parameter (in config.xml file) must be set to 'true'. OperationResultPanel.result=Výsledok ResourceTasksPanel.definedTasks=Defined tasks ResourceTasksPanel.noTasksSelected=No tasks were selected. -ObjectBrowserPanel.chooseObject=Choose object -TypedAssignablePanel.selectObjects=Vyberte objekt(y) -OrgTreeAssignablePanel.selectOrg=Select organization(s) -ChooseFocusTypeDialogPanel.chooseType=Choose type +ObjectBrowserPanel.chooseObject=Vyberte objekt +TypedAssignablePanel.selectObjects=Vyberte objekt(y) +OrgTreeAssignablePanel.selectOrg=Vyberte organizáciu(e) +ChooseFocusTypeDialogPanel.chooseType=Vyberte typ TestConnectionResultPanel.testConnection.result=Test connection result(s) TestConnectionResultPanel.message=Test is running, please, wait for results. operation.com.evolveum.midpoint.web.page.admin.configuration.PageSystemConfiguration.updateSystemConfiguration=Update system configuration (GUI) @@ -3455,9 +3457,9 @@ operation.com.evolveum.midpoint.web.page.admin.certification.PageCertDefinitions operation.com.evolveum.midpoint.web.page.admin.certification.PageCertDefinitions.deleteDefinition=Zmazať definíciu SceneDto.unnamed=(unnamed) -LockoutStatusPanel.undoButtonLabel=Undo -LockoutStatusPanel.unlockButtonLabel=Set to "Normal" -LockoutStatusPanel.changesSaving=(will be applied after Save button click) +LockoutStatusPanel.undoButtonLabel=Vrátiť späť +LockoutStatusPanel.unlockButtonLabel=Nastaviť na "Normálny" +LockoutStatusPanel.changesSaving=(aplikuje sa po kliknutí na tlačidlo Uložiť) operation.com.evolveum.midpoint.web.page.admin.server.PageTaskEdit.saveTask=Save task (GUI) operation.com.evolveum.midpoint.web.page.admin.users.PageUsers.unlockUsers=Unlock user operation.com.evolveum.midpoint.web.page.admin.workflow.PageProcessInstances.stopProcessInstance=Stop process instance @@ -3498,7 +3500,7 @@ operation.com.evolveum.midpoint.web.page.admin.services.PageServices.reconcileOb operation.com.evolveum.midpoint.web.page.admin.services.PageServices.deleteObjects=Delete services (GUI) operation.com.evolveum.midpoint.web.page.admin.services.PageServices.deleteObject=Delete service (GUI) operation.com.evolveum.midpoint.web.page.admin.resources.ResourceContentTabPanel.importObject=Import object (GUI) -PageConnectorHosts.title=Konektor host-u +PageConnectorHosts.title=Hostitelia konektorov operation.com.evolveum.midpoint.web.page.admin.configuration.PageRepositoryQuery.checkQuery=Check query (GUI) operation.com.evolveum.midpoint.web.page.admin.configuration.PageRepositoryQuery.translateQuery=Translate query (GUI) operation.com.evolveum.midpoint.web.page.admin.configuration.PageRepositoryQuery.executeQuery=Execute query (GUI) @@ -3528,10 +3530,12 @@ PageAssignmentConflicts.title=Assignments conflicts PageAssignmentConflicts.back=Back PageAssignmentConflicts.submit=Submit AssignmentCatalogPanel.selectTargetUser=Select target user +AssignmentCatalogPanel.selectSourceUser=Select assignments source user +AssignmentCatalogPanel.sourceUserSelected=Assignments source user: {0} AssignmentCatalogPanel.selectAssignmentsUserOwner=Select assignments user owner AssignmentCatalogPanel.requestForMe=Target user: me -AssignmentCatalogPanel.requestFor=Target user: -AssignmentCatalogPanel.requestForMultiple={0} users selected +AssignmentCatalogPanel.requestFor=Target user: {0} +AssignmentCatalogPanel.requestForMultiple={0} target users selected AssignmentCatalogPanel.assignmentsOwner={0}'s assignments MultiButtonPanel.plusIconTitle=Add item to shopping cart MultiButtonPanel.assignmentDetailsPopupTitle=Assignment details @@ -3719,21 +3723,21 @@ ApprovalProcessesPreviewPanel.processRelatedTo=Approval process related to {0} ApprovalProcessesPreviewPanel.process=Approval process ApprovalProcessExecutionInformationPanel.stage=Stage {0}/{1} PageImportResource.title=Import resource definition -AssignmentType.activation=Activation +AssignmentType.activation=Aktivácia AssignmentType.lifecycleState=Lifecycle state AssignmnetType.accepted=Accepted AssignmentType.policySituation=Policy situation ObjectReferenceType.relation=Vzťah -FocusType.consents=Consents +FocusType.consents=Súhlasy AbstractAssignmentDetailsPanel.properties=Vlastnosti AssignmentPanel.doneButton=Hotovo AssignmentPanel.cancelButton=Zrušiť AssignmentPanel.noName=n/a ObjectPolicyConfigurationEditor.conflictResolution=(conflict resolution) -PageSelfConsents.title=Consents -SelfConsentPanel.button.revoke=Revoke -SelfConsentPanel.button.agree=Agree -PageAdmin.menu.consent=Consents +PageSelfConsents.title=Súhlasy +SelfConsentPanel.button.revoke=Odmietnuť +SelfConsentPanel.button.agree=Udeliť súhlas +PageAdmin.menu.consent=Súhlasy MultiValueExpandablePanel.deleteConfirmationMessage=Do you really want to delete {0} item? PolicyRulePropertiesPanel.exclusionConstraints=Add exclusion PolicyRulePropertiesPanel.minAssigneesConstraints=minAssignees @@ -3748,4 +3752,6 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Policy ExclusionPolicyConstraintPanel.exclusionTitle=Exclusion +ValuePolicyBasicPanel.valuePolicy.name=Name +ValuePolicyBasicPanel.valuePolicy.description=Description comboInput.nullValid=Vyberte hodnotu diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_tr.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_tr.properties index d5f171d0a08..8683deeceb7 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_tr.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_tr.properties @@ -1083,6 +1083,7 @@ PageAdmin.menu.top.users.org=Organizasyon Yapısı PageAdmin.menu.top.users.org.tree=Organizasyon ağacı PageAdmin.menu.top.users=Kullanıcılar PageAdmin.menu.top.valuePolicies.list= List value policies +PageAdmin.menu.top.valuePolicies.new = New value policy PageAdmin.menu.top.valuePolicies= Value policies PageAdmin.menu.top.workItems.listClaimable=Talep edebileceğim işler PageAdmin.menu.top.workItems.list=İş öğelerini listele @@ -2265,6 +2266,7 @@ MultipleAssignmentSelector.orgUnit=Org. birimi pageValuePolicies.table.description=Description pageValuePolicies.button.delete=Delete PageValuePolicies.title=List value policies +PageValuePolicy.title = Value policy pageWorkItem.accordionLabel.additionalData=İlgili veri (teknik bilgi) pageWorkItem.accordionLabel.objectNew=Önerilen değişiklik sonrasındaki obje(teknik bilgi) pageWorkItem.accordionLabel.objectOld=Değişim öncesindeki obje (teknik bilgi) @@ -2325,6 +2327,7 @@ TaskWfParentPanel.requestsHelp=Değişiklikler için tüm onaylama işlemleri bu workItemPanel.otherWorkItems=Bu istek için bulunan diğer iş kalemleri workItemPanel.requests=Talepler workItemPanel.relatedRequests=İlgili talepler +workItemPanel.reasons=Reasons for the approval process workItemPanel.approverComment=Onaylayıcının yorumu workItemPanel.approverInstruction=Approver instruction pageWorkItems.button.approve=Kabul et @@ -2853,7 +2856,6 @@ SystemConfigPanel.deploymentInformation.logoImageUrl = Logo image URL SystemConfigPanel.deploymentInformation.logoCssClass = Icon css class SystemConfigPanel.deploymentInformation.customerUrl = Customer url SystemConfigPanel.deploymentInformation.partnerName = Partner name -SystemConfigPanel.deploymentInformation.skin = Template skin SystemConfigPanel.deploymentInformation.subscriptionIdentifier = Subscription identifier SystemConfigPanel.deprecated.objectPolicy=Konfigürasyonun bu kısmı artık kullanılmıyor. Burada sadece uyumluluk maksatıyla bulunmaktadır. Lütfen aşağıdaki bileşeni kullanarak nesne politiklarını tanımlayınız. SystemConfigPanel.mail.config.placeholder=Yeni Konifgürasyon @@ -2883,7 +2885,7 @@ SystemConfigPanel.title.passwordPolicy=Genel şifre politikası SystemConfigPanel.title.securityPolicy=Global güvenlik politikası SystemConfigPanel.title.userTemplate=Ön tanımlı kullanıcı şablonu SystemConfigPanel.tooltip.duration=Format: P[n][p], n-number, p-period (d - days, m - months, ...), P3M - cleanup every 3 months -SystemConfigPanel.tooltip.color = Hex format, e.g. #3e934a for a "dark green" +SystemConfigPanel.tooltip.color =Hex format, e.g. #3c8dbc for the default "blue-light" color SystemInfoPanel.cpuUsage=CPU Kullanımı SystemInfoPanel.heapMemory=Yığın bellek(kullanılan/adanmış/maks) SystemInfoPanel.nonHeapMemory=Yığın olmayan bellek (kullanılan/adanmış/maks) @@ -3157,7 +3159,7 @@ ChangePasswordPanel.helpInfo=

This portion of the credentials dialog controls ChangePasswordPanel.helpPopupTitle=Şifre iletimi yardımı PageBase.button.tooltip.clearSearch=Temizle mainForm.uploadTooLarge = Yükleme büyüklüğü ${maxSize} den az olmalıdır. -mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage}PageSelfCredentials.couldntResolve=Couldn't resolve resource. +mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage} PageSelfCredentials.couldntResolve=Kaynağı çözümleyemedi. roleMemberPanel.type=Tip: roleMemberPanel.tenant=Tenant: @@ -3528,10 +3530,12 @@ PageAssignmentConflicts.title=Atama çakışmaları PageAssignmentConflicts.back=Geri PageAssignmentConflicts.submit=Gönder AssignmentCatalogPanel.selectTargetUser=Select target user +AssignmentCatalogPanel.selectSourceUser=Select assignments source user +AssignmentCatalogPanel.sourceUserSelected=Assignments source user: {0} AssignmentCatalogPanel.selectAssignmentsUserOwner=Select assignments user owner AssignmentCatalogPanel.requestForMe=Target user: me -AssignmentCatalogPanel.requestFor=Target user: -AssignmentCatalogPanel.requestForMultiple={0} users selected +AssignmentCatalogPanel.requestFor=Target user: {0} +AssignmentCatalogPanel.requestForMultiple={0} target users selected AssignmentCatalogPanel.assignmentsOwner={0}'s assignments MultiButtonPanel.plusIconTitle=Add item to shopping cart MultiButtonPanel.assignmentDetailsPopupTitle=Assignment details @@ -3748,4 +3752,6 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Policy ExclusionPolicyConstraintPanel.exclusionTitle=Exclusion +ValuePolicyBasicPanel.valuePolicy.name=Name +ValuePolicyBasicPanel.valuePolicy.description=Description comboInput.nullValid=Choose one diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_zh_CN.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_zh_CN.properties index 47aca56b5c7..b93e567bb99 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_zh_CN.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_zh_CN.properties @@ -1083,6 +1083,7 @@ PageAdmin.menu.top.users.org=组织结构 PageAdmin.menu.top.users.org.tree=组织机构树 PageAdmin.menu.top.users=用户 PageAdmin.menu.top.valuePolicies.list= List value policies +PageAdmin.menu.top.valuePolicies.new = New value policy PageAdmin.menu.top.valuePolicies= Value policies PageAdmin.menu.top.workItems.listClaimable=可以获取的工作项 PageAdmin.menu.top.workItems.list=我的工作项 @@ -2265,6 +2266,7 @@ MultipleAssignmentSelector.orgUnit=组织单元 pageValuePolicies.table.description=Description pageValuePolicies.button.delete=Delete PageValuePolicies.title=List value policies +PageValuePolicy.title = Value policy pageWorkItem.accordionLabel.additionalData=相关数据(技术提示) pageWorkItem.accordionLabel.objectNew=变动提交后的对象(技术提示) pageWorkItem.accordionLabel.objectOld=对更前的对象(技术提示) @@ -2325,6 +2327,7 @@ TaskWfParentPanel.requestsHelp=显示所有变更的审批流程。 workItemPanel.otherWorkItems=请求的其他工作项 workItemPanel.requests=请求 workItemPanel.relatedRequests=相关请求 +workItemPanel.reasons=Reasons for the approval process workItemPanel.approverComment=审批人备注 workItemPanel.approverInstruction=审批人说明 pageWorkItems.button.approve=审批 @@ -2853,7 +2856,6 @@ SystemConfigPanel.deploymentInformation.logoImageUrl = Logo image URL SystemConfigPanel.deploymentInformation.logoCssClass = Icon css class SystemConfigPanel.deploymentInformation.customerUrl = Customer url SystemConfigPanel.deploymentInformation.partnerName = Partner name -SystemConfigPanel.deploymentInformation.skin = Template skin SystemConfigPanel.deploymentInformation.subscriptionIdentifier = Subscription identifier SystemConfigPanel.deprecated.objectPolicy=此部分配置已弃用。它在这里被保留为兼容性目的。请使用下面的组件定义对象策略。 SystemConfigPanel.mail.config.placeholder=新配置 @@ -2883,7 +2885,7 @@ SystemConfigPanel.title.passwordPolicy=全局的密码策略 SystemConfigPanel.title.securityPolicy=全局安全策略 SystemConfigPanel.title.userTemplate=默认用户模板 SystemConfigPanel.tooltip.duration=Format: P[n][p], n-number, p-period (d - days, m - months, ...), P3M - cleanup every 3 months -SystemConfigPanel.tooltip.color = Hex format, e.g. #3e934a for a "dark green" +SystemConfigPanel.tooltip.color =Hex format, e.g. #3c8dbc for the default "blue-light" color SystemInfoPanel.cpuUsage=CPU使用率 SystemInfoPanel.heapMemory=堆栈内存(已用/已提交/最大) SystemInfoPanel.nonHeapMemory=非堆栈内容(已用/已提交/最大) @@ -3157,7 +3159,7 @@ ChangePasswordPanel.helpInfo=

This portion of the credentials dialog controls ChangePasswordPanel.helpPopupTitle=密码同步帮助 PageBase.button.tooltip.clearSearch=清除 mainForm.uploadTooLarge = 上传文件必须小于${maxSize}。 -mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage}PageSelfCredentials.couldntResolve=Couldn't resolve resource. +mainForm.uploadFailed = File failed to upload: ${exception.localizedMessage} PageSelfCredentials.couldntResolve=不能解析资源。 roleMemberPanel.type=类型: roleMemberPanel.tenant=租户: @@ -3528,10 +3530,12 @@ PageAssignmentConflicts.title=分配冲突 PageAssignmentConflicts.back=返回 PageAssignmentConflicts.submit=提交 AssignmentCatalogPanel.selectTargetUser=选择目标用户 +AssignmentCatalogPanel.selectSourceUser=Select assignments source user +AssignmentCatalogPanel.sourceUserSelected=Assignments source user: {0} AssignmentCatalogPanel.selectAssignmentsUserOwner=选择分配用户所有者 AssignmentCatalogPanel.requestForMe=目标用户:自己 -AssignmentCatalogPanel.requestFor=目标用户: -AssignmentCatalogPanel.requestForMultiple=已选择{0}个用户 +AssignmentCatalogPanel.requestFor=Target user: {0} +AssignmentCatalogPanel.requestForMultiple={0} target users selected AssignmentCatalogPanel.assignmentsOwner={0}的分配 MultiButtonPanel.plusIconTitle=添加到购物车 MultiButtonPanel.assignmentDetailsPopupTitle=分配详情 @@ -3748,4 +3752,6 @@ AbstractPolicyConstraintType.enforcement=Enforcement ExclusionPolicyConstraintType.targetRef=Target reference ExclusionPolicyConstraintType.policy=Policy ExclusionPolicyConstraintPanel.exclusionTitle=Exclusion +ValuePolicyBasicPanel.valuePolicy.name=Name +ValuePolicyBasicPanel.valuePolicy.description=Description comboInput.nullValid=Choose one diff --git a/infra/schema/src/main/resources/localization/schema_cs.properties b/infra/schema/src/main/resources/localization/schema_cs.properties index d86e0d888c4..41cdb6cbb3b 100644 --- a/infra/schema/src/main/resources/localization/schema_cs.properties +++ b/infra/schema/src/main/resources/localization/schema_cs.properties @@ -327,8 +327,8 @@ AssignmentType.tenantReference=Partaj AssignmentType.orgReference=Organizace ActivationType.activation=Aktivace ActivationType.validityStatus=Doba platnosti -ActivationType.lockOutStatus=Stav výluky -ActivationType.lockOutExpiration=Exspirace výluky +ActivationType.lockOutStatus=Stav uzamčení +ActivationType.lockOutExpiration=Exspirace uzamčení ConnectorType.displayName=Zobrazené jméno ShadowType.activation=Aktivace AbstractRoleType.inducement=Dědění diff --git a/infra/schema/src/main/resources/localization/schema_sk.properties b/infra/schema/src/main/resources/localization/schema_sk.properties index 17f901dca68..8a8149dcbac 100644 --- a/infra/schema/src/main/resources/localization/schema_sk.properties +++ b/infra/schema/src/main/resources/localization/schema_sk.properties @@ -39,14 +39,14 @@ ActivationStatusType.null=Nedefinovaný ActivationType.administrativeStatus=Administratívny stav ActivationType.effectiveStatus=Effective status ActivationType.enabled=Povolený -ActivationType.properties=Properties +ActivationType.properties=Vlastnosti ActivationType.title=Aktivácia ActivationType.validFrom=Platný od ActivationType.validTo=Platný do ActivityType.FOCUS_OPERATION=Operácia nad focus objektom (repozitár) ActivityType.NOTIFICATIONS=Posielanie notifikácií -ActivityType.PROJECTOR=Výpočet projekcí pre focus objekt -ActivityType.RESOURCE_OBJECT_OPERATION=Operácia nad zdrojom +ActivityType.PROJECTOR=Výpočet projekcií pre focus objekt +ActivityType.RESOURCE_OBJECT_OPERATION=Operácia nad koncovým systémom ActivityType.WORKFLOWS=Considering or starting approval workflows AssignmentPolicyEnforcementType.FULL=Úplný AssignmentPolicyEnforcementType.LEGALIZE=Legalizovať @@ -58,7 +58,7 @@ AssignmentType.tenant=Tenant AssignmentType.project=Org. jednotka/Projekt AttributeFetchStrategyType.EXPLICIT=Explicitný AttributeFetchStrategyType.IMPLICIT=Implicitný -AttributeFetchStrategyType.MINIMAL=Minimal +AttributeFetchStrategyType.MINIMAL=Minimálny AuditEventStageType.EXECUTION=Spracovanie AuditEventStageType.REQUEST=Požiadavka AuditEventType.ADD_OBJECT=Pridať objekt @@ -116,9 +116,9 @@ CapabilitiesType.read=Čítať CapabilitiesType.auxiliaryObjectClasses=Auxiliary Object Classes CapabilitiesType.pagedSearch=Paged Search CapabilitiesType.script=Skript -ChangeType.ADD=Pridať -ChangeType.DELETE=Zmazať -ChangeType.MODIFY=Zmeniť +ChangeType.ADD=Pridanie +ChangeType.DELETE=Zmazanie +ChangeType.MODIFY=Zmena ConnectorOperationalStatus.connectorClassName=Connector class name ConnectorOperationalStatus.poolConfigMinSize=Minimum pool size ConnectorOperationalStatus.poolConfigMaxSize=Maximum pool size @@ -133,7 +133,7 @@ FocusType.assignment=Priradenia FocusType.inducement=Stimuly FocusType.delegations=Delegations FocusType.delegatedToMe=Delegated to me -FocusType.displayName=Zobraziť meno +FocusType.displayName=Zobrazované meno LockoutStatusType.LOCKED=Zamknutý LockoutStatusType.NORMAL=Normálny LockoutStatusType.UNDEFINED=Nedefinovaný @@ -195,7 +195,7 @@ ObjectType.ShadowType=Sledovať ObjectType.SystemConfigurationType=Konfigurácia systému ObjectType.TaskType=Úloha ObjectType.UserType=Používateľ -ObjectType.ServiceType=Service +ObjectType.ServiceType=Služba ObjectType.ValuePolicyType=Hodnotová politika ObjectType.name=Názov ObjectType.parentOrgRef=Rodičovské org. jednotky @@ -252,7 +252,7 @@ ShadowKindType.GENERIC=Generický SynchronizationSituationType.DELETED=Zmazané SynchronizationSituationType.DISPUTED=Sporný SynchronizationSituationType.LINKED=Pripojený -SynchronizationSituationType.null=Vyberte jednu +SynchronizationSituationType.null=Vyberte hodnotu SynchronizationSituationType.UNLINKED=Odpojený SynchronizationSituationType.UNMATCHED=Bez zhody ThreadStopActionType.CLOSE=Zatvoriť @@ -264,11 +264,11 @@ UserType.familyName=Priezvisko UserType.fullName=Celé meno UserType.givenName=Krstné meno FailedOperationTypeType.ADD=Pridať -FailedOperationTypeType.GET=Get +FailedOperationTypeType.GET=Načítať FailedOperationTypeType.MODIFY=Zmeniť FailedOperationTypeType.DELETE=Zmazať AbstractRoleType.description=Popis -AbstractRoleType.displayName=Zobraziť meno +AbstractRoleType.displayName=Zobrazované meno TaskType.kind=Druh TaskType.intent=Účel TaskType.objectClass=Object Class @@ -295,40 +295,40 @@ ObjectTypes.LOOKUP_TABLE=Lookup tabuľka ObjectTypes.ACCESS_CERTIFICATION_DEFINITION=Certification definition ObjectTypes.ACCESS_CERTIFICATION_CAMPAIGN=Certification campaign ObjectTypes.SEQUENCE=Postupnosť -ObjectTypes.SERVICE=Service +ObjectTypes.SERVICE=Služba ObjectTypes.OBJECT=Objekt -OrgType.parentOrganization=Parent Organization +OrgType.parentOrganization=Rodičovská organizácia ObjectType.extension=Rozšírenia FocusType.assignmentKey=Priradenie -FocusType.jpegPhoto=Jpeg photo -UserType.additionalName=Additional Name -UserType.nickname=Nickname -UserType.honorificPrefix=Honorific Prefix -UserType.honorificSuffix=Honorific Suffix -UserType.title=Title -UserType.preferredLanguage=Preferred Language -UserType.locale=Locale -UserType.timezone=Timezone -UserType.EmailAddress=Email Address -UserType.telephoneNumber=Telephone Number -UserType.employeeNumber=Employee Number -UserType.employeeType=Employee Type +FocusType.jpegPhoto=Fotografia vo formáte JPEG +UserType.additionalName=Ďalšie meno +UserType.nickname=Prezývka +UserType.honorificPrefix=Titul pred menom +UserType.honorificSuffix=Titul za menom +UserType.title=Oslovenie +UserType.preferredLanguage=Preferovaný jazyk +UserType.locale=Miestne nastavenia +UserType.timezone=Časová zóna +UserType.EmailAddress=E-mailová adresa +UserType.telephoneNumber=Telefónne číslo +UserType.employeeNumber=Číslo zamestnanca +UserType.employeeType=Typ zamestnanca UserType.costCenter=Nákladové centrum UserType.organization=Organizácia -UserType.organizationalUnit=Organizational Unit +UserType.organizationalUnit=Organizačná jednotka UserType.locality=Lokalita UserType.credentials=Nastavenia CredentialsType.password=Heslo CredentialsType.securityQuestions=Znulovať bezpečnostné otázky AssignmentType.assignment=Priradenie AssignmentType.target=Cieľ -AssignmentType.construction=Construction -AssignmentType.tenantReference=Tenant reference -AssignmentType.orgReference=Org reference +AssignmentType.construction=Konštrukcia +AssignmentType.tenantReference=Tenant +AssignmentType.orgReference=Organizácia ActivationType.activation=Aktivácia -ActivationType.validityStatus=Validity Status -ActivationType.lockOutStatus=Lock-out Status -ActivationType.lockOutExpiration=Lock-out Expiration +ActivationType.validityStatus=Čas platnosti +ActivationType.lockOutStatus=Stav uzamknutia +ActivationType.lockOutExpiration=Exspirácia uzamknutia ConnectorType.displayName=Zobraziť meno ShadowType.activation=Aktivácia AbstractRoleType.inducement=Stimul @@ -337,9 +337,9 @@ AbstractRoleType.riskLevel=Úroveň rizika AbstractRoleType.owner=Vlastník AbstractRoleType.approver=Schvaľovateľ AbstractRoleType.idempotent=Idempotent -RoleType.roleType=Role Type +RoleType.roleType=Typ roly OrgType.type=Typ -OrgType.isTenant=Is Tenant +OrgType.isTenant=Je tenant OrgType.CostCenter=Nákladové centrum OrgType.displayOrder=Display Order OrgType.securityPolicy=Security Policy From 8c03cff38047503cc231f8a0dbb4ad280dfd3488 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Sat, 23 Sep 2017 13:47:43 +0200 Subject: [PATCH 44/97] Storing policy situations (new version). No optimizations yet. --- .../com/evolveum/midpoint/prism/Item.java | 7 + .../midpoint/prism/delta/ContainerDelta.java | 72 +++- .../prism/delta/builder/DeltaBuilder.java | 35 ++ .../prism/delta/builder/S_ValuesEntry.java | 5 +- .../model/impl/lens/ChangeExecutor.java | 5 - .../projector/AssignmentTripleEvaluator.java | 8 +- .../policy/PolicySituationUpdater.java | 342 +++++++----------- 7 files changed, 237 insertions(+), 237 deletions(-) diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/Item.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/Item.java index 2ec49b934ce..4a92db4d7b4 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/Item.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/Item.java @@ -32,6 +32,7 @@ import java.lang.reflect.Constructor; import java.util.*; import java.util.function.Function; +import java.util.stream.Collectors; /** * Item is a common abstraction of Property and PropertyContainer. @@ -312,6 +313,12 @@ public PrismValue findValue(PrismValue value, boolean ignoreMetadata) { return null; } + public List findValuesIgnoreMetadata(PrismValue value) { + return getValues().stream() + .filter(v -> v.equalsComplex(value, true, false)) + .collect(Collectors.toList()); + } + /** * Returns value that is previous to the specified value. * Note that the order is semantically insignificant and this is used only diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ContainerDelta.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ContainerDelta.java index 0f91ab239cb..1d593a1379d 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ContainerDelta.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ContainerDelta.java @@ -27,6 +27,8 @@ import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.logging.Trace; +import org.apache.commons.collections4.CollectionUtils; public class ContainerDelta extends ItemDelta,PrismContainerDefinition> implements PrismContainerable { @@ -183,19 +185,21 @@ private Collection findItemValues(Long id, ItemPath path, Collection void expand(PrismObject object) throws SchemaException { + public void expand(PrismObject object, Trace logger) throws SchemaException { + PrismContainer container = null; + ItemPath path = this.getPath(); + if (object != null) { + container = object.findContainer(path); + } if (valuesToDelete != null) { - ItemPath path = this.getPath(); - PrismContainer container = null; - if (object != null) { - container = object.findContainer(path); - } Iterator> iterator = valuesToDelete.iterator(); while (iterator.hasNext()) { PrismContainerValue deltaCVal = iterator.next(); - if ((deltaCVal.getItems() == null || deltaCVal.getItems().isEmpty())) { + if (CollectionUtils.isEmpty(deltaCVal.getItems())) { Long id = deltaCVal.getId(); if (id == null) { throw new IllegalArgumentException("No id and no items in value "+deltaCVal+" in delete set in "+this); @@ -206,17 +210,65 @@ public void expand(PrismObject object) throws SchemaEx for (Item containerItem: containerCVal.getItems()) { deltaCVal.add(containerItem.clone()); } - continue; } } // id-only value with ID that is not in the object any more: delete the value from delta iterator.remove(); + } else if (deltaCVal.getId() == null) { + if (container != null) { + @SuppressWarnings("unchecked") + List> containerCVals = + (List>) + container.findValuesIgnoreMetadata(deltaCVal); + if (containerCVals.size() > 1) { + logger.warn("More values to be deleted are matched by a single value in delete delta: values={}, delta value={}", + containerCVals, deltaCVal); + } else if (containerCVals.size() == 1) { + deltaCVal.setId(containerCVals.get(0).getId()); + } + // for the time being let's keep non-existent values in the delta + } } } } + if (valuesToAdd != null) { + assert valuesToReplace == null; + long maxId = getMaxId(container); + processIdentifiers(maxId, valuesToAdd); + } + if (valuesToReplace != null) { + assert valuesToAdd == null; + processIdentifiers(0, valuesToReplace); + } } - @Override + private void processIdentifiers(long maxId, Collection> values) { + for (PrismContainerValue value : values) { + if (value.getId() != null && value.getId() > maxId) { + maxId = value.getId(); + } + } + for (PrismContainerValue value : values) { + if (value.getId() == null) { + value.setId(++maxId); + } + } + } + + private long getMaxId(PrismContainer container) { + if (container == null) { + return 0; + } + long max = 0; + for (PrismContainerValue value : container.getValues()) { + if (value.getId() != null && value.getId() > max) { + max = value.getId(); + } + } + return max; + } + + @Override protected boolean isValueEquivalent(PrismContainerValue a, PrismContainerValue b) { if (!super.isValueEquivalent(a, b)) { return false; diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/DeltaBuilder.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/DeltaBuilder.java index 3c73ce36cb7..5cca1f15da8 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/DeltaBuilder.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/DeltaBuilder.java @@ -185,6 +185,41 @@ public S_MaybeDelete add(Collection values) { return this; } + @Override + public S_ValuesEntry old(Object... realValues) { + return oldRealValues(Arrays.asList(realValues)); + } + + @Override + public S_ValuesEntry oldRealValues(Collection realValues) { + for (Object v : realValues) { + if (v != null) { + currentDelta.addEstimatedOldValue(toPrismValue(currentDelta, v)); + } + } + return this; + } + + @Override + public S_ValuesEntry old(PrismValue... values) { + for (PrismValue v : values) { + if (v != null) { + currentDelta.addEstimatedOldValue(v); + } + } + return this; + } + + @Override + public S_ValuesEntry old(Collection values) { + for (PrismValue v : values) { + if (v != null) { + currentDelta.addEstimatedOldValue(v); + } + } + return this; + } + @Override public S_ItemEntry delete(Object... realValues) { return deleteRealValues(Arrays.asList(realValues)); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/S_ValuesEntry.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/S_ValuesEntry.java index 3ab8f9de9d0..25237c86a6d 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/S_ValuesEntry.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/S_ValuesEntry.java @@ -42,5 +42,8 @@ public interface S_ValuesEntry { S_ItemEntry replaceRealValues(Collection realValues); S_ItemEntry replace(PrismValue... values); S_ItemEntry replace(Collection values); - + S_ValuesEntry old(Object... realValues); + S_ValuesEntry oldRealValues(Collection realValues); + S_ValuesEntry old(PrismValue... values); + S_ValuesEntry old(Collection values); } 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 6fc341b5c85..0b8bc1efbcd 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 @@ -155,11 +155,6 @@ public boolean executeChanges(LensContext context, Tas } focusContext.clearPendingPolicySituationModifications(); - if (!focusContext.isDelete()) { - focusDelta = policySituationUpdater.applyAssignmentSituation(context, focusDelta); - policySituationUpdater.storeFocusPolicySituation(context); - } - if (focusDelta != null) { ObjectPolicyConfigurationType objectPolicyConfigurationType = focusContext diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentTripleEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentTripleEvaluator.java index 075f78d5768..812273c3c60 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentTripleEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentTripleEvaluator.java @@ -140,7 +140,13 @@ public DeltaSetTriple> processAllAssignments() throws ObjectDelta focusDelta = focusContext.getDelta(); ContainerDelta assignmentDelta = getExecutionWaveAssignmentDelta(focusContext); - assignmentDelta.expand(focusContext.getObjectCurrent()); + assignmentDelta.expand(focusContext.getObjectCurrent(), LOGGER); + + // Now we should have IDs for all assignments except for some borderline ones used in delete deltas + // (if the value to be deleted is not in object or if the value is ambiguous). This could have some negative + // impact on policy rules; namely, if there are some policy situations determined for such assignments, + // and the processing ends prematurely, it is possible that these situations will not be recorded. + // TODO determine if it's really this case LOGGER.trace("Assignment delta:\n{}", assignmentDelta.debugDump()); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicySituationUpdater.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicySituationUpdater.java index ea46eb3e4be..a14da94f58c 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicySituationUpdater.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicySituationUpdater.java @@ -32,11 +32,11 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.collections4.CollectionUtils; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.*; +import java.util.Objects; /** * Takes care of updating policySituation for focus and assignments. (Originally was a part of PolicyRuleProcessor.) @@ -51,238 +51,140 @@ public class PolicySituationUpdater { @Autowired private PrismContext prismContext; - public ObjectDelta applyAssignmentSituation(LensContext context, ObjectDelta focusDelta) - throws SchemaException { - if (context.getFocusClass() == null || !FocusType.class.isAssignableFrom(context.getFocusClass())) { - return focusDelta; - } - LensContext contextOfFocus = (LensContext) context; - if (focusDelta != null && focusDelta.isAdd()) { - applyAssignmentSituationOnAdd(contextOfFocus, (PrismObject) focusDelta.getObjectToAdd()); - return focusDelta; - } else if (focusDelta == null || focusDelta.isModify()) { - return applyAssignmentSituationOnModify(contextOfFocus, focusDelta); - } else { - return focusDelta; +// private List getTriggers(EvaluatedAssignmentImpl evaluatedAssignment) { +// List rv = new ArrayList<>(); +// for (EvaluatedPolicyRule policyRule : evaluatedAssignment.getAllTargetsPolicyRules()) { +// for (EvaluatedPolicyRuleTrigger trigger : policyRule.getTriggers()) { +// EvaluatedPolicyRuleTriggerType triggerType = trigger.toEvaluatedPolicyRuleTriggerType(policyRule, false).clone(); +// simplifyTrigger(triggerType); +// rv.add(triggerType); +// } +// } +// return rv; +// } +// +// private void simplifyTrigger(EvaluatedPolicyRuleTriggerType trigger) { +// deleteAssignments(trigger.getAssignmentPath()); +// if (trigger instanceof EvaluatedExclusionTriggerType) { +// EvaluatedExclusionTriggerType exclusionTrigger = (EvaluatedExclusionTriggerType) trigger; +// deleteAssignments(exclusionTrigger.getConflictingObjectPath()); +// exclusionTrigger.setConflictingAssignment(null); +// } else if (trigger instanceof EvaluatedSituationTriggerType) { +// for (EvaluatedPolicyRuleType sourceRule : ((EvaluatedSituationTriggerType) trigger).getSourceRule()) { +// for (EvaluatedPolicyRuleTriggerType sourceTrigger : sourceRule.getTrigger()) { +// simplifyTrigger(sourceTrigger); +// } +// } +// } +// } + +// private void deleteAssignments(AssignmentPathType path) { +// if (path == null) { +// return; +// } +// for (AssignmentPathSegmentType segment : path.getSegment()) { +// segment.setAssignment(null); +// } +// } + +// private boolean shouldSituationBeUpdated(EvaluatedAssignment evaluatedAssignment, +// List triggers) { +// if (PolicyRuleTypeUtil.canBePacked(evaluatedAssignment.getAssignmentType().getTrigger())) { +// return true; +// } +// Set currentSituations = new HashSet<>(evaluatedAssignment.getAssignmentType().getPolicySituation()); +// List currentTriggersUnpacked = PolicyRuleTypeUtil.unpack(evaluatedAssignment.getAssignmentType().getTrigger()); +// // if the current situations different from the ones in the old assignment => update +// // (provided that the situations in the assignment were _not_ changed directly via a delta!!!) TODO check this +// if (!currentSituations.equals(new HashSet<>(evaluatedAssignment.getPolicySituations()))) { +// LOGGER.trace("computed policy situations are different from the current ones"); +// return true; +// } +// if (!PolicyRuleTypeUtil.triggerCollectionsEqual(triggers, currentTriggersUnpacked)) { +// LOGGER.trace("computed policy rules triggers are different from the current ones"); +// return true; +// } +// return false; +// } + + + public void applyObjectSituation(LensContext context, List rulesToRecord) throws SchemaException { + // compute policySituation and triggeredPolicyRules and compare it with the expected state + // note that we use the new state for the comparison, because if values match we do not need to do anything + LensFocusContext focusContext = context.getFocusContext(); + F objectNew = focusContext.getObjectNew().asObjectable(); + ComputationResult cr = compute(rulesToRecord, objectNew.getPolicySituation(), objectNew.getTriggeredPolicyRule()); + if (cr.situationsNeedUpdate) { + focusContext.addToPendingPolicySituationModifications(DeltaBuilder.deltaFor(ObjectType.class, prismContext) + .item(ObjectType.F_POLICY_SITUATION) + .oldRealValues(cr.oldPolicySituations) + .replaceRealValues(cr.newPolicySituations) + .asItemDelta()); + } + if (cr.rulesNeedUpdate) { + focusContext.addToPendingPolicySituationModifications(DeltaBuilder.deltaFor(ObjectType.class, prismContext) + .item(ObjectType.F_TRIGGERED_POLICY_RULE) + .oldRealValues(cr.oldTriggeredRules) + .replaceRealValues(cr.newTriggeredRules) + .asItemDelta()); } } - private void applyAssignmentSituationOnAdd(LensContext context, - PrismObject objectToAdd) throws SchemaException { - if (context.getEvaluatedAssignmentTriple() == null) { - return; - } - T focus = objectToAdd.asObjectable(); - for (EvaluatedAssignmentImpl evaluatedAssignment : context.getEvaluatedAssignmentTriple().getNonNegativeValues()) { - LOGGER.trace("Applying assignment situation on object ADD for {}", evaluatedAssignment); - List triggers = getTriggers(evaluatedAssignment); - if (!shouldSituationBeUpdated(evaluatedAssignment, triggers)) { - continue; - } - AssignmentType assignment = evaluatedAssignment.getAssignmentType(); - if (assignment.getId() != null) { - ItemDelta.applyTo(getAssignmentModificationDelta(evaluatedAssignment, triggers), objectToAdd); + public void applyAssignmentSituation(LensContext context, + EvaluatedAssignmentImpl evaluatedAssignment, List rulesToRecord) throws SchemaException { + LensFocusContext focusContext = context.getFocusContext(); + AssignmentType assignment = evaluatedAssignment.getAssignmentType(false); + Long id = assignment.getId(); + ComputationResult cr = compute(rulesToRecord, assignment.getPolicySituation(), assignment.getTriggeredPolicyRule()); + boolean missedUpdate = false; + if (cr.situationsNeedUpdate) { + if (id != null) { + focusContext.addToPendingPolicySituationModifications(DeltaBuilder.deltaFor(ObjectType.class, prismContext) + .item(FocusType.F_ASSIGNMENT, id, AssignmentType.F_POLICY_SITUATION) + .oldRealValues(cr.oldPolicySituations) + .replaceRealValues(cr.newPolicySituations) + .asItemDelta()); } else { - int i = focus.getAssignment().indexOf(assignment); - if (i < 0) { - throw new IllegalStateException("Assignment to be replaced not found in an object to add: " + assignment + " / " + objectToAdd); - } - copyPolicyData(focus.getAssignment().get(i), evaluatedAssignment, triggers); + missedUpdate = true; } } - } - - private ObjectDelta applyAssignmentSituationOnModify(LensContext context, - ObjectDelta objectDelta) throws SchemaException { - if (context.getEvaluatedAssignmentTriple() == null) { - return objectDelta; - } - for (EvaluatedAssignmentImpl evaluatedAssignment : context.getEvaluatedAssignmentTriple().getNonNegativeValues()) { - LOGGER.trace("Applying assignment situation on object MODIFY for {}", evaluatedAssignment); - List triggers = getTriggers(evaluatedAssignment); - if (!shouldSituationBeUpdated(evaluatedAssignment, triggers)) { - continue; - } - AssignmentType assignment = evaluatedAssignment.getAssignmentType(); - if (assignment.getId() != null) { - objectDelta = swallow(context, objectDelta, getAssignmentModificationDelta(evaluatedAssignment, triggers)); + if (cr.rulesNeedUpdate) { + if (id != null) { + focusContext.addToPendingPolicySituationModifications(DeltaBuilder.deltaFor(ObjectType.class, prismContext) + .item(FocusType.F_ASSIGNMENT, id, AssignmentType.F_TRIGGERED_POLICY_RULE) + .oldRealValues(cr.oldTriggeredRules) + .replaceRealValues(cr.newTriggeredRules) + .asItemDelta()); } else { - if (objectDelta == null) { - throw new IllegalStateException("No object delta!"); - } - ContainerDelta assignmentDelta = objectDelta.findContainerDelta(FocusType.F_ASSIGNMENT); - if (assignmentDelta == null) { - throw new IllegalStateException("Unnumbered assignment (" + assignment - + ") couldn't be found in object delta (no assignment modification): " + objectDelta); - } - PrismContainerValue assignmentInDelta = assignmentDelta.findValueToAddOrReplace(assignment.asPrismContainerValue()); - if (assignmentInDelta == null) { - throw new IllegalStateException("Unnumbered assignment (" + assignment - + ") couldn't be found in object delta (no corresponding assignment value): " + objectDelta); - } - copyPolicyData(assignmentInDelta.asContainerable(), evaluatedAssignment, triggers); - } - } - return objectDelta; - } - - @NotNull - private List> getAssignmentModificationDelta( - EvaluatedAssignmentImpl evaluatedAssignment, List triggers) throws SchemaException { - Long id = evaluatedAssignment.getAssignmentType().getId(); - if (id == null) { - throw new IllegalArgumentException("Assignment with no ID: " + evaluatedAssignment); - } - List> deltas = new ArrayList<>(); - Set currentSituations = new HashSet<>(evaluatedAssignment.getAssignmentType().getPolicySituation()); - Set newSituations = new HashSet<>(evaluatedAssignment.getPolicySituations()); - CollectionUtils.addIgnoreNull(deltas, createSituationDelta( - new ItemPath(FocusType.F_ASSIGNMENT, id, AssignmentType.F_POLICY_SITUATION), currentSituations, newSituations)); - Set currentTriggers = new HashSet<>(evaluatedAssignment.getAssignmentType().getTrigger()); - Set newTriggers = new HashSet<>(PolicyRuleTypeUtil.pack(triggers)); - CollectionUtils.addIgnoreNull(deltas, createTriggerDelta( - new ItemPath(FocusType.F_ASSIGNMENT, id, AssignmentType.F_TRIGGER), currentTriggers, newTriggers)); - return deltas; - } - - private ObjectDelta swallow(LensContext context, ObjectDelta objectDelta, - List> deltas) throws SchemaException { - if (deltas.isEmpty()) { - return objectDelta; - } - if (objectDelta == null) { - if (context.getFocusClass() == null) { - throw new IllegalStateException("No focus class in " + context); - } - if (context.getFocusContext() == null) { - throw new IllegalStateException("No focus context in " + context); + missedUpdate = true; } - objectDelta = (ObjectDelta) new ObjectDelta(context.getFocusClass(), ChangeType.MODIFY, prismContext); - objectDelta.setOid(context.getFocusContext().getOid()); } - objectDelta.swallow(deltas); - return objectDelta; - } - - private List getTriggers(EvaluatedAssignmentImpl evaluatedAssignment) { - List rv = new ArrayList<>(); - for (EvaluatedPolicyRule policyRule : evaluatedAssignment.getAllTargetsPolicyRules()) { - for (EvaluatedPolicyRuleTrigger trigger : policyRule.getTriggers()) { - EvaluatedPolicyRuleTriggerType triggerType = trigger.toEvaluatedPolicyRuleTriggerType(policyRule, false).clone(); - simplifyTrigger(triggerType); - rv.add(triggerType); - } + if (missedUpdate) { + LOGGER.warn("Policy situation/rules for assignment cannot be updated, because it has no ID; assignment = {}, in object {}", + assignment, focusContext.getObjectAny()); } - return rv; } - private void simplifyTrigger(EvaluatedPolicyRuleTriggerType trigger) { - deleteAssignments(trigger.getAssignmentPath()); - if (trigger instanceof EvaluatedExclusionTriggerType) { - EvaluatedExclusionTriggerType exclusionTrigger = (EvaluatedExclusionTriggerType) trigger; - deleteAssignments(exclusionTrigger.getConflictingObjectPath()); - exclusionTrigger.setConflictingAssignment(null); - } else if (trigger instanceof EvaluatedSituationTriggerType) { - for (EvaluatedPolicyRuleType sourceRule : ((EvaluatedSituationTriggerType) trigger).getSourceRule()) { - for (EvaluatedPolicyRuleTriggerType sourceTrigger : sourceRule.getTrigger()) { - simplifyTrigger(sourceTrigger); - } - } - } + private ComputationResult compute(@NotNull List rulesToRecord, @NotNull List existingPolicySituation, + @NotNull List existingTriggeredPolicyRule) { + ComputationResult cr = new ComputationResult(); + for (EvaluatedPolicyRule rule : rulesToRecord) { + cr.newPolicySituations.add(rule.getPolicySituation()); + cr.newTriggeredRules.add(rule.toEvaluatedPolicyRuleType(true)); + } + cr.oldPolicySituations.addAll(existingPolicySituation); + cr.oldTriggeredRules.addAll(existingTriggeredPolicyRule); + cr.situationsNeedUpdate = !Objects.equals(cr.oldPolicySituations, cr.newPolicySituations); + cr.rulesNeedUpdate = !Objects.equals(cr.oldTriggeredRules, cr.newTriggeredRules); + return cr; } - private void deleteAssignments(AssignmentPathType path) { - if (path == null) { - return; - } - for (AssignmentPathSegmentType segment : path.getSegment()) { - segment.setAssignment(null); - } - } - - private void copyPolicyData(AssignmentType targetAssignment, EvaluatedAssignmentImpl evaluatedAssignment, - List triggers) { - targetAssignment.getPolicySituation().clear(); - targetAssignment.getPolicySituation().addAll(evaluatedAssignment.getPolicySituations()); - targetAssignment.getTrigger().clear(); - targetAssignment.getTrigger().addAll(PolicyRuleTypeUtil.pack(triggers)); - } - - private boolean shouldSituationBeUpdated(EvaluatedAssignment evaluatedAssignment, - List triggers) { - if (PolicyRuleTypeUtil.canBePacked(evaluatedAssignment.getAssignmentType().getTrigger())) { - return true; - } - Set currentSituations = new HashSet<>(evaluatedAssignment.getAssignmentType().getPolicySituation()); - List currentTriggersUnpacked = PolicyRuleTypeUtil.unpack(evaluatedAssignment.getAssignmentType().getTrigger()); - // if the current situations different from the ones in the old assignment => update - // (provided that the situations in the assignment were _not_ changed directly via a delta!!!) TODO check this - if (!currentSituations.equals(new HashSet<>(evaluatedAssignment.getPolicySituations()))) { - LOGGER.trace("computed policy situations are different from the current ones"); - return true; - } - if (!PolicyRuleTypeUtil.triggerCollectionsEqual(triggers, currentTriggersUnpacked)) { - LOGGER.trace("computed policy rules triggers are different from the current ones"); - return true; - } - return false; - } - - public void storeFocusPolicySituation(LensContext context) - throws SchemaException { - if (context.getFocusContext() == null || context.getFocusClass() == null || !FocusType.class.isAssignableFrom(context.getFocusClass())) { - return; - } - @SuppressWarnings({"raw", "unchecked"}) - LensFocusContext focusContext = (LensFocusContext) context.getFocusContext(); - Set currentSituations = focusContext.getObjectCurrent() != null ? - new HashSet<>(focusContext.getObjectCurrent().asObjectable().getPolicySituation()) : Collections.emptySet(); - Set newSituations = new HashSet<>(focusContext.getPolicySituations()); - PropertyDelta situationsDelta = createSituationDelta( - new ItemPath(FocusType.F_POLICY_SITUATION), currentSituations, newSituations); - if (situationsDelta != null) { - focusContext.swallowToProjectionWaveSecondaryDelta(situationsDelta); - } - } - - @Nullable - private PropertyDelta createSituationDelta(ItemPath path, Set currentSituations, Set newSituations) - throws SchemaException { - if (newSituations.equals(currentSituations)) { - return null; - } - @SuppressWarnings({ "unchecked", "raw" }) - PropertyDelta situationsDelta = (PropertyDelta) DeltaBuilder.deltaFor(FocusType.class, prismContext) - .item(path) - .add(CollectionUtils.subtract(newSituations, currentSituations).toArray()) - .delete(CollectionUtils.subtract(currentSituations, newSituations).toArray()) - .asItemDelta(); - situationsDelta.setEstimatedOldValues(PrismPropertyValue.wrap(currentSituations)); - return situationsDelta; - } - - private PropertyDelta createTriggerDelta(ItemPath path, Set currentTriggers, Set newTriggers) - throws SchemaException { - if (newTriggers.equals(currentTriggers)) { - return null; - } - @SuppressWarnings({ "unchecked", "raw" }) - PropertyDelta triggersDelta = (PropertyDelta) - DeltaBuilder.deltaFor(FocusType.class, prismContext) - .item(path) - .replace(newTriggers.toArray()) // TODO or add + delete? - .asItemDelta(); - triggersDelta.setEstimatedOldValues(PrismPropertyValue.wrap(currentTriggers)); - return triggersDelta; - } - - public void applyAssignmentSituation(LensContext context, - EvaluatedAssignmentImpl evaluatedAssignment, - List rulesToRecord) { - // TODO - } - - public void applyObjectSituation(LensContext context, List rulesToRecord) { - + private class ComputationResult { + final Set oldPolicySituations = new HashSet<>(); + final Set newPolicySituations = new HashSet<>(); + final Set oldTriggeredRules = new HashSet<>(); + final Set newTriggeredRules = new HashSet<>(); + boolean situationsNeedUpdate; + boolean rulesNeedUpdate; } } From 1dd3970dba8eb6a0de372423cd6c066688dbdfcb Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Sat, 23 Sep 2017 13:56:01 +0200 Subject: [PATCH 45/97] Fixed "privileged" flag. --- .../model/impl/scripting/ExecutionContext.java | 9 +++------ .../impl/scripting/ScriptingExpressionEvaluator.java | 11 +++++------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java index d00c56ef2f9..314f3dc1709 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java @@ -38,7 +38,7 @@ public class ExecutionContext { private static final Trace LOGGER = TraceManager.getTrace(ExecutionContext.class); - private boolean privileged; + private final boolean privileged; private final ScriptingExpressionEvaluationOptionsType options; private final Task task; private final ScriptingExpressionEvaluator scriptingExpressionEvaluator; @@ -49,10 +49,11 @@ public class ExecutionContext { public ExecutionContext(ScriptingExpressionEvaluationOptionsType options, Task task, ScriptingExpressionEvaluator scriptingExpressionEvaluator, - Map initialVariables) { + boolean privileged, Map initialVariables) { this.options = options; this.task = task; this.scriptingExpressionEvaluator = scriptingExpressionEvaluator; + this.privileged = privileged; this.initialVariables = initialVariables; } @@ -143,8 +144,4 @@ public PrismContext getPrismContext() { public boolean isPrivileged() { return privileged; } - - public void setPrivileged(boolean privileged) { - this.privileged = privileged; - } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java index 97c4d86ff13..18fe3454a20 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java @@ -141,7 +141,7 @@ public void evaluateExpressionInBackground(ExecuteScriptType executeScriptComman */ public ExecutionContext evaluateExpression(ScriptingExpressionType expression, Task task, OperationResult result) throws ScriptExecutionException { - ExecutionContext context = evaluateExpression(expression, PipelineData.createEmpty(), null, emptyMap(), task, result); + ExecutionContext context = evaluateExpression(expression, PipelineData.createEmpty(), null, emptyMap(), false, task, result); context.computeResults(); return context; } @@ -155,7 +155,7 @@ public ExecutionContext evaluateExpression(@NotNull ExecuteScriptType executeScr public ExecutionContext evaluateExpression(@NotNull ExecuteScriptType executeScript, @NotNull Map initialVariables, Task task, OperationResult result) throws ScriptExecutionException { Validate.notNull(executeScript.getScriptingExpression(), "Scripting expression must be present"); ExecutionContext context = evaluateExpression(executeScript.getScriptingExpression().getValue(), - PipelineData.parseFrom(executeScript.getInput(), initialVariables, prismContext), executeScript.getOptions(), initialVariables, task, result); + PipelineData.parseFrom(executeScript.getInput(), initialVariables, prismContext), executeScript.getOptions(), initialVariables, false, task, result); context.computeResults(); return context; } @@ -164,8 +164,7 @@ public ExecutionContext evaluateExpression(@NotNull ExecuteScriptType executeScr public ExecutionContext evaluateExpressionPrivileged(@NotNull ExecuteScriptType executeScript, @NotNull Map initialVariables, Task task, OperationResult result) throws ScriptExecutionException { Validate.notNull(executeScript.getScriptingExpression(), "Scripting expression must be present"); ExecutionContext context = evaluateExpression(executeScript.getScriptingExpression().getValue(), - PipelineData.parseFrom(executeScript.getInput(), initialVariables, prismContext), executeScript.getOptions(), initialVariables, task, result); - context.setPrivileged(true); + PipelineData.parseFrom(executeScript.getInput(), initialVariables, prismContext), executeScript.getOptions(), initialVariables, true, task, result); context.computeResults(); return context; } @@ -173,8 +172,8 @@ public ExecutionContext evaluateExpressionPrivileged(@NotNull ExecuteScriptType // main entry point from the outside private ExecutionContext evaluateExpression(ScriptingExpressionType expression, PipelineData data, ScriptingExpressionEvaluationOptionsType options, Map initialVariables, - Task task, OperationResult result) throws ScriptExecutionException { - ExecutionContext context = new ExecutionContext(options, task, this, initialVariables); + boolean privileged, Task task, OperationResult result) throws ScriptExecutionException { + ExecutionContext context = new ExecutionContext(options, task, this, privileged, initialVariables); PipelineData output; try { output = evaluateExpression(expression, data, context, result); From 4d359a2d1dd790f5ba7b42a1f1573dbc99443ca4 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Sat, 23 Sep 2017 13:56:01 +0200 Subject: [PATCH 46/97] Fixed "privileged" flag. (cherry picked from commit 1dd3970) --- .../model/impl/scripting/ExecutionContext.java | 9 +++------ .../impl/scripting/ScriptingExpressionEvaluator.java | 11 +++++------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java index d00c56ef2f9..314f3dc1709 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java @@ -38,7 +38,7 @@ public class ExecutionContext { private static final Trace LOGGER = TraceManager.getTrace(ExecutionContext.class); - private boolean privileged; + private final boolean privileged; private final ScriptingExpressionEvaluationOptionsType options; private final Task task; private final ScriptingExpressionEvaluator scriptingExpressionEvaluator; @@ -49,10 +49,11 @@ public class ExecutionContext { public ExecutionContext(ScriptingExpressionEvaluationOptionsType options, Task task, ScriptingExpressionEvaluator scriptingExpressionEvaluator, - Map initialVariables) { + boolean privileged, Map initialVariables) { this.options = options; this.task = task; this.scriptingExpressionEvaluator = scriptingExpressionEvaluator; + this.privileged = privileged; this.initialVariables = initialVariables; } @@ -143,8 +144,4 @@ public PrismContext getPrismContext() { public boolean isPrivileged() { return privileged; } - - public void setPrivileged(boolean privileged) { - this.privileged = privileged; - } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java index 97c4d86ff13..18fe3454a20 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java @@ -141,7 +141,7 @@ public void evaluateExpressionInBackground(ExecuteScriptType executeScriptComman */ public ExecutionContext evaluateExpression(ScriptingExpressionType expression, Task task, OperationResult result) throws ScriptExecutionException { - ExecutionContext context = evaluateExpression(expression, PipelineData.createEmpty(), null, emptyMap(), task, result); + ExecutionContext context = evaluateExpression(expression, PipelineData.createEmpty(), null, emptyMap(), false, task, result); context.computeResults(); return context; } @@ -155,7 +155,7 @@ public ExecutionContext evaluateExpression(@NotNull ExecuteScriptType executeScr public ExecutionContext evaluateExpression(@NotNull ExecuteScriptType executeScript, @NotNull Map initialVariables, Task task, OperationResult result) throws ScriptExecutionException { Validate.notNull(executeScript.getScriptingExpression(), "Scripting expression must be present"); ExecutionContext context = evaluateExpression(executeScript.getScriptingExpression().getValue(), - PipelineData.parseFrom(executeScript.getInput(), initialVariables, prismContext), executeScript.getOptions(), initialVariables, task, result); + PipelineData.parseFrom(executeScript.getInput(), initialVariables, prismContext), executeScript.getOptions(), initialVariables, false, task, result); context.computeResults(); return context; } @@ -164,8 +164,7 @@ public ExecutionContext evaluateExpression(@NotNull ExecuteScriptType executeScr public ExecutionContext evaluateExpressionPrivileged(@NotNull ExecuteScriptType executeScript, @NotNull Map initialVariables, Task task, OperationResult result) throws ScriptExecutionException { Validate.notNull(executeScript.getScriptingExpression(), "Scripting expression must be present"); ExecutionContext context = evaluateExpression(executeScript.getScriptingExpression().getValue(), - PipelineData.parseFrom(executeScript.getInput(), initialVariables, prismContext), executeScript.getOptions(), initialVariables, task, result); - context.setPrivileged(true); + PipelineData.parseFrom(executeScript.getInput(), initialVariables, prismContext), executeScript.getOptions(), initialVariables, true, task, result); context.computeResults(); return context; } @@ -173,8 +172,8 @@ public ExecutionContext evaluateExpressionPrivileged(@NotNull ExecuteScriptType // main entry point from the outside private ExecutionContext evaluateExpression(ScriptingExpressionType expression, PipelineData data, ScriptingExpressionEvaluationOptionsType options, Map initialVariables, - Task task, OperationResult result) throws ScriptExecutionException { - ExecutionContext context = new ExecutionContext(options, task, this, initialVariables); + boolean privileged, Task task, OperationResult result) throws ScriptExecutionException { + ExecutionContext context = new ExecutionContext(options, task, this, privileged, initialVariables); PipelineData output; try { output = evaluateExpression(expression, data, context, result); From 767218bdc8b928e8bcbea2cb25519afd3b15a9d6 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Sat, 23 Sep 2017 15:11:58 +0200 Subject: [PATCH 47/97] Fixed applyDefinition for polymorphic types. --- .../midpoint/prism/PrismContainerValue.java | 19 ++++++++++++++++--- .../midpoint/schema/TestParseTask.java | 5 +++++ .../src/test/resources/common/task-1.xml | 9 +++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java index 7980445d5f2..ac711bb15b0 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java @@ -1183,10 +1183,22 @@ public void applyDefinition(ItemDefinition definition, boolean force) throws Sch public void applyDefinition(@NotNull PrismContainerDefinition containerDef, boolean force) throws SchemaException { checkMutability(); - if (complexTypeDefinition != null && !force) { - return; // there's a definition already + ComplexTypeDefinition definitionToUse = containerDef.getComplexTypeDefinition(); + if (complexTypeDefinition != null) { + if (!force) { + return; // there's a definition already + } + if (!complexTypeDefinition.getTypeName().equals(containerDef.getTypeName())) { + // this is the case in which we are going to overwrite a specific definition + // (e.g. WfPrimaryChangeProcessorStateType) with a generic one (e.g. WfProcessorSpecificStateType) + // --> we should either skip this, or fetch the fresh definition from the prism context + ComplexTypeDefinition freshCtd = prismContext.getSchemaRegistry().findComplexTypeDefinitionByType(complexTypeDefinition.getTypeName()); + if (freshCtd != null) { + definitionToUse = freshCtd; + } + } } - replaceComplexTypeDefinition(containerDef.getComplexTypeDefinition()); + replaceComplexTypeDefinition(definitionToUse); // we need to continue even if CTD is null or 'any' - e.g. to resolve definitions within object extension if (items != null) { for (Item item : items) { @@ -1209,6 +1221,7 @@ public void applyDefinition(@NotNull PrismContainerDefinition containerDef, b * This method can both return null and throws exception. It returns null in case there is no definition * but it is OK (e.g. runtime schema). It throws exception if there is no definition and it is not OK. */ + @SuppressWarnings("unchecked") private ID determineItemDefinition(QName itemName, @Nullable ComplexTypeDefinition ctd) throws SchemaException { ID itemDefinition = ctd != null ? ctd.findItemDefinition(itemName) : null; if (itemDefinition != null) { diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestParseTask.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestParseTask.java index a18c848f429..4553a044d6c 100644 --- a/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestParseTask.java +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestParseTask.java @@ -46,6 +46,7 @@ import java.io.IOException; import static com.evolveum.midpoint.prism.util.PrismTestUtil.getPrismContext; +import static com.evolveum.midpoint.prism.util.PrismTestUtil.getSchemaRegistry; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; @@ -79,6 +80,10 @@ public void testParseTaskFile() throws Exception { System.out.println(task.debugDump()); assertTask(task); + + PrismObjectDefinition taskDef = getSchemaRegistry().findObjectDefinitionByCompileTimeClass(TaskType.class); + task.applyDefinition(taskDef); + task.getValue().applyDefinition(taskDef); } @Test diff --git a/infra/schema/src/test/resources/common/task-1.xml b/infra/schema/src/test/resources/common/task-1.xml index ad1d7b25118..668debd3de0 100644 --- a/infra/schema/src/test/resources/common/task-1.xml +++ b/infra/schema/src/test/resources/common/task-1.xml @@ -62,4 +62,13 @@ single + + + 1 + abc + def + + aspect + + From ac6d1d94714b67eb8895e688fd7a4b6c6a11c14b Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Sat, 23 Sep 2017 15:56:19 +0200 Subject: [PATCH 48/97] Fixed common tests. --- .../midpoint/prism/PrismContainerValue.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java index ac711bb15b0..36f98a9c09f 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java @@ -1189,12 +1189,16 @@ public void applyDefinition(@NotNull PrismContainerDefinition containerDef, b return; // there's a definition already } if (!complexTypeDefinition.getTypeName().equals(containerDef.getTypeName())) { - // this is the case in which we are going to overwrite a specific definition - // (e.g. WfPrimaryChangeProcessorStateType) with a generic one (e.g. WfProcessorSpecificStateType) - // --> we should either skip this, or fetch the fresh definition from the prism context - ComplexTypeDefinition freshCtd = prismContext.getSchemaRegistry().findComplexTypeDefinitionByType(complexTypeDefinition.getTypeName()); - if (freshCtd != null) { - definitionToUse = freshCtd; + if (!definitionToUse.isRuntimeSchema()) { + // this is the case in which we are going to overwrite a specific definition + // (e.g. WfPrimaryChangeProcessorStateType) with a generic one (e.g. WfProcessorSpecificStateType) + // --> we should either skip this, or fetch the fresh definition from the prism context + ComplexTypeDefinition freshCtd = prismContext.getSchemaRegistry().findComplexTypeDefinitionByType(complexTypeDefinition.getTypeName()); + if (freshCtd != null) { + definitionToUse = freshCtd; + } + } else { + // we are probably applying a dynamic definition over static one -- so, let's proceed } } } From 1d8175687dc15e7fa40ffa1c7a9352c3b55cc2e5 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Sat, 23 Sep 2017 16:14:33 +0200 Subject: [PATCH 49/97] Fixed provisioning tests. --- .../evolveum/midpoint/provisioning/util/ProvisioningUtil.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java index 2543e6d3cf5..53667924586 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java @@ -135,8 +135,10 @@ public static ExecuteProvisioningScriptOperation convertToScriptOperation( ProvisioningScriptType scriptType, String desc, PrismContext prismContext) throws SchemaException { ExecuteProvisioningScriptOperation scriptOperation = new ExecuteProvisioningScriptOperation(); - PrismPropertyDefinition scriptArgumentDefinition = new PrismPropertyDefinitionImpl( + PrismPropertyDefinitionImpl scriptArgumentDefinition = new PrismPropertyDefinitionImpl( FAKE_SCRIPT_ARGUMENT_NAME, DOMUtil.XSD_STRING, prismContext); + scriptArgumentDefinition.setMinOccurs(0); + scriptArgumentDefinition.setMaxOccurs(-1); for (ProvisioningScriptArgumentType argument : scriptType.getArgument()) { ExecuteScriptArgument arg = new ExecuteScriptArgument(argument.getName(), From 8143636a0c2bd11e9331b008c9a658e5125aa1d4 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Sat, 23 Sep 2017 18:35:54 +0200 Subject: [PATCH 50/97] Fixed provisioning tests. --- .../midpoint/model/test/AbstractModelIntegrationTest.java | 4 ++-- .../midpoint/repo/sql/helpers/ObjectRetriever.java | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java index 50fd7fca257..b1d88eeb8ee 100644 --- a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java +++ b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java @@ -4442,12 +4442,12 @@ protected String getTopOrgOid() { protected void transplantGlobalPolicyRulesAdd(File configWithGlobalRulesFile, Task task, OperationResult parentResult) throws SchemaException, IOException, ObjectNotFoundException, ObjectAlreadyExistsException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException { // copy rules from the file into live system config object PrismObject rules = prismContext.parserFor(configWithGlobalRulesFile).parse(); - ObjectDelta delta = (ObjectDelta) DeltaBuilder.deltaFor(SystemConfigurationType.class, prismContext) + ObjectDelta delta = DeltaBuilder.deltaFor(SystemConfigurationType.class, prismContext) .item(SystemConfigurationType.F_GLOBAL_POLICY_RULE).add( rules.asObjectable().getGlobalPolicyRule().stream() .map(r -> r.clone().asPrismContainerValue()) .collect(Collectors.toList())) - .asObjectDelta(SystemObjectsType.SYSTEM_CONFIGURATION.value()); + .asObjectDeltaCast(SystemObjectsType.SYSTEM_CONFIGURATION.value()); modelService.executeChanges(MiscSchemaUtil.createCollection(delta), null, task, parentResult); } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java index f3dd0c43bbe..d4de819f92d 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java @@ -573,10 +573,14 @@ private void applyShadowAttributeDefinitions(Class anyValue if (item.getDefinition() == null) { RValueType rValType = (RValueType) value[2]; if (rValType == RValueType.PROPERTY) { - PrismPropertyDefinition def = new PrismPropertyDefinitionImpl<>(name, type, object.getPrismContext()); + PrismPropertyDefinitionImpl def = new PrismPropertyDefinitionImpl<>(name, type, object.getPrismContext()); + def.setMinOccurs(0); + def.setMaxOccurs(-1); item.applyDefinition(def, true); } else if (rValType == RValueType.REFERENCE) { - PrismReferenceDefinition def = new PrismReferenceDefinitionImpl(name, type, object.getPrismContext()); + PrismReferenceDefinitionImpl def = new PrismReferenceDefinitionImpl(name, type, object.getPrismContext()); + def.setMinOccurs(0); + def.setMaxOccurs(-1); item.applyDefinition(def, true); } else { throw new UnsupportedOperationException("Unsupported value type " + rValType); From 86f22665fce17a0ae8cf2410e0d7344319ec64e0 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Sun, 24 Sep 2017 14:24:47 +0200 Subject: [PATCH 51/97] Fixed UCF tests (by a temporary hack). --- .../com/evolveum/midpoint/prism/PrismContainerValue.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java index 36f98a9c09f..668210123fa 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java @@ -1189,12 +1189,16 @@ public void applyDefinition(@NotNull PrismContainerDefinition containerDef, b return; // there's a definition already } if (!complexTypeDefinition.getTypeName().equals(containerDef.getTypeName())) { - if (!definitionToUse.isRuntimeSchema()) { + // the second condition is a hack because e.g. + // {http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.icf.dummy/com.evolveum.icf.dummy.connector.DummyConnector}ConfigurationType + // is clearly a runtime schema but it is _not_ marked as such (why?) -- see TestUcfDummy + if (!definitionToUse.isRuntimeSchema() && definitionToUse.getCompileTimeClass() != null) { // this is the case in which we are going to overwrite a specific definition // (e.g. WfPrimaryChangeProcessorStateType) with a generic one (e.g. WfProcessorSpecificStateType) // --> we should either skip this, or fetch the fresh definition from the prism context ComplexTypeDefinition freshCtd = prismContext.getSchemaRegistry().findComplexTypeDefinitionByType(complexTypeDefinition.getTypeName()); if (freshCtd != null) { + System.out.println("Using " + freshCtd + " instead of " + definitionToUse); definitionToUse = freshCtd; } } else { From 86450e22aa4c2c581a4f1fba8db6c66b1acc17bd Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Sun, 24 Sep 2017 17:07:06 +0200 Subject: [PATCH 52/97] Fixing tests up to and including model-intest. --- .../com/evolveum/midpoint/common/StaticExpressionUtil.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/StaticExpressionUtil.java b/infra/common/src/main/java/com/evolveum/midpoint/common/StaticExpressionUtil.java index e6c11e3ec4a..78e6061bdc7 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/StaticExpressionUtil.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/StaticExpressionUtil.java @@ -32,6 +32,7 @@ import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.util.JAXBUtil; +import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionReturnMultiplicityType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionType; @@ -67,9 +68,10 @@ public static Object getStaticOutput(ExpressionType expressionType, PrismPropert default: throw new IllegalStateException("Unknown return type "+multiplicity); } } else { + Collection realValues = output.getRealValues(); switch (multiplicity) { - case MULTI: return output.getRealValues(); - case SINGLE: return output.getRealValue(); + case MULTI: return realValues; + case SINGLE: return MiscUtil.extractSingleton(realValues); default: throw new IllegalStateException("Unknown return type "+multiplicity); } } From f6b8bdb1def21d9e30833acaaa2a896ca2d9d0f0 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 25 Sep 2017 06:40:05 +0200 Subject: [PATCH 53/97] Tentative fix for MID-4145. --- .../model/impl/lens/ChangeExecutor.java | 2 +- .../credentials/CredentialsProcessor.java | 18 +++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) 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 834c11784d6..daae3f404aa 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 @@ -187,7 +187,7 @@ public boolean executeChanges(LensContext context, Tas try { // Will remove credential deltas or hash them - focusDelta = credentialsProcessor.transformFocusExectionDelta(context, focusDelta); + focusDelta = credentialsProcessor.transformFocusExecutionDelta(context, focusDelta); } catch (EncryptionException e) { recordFatalError(subResult, result, null, e); result.computeStatus(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/credentials/CredentialsProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/credentials/CredentialsProcessor.java index 95b2f29b3e7..b847264d3db 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/credentials/CredentialsProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/credentials/CredentialsProcessor.java @@ -22,14 +22,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.evolveum.midpoint.model.common.mapping.MappingFactory; import com.evolveum.midpoint.model.common.stringpolicy.ValuePolicyProcessor; import com.evolveum.midpoint.model.impl.ModelObjectResolver; import com.evolveum.midpoint.model.impl.lens.LensContext; import com.evolveum.midpoint.model.impl.lens.LensFocusContext; import com.evolveum.midpoint.model.impl.lens.OperationalDataManager; -import com.evolveum.midpoint.model.impl.lens.projector.MappingEvaluator; -import com.evolveum.midpoint.model.impl.security.SecurityHelper; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismProperty; import com.evolveum.midpoint.prism.PrismPropertyValue; @@ -55,7 +52,6 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.SecurityPolicyType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ValuePolicyType; import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType; @@ -153,7 +149,7 @@ private void processFocusSecurityQuestions(LensContext context, XMLGre /** * Called from ChangeExecutor. Will modify the execution deltas to hash or remove credentials if needed. */ - public ObjectDelta transformFocusExectionDelta(LensContext context, ObjectDelta focusDelta) throws SchemaException, EncryptionException { + public ObjectDelta transformFocusExecutionDelta(LensContext context, ObjectDelta focusDelta) throws SchemaException, EncryptionException { LensFocusContext focusContext = context.getFocusContext(); SecurityPolicyType securityPolicy = focusContext.getSecurityPolicy(); if (securityPolicy == null) { @@ -164,13 +160,13 @@ public ObjectDelta transformFocusExectionDelta(LensCon return focusDelta; } ObjectDelta transformedDelta = focusDelta.clone(); - transformFocusExectionDeltaCredential(context, credsType, credsType.getPassword(), SchemaConstants.PATH_PASSWORD_VALUE, transformedDelta); + transformFocusExecutionDeltaCredential(context, credsType, credsType.getPassword(), SchemaConstants.PATH_PASSWORD_VALUE, transformedDelta); // TODO: nonce and others return transformedDelta; } - private void transformFocusExectionDeltaCredential(LensContext context, + private void transformFocusExecutionDeltaCredential(LensContext context, CredentialsPolicyType credsType, CredentialPolicyType credPolicyType, ItemPath valuePropertyPath, ObjectDelta delta) throws SchemaException, EncryptionException { if (delta.isDelete()) { @@ -186,10 +182,11 @@ private void transformFocusExectionDeltaCredential(LensCo if (storageType == null || storageType == CredentialsStorageTypeType.ENCRYPTION) { return; } else if (storageType == CredentialsStorageTypeType.HASHING) { - PrismPropertyValue pval = null; if (delta.isAdd()) { PrismProperty prop = delta.getObjectToAdd().findProperty(valuePropertyPath); - hashValues(prop.getValues(), storageMethod); + if (prop != null) { + hashValues(prop.getValues(), storageMethod); + } } else { PropertyDelta propDelta = delta.findPropertyDelta(valuePropertyPath); if (propDelta != null) { @@ -209,9 +206,8 @@ private void transformFocusExectionDeltaCredential(LensCo } } } else { - throw new SchemaException("Unkwnon storage type "+storageType); + throw new SchemaException("Unknown storage type "+storageType); } - } private void hashValues(Collection> values, From 3a0cd2459a90c82d3d0fa165ff993db938fe6e6b Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 25 Sep 2017 07:03:07 +0200 Subject: [PATCH 54/97] Attempt to fix MID-4160: Expected that spring security principal will be of type MidPointPrincipal (added logging out from task execution thread on task handler finish and clearing the security context before attempting log-in at task start) --- .../quartzimpl/execution/JobExecutor.java | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java index 460f470c51f..b17ae34a487 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java @@ -35,6 +35,7 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.lang.Validate; import org.quartz.*; +import org.springframework.security.core.Authentication; import javax.xml.datatype.Duration; import java.util.ArrayList; @@ -165,6 +166,8 @@ public void execute(JobExecutionContext context) throws JobExecutionException { // Setup Spring Security context PrismObject taskOwner = task.getOwner(); try { + // just to be sure we won't run the owner-setting login with any garbage security context (see MID-4160) + taskManagerImpl.getSecurityEnforcer().setupPreAuthenticatedSecurityContext((Authentication) null); taskManagerImpl.getSecurityEnforcer().setupPreAuthenticatedSecurityContext(taskOwner); } catch (SchemaException e) { LoggingUtils.logUnexpectedException(LOGGER, "Task with OID {} cannot be executed: error setting security context", e, oid); @@ -182,17 +185,23 @@ public void execute(JobExecutionContext context) throws JobExecutionException { } } finally { - waitForTransientChildrenAndCloseThem(executionResult); // this is only a safety net; because we've waited for children just after executing a handler - taskManagerImpl.unregisterRunningTask(task); - executingThread = null; + try { + waitForTransientChildrenAndCloseThem(executionResult); // this is only a safety net; because we've waited for children just after executing a handler - if (!task.canRun()) { - processTaskStop(executionResult); - } + taskManagerImpl.unregisterRunningTask(task); + executingThread = null; - logThreadRunFinish(handler); - taskManagerImpl.notifyTaskThreadFinish(task); + if (!task.canRun()) { + processTaskStop(executionResult); + } + + logThreadRunFinish(handler); + taskManagerImpl.notifyTaskThreadFinish(task); + } finally { + // "logout" this thread + taskManagerImpl.getSecurityEnforcer().setupPreAuthenticatedSecurityContext((Authentication) null); + } } } From 6a0a2dd1bba4b874c614cc6f7de8e43965472f0d Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 25 Sep 2017 07:18:20 +0200 Subject: [PATCH 55/97] Forgotten dependency --- repo/task-quartz-impl/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/repo/task-quartz-impl/pom.xml b/repo/task-quartz-impl/pom.xml index e7d311cad05..886d8b72360 100644 --- a/repo/task-quartz-impl/pom.xml +++ b/repo/task-quartz-impl/pom.xml @@ -88,6 +88,10 @@ org.springframework spring-beans + + org.springframework.security + spring-security-core + javax.xml.bind jaxb-api From 84c6889cf3b9db99b5ce37d76423c36fc15af92d Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 25 Sep 2017 13:35:50 +0200 Subject: [PATCH 56/97] Storing policy state works for most basic scenarios. --- .../midpoint/prism/PrismContainerValue.java | 4 + .../midpoint/prism/delta/ContainerDelta.java | 37 +--- .../midpoint/prism/delta/ItemDelta.java | 6 + .../midpoint/prism/path/ItemPath.java | 26 +-- .../public/common/common-model-context-3.xsd | 2 +- .../com/evolveum/midpoint/util/MiscUtil.java | 2 +- .../model/api/context/AssignmentPath.java | 2 +- .../api/context/AssignmentPathSegment.java | 2 +- .../context/EvaluatedCompositeTrigger.java | 7 +- .../context/EvaluatedExclusionTrigger.java | 10 +- .../EvaluatedHasAssignmentTrigger.java | 4 +- .../context/EvaluatedModificationTrigger.java | 4 +- .../context/EvaluatedMultiplicityTrigger.java | 4 +- .../api/context/EvaluatedPolicyRule.java | 2 +- .../context/EvaluatedPolicyRuleTrigger.java | 16 +- .../context/EvaluatedSituationTrigger.java | 6 +- .../api/context/EvaluatedStateTrigger.java | 4 +- .../context/EvaluatedTimeValidityTrigger.java | 4 +- .../context/EvaluatedTransitionTrigger.java | 6 +- .../impl/hooks/PolicyRuleEnforcerHook.java | 3 +- .../model/impl/lens/AssignmentPathImpl.java | 5 +- .../impl/lens/AssignmentPathSegmentImpl.java | 6 +- .../model/impl/lens/AssignmentSpec.java | 60 ++++++ .../model/impl/lens/ChangeExecutor.java | 100 +++++++-- .../impl/lens/EvaluatedAssignmentImpl.java | 15 +- .../impl/lens/EvaluatedPolicyRuleImpl.java | 12 +- .../model/impl/lens/LensElementContext.java | 53 ++++- .../model/impl/lens/LensFocusContext.java | 25 +++ .../projector/AssignmentTripleEvaluator.java | 6 - .../impl/lens/projector/FocusProcessor.java | 3 +- .../projector/policy/PolicyRuleProcessor.java | 17 +- .../policy/PolicySituationUpdater.java | 190 ------------------ .../projector/policy/PolicyStateUpdater.java | 127 ++++++++++++ .../model/impl/lens/TestPolicyMetadata.java | 2 +- .../model/impl/lens/TestPolicyRules2.java | 26 +-- .../lens/role-judge-situation-only.xml | 3 +- .../lens/role-pirate-situation-only.xml | 1 + .../src/test/resources/lens/role-thief.xml | 5 +- .../intest/rbac/TestSegregationOfDuties.java | 2 +- .../primary/policy/ApprovalSchemaBuilder.java | 2 +- 40 files changed, 461 insertions(+), 350 deletions(-) create mode 100644 model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentSpec.java delete mode 100644 model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicySituationUpdater.java create mode 100644 model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateUpdater.java diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java index 8293d9db067..fb8d0623d82 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContainerValue.java @@ -1648,6 +1648,10 @@ public static List asContainerables(List c.asContainerable()).collect(Collectors.toList()); } + public static Collection asContainerables(Collection> pcvs) { + return pcvs.stream().map(c -> c.asContainerable()).collect(Collectors.toList()); + } + /** * Set origin type to all values and subvalues */ diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ContainerDelta.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ContainerDelta.java index 1d593a1379d..eb092c43e75 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ContainerDelta.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ContainerDelta.java @@ -187,7 +187,7 @@ private Collection findItemValues(Long id, ItemPath path, Collection void expand(PrismObject object, Trace logger) throws SchemaException { PrismContainer container = null; @@ -231,41 +231,6 @@ public void expand(PrismObject object, Trace logger) t } } } - if (valuesToAdd != null) { - assert valuesToReplace == null; - long maxId = getMaxId(container); - processIdentifiers(maxId, valuesToAdd); - } - if (valuesToReplace != null) { - assert valuesToAdd == null; - processIdentifiers(0, valuesToReplace); - } - } - - private void processIdentifiers(long maxId, Collection> values) { - for (PrismContainerValue value : values) { - if (value.getId() != null && value.getId() > maxId) { - maxId = value.getId(); - } - } - for (PrismContainerValue value : values) { - if (value.getId() == null) { - value.setId(++maxId); - } - } - } - - private long getMaxId(PrismContainer container) { - if (container == null) { - return 0; - } - long max = 0; - for (PrismContainerValue value : container.getValues()) { - if (value.getId() != null && value.getId() > max) { - max = value.getId(); - } - } - return max; } @Override diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ItemDelta.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ItemDelta.java index 2d74a08b5b2..eac837d965b 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ItemDelta.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ItemDelta.java @@ -1500,6 +1500,12 @@ private void filterValuesSet(Collection set, Function function) { public abstract ItemDelta clone(); + public ItemDelta cloneWithChangedParentPath(ItemPath newParentPath) { + ItemDelta clone = clone(); + clone.setParentPath(newParentPath); + return clone; + } + protected void copyValues(ItemDelta clone) { clone.definition = this.definition; clone.elementName = this.elementName; diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ItemPath.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ItemPath.java index 6a95532dc20..0522eefa0ca 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ItemPath.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/path/ItemPath.java @@ -72,19 +72,21 @@ public ItemPath(String... names) { } } - public ItemPath(Object... namesOrIds) { - this.segments = new ArrayList<>(namesOrIds.length); - for (Object nameOrId : namesOrIds) { - if (nameOrId instanceof QName) { - add((QName) nameOrId); - } else if (nameOrId instanceof String) { - add(stringToQName((String) nameOrId)); - } else if (nameOrId instanceof Long) { - this.segments.add(new IdItemPathSegment((Long) nameOrId)); - } else if (nameOrId instanceof Integer) { - this.segments.add(new IdItemPathSegment(((Integer) nameOrId).longValue())); + public ItemPath(Object... namesOrIdsOrSegments) { + this.segments = new ArrayList<>(namesOrIdsOrSegments.length); + for (Object nameOrIdOrSegment : namesOrIdsOrSegments) { + if (nameOrIdOrSegment instanceof ItemPathSegment) { + add((ItemPathSegment) nameOrIdOrSegment); + } else if (nameOrIdOrSegment instanceof QName) { + add((QName) nameOrIdOrSegment); + } else if (nameOrIdOrSegment instanceof String) { + add(stringToQName((String) nameOrIdOrSegment)); + } else if (nameOrIdOrSegment instanceof Long) { + this.segments.add(new IdItemPathSegment((Long) nameOrIdOrSegment)); + } else if (nameOrIdOrSegment instanceof Integer) { + this.segments.add(new IdItemPathSegment(((Integer) nameOrIdOrSegment).longValue())); } else { - throw new IllegalArgumentException("Invalid item path segment value: " + nameOrId); + throw new IllegalArgumentException("Invalid item path segment value: " + nameOrIdOrSegment); } } } diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-model-context-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-model-context-3.xsd index 0e306f80e99..f84179a5633 100644 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-model-context-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-model-context-3.xsd @@ -650,7 +650,7 @@ - + diff --git a/infra/util/src/main/java/com/evolveum/midpoint/util/MiscUtil.java b/infra/util/src/main/java/com/evolveum/midpoint/util/MiscUtil.java index 39adf59534b..4decf24e6f4 100644 --- a/infra/util/src/main/java/com/evolveum/midpoint/util/MiscUtil.java +++ b/infra/util/src/main/java/com/evolveum/midpoint/util/MiscUtil.java @@ -610,7 +610,7 @@ public static String nullIfEmpty(String s) { } /** - * Returns true if the collection contains at leat one pair of equals elements. + * Returns true if the collection contains at least one pair of equals elements. */ public static boolean hasDuplicates(Collection collection) { Set set = new HashSet<>(); diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/AssignmentPath.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/AssignmentPath.java index 2b0a4e008dd..1257f81954c 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/AssignmentPath.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/AssignmentPath.java @@ -68,5 +68,5 @@ public interface AssignmentPath extends DebugDumpable, ShortDumpable { @NotNull List getFirstOrderChain(); - AssignmentPathType toAssignmentPathType(); + AssignmentPathType toAssignmentPathType(boolean includeAssignmentsContent); } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/AssignmentPathSegment.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/AssignmentPathSegment.java index b71bd153eb3..4dd8af1a9ad 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/AssignmentPathSegment.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/AssignmentPathSegment.java @@ -74,5 +74,5 @@ public interface AssignmentPathSegment extends DebugDumpable, ShortDumpable { boolean isDelegation(); @NotNull - AssignmentPathSegmentType toAssignmentPathSegmentType(); + AssignmentPathSegmentType toAssignmentPathSegmentType(boolean includeAssignmentsContent); } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedCompositeTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedCompositeTrigger.java index ecfef70a89e..2f0207eda4d 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedCompositeTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedCompositeTrigger.java @@ -77,11 +77,12 @@ protected void debugDumpSpecific(StringBuilder sb, int indent) { } @Override - public EvaluatedLogicalTriggerType toEvaluatedPolicyRuleTriggerType(EvaluatedPolicyRule owningRule, boolean respectFinalFlag) { + public EvaluatedLogicalTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, + boolean respectFinalFlag) { EvaluatedLogicalTriggerType rv = new EvaluatedLogicalTriggerType(); - fillCommonContent(rv, owningRule); + fillCommonContent(rv); if (!respectFinalFlag || !isFinal()) { - innerTriggers.forEach(t -> rv.getEmbedded().add(t.toEvaluatedPolicyRuleTriggerType(owningRule, respectFinalFlag))); + innerTriggers.forEach(t -> rv.getEmbedded().add(t.toEvaluatedPolicyRuleTriggerType(includeAssignmentsContent, respectFinalFlag))); } return rv; } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedExclusionTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedExclusionTrigger.java index ef6efd09109..cf3bbc72048 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedExclusionTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedExclusionTrigger.java @@ -77,16 +77,18 @@ protected void debugDumpSpecific(StringBuilder sb, int indent) { } @Override - public EvaluatedExclusionTriggerType toEvaluatedPolicyRuleTriggerType(EvaluatedPolicyRule owningRule, + public EvaluatedExclusionTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, boolean respectFinalFlag) { EvaluatedExclusionTriggerType rv = new EvaluatedExclusionTriggerType(); - fillCommonContent(rv, owningRule); + fillCommonContent(rv); rv.setConflictingObjectRef(ObjectTypeUtil.createObjectRef(conflictingTarget)); rv.setConflictingObjectDisplayName(ObjectTypeUtil.getDisplayName(conflictingTarget)); if (conflictingPath != null) { - rv.setConflictingObjectPath(conflictingPath.toAssignmentPathType()); + rv.setConflictingObjectPath(conflictingPath.toAssignmentPathType(includeAssignmentsContent)); + } + if (includeAssignmentsContent && conflictingAssignment.getAssignmentType() != null) { + rv.setConflictingAssignment(conflictingAssignment.getAssignmentType().clone()); } - rv.setConflictingAssignment(conflictingAssignment.getAssignmentType()); return rv; } } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedHasAssignmentTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedHasAssignmentTrigger.java index 922eb62974f..18a2c178595 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedHasAssignmentTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedHasAssignmentTrigger.java @@ -31,10 +31,10 @@ public EvaluatedHasAssignmentTrigger(@NotNull PolicyConstraintKindType kind, @No } @Override - public EvaluatedHasAssignmentTriggerType toEvaluatedPolicyRuleTriggerType(EvaluatedPolicyRule owningRule, + public EvaluatedHasAssignmentTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, boolean respectFinalFlag) { EvaluatedHasAssignmentTriggerType rv = new EvaluatedHasAssignmentTriggerType(); - fillCommonContent(rv, owningRule); + fillCommonContent(rv); return rv; } } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedModificationTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedModificationTrigger.java index 9264e15378a..c89b4de5a0a 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedModificationTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedModificationTrigger.java @@ -31,10 +31,10 @@ public EvaluatedModificationTrigger(@NotNull PolicyConstraintKindType kind, @Not } @Override - public EvaluatedModificationTriggerType toEvaluatedPolicyRuleTriggerType(EvaluatedPolicyRule owningRule, + public EvaluatedModificationTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, boolean respectFinalFlag) { EvaluatedModificationTriggerType rv = new EvaluatedModificationTriggerType(); - fillCommonContent(rv, owningRule); + fillCommonContent(rv); return rv; } } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedMultiplicityTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedMultiplicityTrigger.java index f4f0bd9a047..3c4bc09bb1c 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedMultiplicityTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedMultiplicityTrigger.java @@ -31,10 +31,10 @@ public EvaluatedMultiplicityTrigger(@NotNull PolicyConstraintKindType kind, @Not } @Override - public EvaluatedMultiplicityTriggerType toEvaluatedPolicyRuleTriggerType(EvaluatedPolicyRule owningRule, + public EvaluatedMultiplicityTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, boolean respectFinalFlag) { EvaluatedMultiplicityTriggerType rv = new EvaluatedMultiplicityTriggerType(); - fillCommonContent(rv, owningRule); + fillCommonContent(rv); return rv; } } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRule.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRule.java index c9399e27b9b..04c4eaf7ba3 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRule.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRule.java @@ -66,7 +66,7 @@ default boolean isTriggered() { Collection getPolicyExceptions(); - EvaluatedPolicyRuleType toEvaluatedPolicyRuleType(boolean respectFinalFlag); + EvaluatedPolicyRuleType toEvaluatedPolicyRuleType(boolean includeAssignmentsContent, boolean respectFinalFlag); boolean isGlobal(); diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRuleTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRuleTrigger.java index 96b4ba6d6e8..4ee911c2a0f 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRuleTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRuleTrigger.java @@ -16,7 +16,6 @@ package com.evolveum.midpoint.model.api.context; import com.evolveum.midpoint.schema.util.LocalizationUtil; -import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.schema.util.PolicyRuleTypeUtil; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.DebugUtil; @@ -131,26 +130,17 @@ public String toDiagShortcut() { return PolicyRuleTypeUtil.toDiagShortcut(constraintKind); } - public EvaluatedPolicyRuleTriggerType toEvaluatedPolicyRuleTriggerType(EvaluatedPolicyRule owningRule, + public EvaluatedPolicyRuleTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, boolean respectFinalFlag) { EvaluatedPolicyRuleTriggerType rv = new EvaluatedPolicyRuleTriggerType(); - fillCommonContent(rv, owningRule); + fillCommonContent(rv); return rv; } - protected void fillCommonContent(EvaluatedPolicyRuleTriggerType tt, EvaluatedPolicyRule owningRule) { - tt.setRuleName(owningRule.getName()); + protected void fillCommonContent(EvaluatedPolicyRuleTriggerType tt) { tt.setConstraintKind(constraintKind); //tt.setConstraint(constraint); tt.setMessage(LocalizationUtil.createLocalizableMessageType(message)); - if (owningRule.getAssignmentPath() != null) { - tt.setAssignmentPath(owningRule.getAssignmentPath().toAssignmentPathType()); - } - ObjectType directOwner = owningRule.getDirectOwner(); - if (directOwner != null) { - tt.setDirectOwnerRef(ObjectTypeUtil.createObjectRef(directOwner)); - tt.setDirectOwnerDisplayName(ObjectTypeUtil.getDisplayName(directOwner)); - } PolicyConstraintPresentationType presentation = constraint.getPresentation(); if (presentation != null) { tt.setFinal(presentation.isFinal()); diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedSituationTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedSituationTrigger.java index 950a6f41098..855bc15b062 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedSituationTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedSituationTrigger.java @@ -103,12 +103,12 @@ protected void debugDumpSpecific(StringBuilder sb, int indent) { } @Override - public EvaluatedSituationTriggerType toEvaluatedPolicyRuleTriggerType(EvaluatedPolicyRule owningRule, + public EvaluatedSituationTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, boolean respectFinalFlag) { EvaluatedSituationTriggerType rv = new EvaluatedSituationTriggerType(); - fillCommonContent(rv, owningRule); + fillCommonContent(rv); if (!respectFinalFlag || !isFinal()) { - sourceRules.forEach(r -> rv.getSourceRule().add(r.toEvaluatedPolicyRuleType(false))); + sourceRules.forEach(r -> rv.getSourceRule().add(r.toEvaluatedPolicyRuleType(false, false))); } return rv; } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedStateTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedStateTrigger.java index b4c12197d4a..9b9ec499f4b 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedStateTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedStateTrigger.java @@ -33,9 +33,9 @@ public EvaluatedStateTrigger(@NotNull PolicyConstraintKindType kind, @NotNull St } @Override - public EvaluatedStateTriggerType toEvaluatedPolicyRuleTriggerType(EvaluatedPolicyRule owningRule, boolean respectFinalFlag) { + public EvaluatedStateTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, boolean respectFinalFlag) { EvaluatedStateTriggerType rv = new EvaluatedStateTriggerType(); - fillCommonContent(rv, owningRule); + fillCommonContent(rv); return rv; } } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTimeValidityTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTimeValidityTrigger.java index 2c29cab8aa4..4fce27c3fdf 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTimeValidityTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTimeValidityTrigger.java @@ -31,10 +31,10 @@ public EvaluatedTimeValidityTrigger(@NotNull PolicyConstraintKindType kind, @Not } @Override - public EvaluatedTimeValidityTriggerType toEvaluatedPolicyRuleTriggerType(EvaluatedPolicyRule owningRule, + public EvaluatedTimeValidityTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, boolean respectFinalFlag) { EvaluatedTimeValidityTriggerType rv = new EvaluatedTimeValidityTriggerType(); - fillCommonContent(rv, owningRule); + fillCommonContent(rv); return rv; } } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTransitionTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTransitionTrigger.java index ed0ab738e3b..6aa4ad9cc07 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTransitionTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTransitionTrigger.java @@ -75,12 +75,12 @@ protected void debugDumpSpecific(StringBuilder sb, int indent) { } @Override - public EvaluatedTransitionTriggerType toEvaluatedPolicyRuleTriggerType(EvaluatedPolicyRule owningRule, + public EvaluatedTransitionTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, boolean respectFinalFlag) { EvaluatedTransitionTriggerType rv = new EvaluatedTransitionTriggerType(); - fillCommonContent(rv, owningRule); + fillCommonContent(rv); if (!respectFinalFlag || !isFinal()) { - innerTriggers.forEach(t -> rv.getEmbedded().add(t.toEvaluatedPolicyRuleTriggerType(owningRule, respectFinalFlag))); + innerTriggers.forEach(t -> rv.getEmbedded().add(t.toEvaluatedPolicyRuleTriggerType(includeAssignmentsContent, respectFinalFlag))); } return rv; } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/hooks/PolicyRuleEnforcerHook.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/hooks/PolicyRuleEnforcerHook.java index 6b654e07fbc..5c9da6cc42e 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/hooks/PolicyRuleEnforcerHook.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/hooks/PolicyRuleEnforcerHook.java @@ -135,7 +135,8 @@ private void enforceTriggeredRules(EvaluationContext evalC continue; } - evalCtx.rules.add(policyRule.toEvaluatedPolicyRuleType(true)); + // TODO really include assignments content? + evalCtx.rules.add(policyRule.toEvaluatedPolicyRuleType(true, true)); for (EvaluatedPolicyRuleTrigger trigger: triggers) { if (trigger.getMessage() != null) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentPathImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentPathImpl.java index 27227c86b58..a4bf880030e 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentPathImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentPathImpl.java @@ -23,7 +23,6 @@ import com.evolveum.midpoint.model.api.context.AssignmentPath; import com.evolveum.midpoint.model.api.context.AssignmentPathSegment; -import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentPathType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; @@ -205,9 +204,9 @@ public void shortDump(StringBuilder sb) { } @Override - public AssignmentPathType toAssignmentPathType() { + public AssignmentPathType toAssignmentPathType(boolean includeAssignmentsContent) { AssignmentPathType rv = new AssignmentPathType(); - segments.forEach(seg -> rv.getSegment().add(seg.toAssignmentPathSegmentType())); + segments.forEach(seg -> rv.getSegment().add(seg.toAssignmentPathSegmentType(includeAssignmentsContent))); return rv; } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentPathSegmentImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentPathSegmentImpl.java index 8e8742b8953..4e973d96ca2 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentPathSegmentImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentPathSegmentImpl.java @@ -595,11 +595,13 @@ public String debugDump(int indent) { @NotNull @Override - public AssignmentPathSegmentType toAssignmentPathSegmentType() { + public AssignmentPathSegmentType toAssignmentPathSegmentType(boolean includeAssignmentsContent) { AssignmentPathSegmentType rv = new AssignmentPathSegmentType(); AssignmentType assignment = getAssignment(evaluatedForOld); // a bit of hack, but probably ok for now if (assignment != null) { - rv.setAssignment(assignment); + if (includeAssignmentsContent) { + rv.setAssignment(assignment.clone()); + } rv.setAssignmentId(assignment.getId()); } if (source != null) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentSpec.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentSpec.java new file mode 100644 index 00000000000..713c04f4d3e --- /dev/null +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentSpec.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.model.impl.lens; + +import com.evolveum.midpoint.prism.delta.PlusMinusZero; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; +import org.jetbrains.annotations.NotNull; + +import java.io.Serializable; +import java.util.Objects; + +/** + * A key for assignment:mode => modifications map (for policy state). + * + * @author mederly + */ +public class AssignmentSpec implements Serializable { + + @NotNull public final AssignmentType assignment; + @NotNull public final PlusMinusZero mode; + + public AssignmentSpec(@NotNull AssignmentType assignment, @NotNull PlusMinusZero mode) { + this.assignment = assignment; + this.mode = mode; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof AssignmentSpec)) + return false; + AssignmentSpec that = (AssignmentSpec) o; + return Objects.equals(assignment, that.assignment) && mode == that.mode; + } + + @Override + public int hashCode() { + return Objects.hash(assignment, mode); + } + + @Override + public String toString() { + return mode + ":" + assignment; + } +} 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 0b8bc1efbcd..9ea71d25a54 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 @@ -19,11 +19,13 @@ import static com.evolveum.midpoint.model.api.ProgressInformation.ActivityType.FOCUS_OPERATION; import static com.evolveum.midpoint.model.api.ProgressInformation.ActivityType.RESOURCE_OBJECT_OPERATION; import static com.evolveum.midpoint.model.api.ProgressInformation.StateType.ENTERING; +import static com.evolveum.midpoint.prism.PrismContainerValue.asContainerables; import static com.evolveum.midpoint.schema.internals.InternalsConfig.consistencyChecks; import com.evolveum.midpoint.common.Clock; import com.evolveum.midpoint.common.SynchronizationUtils; -import com.evolveum.midpoint.model.impl.lens.projector.policy.PolicySituationUpdater; +import com.evolveum.midpoint.model.impl.lens.projector.policy.PolicyStateUpdater; +import com.evolveum.midpoint.prism.delta.*; import com.evolveum.midpoint.repo.api.ConflictWatcher; import com.evolveum.midpoint.repo.common.expression.Expression; import com.evolveum.midpoint.repo.common.expression.ExpressionEvaluationContext; @@ -42,12 +44,6 @@ import com.evolveum.midpoint.model.impl.util.Utils; import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.crypto.EncryptionException; -import com.evolveum.midpoint.prism.delta.ChangeType; -import com.evolveum.midpoint.prism.delta.ItemDelta; -import com.evolveum.midpoint.prism.delta.ObjectDelta; -import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; -import com.evolveum.midpoint.prism.delta.PropertyDelta; -import com.evolveum.midpoint.prism.delta.ReferenceDelta; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.xnode.PrimitiveXNode; import com.evolveum.midpoint.provisioning.api.ProvisioningOperationOptions; @@ -88,6 +84,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.List; +import java.util.Map; import javax.annotation.PostConstruct; import javax.xml.bind.JAXBElement; @@ -119,7 +116,7 @@ public class ChangeExecutor { @Autowired private Clock clock; @Autowired private ModelObjectResolver objectResolver; @Autowired private OperationalDataManager metadataManager; - @Autowired private PolicySituationUpdater policySituationUpdater; + @Autowired private PolicyStateUpdater policyStateUpdater; @Autowired private CredentialsProcessor credentialsProcessor; private PrismObjectDefinition userDefinition = null; @@ -150,10 +147,8 @@ public boolean executeChanges(LensContext context, Tas if (focusContext != null) { ObjectDelta focusDelta = focusContext.getWaveExecutableDelta(context.getExecutionWave()); - for (ItemDelta itemDelta : focusContext.getPendingPolicySituationModifications()) { - focusContext.swallowToSecondaryDelta(itemDelta); - } - focusContext.clearPendingPolicySituationModifications(); + focusDelta = applyPendingObjectPolicyStateModifications(focusContext, focusDelta); + applyPendingAssignmentPolicyStateModifications(focusContext, focusDelta); if (focusDelta != null) { @@ -371,6 +366,87 @@ public boolean executeChanges(LensContext context, Tas } + private ObjectDelta applyPendingObjectPolicyStateModifications(LensFocusContext focusContext, + ObjectDelta focusDelta) throws SchemaException { + for (ItemDelta itemDelta : focusContext.getPendingObjectPolicyStateModifications()) { + focusDelta = focusContext.swallowToDelta(focusDelta, itemDelta); + } + focusContext.clearPendingObjectPolicyStateModifications(); + return focusDelta; + } + + private void applyPendingAssignmentPolicyStateModifications(LensFocusContext focusContext, ObjectDelta focusDelta) + throws SchemaException { + if (focusDelta != null) { + for (Map.Entry>> entry : focusContext + .getPendingAssignmentPolicyStateModifications().entrySet()) { + PlusMinusZero mode = entry.getKey().mode; + if (mode == PlusMinusZero.MINUS) { + continue; // this assignment is being thrown out anyway, so let's ignore it + } + AssignmentType assignmentToFind = entry.getKey().assignment; + List> modifications = entry.getValue(); + if (modifications.isEmpty()) { + continue; + } + LOGGER.trace("Applying policy state modifications for {} ({}):\n{}", assignmentToFind, mode, + DebugUtil.debugDumpLazily(modifications)); + if (mode == PlusMinusZero.ZERO) { + if (assignmentToFind.getId() == null) { + throw new IllegalStateException("Existing assignment with null id: " + assignmentToFind); + } + for (ItemDelta modification : modifications) { + focusContext.swallowToDelta(focusDelta, modification); + } + } else { + assert mode == PlusMinusZero.PLUS; + if (focusDelta.isAdd()) { + swallowIntoValues(((FocusType) focusDelta.getObjectToAdd().asObjectable()).getAssignment(), + assignmentToFind, modifications); + } else { + ContainerDelta assignmentDelta = focusDelta.findContainerDelta(FocusType.F_ASSIGNMENT); + if (assignmentDelta == null) { + throw new IllegalStateException( + "We have 'plus' assignment to modify but there's no assignment delta. Assignment=" + + assignmentToFind + ", objectDelta=" + focusDelta); + } + if (assignmentDelta.isReplace()) { + swallowIntoValues(asContainerables(assignmentDelta.getValuesToReplace()), assignmentToFind, + modifications); + } else if (assignmentDelta.isAdd()) { + swallowIntoValues(asContainerables(assignmentDelta.getValuesToAdd()), assignmentToFind, + modifications); + } else { + throw new IllegalStateException( + "We have 'plus' assignment to modify but there're no values to add or replace in assignment delta. Assignment=" + + assignmentToFind + ", objectDelta=" + focusDelta); + } + } + } + } + } + focusContext.clearPendingAssignmentPolicyStateModifications(); + } + + private void swallowIntoValues(Collection assignments, AssignmentType assignmentToFind, List> modifications) + throws SchemaException { + for (AssignmentType assignment : assignments) { + PrismContainerValue pcv = assignment.asPrismContainerValue(); + PrismContainerValue pcvToFind = assignmentToFind.asPrismContainerValue(); + if (pcv.representsSameValue(pcvToFind, false) || pcv.equalsRealValue(pcvToFind)) { + // TODO what if ID of the assignment being added is changed in repo? Hopefully it will be not. + for (ItemDelta modification : modifications) { + ItemPath newParentPath = modification.getParentPath().rest().rest(); // killing assignment + ID + ItemDelta pathRelativeModification = modification.cloneWithChangedParentPath(newParentPath); + pathRelativeModification.applyTo(pcv); + } + return; + } + } + // TODO change to warning + throw new IllegalStateException("We have 'plus' assignment to modify but it couldn't be found in assignment delta. Assignment=" + assignmentToFind + ", new assignments=" + assignments); + } + private boolean shouldBeDeleted(ObjectDelta accDelta, LensProjectionContext accCtx) { return (accDelta == null || accDelta.isEmpty()) && (accCtx.getSynchronizationPolicyDecision() == SynchronizationPolicyDecision.DELETE diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java index 634c4f168b9..0f2193aaeee 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java @@ -512,9 +512,9 @@ public String toString() { public String toHumanReadableString() { if (target != null) { return "EvaluatedAssignment(" + target + ")"; - } else if (constructionTriple != null && !constructionTriple.isEmpty()) { + } else if (!constructionTriple.isEmpty()) { return "EvaluatedAssignment(" + constructionTriple + ")"; - } else if (personaConstructionTriple != null && !personaConstructionTriple.isEmpty()) { + } else if (!personaConstructionTriple.isEmpty()) { return "EvaluatedAssignment(" + personaConstructionTriple + ")"; } else { return toString(); @@ -527,4 +527,15 @@ public List getNonNegativeTargets() { rv.addAll(roles.getPlusSet()); return rv; } + + @NotNull + public PlusMinusZero getMode() { + if (assignmentIdi.getItemOld() == null) { + return PlusMinusZero.PLUS; + } else if (assignmentIdi.getItemNew() == null) { + return PlusMinusZero.MINUS; + } else { + return PlusMinusZero.ZERO; + } + } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedPolicyRuleImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedPolicyRuleImpl.java index 0795f421ad8..67391dac922 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedPolicyRuleImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedPolicyRuleImpl.java @@ -312,10 +312,18 @@ private void createMessageTreeNode(TreeNode root, EvaluatedP */ @Override - public EvaluatedPolicyRuleType toEvaluatedPolicyRuleType(boolean respectFinalFlag) { + public EvaluatedPolicyRuleType toEvaluatedPolicyRuleType(boolean includeAssignmentsContent, boolean respectFinalFlag) { EvaluatedPolicyRuleType rv = new EvaluatedPolicyRuleType(); //rv.setPolicyRule(policyRuleType); // DO NOT use this, in order to avoid large data in assignments - triggers.forEach(t -> rv.getTrigger().add(t.toEvaluatedPolicyRuleTriggerType(this, respectFinalFlag))); + rv.setRuleName(getName()); + if (assignmentPath != null) { + rv.setAssignmentPath(assignmentPath.toAssignmentPathType(includeAssignmentsContent)); + } + if (directOwner != null) { + rv.setDirectOwnerRef(ObjectTypeUtil.createObjectRef(directOwner)); + rv.setDirectOwnerDisplayName(ObjectTypeUtil.getDisplayName(directOwner)); + } + triggers.forEach(t -> rv.getTrigger().add(t.toEvaluatedPolicyRuleTriggerType(includeAssignmentsContent, respectFinalFlag))); return rv; } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java index fee71efd96c..ad8ea5e5071 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java @@ -15,12 +15,11 @@ */ package com.evolveum.midpoint.model.impl.lens; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; +import java.util.*; import com.evolveum.midpoint.prism.ConsistencyCheckScope; import com.evolveum.midpoint.prism.Objectable; +import com.evolveum.midpoint.prism.delta.PlusMinusZero; import com.evolveum.midpoint.schema.DeltaConvertor; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; @@ -74,12 +73,17 @@ public abstract class LensElementContext implements ModelE private String iterationToken; /** - * These are policy situation modifications that should be applied regardless of how the clockwork is exited + * These are policy state modifications that should be applied regardless of how the clockwork is exited * (e.g. in primary state, in final state, with an exception). * * Currently implemented only for focus, not for projections. */ - @NotNull private transient final List> pendingPolicySituationModifications = new ArrayList<>(); + @NotNull private transient final List> pendingObjectPolicyStateModifications = new ArrayList<>(); + + /** + * Policy state modifications for assignments. + */ + @NotNull private transient final Map>> pendingAssignmentPolicyStateModifications = new HashMap<>(); /** * Initial intent regarding the account. It indicated what the initiator of the operation WANTS TO DO with the @@ -258,16 +262,43 @@ public void swallowToPrimaryDelta(ItemDelta itemDelta) throws SchemaExcepti public abstract void swallowToSecondaryDelta(ItemDelta itemDelta) throws SchemaException; - public List> getPendingPolicySituationModifications() { - return pendingPolicySituationModifications; + // TODO deduplicate with swallowToSecondaryDelta in LensFocusContext + public ObjectDelta swallowToDelta(ObjectDelta originalDelta, ItemDelta propDelta) throws SchemaException { + if (originalDelta == null) { + originalDelta = new ObjectDelta(getObjectTypeClass(), ChangeType.MODIFY, getPrismContext()); + originalDelta.setOid(getOid()); + } else if (originalDelta.containsModification(propDelta, true, true)) { + return originalDelta; + } + originalDelta.swallow(propDelta); + return originalDelta; + } + + @NotNull + public List> getPendingObjectPolicyStateModifications() { + return pendingObjectPolicyStateModifications; + } + + public void clearPendingObjectPolicyStateModifications() { + pendingObjectPolicyStateModifications.clear(); + } + + public void addToPendingObjectPolicyStateModifications(ItemDelta modification) { + pendingObjectPolicyStateModifications.add(modification); + } + + @NotNull + public Map>> getPendingAssignmentPolicyStateModifications() { + return pendingAssignmentPolicyStateModifications; } - public void clearPendingPolicySituationModifications() { - pendingPolicySituationModifications.clear(); + public void clearPendingAssignmentPolicyStateModifications() { + pendingAssignmentPolicyStateModifications.clear(); } - public void addToPendingPolicySituationModifications(ItemDelta modification) { - pendingPolicySituationModifications.add(modification); + public void addToPendingAssignmentPolicyStateModifications(@NotNull AssignmentType assignment, @NotNull PlusMinusZero mode, @NotNull ItemDelta modification) { + AssignmentSpec spec = new AssignmentSpec(assignment, mode); + pendingAssignmentPolicyStateModifications.computeIfAbsent(spec, k -> new ArrayList<>()).add(modification); } public boolean isAdd() { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensFocusContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensFocusContext.java index 7c661c2697e..00b44390cb2 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensFocusContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensFocusContext.java @@ -16,6 +16,8 @@ package com.evolveum.midpoint.model.impl.lens; import java.util.Collection; +import java.util.List; +import java.util.Map; import com.evolveum.midpoint.repo.common.expression.ObjectDeltaObject; import com.evolveum.midpoint.prism.Objectable; @@ -368,6 +370,29 @@ public String debugDump(int indent, boolean showTriples) { sb.append(secondaryDeltas.debugDump(indent + 2)); } + // pending policy state modifications (object + assignments) + sb.append("\n"); + DebugUtil.indentDebugDump(sb, indent + 1); + sb.append(getDebugDumpTitle("pending object policy state modifications")).append(":"); + if (getPendingObjectPolicyStateModifications().isEmpty()) { + sb.append(" empty"); + } else { + sb.append("\n"); + sb.append(DebugUtil.debugDump(getPendingObjectPolicyStateModifications(), indent + 2)); + } + + for (Map.Entry>> entry : getPendingAssignmentPolicyStateModifications().entrySet()) { + sb.append("\n"); + DebugUtil.indentDebugDump(sb, indent + 1); + sb.append(getDebugDumpTitle("pending assignment policy state modifications for ")).append(entry.getKey()).append(":"); + if (entry.getValue().isEmpty()) { + sb.append(" empty"); + } else { + sb.append("\n"); + sb.append(DebugUtil.debugDump(entry.getValue(), indent + 2)); + } + } + sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, getDebugDumpTitle("executed deltas"), getExecutedDeltas(), indent+1); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentTripleEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentTripleEvaluator.java index 812273c3c60..b5ee38a9fb6 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentTripleEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentTripleEvaluator.java @@ -142,12 +142,6 @@ public DeltaSetTriple> processAllAssignments() throws ContainerDelta assignmentDelta = getExecutionWaveAssignmentDelta(focusContext); assignmentDelta.expand(focusContext.getObjectCurrent(), LOGGER); - // Now we should have IDs for all assignments except for some borderline ones used in delete deltas - // (if the value to be deleted is not in object or if the value is ambiguous). This could have some negative - // impact on policy rules; namely, if there are some policy situations determined for such assignments, - // and the processing ends prematurely, it is possible that these situations will not be recorded. - // TODO determine if it's really this case - LOGGER.trace("Assignment delta:\n{}", assignmentDelta.debugDump()); SmartAssignmentCollection assignmentCollection = new SmartAssignmentCollection<>(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java index a72191f2adc..394435a633f 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java @@ -260,7 +260,8 @@ private void processFocusFocus(LensContext context, Str // ASSIGNMENTS - focusContext.clearPendingPolicySituationModifications(); + focusContext.clearPendingObjectPolicyStateModifications(); + focusContext.clearPendingAssignmentPolicyStateModifications(); LensUtil.partialExecute("assignments", () -> assignmentProcessor.processAssignmentsProjections(context, now, task, result), diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java index a04d3df97f0..a56794de0eb 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java @@ -69,7 +69,7 @@ public class PolicyRuleProcessor { @Autowired @Qualifier("cacheRepositoryService") private RepositoryService repositoryService; @Autowired private MappingFactory mappingFactory; @Autowired private MappingEvaluator mappingEvaluator; - @Autowired private PolicySituationUpdater situationUpdater; + @Autowired private PolicyStateUpdater policyStateUpdater; @Autowired private AssignmentConstraintEvaluator assignmentConstraintEvaluator; @Autowired private HasAssignmentConstraintEvaluator hasAssignmentConstraintEvaluator; @@ -149,7 +149,7 @@ public void evaluateAssignmentPolicyRules(LensContext c } } } - situationUpdater.applyAssignmentSituation(context, evaluatedAssignment, globalCtx.rulesToRecord); + policyStateUpdater.applyAssignmentState(context, evaluatedAssignment, globalCtx.rulesToRecord); } exclusionConstraintEvaluator.checkExclusionsLegacy(context, evaluatedAssignmentTriple.getPlusSet(), @@ -214,7 +214,7 @@ public void evaluateObjectPolicyRules(LensContext conte for (EvaluatedPolicyRule rule : situationRules) { evaluateFocusRule(rule, context, globalCtx, task, result); } - situationUpdater.applyObjectSituation(context, globalCtx.rulesToRecord); + policyStateUpdater.applyObjectState(context, globalCtx.rulesToRecord); } private Collection getAllGlobalRules(LensContext context) { @@ -319,21 +319,12 @@ private void evaluateRule(PolicyRuleEvaluationContext c } ctx.triggerRule(triggers); } - if (ctx.policyRule.getActions() != null && ctx.policyRule.getActions().getRecordSituation() != null) { + if (ctx.policyRule.isTriggered() && ctx.policyRule.getActions() != null && ctx.policyRule.getActions().getRecordSituation() != null) { ctx.record(); } traceRuleEvaluationResult(ctx.policyRule, ctx); } -// private void prepareSituationDeltas(PolicyRuleEvaluationContext ctx, -// RecordSituationPolicyActionType recordAction) { -// if (ctx instanceof AssignmentPolicyRuleEvaluationContext) { -// situationUpdater.prepareAssignmentSituationDeltas(); -// } else { -// situationUpdater.prepareObjectSituationDeltas(ctx.lensContext, recordAction); -// } -// } - // returns non-empty list if the constraints evaluated to true (if allMustApply, all of the constraints must apply; otherwise, at least one must apply) @SuppressWarnings("unchecked") @NotNull diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicySituationUpdater.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicySituationUpdater.java deleted file mode 100644 index a14da94f58c..00000000000 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicySituationUpdater.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2010-2017 Evolveum - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.evolveum.midpoint.model.impl.lens.projector.policy; - -import com.evolveum.midpoint.model.api.context.EvaluatedAssignment; -import com.evolveum.midpoint.model.api.context.EvaluatedPolicyRule; -import com.evolveum.midpoint.model.api.context.EvaluatedPolicyRuleTrigger; -import com.evolveum.midpoint.model.impl.lens.EvaluatedAssignmentImpl; -import com.evolveum.midpoint.model.impl.lens.LensContext; -import com.evolveum.midpoint.model.impl.lens.LensFocusContext; -import com.evolveum.midpoint.prism.*; -import com.evolveum.midpoint.prism.delta.*; -import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder; -import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.schema.util.PolicyRuleTypeUtil; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.*; -import org.apache.commons.collections4.CollectionUtils; -import org.jetbrains.annotations.NotNull; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.util.*; -import java.util.Objects; - -/** - * Takes care of updating policySituation for focus and assignments. (Originally was a part of PolicyRuleProcessor.) - * - * @author semancik - * @author mederly - */ -@Component -public class PolicySituationUpdater { - - private static final Trace LOGGER = TraceManager.getTrace(PolicySituationUpdater.class); - - @Autowired private PrismContext prismContext; - -// private List getTriggers(EvaluatedAssignmentImpl evaluatedAssignment) { -// List rv = new ArrayList<>(); -// for (EvaluatedPolicyRule policyRule : evaluatedAssignment.getAllTargetsPolicyRules()) { -// for (EvaluatedPolicyRuleTrigger trigger : policyRule.getTriggers()) { -// EvaluatedPolicyRuleTriggerType triggerType = trigger.toEvaluatedPolicyRuleTriggerType(policyRule, false).clone(); -// simplifyTrigger(triggerType); -// rv.add(triggerType); -// } -// } -// return rv; -// } -// -// private void simplifyTrigger(EvaluatedPolicyRuleTriggerType trigger) { -// deleteAssignments(trigger.getAssignmentPath()); -// if (trigger instanceof EvaluatedExclusionTriggerType) { -// EvaluatedExclusionTriggerType exclusionTrigger = (EvaluatedExclusionTriggerType) trigger; -// deleteAssignments(exclusionTrigger.getConflictingObjectPath()); -// exclusionTrigger.setConflictingAssignment(null); -// } else if (trigger instanceof EvaluatedSituationTriggerType) { -// for (EvaluatedPolicyRuleType sourceRule : ((EvaluatedSituationTriggerType) trigger).getSourceRule()) { -// for (EvaluatedPolicyRuleTriggerType sourceTrigger : sourceRule.getTrigger()) { -// simplifyTrigger(sourceTrigger); -// } -// } -// } -// } - -// private void deleteAssignments(AssignmentPathType path) { -// if (path == null) { -// return; -// } -// for (AssignmentPathSegmentType segment : path.getSegment()) { -// segment.setAssignment(null); -// } -// } - -// private boolean shouldSituationBeUpdated(EvaluatedAssignment evaluatedAssignment, -// List triggers) { -// if (PolicyRuleTypeUtil.canBePacked(evaluatedAssignment.getAssignmentType().getTrigger())) { -// return true; -// } -// Set currentSituations = new HashSet<>(evaluatedAssignment.getAssignmentType().getPolicySituation()); -// List currentTriggersUnpacked = PolicyRuleTypeUtil.unpack(evaluatedAssignment.getAssignmentType().getTrigger()); -// // if the current situations different from the ones in the old assignment => update -// // (provided that the situations in the assignment were _not_ changed directly via a delta!!!) TODO check this -// if (!currentSituations.equals(new HashSet<>(evaluatedAssignment.getPolicySituations()))) { -// LOGGER.trace("computed policy situations are different from the current ones"); -// return true; -// } -// if (!PolicyRuleTypeUtil.triggerCollectionsEqual(triggers, currentTriggersUnpacked)) { -// LOGGER.trace("computed policy rules triggers are different from the current ones"); -// return true; -// } -// return false; -// } - - - public void applyObjectSituation(LensContext context, List rulesToRecord) throws SchemaException { - // compute policySituation and triggeredPolicyRules and compare it with the expected state - // note that we use the new state for the comparison, because if values match we do not need to do anything - LensFocusContext focusContext = context.getFocusContext(); - F objectNew = focusContext.getObjectNew().asObjectable(); - ComputationResult cr = compute(rulesToRecord, objectNew.getPolicySituation(), objectNew.getTriggeredPolicyRule()); - if (cr.situationsNeedUpdate) { - focusContext.addToPendingPolicySituationModifications(DeltaBuilder.deltaFor(ObjectType.class, prismContext) - .item(ObjectType.F_POLICY_SITUATION) - .oldRealValues(cr.oldPolicySituations) - .replaceRealValues(cr.newPolicySituations) - .asItemDelta()); - } - if (cr.rulesNeedUpdate) { - focusContext.addToPendingPolicySituationModifications(DeltaBuilder.deltaFor(ObjectType.class, prismContext) - .item(ObjectType.F_TRIGGERED_POLICY_RULE) - .oldRealValues(cr.oldTriggeredRules) - .replaceRealValues(cr.newTriggeredRules) - .asItemDelta()); - } - } - - public void applyAssignmentSituation(LensContext context, - EvaluatedAssignmentImpl evaluatedAssignment, List rulesToRecord) throws SchemaException { - LensFocusContext focusContext = context.getFocusContext(); - AssignmentType assignment = evaluatedAssignment.getAssignmentType(false); - Long id = assignment.getId(); - ComputationResult cr = compute(rulesToRecord, assignment.getPolicySituation(), assignment.getTriggeredPolicyRule()); - boolean missedUpdate = false; - if (cr.situationsNeedUpdate) { - if (id != null) { - focusContext.addToPendingPolicySituationModifications(DeltaBuilder.deltaFor(ObjectType.class, prismContext) - .item(FocusType.F_ASSIGNMENT, id, AssignmentType.F_POLICY_SITUATION) - .oldRealValues(cr.oldPolicySituations) - .replaceRealValues(cr.newPolicySituations) - .asItemDelta()); - } else { - missedUpdate = true; - } - } - if (cr.rulesNeedUpdate) { - if (id != null) { - focusContext.addToPendingPolicySituationModifications(DeltaBuilder.deltaFor(ObjectType.class, prismContext) - .item(FocusType.F_ASSIGNMENT, id, AssignmentType.F_TRIGGERED_POLICY_RULE) - .oldRealValues(cr.oldTriggeredRules) - .replaceRealValues(cr.newTriggeredRules) - .asItemDelta()); - } else { - missedUpdate = true; - } - } - if (missedUpdate) { - LOGGER.warn("Policy situation/rules for assignment cannot be updated, because it has no ID; assignment = {}, in object {}", - assignment, focusContext.getObjectAny()); - } - } - - private ComputationResult compute(@NotNull List rulesToRecord, @NotNull List existingPolicySituation, - @NotNull List existingTriggeredPolicyRule) { - ComputationResult cr = new ComputationResult(); - for (EvaluatedPolicyRule rule : rulesToRecord) { - cr.newPolicySituations.add(rule.getPolicySituation()); - cr.newTriggeredRules.add(rule.toEvaluatedPolicyRuleType(true)); - } - cr.oldPolicySituations.addAll(existingPolicySituation); - cr.oldTriggeredRules.addAll(existingTriggeredPolicyRule); - cr.situationsNeedUpdate = !Objects.equals(cr.oldPolicySituations, cr.newPolicySituations); - cr.rulesNeedUpdate = !Objects.equals(cr.oldTriggeredRules, cr.newTriggeredRules); - return cr; - } - - private class ComputationResult { - final Set oldPolicySituations = new HashSet<>(); - final Set newPolicySituations = new HashSet<>(); - final Set oldTriggeredRules = new HashSet<>(); - final Set newTriggeredRules = new HashSet<>(); - boolean situationsNeedUpdate; - boolean rulesNeedUpdate; - } -} diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateUpdater.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateUpdater.java new file mode 100644 index 00000000000..6c859f7479c --- /dev/null +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateUpdater.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.model.impl.lens.projector.policy; + +import com.evolveum.midpoint.model.api.context.EvaluatedPolicyRule; +import com.evolveum.midpoint.model.impl.lens.EvaluatedAssignmentImpl; +import com.evolveum.midpoint.model.impl.lens.LensContext; +import com.evolveum.midpoint.model.impl.lens.LensFocusContext; +import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.delta.PlusMinusZero; +import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder; +import com.evolveum.midpoint.prism.path.IdItemPathSegment; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.Objects; + +/** + * Takes care of updating policySituation and triggered rules for focus and assignments. (Originally was a part of PolicyRuleProcessor.) + * + * @author semancik + * @author mederly + */ +@Component +public class PolicyStateUpdater { + + private static final Trace LOGGER = TraceManager.getTrace(PolicyStateUpdater.class); + + @Autowired private PrismContext prismContext; + + public void applyObjectState(LensContext context, List rulesToRecord) throws SchemaException { + // compute policySituation and triggeredPolicyRules and compare it with the expected state + // note that we use the new state for the comparison, because if values match we do not need to do anything + LensFocusContext focusContext = context.getFocusContext(); + F objectNew = focusContext.getObjectNew().asObjectable(); + ComputationResult cr = compute(rulesToRecord, objectNew.getPolicySituation(), objectNew.getTriggeredPolicyRule()); + if (cr.situationsNeedUpdate) { + focusContext.addToPendingObjectPolicyStateModifications(DeltaBuilder.deltaFor(ObjectType.class, prismContext) + .item(ObjectType.F_POLICY_SITUATION) + .oldRealValues(cr.oldPolicySituations) + .replaceRealValues(cr.newPolicySituations) + .asItemDelta()); + } + if (cr.rulesNeedUpdate) { + focusContext.addToPendingObjectPolicyStateModifications(DeltaBuilder.deltaFor(ObjectType.class, prismContext) + .item(ObjectType.F_TRIGGERED_POLICY_RULE) + .oldRealValues(cr.oldTriggeredRules) + .replaceRealValues(cr.newTriggeredRules) + .asItemDelta()); + } + } + + public void applyAssignmentState(LensContext context, + EvaluatedAssignmentImpl evaluatedAssignment, List rulesToRecord) throws SchemaException { + LensFocusContext focusContext = context.getFocusContext(); + AssignmentType assignmentNew = evaluatedAssignment.getAssignmentType(false); + AssignmentType assignmentOld = evaluatedAssignment.getAssignmentType(true); + if (assignmentOld == null && assignmentNew == null) { + throw new IllegalStateException("Policy situation/rules for assignment cannot be updated, because the " + + "assignment itself is missing in "+evaluatedAssignment+", in object "+focusContext.getObjectAny()); + } + // this value is to be used to find correct assignment in objectDelta to apply the modifications (if no ID is present) + @NotNull AssignmentType assignmentToMatch = assignmentOld != null ? assignmentOld : assignmentNew; + // this value is used to compute policy situation/rules modifications + @NotNull AssignmentType assignmentToCompute = assignmentNew != null ? assignmentNew : assignmentOld; + @NotNull PlusMinusZero mode = evaluatedAssignment.getMode(); + + Long id = assignmentToMatch.getId(); + ComputationResult cr = compute(rulesToRecord, assignmentToCompute.getPolicySituation(), assignmentToCompute.getTriggeredPolicyRule()); + if (cr.situationsNeedUpdate) { + focusContext.addToPendingAssignmentPolicyStateModifications(assignmentToMatch, mode, DeltaBuilder.deltaFor(FocusType.class, prismContext) + .item(FocusType.F_ASSIGNMENT, new IdItemPathSegment(id), AssignmentType.F_POLICY_SITUATION) + .oldRealValues(cr.oldPolicySituations) + .replaceRealValues(cr.newPolicySituations) + .asItemDelta()); + } + if (cr.rulesNeedUpdate) { + focusContext.addToPendingAssignmentPolicyStateModifications(assignmentToMatch, mode, DeltaBuilder.deltaFor(FocusType.class, prismContext) + .item(FocusType.F_ASSIGNMENT, new IdItemPathSegment(id), AssignmentType.F_TRIGGERED_POLICY_RULE) + .oldRealValues(cr.oldTriggeredRules) + .replaceRealValues(cr.newTriggeredRules) + .asItemDelta()); + } + } + + private ComputationResult compute(@NotNull List rulesToRecord, @NotNull List existingPolicySituation, + @NotNull List existingTriggeredPolicyRule) { + ComputationResult cr = new ComputationResult(); + for (EvaluatedPolicyRule rule : rulesToRecord) { + cr.newPolicySituations.add(rule.getPolicySituation()); + cr.newTriggeredRules.add(rule.toEvaluatedPolicyRuleType(false, true)); + } + cr.oldPolicySituations.addAll(existingPolicySituation); + cr.oldTriggeredRules.addAll(existingTriggeredPolicyRule); + cr.situationsNeedUpdate = !Objects.equals(cr.oldPolicySituations, cr.newPolicySituations); + cr.rulesNeedUpdate = !Objects.equals(cr.oldTriggeredRules, cr.newTriggeredRules); + return cr; + } + + private class ComputationResult { + final Set oldPolicySituations = new HashSet<>(); + final Set newPolicySituations = new HashSet<>(); + final Set oldTriggeredRules = new HashSet<>(); + final Set newTriggeredRules = new HashSet<>(); + boolean situationsNeedUpdate; + boolean rulesNeedUpdate; + } +} diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyMetadata.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyMetadata.java index 96a5ceb46a8..7b74f60330f 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyMetadata.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyMetadata.java @@ -90,7 +90,7 @@ public void test100JackAssignRoleJudge() throws Exception { assertAssignedRole(USER_JACK_OID, ROLE_JUDGE_OID, task, result); assertEquals("Wrong # of assignments", 1, jack.getAssignment().size()); assertEquals("Wrong policy situations", - Collections.singletonList(SchemaConstants.MODEL_POLICY_SITUATION_ASSIGNMENT_MODIFIED), + Collections.emptyList(), jack.getAssignment().get(0).getPolicySituation()); } diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules2.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules2.java index f71ba11242d..26865e22941 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules2.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules2.java @@ -314,13 +314,13 @@ public void test130JackMoveTo1900AndAssignRoleStudent() throws Exception { assertFocusTriggers(context, PolicyConstraintKindType.HAS_NO_ASSIGNMENT, 1); assertFocusTriggers(context, PolicyConstraintKindType.TRANSITION, 3); - assertAssignmentPolicySituation(context, roleStudentOid, - SchemaConstants.MODEL_POLICY_SITUATION_ASSIGNMENT_MODIFIED, - SchemaConstants.MODEL_POLICY_SITUATION_OBJECT_STATE); - assertFocusPolicySituation(context, - SchemaConstants.MODEL_POLICY_SITUATION_OBJECT_STATE, - SchemaConstants.MODEL_POLICY_SITUATION_HAS_ASSIGNMENT, - SchemaConstants.MODEL_POLICY_SITUATION_HAS_NO_ASSIGNMENT); +// assertAssignmentPolicySituation(context, roleStudentOid, +// SchemaConstants.MODEL_POLICY_SITUATION_ASSIGNMENT_MODIFIED, +// SchemaConstants.MODEL_POLICY_SITUATION_OBJECT_STATE); +// assertFocusPolicySituation(context, +// SchemaConstants.MODEL_POLICY_SITUATION_OBJECT_STATE, +// SchemaConstants.MODEL_POLICY_SITUATION_HAS_ASSIGNMENT, +// SchemaConstants.MODEL_POLICY_SITUATION_HAS_NO_ASSIGNMENT); } @Test @@ -560,12 +560,12 @@ public void test170AddPeter() throws Exception { // instead of "false-true" and "false-any" situations! // adapt the test after fixing MID-4126 - assertAssignmentPolicySituation(context, roleStudentOid, - SchemaConstants.MODEL_POLICY_SITUATION_OBJECT_STATE); - assertFocusPolicySituation(context, - SchemaConstants.MODEL_POLICY_SITUATION_OBJECT_STATE, - SchemaConstants.MODEL_POLICY_SITUATION_HAS_ASSIGNMENT, - SchemaConstants.MODEL_POLICY_SITUATION_HAS_NO_ASSIGNMENT); +// assertAssignmentPolicySituation(context, roleStudentOid, +// SchemaConstants.MODEL_POLICY_SITUATION_OBJECT_STATE); +// assertFocusPolicySituation(context, +// SchemaConstants.MODEL_POLICY_SITUATION_OBJECT_STATE, +// SchemaConstants.MODEL_POLICY_SITUATION_HAS_ASSIGNMENT, +// SchemaConstants.MODEL_POLICY_SITUATION_HAS_NO_ASSIGNMENT); } /** diff --git a/model/model-impl/src/test/resources/lens/role-judge-situation-only.xml b/model/model-impl/src/test/resources/lens/role-judge-situation-only.xml index 8f31d72ffca..5be082f4bac 100644 --- a/model/model-impl/src/test/resources/lens/role-judge-situation-only.xml +++ b/model/model-impl/src/test/resources/lens/role-judge-situation-only.xml @@ -30,7 +30,8 @@ - + + diff --git a/model/model-impl/src/test/resources/lens/role-pirate-situation-only.xml b/model/model-impl/src/test/resources/lens/role-pirate-situation-only.xml index c1920e3c60e..6926f03edb6 100644 --- a/model/model-impl/src/test/resources/lens/role-pirate-situation-only.xml +++ b/model/model-impl/src/test/resources/lens/role-pirate-situation-only.xml @@ -31,6 +31,7 @@ + diff --git a/model/model-impl/src/test/resources/lens/role-thief.xml b/model/model-impl/src/test/resources/lens/role-thief.xml index e9c2b997a4c..b10a9fbbc2c 100644 --- a/model/model-impl/src/test/resources/lens/role-thief.xml +++ b/model/model-impl/src/test/resources/lens/role-thief.xml @@ -26,7 +26,10 @@ - + + + + diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestSegregationOfDuties.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestSegregationOfDuties.java index afa8a531d2d..de47a44faef 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestSegregationOfDuties.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestSegregationOfDuties.java @@ -1340,7 +1340,7 @@ public void test822GuybrushAssignRoleMinister() throws Exception { assertAssignedRole(userAfter, ROLE_CRIMINAL_OID); assertAssignedRole(userAfter, ROLE_MINISTER_OID); - assertPolicySituation(userAfter, ROLE_MINISTER_OID, SchemaConstants.MODEL_POLICY_SITUATION_EXCLUSION_VIOLATION); + //assertPolicySituation(userAfter, ROLE_MINISTER_OID, SchemaConstants.MODEL_POLICY_SITUATION_EXCLUSION_VIOLATION); } @Test diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java index 152e3babf3c..eb45daa88cb 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java @@ -208,7 +208,7 @@ private void processFragmentGroup(List fragments, ApprovalSchemaType r SchemaAttachedPolicyRuleType attachedRule = new SchemaAttachedPolicyRuleType(); attachedRule.setStageMin(from); attachedRule.setStageMax(i - 1); - attachedRule.setRule(firstFragment.policyRule.toEvaluatedPolicyRuleType(false)); + attachedRule.setRule(firstFragment.policyRule.toEvaluatedPolicyRuleType(false, true)); attachedRules.getEntry().add(attachedRule); } } From ef245d7b27ca1b8085d8bb92a9e491939372cdc4 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 25 Sep 2017 13:51:13 +0200 Subject: [PATCH 57/97] Renamed recordSituation->record and fixed schema tests. --- .../resources/xml/ns/public/common/common-policy-3.xsd | 4 ++-- .../com/evolveum/midpoint/schema/util/SchemaTestUtil.java | 2 +- .../src/test/resources/complex/system-configuration.xml | 8 ++++---- .../impl/lens/projector/policy/PolicyRuleProcessor.java | 2 +- .../{TestPolicyMetadata.java => TestPolicyState.java} | 8 ++++---- .../src/test/resources/lens/role-judge-situation-only.xml | 2 +- .../test/resources/lens/role-pirate-situation-only.xml | 2 +- model/model-impl/src/test/resources/lens/role-thief.xml | 2 +- model/model-impl/testng-unit.xml | 2 +- 9 files changed, 16 insertions(+), 16 deletions(-) rename model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/{TestPolicyMetadata.java => TestPolicyState.java} (93%) diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd index 534cb7687dd..25810227239 100644 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd @@ -1014,7 +1014,7 @@ - + Record action. The operation will proceed. Policy situation will be recorded for @@ -1375,7 +1375,7 @@ - + TODO diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/util/SchemaTestUtil.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/util/SchemaTestUtil.java index 5b108c5c15e..fe27db9d7e5 100644 --- a/infra/schema/src/test/java/com/evolveum/midpoint/schema/util/SchemaTestUtil.java +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/util/SchemaTestUtil.java @@ -86,7 +86,7 @@ public static void assertFocusDefinition(ComplexTypeDefinition complexTypeDefini PrismContainerDefinition assignmentContainer = complexTypeDefinition.findContainerDefinition(UserType.F_ASSIGNMENT); PrismAsserts.assertDefinition(assignmentContainer, UserType.F_ASSIGNMENT, AssignmentType.COMPLEX_TYPE, 0, -1); assertFalse("Assignment is runtime", assignmentContainer.isRuntimeSchema()); - assertEquals("Assignment definition size", 21, assignmentContainer.getDefinitions().size()); + assertEquals("Assignment definition size", 22, assignmentContainer.getDefinitions().size()); PrismContainerDefinition constructionContainer = assignmentContainer.findContainerDefinition(AssignmentType.F_CONSTRUCTION); PrismAsserts.assertDefinition(constructionContainer, AssignmentType.F_CONSTRUCTION, ConstructionType.COMPLEX_TYPE, 0, 1); diff --git a/model/certification-impl/src/test/resources/complex/system-configuration.xml b/model/certification-impl/src/test/resources/complex/system-configuration.xml index 8c8cd007d65..ac1cbdb3a3d 100644 --- a/model/certification-impl/src/test/resources/complex/system-configuration.xml +++ b/model/certification-impl/src/test/resources/complex/system-configuration.xml @@ -394,9 +394,9 @@ http://sample.org/situations#incomplete-role-c1-to-c4 - + full - + RoleType @@ -412,9 +412,9 @@ http://sample.org/situations#active-role-with-no-identifier - + none - + RoleType diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java index a56794de0eb..5fb0be2dc03 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java @@ -319,7 +319,7 @@ private void evaluateRule(PolicyRuleEvaluationContext c } ctx.triggerRule(triggers); } - if (ctx.policyRule.isTriggered() && ctx.policyRule.getActions() != null && ctx.policyRule.getActions().getRecordSituation() != null) { + if (ctx.policyRule.isTriggered() && ctx.policyRule.getActions() != null && ctx.policyRule.getActions().getRecord() != null) { ctx.record(); } traceRuleEvaluationResult(ctx.policyRule, ctx); diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyMetadata.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyState.java similarity index 93% rename from model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyMetadata.java rename to model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyState.java index 7b74f60330f..b5fbff1586d 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyMetadata.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyState.java @@ -43,7 +43,7 @@ */ @ContextConfiguration(locations = {"classpath:ctx-model-test-main.xml"}) @DirtiesContext(classMode = ClassMode.AFTER_CLASS) -public class TestPolicyMetadata extends AbstractLensTest { +public class TestPolicyState extends AbstractLensTest { private static final String ROLE_JUDGE_POLICY_RULE_EXCLUSION_NAME = "criminal exclusion"; @@ -73,7 +73,7 @@ public void test100JackAssignRoleJudge() throws Exception { TestUtil.displayTestTitle(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestPolicyMetadata.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestPolicyState.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -100,7 +100,7 @@ public void test110JackAssignRolePirate() throws Exception { TestUtil.displayTestTitle(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestPolicyMetadata.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestPolicyState.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -130,7 +130,7 @@ public void test120RecomputeJack() throws Exception { TestUtil.displayTestTitle(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestPolicyMetadata.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestPolicyState.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN diff --git a/model/model-impl/src/test/resources/lens/role-judge-situation-only.xml b/model/model-impl/src/test/resources/lens/role-judge-situation-only.xml index 5be082f4bac..59d5135c804 100644 --- a/model/model-impl/src/test/resources/lens/role-judge-situation-only.xml +++ b/model/model-impl/src/test/resources/lens/role-judge-situation-only.xml @@ -30,7 +30,7 @@ - + diff --git a/model/model-impl/src/test/resources/lens/role-pirate-situation-only.xml b/model/model-impl/src/test/resources/lens/role-pirate-situation-only.xml index 6926f03edb6..2fd1c58578e 100644 --- a/model/model-impl/src/test/resources/lens/role-pirate-situation-only.xml +++ b/model/model-impl/src/test/resources/lens/role-pirate-situation-only.xml @@ -31,7 +31,7 @@ - + diff --git a/model/model-impl/src/test/resources/lens/role-thief.xml b/model/model-impl/src/test/resources/lens/role-thief.xml index b10a9fbbc2c..ce91c6dd203 100644 --- a/model/model-impl/src/test/resources/lens/role-thief.xml +++ b/model/model-impl/src/test/resources/lens/role-thief.xml @@ -28,7 +28,7 @@ - + diff --git a/model/model-impl/testng-unit.xml b/model/model-impl/testng-unit.xml index 1e2d2b012fd..b6c29d43ecc 100644 --- a/model/model-impl/testng-unit.xml +++ b/model/model-impl/testng-unit.xml @@ -72,7 +72,7 @@ - + From 64d50bd3b715604613ef1b5bf42c10e8562a2c14 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 25 Sep 2017 14:17:47 +0200 Subject: [PATCH 58/97] Implemented triggerStorageStrategy. --- .../context/EvaluatedCompositeTrigger.java | 7 +-- .../context/EvaluatedExclusionTrigger.java | 21 ++++--- .../EvaluatedHasAssignmentTrigger.java | 3 +- .../context/EvaluatedModificationTrigger.java | 3 +- .../context/EvaluatedMultiplicityTrigger.java | 3 +- .../api/context/EvaluatedPolicyRule.java | 2 +- .../context/EvaluatedPolicyRuleTrigger.java | 4 +- .../context/EvaluatedSituationTrigger.java | 7 +-- .../api/context/EvaluatedStateTrigger.java | 2 +- .../context/EvaluatedTimeValidityTrigger.java | 3 +- .../context/EvaluatedTransitionTrigger.java | 7 +-- .../PolicyRuleExternalizationOptions.java | 58 +++++++++++++++++++ .../impl/hooks/PolicyRuleEnforcerHook.java | 4 +- .../impl/lens/EvaluatedPolicyRuleImpl.java | 15 +++-- .../projector/policy/PolicyStateUpdater.java | 6 +- .../lens/role-pirate-situation-only.xml | 4 +- .../primary/policy/ApprovalSchemaBuilder.java | 4 +- 17 files changed, 109 insertions(+), 44 deletions(-) create mode 100644 model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/PolicyRuleExternalizationOptions.java diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedCompositeTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedCompositeTrigger.java index 2f0207eda4d..d2cdc1b0798 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedCompositeTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedCompositeTrigger.java @@ -77,12 +77,11 @@ protected void debugDumpSpecific(StringBuilder sb, int indent) { } @Override - public EvaluatedLogicalTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, - boolean respectFinalFlag) { + public EvaluatedLogicalTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { EvaluatedLogicalTriggerType rv = new EvaluatedLogicalTriggerType(); fillCommonContent(rv); - if (!respectFinalFlag || !isFinal()) { - innerTriggers.forEach(t -> rv.getEmbedded().add(t.toEvaluatedPolicyRuleTriggerType(includeAssignmentsContent, respectFinalFlag))); + if (!options.isRespectFinalFlag() || !isFinal()) { + innerTriggers.forEach(t -> rv.getEmbedded().add(t.toEvaluatedPolicyRuleTriggerType(options))); } return rv; } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedExclusionTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedExclusionTrigger.java index cf3bbc72048..1b364bd9f94 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedExclusionTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedExclusionTrigger.java @@ -24,6 +24,8 @@ import java.util.Objects; +import static com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyTriggerStorageStrategyType.FULL; + /** * @author mederly */ @@ -77,17 +79,18 @@ protected void debugDumpSpecific(StringBuilder sb, int indent) { } @Override - public EvaluatedExclusionTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, - boolean respectFinalFlag) { + public EvaluatedExclusionTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { EvaluatedExclusionTriggerType rv = new EvaluatedExclusionTriggerType(); fillCommonContent(rv); - rv.setConflictingObjectRef(ObjectTypeUtil.createObjectRef(conflictingTarget)); - rv.setConflictingObjectDisplayName(ObjectTypeUtil.getDisplayName(conflictingTarget)); - if (conflictingPath != null) { - rv.setConflictingObjectPath(conflictingPath.toAssignmentPathType(includeAssignmentsContent)); - } - if (includeAssignmentsContent && conflictingAssignment.getAssignmentType() != null) { - rv.setConflictingAssignment(conflictingAssignment.getAssignmentType().clone()); + if (options.getTriggerStorageStrategy() == FULL) { + rv.setConflictingObjectRef(ObjectTypeUtil.createObjectRef(conflictingTarget)); + rv.setConflictingObjectDisplayName(ObjectTypeUtil.getDisplayName(conflictingTarget)); + if (conflictingPath != null) { + rv.setConflictingObjectPath(conflictingPath.toAssignmentPathType(options.isIncludeAssignmentsContent())); + } + if (options.isIncludeAssignmentsContent() && conflictingAssignment.getAssignmentType() != null) { + rv.setConflictingAssignment(conflictingAssignment.getAssignmentType().clone()); + } } return rv; } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedHasAssignmentTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedHasAssignmentTrigger.java index 18a2c178595..b2634123bd9 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedHasAssignmentTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedHasAssignmentTrigger.java @@ -31,8 +31,7 @@ public EvaluatedHasAssignmentTrigger(@NotNull PolicyConstraintKindType kind, @No } @Override - public EvaluatedHasAssignmentTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, - boolean respectFinalFlag) { + public EvaluatedHasAssignmentTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { EvaluatedHasAssignmentTriggerType rv = new EvaluatedHasAssignmentTriggerType(); fillCommonContent(rv); return rv; diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedModificationTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedModificationTrigger.java index c89b4de5a0a..bf47c26488d 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedModificationTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedModificationTrigger.java @@ -31,8 +31,7 @@ public EvaluatedModificationTrigger(@NotNull PolicyConstraintKindType kind, @Not } @Override - public EvaluatedModificationTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, - boolean respectFinalFlag) { + public EvaluatedModificationTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { EvaluatedModificationTriggerType rv = new EvaluatedModificationTriggerType(); fillCommonContent(rv); return rv; diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedMultiplicityTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedMultiplicityTrigger.java index 3c4bc09bb1c..9e1ee567672 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedMultiplicityTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedMultiplicityTrigger.java @@ -31,8 +31,7 @@ public EvaluatedMultiplicityTrigger(@NotNull PolicyConstraintKindType kind, @Not } @Override - public EvaluatedMultiplicityTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, - boolean respectFinalFlag) { + public EvaluatedMultiplicityTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { EvaluatedMultiplicityTriggerType rv = new EvaluatedMultiplicityTriggerType(); fillCommonContent(rv); return rv; diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRule.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRule.java index 04c4eaf7ba3..8ef51b2759d 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRule.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRule.java @@ -66,7 +66,7 @@ default boolean isTriggered() { Collection getPolicyExceptions(); - EvaluatedPolicyRuleType toEvaluatedPolicyRuleType(boolean includeAssignmentsContent, boolean respectFinalFlag); + EvaluatedPolicyRuleType toEvaluatedPolicyRuleType(PolicyRuleExternalizationOptions options); boolean isGlobal(); diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRuleTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRuleTrigger.java index 4ee911c2a0f..31ebe4b4c6c 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRuleTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRuleTrigger.java @@ -130,8 +130,7 @@ public String toDiagShortcut() { return PolicyRuleTypeUtil.toDiagShortcut(constraintKind); } - public EvaluatedPolicyRuleTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, - boolean respectFinalFlag) { + public EvaluatedPolicyRuleTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { EvaluatedPolicyRuleTriggerType rv = new EvaluatedPolicyRuleTriggerType(); fillCommonContent(rv); return rv; @@ -139,7 +138,6 @@ public EvaluatedPolicyRuleTriggerType toEvaluatedPolicyRuleTriggerType(boolean i protected void fillCommonContent(EvaluatedPolicyRuleTriggerType tt) { tt.setConstraintKind(constraintKind); - //tt.setConstraint(constraint); tt.setMessage(LocalizationUtil.createLocalizableMessageType(message)); PolicyConstraintPresentationType presentation = constraint.getPresentation(); if (presentation != null) { diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedSituationTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedSituationTrigger.java index 855bc15b062..063c358ec05 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedSituationTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedSituationTrigger.java @@ -103,12 +103,11 @@ protected void debugDumpSpecific(StringBuilder sb, int indent) { } @Override - public EvaluatedSituationTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, - boolean respectFinalFlag) { + public EvaluatedSituationTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { EvaluatedSituationTriggerType rv = new EvaluatedSituationTriggerType(); fillCommonContent(rv); - if (!respectFinalFlag || !isFinal()) { - sourceRules.forEach(r -> rv.getSourceRule().add(r.toEvaluatedPolicyRuleType(false, false))); + if (!options.isRespectFinalFlag() || !isFinal()) { + sourceRules.forEach(r -> rv.getSourceRule().add(r.toEvaluatedPolicyRuleType(options))); } return rv; } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedStateTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedStateTrigger.java index 9b9ec499f4b..36a44eff9c6 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedStateTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedStateTrigger.java @@ -33,7 +33,7 @@ public EvaluatedStateTrigger(@NotNull PolicyConstraintKindType kind, @NotNull St } @Override - public EvaluatedStateTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, boolean respectFinalFlag) { + public EvaluatedStateTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { EvaluatedStateTriggerType rv = new EvaluatedStateTriggerType(); fillCommonContent(rv); return rv; diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTimeValidityTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTimeValidityTrigger.java index 4fce27c3fdf..9dbc954b8fb 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTimeValidityTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTimeValidityTrigger.java @@ -31,8 +31,7 @@ public EvaluatedTimeValidityTrigger(@NotNull PolicyConstraintKindType kind, @Not } @Override - public EvaluatedTimeValidityTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, - boolean respectFinalFlag) { + public EvaluatedTimeValidityTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { EvaluatedTimeValidityTriggerType rv = new EvaluatedTimeValidityTriggerType(); fillCommonContent(rv); return rv; diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTransitionTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTransitionTrigger.java index 6aa4ad9cc07..82c8fdb506f 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTransitionTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTransitionTrigger.java @@ -75,12 +75,11 @@ protected void debugDumpSpecific(StringBuilder sb, int indent) { } @Override - public EvaluatedTransitionTriggerType toEvaluatedPolicyRuleTriggerType(boolean includeAssignmentsContent, - boolean respectFinalFlag) { + public EvaluatedTransitionTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { EvaluatedTransitionTriggerType rv = new EvaluatedTransitionTriggerType(); fillCommonContent(rv); - if (!respectFinalFlag || !isFinal()) { - innerTriggers.forEach(t -> rv.getEmbedded().add(t.toEvaluatedPolicyRuleTriggerType(includeAssignmentsContent, respectFinalFlag))); + if (!options.isRespectFinalFlag() || !isFinal()) { + innerTriggers.forEach(t -> rv.getEmbedded().add(t.toEvaluatedPolicyRuleTriggerType(options))); } return rv; } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/PolicyRuleExternalizationOptions.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/PolicyRuleExternalizationOptions.java new file mode 100644 index 00000000000..2e8ac2a4f47 --- /dev/null +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/PolicyRuleExternalizationOptions.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.model.api.context; + +import com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyTriggerStorageStrategyType; +import org.jetbrains.annotations.NotNull; + +import java.io.Serializable; + +import static com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyTriggerStorageStrategyType.FULL; + +/** + * @author mederly + */ +public class PolicyRuleExternalizationOptions implements Serializable { + + @NotNull private PolicyTriggerStorageStrategyType triggerStorageStrategy; + private boolean includeAssignmentsContent; + private boolean respectFinalFlag; + + public PolicyRuleExternalizationOptions() { + this(FULL, false, true); + } + + public PolicyRuleExternalizationOptions(PolicyTriggerStorageStrategyType triggerStorageStrategy, + boolean includeAssignmentsContent, boolean respectFinalFlag) { + this.triggerStorageStrategy = triggerStorageStrategy != null ? triggerStorageStrategy : FULL; + this.includeAssignmentsContent = includeAssignmentsContent; + this.respectFinalFlag = respectFinalFlag; + } + + @NotNull + public PolicyTriggerStorageStrategyType getTriggerStorageStrategy() { + return triggerStorageStrategy; + } + + public boolean isIncludeAssignmentsContent() { + return includeAssignmentsContent; + } + + public boolean isRespectFinalFlag() { + return respectFinalFlag; + } +} diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/hooks/PolicyRuleEnforcerHook.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/hooks/PolicyRuleEnforcerHook.java index 5c9da6cc42e..e9f4e234f8f 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/hooks/PolicyRuleEnforcerHook.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/hooks/PolicyRuleEnforcerHook.java @@ -40,6 +40,8 @@ import java.util.Collections; import java.util.List; +import static com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyTriggerStorageStrategyType.FULL; + /** * Hook used to enforce the policy rules that have the enforce action. * @@ -136,7 +138,7 @@ private void enforceTriggeredRules(EvaluationContext evalC } // TODO really include assignments content? - evalCtx.rules.add(policyRule.toEvaluatedPolicyRuleType(true, true)); + evalCtx.rules.add(policyRule.toEvaluatedPolicyRuleType(new PolicyRuleExternalizationOptions(FULL, true, true))); for (EvaluatedPolicyRuleTrigger trigger: triggers) { if (trigger.getMessage() != null) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedPolicyRuleImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedPolicyRuleImpl.java index 67391dac922..40308f52e06 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedPolicyRuleImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedPolicyRuleImpl.java @@ -31,6 +31,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyTriggerStorageStrategyType.FULL; + /** * @author semancik * @@ -309,21 +311,22 @@ private void createMessageTreeNode(TreeNode root, EvaluatedP /** * Honors "final" but not "hidden" flag. + * @param options */ @Override - public EvaluatedPolicyRuleType toEvaluatedPolicyRuleType(boolean includeAssignmentsContent, boolean respectFinalFlag) { + public EvaluatedPolicyRuleType toEvaluatedPolicyRuleType(PolicyRuleExternalizationOptions options) { EvaluatedPolicyRuleType rv = new EvaluatedPolicyRuleType(); - //rv.setPolicyRule(policyRuleType); // DO NOT use this, in order to avoid large data in assignments rv.setRuleName(getName()); - if (assignmentPath != null) { - rv.setAssignmentPath(assignmentPath.toAssignmentPathType(includeAssignmentsContent)); + boolean isFull = options.getTriggerStorageStrategy() == FULL; + if (isFull && assignmentPath != null) { + rv.setAssignmentPath(assignmentPath.toAssignmentPathType(options.isIncludeAssignmentsContent())); } - if (directOwner != null) { + if (isFull && directOwner != null) { rv.setDirectOwnerRef(ObjectTypeUtil.createObjectRef(directOwner)); rv.setDirectOwnerDisplayName(ObjectTypeUtil.getDisplayName(directOwner)); } - triggers.forEach(t -> rv.getTrigger().add(t.toEvaluatedPolicyRuleTriggerType(includeAssignmentsContent, respectFinalFlag))); + triggers.forEach(t -> rv.getTrigger().add(t.toEvaluatedPolicyRuleTriggerType(options))); return rv; } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateUpdater.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateUpdater.java index 6c859f7479c..63330d650e5 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateUpdater.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateUpdater.java @@ -16,6 +16,7 @@ package com.evolveum.midpoint.model.impl.lens.projector.policy; import com.evolveum.midpoint.model.api.context.EvaluatedPolicyRule; +import com.evolveum.midpoint.model.api.context.PolicyRuleExternalizationOptions; import com.evolveum.midpoint.model.impl.lens.EvaluatedAssignmentImpl; import com.evolveum.midpoint.model.impl.lens.LensContext; import com.evolveum.midpoint.model.impl.lens.LensFocusContext; @@ -107,7 +108,10 @@ private ComputationResult compute(@NotNull List rulesToReco ComputationResult cr = new ComputationResult(); for (EvaluatedPolicyRule rule : rulesToRecord) { cr.newPolicySituations.add(rule.getPolicySituation()); - cr.newTriggeredRules.add(rule.toEvaluatedPolicyRuleType(false, true)); + RecordPolicyActionType recordAction = rule.getActions().getRecord(); + if (recordAction.getTriggerStorageStrategy() != PolicyTriggerStorageStrategyType.NONE) { + cr.newTriggeredRules.add(rule.toEvaluatedPolicyRuleType(new PolicyRuleExternalizationOptions(recordAction.getTriggerStorageStrategy(), false, true))); + } } cr.oldPolicySituations.addAll(existingPolicySituation); cr.oldTriggeredRules.addAll(existingTriggeredPolicyRule); diff --git a/model/model-impl/src/test/resources/lens/role-pirate-situation-only.xml b/model/model-impl/src/test/resources/lens/role-pirate-situation-only.xml index 2fd1c58578e..b936eeab0e2 100644 --- a/model/model-impl/src/test/resources/lens/role-pirate-situation-only.xml +++ b/model/model-impl/src/test/resources/lens/role-pirate-situation-only.xml @@ -31,7 +31,9 @@ - + + messageOnly + diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java index eb45daa88cb..14a86b8f7a6 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java @@ -17,6 +17,7 @@ package com.evolveum.midpoint.wf.impl.processors.primary.policy; import com.evolveum.midpoint.model.api.context.EvaluatedPolicyRule; +import com.evolveum.midpoint.model.api.context.PolicyRuleExternalizationOptions; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.util.CloneUtil; @@ -33,6 +34,7 @@ import javax.xml.namespace.QName; import java.util.*; +import static com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyTriggerStorageStrategyType.FULL; import static java.util.Comparator.naturalOrder; /** @@ -208,7 +210,7 @@ private void processFragmentGroup(List fragments, ApprovalSchemaType r SchemaAttachedPolicyRuleType attachedRule = new SchemaAttachedPolicyRuleType(); attachedRule.setStageMin(from); attachedRule.setStageMax(i - 1); - attachedRule.setRule(firstFragment.policyRule.toEvaluatedPolicyRuleType(false, true)); + attachedRule.setRule(firstFragment.policyRule.toEvaluatedPolicyRuleType(new PolicyRuleExternalizationOptions(FULL, false, true))); attachedRules.getEntry().add(attachedRule); } } From 353b5ee93c81f88c89300570ce6156443895c8ec Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 25 Sep 2017 14:42:00 +0200 Subject: [PATCH 59/97] Migrated from assignment.trigger to assignment.triggeredPolicyRule --- .../dto/CertCaseOrWorkItemDto.java | 28 ++++++++-------- .../test/TestSoDCertification.java | 32 ++++++++++--------- .../midpoint/model/impl/lens/Clockwork.java | 1 + 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertCaseOrWorkItemDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertCaseOrWorkItemDto.java index ddc4cd3e817..45e1fd239f3 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertCaseOrWorkItemDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertCaseOrWorkItemDto.java @@ -208,19 +208,21 @@ public String getConflictingTargets() { return ""; } Set exclusions = new TreeSet<>(); - for (EvaluatedPolicyRuleTriggerType trigger : assignmentCase.getAssignment().getTrigger()) { - if (!(trigger instanceof EvaluatedExclusionTriggerType)) { - continue; - } - EvaluatedExclusionTriggerType exclusionTrigger = (EvaluatedExclusionTriggerType) trigger; - ObjectReferenceType conflicting = exclusionTrigger.getConflictingObjectRef(); - if (conflicting == null) { - continue; - } - if (conflicting.getTargetName() != null) { - exclusions.add(conflicting.getTargetName().getOrig()); - } else { - exclusions.add(conflicting.getOid()); // TODO try to resolve? + for (EvaluatedPolicyRuleType rule : assignmentCase.getAssignment().getTriggeredPolicyRule()) { + for (EvaluatedPolicyRuleTriggerType trigger : rule.getTrigger()) { + if (!(trigger instanceof EvaluatedExclusionTriggerType)) { + continue; + } + EvaluatedExclusionTriggerType exclusionTrigger = (EvaluatedExclusionTriggerType) trigger; + ObjectReferenceType conflicting = exclusionTrigger.getConflictingObjectRef(); + if (conflicting == null) { + continue; + } + if (conflicting.getTargetName() != null) { + exclusions.add(conflicting.getTargetName().getOrig()); + } else { + exclusions.add(conflicting.getOid()); // TODO try to resolve? + } } } return StringUtils.join(exclusions, ", "); diff --git a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestSoDCertification.java b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestSoDCertification.java index e81f15618e0..073bfcab529 100644 --- a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestSoDCertification.java +++ b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestSoDCertification.java @@ -128,23 +128,25 @@ public void test001Triggers() throws Exception { private void assertPacked(AssignmentType assignment, int exclusionExpected, int situationExpected) { int exclusion = 0, situation = 0; - for (EvaluatedPolicyRuleTriggerType trigger : assignment.getTrigger()) { - assertNotNull("Identifier not null in base trigger: " + trigger, trigger.getTriggerId()); - if (trigger instanceof EvaluatedSituationTriggerType) { - EvaluatedSituationTriggerType situationTrigger = (EvaluatedSituationTriggerType) trigger; - int sourceTriggers = 0; - for (EvaluatedPolicyRuleType sourceRule : situationTrigger.getSourceRule()) { - for (EvaluatedPolicyRuleTriggerType sourceTrigger : sourceRule.getTrigger()) { - sourceTriggers++; - assertNotNull("Ref not null in situation source trigger: " + sourceTrigger, sourceTrigger.getRef()); + for (EvaluatedPolicyRuleType rule : assignment.getTriggeredPolicyRule()) { + for (EvaluatedPolicyRuleTriggerType trigger : rule.getTrigger()) { + assertNotNull("Identifier not null in base trigger: " + trigger, trigger.getTriggerId()); + if (trigger instanceof EvaluatedSituationTriggerType) { + EvaluatedSituationTriggerType situationTrigger = (EvaluatedSituationTriggerType) trigger; + int sourceTriggers = 0; + for (EvaluatedPolicyRuleType sourceRule : situationTrigger.getSourceRule()) { + for (EvaluatedPolicyRuleTriggerType sourceTrigger : sourceRule.getTrigger()) { + sourceTriggers++; + assertNotNull("Ref not null in situation source trigger: " + sourceTrigger, sourceTrigger.getRef()); + } } + assertEquals("Wrong # of exclusion triggers in situation trigger", exclusionExpected, sourceTriggers); + situation++; + } else if (trigger instanceof EvaluatedExclusionTriggerType) { + exclusion++; + } else { + fail("Unexpected trigger: " + trigger); } - assertEquals("Wrong # of exclusion triggers in situation trigger", exclusionExpected, sourceTriggers); - situation++; - } else if (trigger instanceof EvaluatedExclusionTriggerType) { - exclusion++; - } else { - fail("Unexpected trigger: " + trigger); } } assertEquals("Wrong # of exclusion triggers", exclusionExpected, exclusion); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java index 2d54d66706c..cd679cbff0a 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java @@ -1428,6 +1428,7 @@ private void authorizeAssignmentRequ assignActionUrl.substring(assignActionUrl.lastIndexOf('#') + 1)); } securityEnforcer.failAuthorization("with assignment", getRequestAuthorizationPhase(context), object, null, null, result); + assert false; // just to keep static checkers happy } // We do not worry about performance here too much. The target was already evaluated. This will be retrieved from repo cache anyway. PrismObject target = objectResolver.resolve(targetRef.asReferenceValue(), "resolving assignment target", task, result); From fbfcea081aa7bfe8a10e76644ca80fa493171011 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 25 Sep 2017 15:31:49 +0200 Subject: [PATCH 60/97] Migrating TestSoDCertification --- .../certification/test/TestSoDCertification.java | 16 ++++++++-------- .../resources/common/system-configuration.xml | 1 + .../src/test/resources/sod/a-test-2a.xml | 2 ++ .../src/test/resources/sod/a-test-2b.xml | 2 ++ .../src/test/resources/sod/a-test-2c.xml | 2 ++ .../src/test/resources/sod/a-test-3x.xml | 1 + .../src/test/resources/sod/a-test-3y.xml | 1 + 7 files changed, 17 insertions(+), 8 deletions(-) diff --git a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestSoDCertification.java b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestSoDCertification.java index 073bfcab529..582b87d6791 100644 --- a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestSoDCertification.java +++ b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestSoDCertification.java @@ -111,33 +111,33 @@ public void test001Triggers() throws Exception { // THEN AssignmentType a2a = findAssignmentByTargetRequired(jack, roleATest2aOid); display("assignment 2a", a2a); - assertPacked(a2a, 2, 1); + assertTriggers(a2a, 2, 1); AssignmentType a2b = findAssignmentByTargetRequired(jack, roleATest2bOid); display("assignment 2b", a2b); - assertPacked(a2b, 2, 1); + assertTriggers(a2b, 2, 1); AssignmentType a2c = findAssignmentByTargetRequired(jack, roleATest2cOid); display("assignment 2c", a2c); - assertPacked(a2c, 2, 1); + assertTriggers(a2c, 2, 1); AssignmentType a3a = findAssignmentByTargetRequired(jack, roleATest3aOid); display("assignment 3a", a3a); - assertPacked(a3a, 1, 1); + assertTriggers(a3a, 1, 1); AssignmentType a3b = findAssignmentByTargetRequired(jack, roleATest3bOid); display("assignment 3b", a3b); - assertPacked(a3b, 1, 1); + assertTriggers(a3b, 1, 1); } - private void assertPacked(AssignmentType assignment, int exclusionExpected, int situationExpected) { + private void assertTriggers(AssignmentType assignment, int exclusionExpected, int situationExpected) { int exclusion = 0, situation = 0; for (EvaluatedPolicyRuleType rule : assignment.getTriggeredPolicyRule()) { for (EvaluatedPolicyRuleTriggerType trigger : rule.getTrigger()) { - assertNotNull("Identifier not null in base trigger: " + trigger, trigger.getTriggerId()); + //assertNotNull("Identifier not null in base trigger: " + trigger, trigger.getTriggerId()); if (trigger instanceof EvaluatedSituationTriggerType) { EvaluatedSituationTriggerType situationTrigger = (EvaluatedSituationTriggerType) trigger; int sourceTriggers = 0; for (EvaluatedPolicyRuleType sourceRule : situationTrigger.getSourceRule()) { for (EvaluatedPolicyRuleTriggerType sourceTrigger : sourceRule.getTrigger()) { sourceTriggers++; - assertNotNull("Ref not null in situation source trigger: " + sourceTrigger, sourceTrigger.getRef()); + //assertNotNull("Ref not null in situation source trigger: " + sourceTrigger, sourceTrigger.getRef()); } } assertEquals("Wrong # of exclusion triggers in situation trigger", exclusionExpected, sourceTriggers); diff --git a/model/certification-impl/src/test/resources/common/system-configuration.xml b/model/certification-impl/src/test/resources/common/system-configuration.xml index c2d374ee66e..d5ecbe90516 100644 --- a/model/certification-impl/src/test/resources/common/system-configuration.xml +++ b/model/certification-impl/src/test/resources/common/system-configuration.xml @@ -53,6 +53,7 @@ + diff --git a/model/certification-impl/src/test/resources/sod/a-test-2a.xml b/model/certification-impl/src/test/resources/sod/a-test-2a.xml index f7d38b463a4..9c9fdb325e0 100644 --- a/model/certification-impl/src/test/resources/sod/a-test-2a.xml +++ b/model/certification-impl/src/test/resources/sod/a-test-2a.xml @@ -28,6 +28,7 @@ + @@ -39,6 +40,7 @@ + diff --git a/model/certification-impl/src/test/resources/sod/a-test-2b.xml b/model/certification-impl/src/test/resources/sod/a-test-2b.xml index 0410d03a913..93a12df6277 100644 --- a/model/certification-impl/src/test/resources/sod/a-test-2b.xml +++ b/model/certification-impl/src/test/resources/sod/a-test-2b.xml @@ -28,6 +28,7 @@ + @@ -39,6 +40,7 @@ + diff --git a/model/certification-impl/src/test/resources/sod/a-test-2c.xml b/model/certification-impl/src/test/resources/sod/a-test-2c.xml index 3a8b9d59679..9d3585debc6 100644 --- a/model/certification-impl/src/test/resources/sod/a-test-2c.xml +++ b/model/certification-impl/src/test/resources/sod/a-test-2c.xml @@ -28,6 +28,7 @@ + @@ -39,6 +40,7 @@ + diff --git a/model/certification-impl/src/test/resources/sod/a-test-3x.xml b/model/certification-impl/src/test/resources/sod/a-test-3x.xml index cc4229f71d3..72a34577f2c 100644 --- a/model/certification-impl/src/test/resources/sod/a-test-3x.xml +++ b/model/certification-impl/src/test/resources/sod/a-test-3x.xml @@ -28,6 +28,7 @@ + diff --git a/model/certification-impl/src/test/resources/sod/a-test-3y.xml b/model/certification-impl/src/test/resources/sod/a-test-3y.xml index e0168ef0670..fa582b7db0d 100644 --- a/model/certification-impl/src/test/resources/sod/a-test-3y.xml +++ b/model/certification-impl/src/test/resources/sod/a-test-3y.xml @@ -28,6 +28,7 @@ + From 8175271056b0aeab291e98993ef2e6e7eb2a168f Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 26 Sep 2017 09:17:17 +0200 Subject: [PATCH 61/97] Minor improvements in handling of indirectly present exclusion triggers. --- .../dto/CertCaseOrWorkItemDto.java | 28 +- .../schema/util/PolicyRuleTypeUtil.java | 28 ++ .../test/TestSoDCertification.java | 8 +- .../src/test/resources/sod/a-test-2a.xml | 6 - .../src/test/resources/sod/a-test-2b.xml | 6 - .../src/test/resources/sod/a-test-2c.xml | 6 - .../src/test/resources/sod/a-test-3x.xml | 3 - .../src/test/resources/sod/a-test-3y.xml | 3 - .../midpoint/model/impl/lens/Clockwork.java | 2 +- .../model/impl/lens/TestPolicyState.java | 158 ----------- .../impl/lens/TestPolicyStateRecording.java | 259 ++++++++++++++++++ .../resources/lens/policy/state/a-test-2a.xml | 44 +++ .../resources/lens/policy/state/a-test-2b.xml | 44 +++ .../resources/lens/policy/state/a-test-2c.xml | 44 +++ .../resources/lens/policy/state/a-test-3a.xml | 29 ++ .../resources/lens/policy/state/a-test-3b.xml | 29 ++ .../resources/lens/policy/state/a-test-3x.xml | 35 +++ .../resources/lens/policy/state/a-test-3y.xml | 35 +++ .../policy/state/metarole-common-rules.xml | 34 +++ .../resources/lens/policy/state/user-bob.xml | 23 ++ model/model-impl/testng-unit.xml | 2 +- 21 files changed, 626 insertions(+), 200 deletions(-) delete mode 100644 model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyState.java create mode 100644 model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java create mode 100644 model/model-impl/src/test/resources/lens/policy/state/a-test-2a.xml create mode 100644 model/model-impl/src/test/resources/lens/policy/state/a-test-2b.xml create mode 100644 model/model-impl/src/test/resources/lens/policy/state/a-test-2c.xml create mode 100644 model/model-impl/src/test/resources/lens/policy/state/a-test-3a.xml create mode 100644 model/model-impl/src/test/resources/lens/policy/state/a-test-3b.xml create mode 100644 model/model-impl/src/test/resources/lens/policy/state/a-test-3x.xml create mode 100644 model/model-impl/src/test/resources/lens/policy/state/a-test-3y.xml create mode 100644 model/model-impl/src/test/resources/lens/policy/state/metarole-common-rules.xml create mode 100644 model/model-impl/src/test/resources/lens/policy/state/user-bob.xml diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertCaseOrWorkItemDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertCaseOrWorkItemDto.java index 45e1fd239f3..55e148c43d3 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertCaseOrWorkItemDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertCaseOrWorkItemDto.java @@ -20,6 +20,7 @@ import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.schema.util.CertCampaignTypeUtil; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; +import com.evolveum.midpoint.schema.util.PolicyRuleTypeUtil; import com.evolveum.midpoint.web.component.util.Selectable; import com.evolveum.midpoint.web.page.admin.certification.CertDecisionHelper; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; @@ -208,21 +209,18 @@ public String getConflictingTargets() { return ""; } Set exclusions = new TreeSet<>(); - for (EvaluatedPolicyRuleType rule : assignmentCase.getAssignment().getTriggeredPolicyRule()) { - for (EvaluatedPolicyRuleTriggerType trigger : rule.getTrigger()) { - if (!(trigger instanceof EvaluatedExclusionTriggerType)) { - continue; - } - EvaluatedExclusionTriggerType exclusionTrigger = (EvaluatedExclusionTriggerType) trigger; - ObjectReferenceType conflicting = exclusionTrigger.getConflictingObjectRef(); - if (conflicting == null) { - continue; - } - if (conflicting.getTargetName() != null) { - exclusions.add(conflicting.getTargetName().getOrig()); - } else { - exclusions.add(conflicting.getOid()); // TODO try to resolve? - } + List allExclusionTriggers = PolicyRuleTypeUtil + .getAllExclusionTriggers(assignmentCase.getAssignment().getTriggeredPolicyRule()); + + for (EvaluatedExclusionTriggerType trigger : allExclusionTriggers) { + ObjectReferenceType conflicting = trigger.getConflictingObjectRef(); + if (conflicting == null) { + continue; + } + if (conflicting.getTargetName() != null) { + exclusions.add(conflicting.getTargetName().getOrig()); + } else { + exclusions.add(conflicting.getOid()); // TODO try to resolve? } } return StringUtils.join(exclusions, ", "); diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/PolicyRuleTypeUtil.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/PolicyRuleTypeUtil.java index 9bf9fe5bebd..7f182da81c4 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/PolicyRuleTypeUtil.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/PolicyRuleTypeUtil.java @@ -633,4 +633,32 @@ private static Supplier getAllExclusionTriggers(List rules) { + List rv = new ArrayList<>(); + getExclusionTriggersFromRules(rv, rules); + return rv; + } + + private static void getExclusionTriggersFromRules(List rv, List rules) { + for (EvaluatedPolicyRuleType rule : rules) { + getExclusionTriggersFromRule(rv, rule); + } + } + + private static void getExclusionTriggersFromRule(List rv, EvaluatedPolicyRuleType rule) { + getExclusionTriggersFromTriggers(rv, rule.getTrigger()); + } + + private static void getExclusionTriggersFromTriggers(List rv, List triggers) { + for (EvaluatedPolicyRuleTriggerType trigger : triggers) { + if (trigger instanceof EvaluatedExclusionTriggerType) { + rv.add((EvaluatedExclusionTriggerType) trigger); + } else if (trigger instanceof EvaluatedEmbeddingTriggerType) { + getExclusionTriggersFromTriggers(rv, ((EvaluatedEmbeddingTriggerType) trigger).getEmbedded()); + } else if (trigger instanceof EvaluatedSituationTriggerType) { + getExclusionTriggersFromRules(rv, ((EvaluatedSituationTriggerType) trigger).getSourceRule()); + } + } + } } diff --git a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestSoDCertification.java b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestSoDCertification.java index 582b87d6791..b7eb388b72d 100644 --- a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestSoDCertification.java +++ b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestSoDCertification.java @@ -22,6 +22,7 @@ import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.CertCampaignTypeUtil; +import com.evolveum.midpoint.schema.util.PolicyRuleTypeUtil; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.test.util.TestUtil; import com.evolveum.midpoint.util.DebugUtil; @@ -149,8 +150,13 @@ private void assertTriggers(AssignmentType assignment, int exclusionExpected, in } } } - assertEquals("Wrong # of exclusion triggers", exclusionExpected, exclusion); + assertEquals("Wrong # of exclusion triggers", 0, exclusion); assertEquals("Wrong # of situation triggers", situationExpected, situation); + + List exclusionTriggers = PolicyRuleTypeUtil + .getAllExclusionTriggers(assignment.getTriggeredPolicyRule()); + display("Exclusion triggers for " + assignment, exclusionTriggers); + assertEquals("Wrong # of extracted exclusion triggers", exclusionExpected, exclusionTriggers.size()); } @Test diff --git a/model/certification-impl/src/test/resources/sod/a-test-2a.xml b/model/certification-impl/src/test/resources/sod/a-test-2a.xml index 9c9fdb325e0..b04d20ed5b8 100644 --- a/model/certification-impl/src/test/resources/sod/a-test-2a.xml +++ b/model/certification-impl/src/test/resources/sod/a-test-2a.xml @@ -27,9 +27,6 @@ - - - @@ -39,9 +36,6 @@ - - - diff --git a/model/certification-impl/src/test/resources/sod/a-test-2b.xml b/model/certification-impl/src/test/resources/sod/a-test-2b.xml index 93a12df6277..cf2b61f704a 100644 --- a/model/certification-impl/src/test/resources/sod/a-test-2b.xml +++ b/model/certification-impl/src/test/resources/sod/a-test-2b.xml @@ -27,9 +27,6 @@ - - - @@ -39,9 +36,6 @@ - - - \ No newline at end of file diff --git a/model/certification-impl/src/test/resources/sod/a-test-2c.xml b/model/certification-impl/src/test/resources/sod/a-test-2c.xml index 9d3585debc6..345cf283f3a 100644 --- a/model/certification-impl/src/test/resources/sod/a-test-2c.xml +++ b/model/certification-impl/src/test/resources/sod/a-test-2c.xml @@ -27,9 +27,6 @@ - - - @@ -39,9 +36,6 @@ - - - \ No newline at end of file diff --git a/model/certification-impl/src/test/resources/sod/a-test-3x.xml b/model/certification-impl/src/test/resources/sod/a-test-3x.xml index 72a34577f2c..33d7e2f8eb3 100644 --- a/model/certification-impl/src/test/resources/sod/a-test-3x.xml +++ b/model/certification-impl/src/test/resources/sod/a-test-3x.xml @@ -27,9 +27,6 @@ - - - \ No newline at end of file diff --git a/model/certification-impl/src/test/resources/sod/a-test-3y.xml b/model/certification-impl/src/test/resources/sod/a-test-3y.xml index fa582b7db0d..ca73b1e7c6d 100644 --- a/model/certification-impl/src/test/resources/sod/a-test-3y.xml +++ b/model/certification-impl/src/test/resources/sod/a-test-3y.xml @@ -27,9 +27,6 @@ - - - \ No newline at end of file diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java index cd679cbff0a..0c17da9269e 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java @@ -1434,7 +1434,7 @@ private void authorizeAssignmentRequ PrismObject target = objectResolver.resolve(targetRef.asReferenceValue(), "resolving assignment target", task, result); if (prohibitPolicies) { - if (changedAssignment.getPolicyRule() != null || !changedAssignment.getPolicyException().isEmpty() || !changedAssignment.getPolicySituation().isEmpty()) { + if (changedAssignment.getPolicyRule() != null || !changedAssignment.getPolicyException().isEmpty() || !changedAssignment.getPolicySituation().isEmpty() || !changedAssignment.getTriggeredPolicyRule().isEmpty()) { securityEnforcer.failAuthorization("with assignment because of policies in the assignment", getRequestAuthorizationPhase(context), object, null, target, result); } } diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyState.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyState.java deleted file mode 100644 index b5fbff1586d..00000000000 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyState.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2010-2017 Evolveum - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.evolveum.midpoint.model.impl.lens; - -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.schema.constants.SchemaConstants; -import com.evolveum.midpoint.schema.internals.InternalMonitor; -import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.task.api.Task; -import com.evolveum.midpoint.test.util.TestUtil; -import com.evolveum.midpoint.util.DebugUtil; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentPolicyEnforcementType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.annotation.DirtiesContext.ClassMode; -import org.springframework.test.context.ContextConfiguration; -import org.testng.annotations.Test; - -import java.util.Collections; - -import static com.evolveum.midpoint.test.IntegrationTestTools.display; -import static org.testng.AssertJUnit.assertEquals; - -/** - * Tests recording of policy situations into objects and assignments. - * - * @author mederly - * - */ -@ContextConfiguration(locations = {"classpath:ctx-model-test-main.xml"}) -@DirtiesContext(classMode = ClassMode.AFTER_CLASS) -public class TestPolicyState extends AbstractLensTest { - - private static final String ROLE_JUDGE_POLICY_RULE_EXCLUSION_NAME = "criminal exclusion"; - - @Override - public void initSystem(Task initTask, OperationResult initResult) throws Exception { - super.initSystem(initTask, initResult); - setDefaultUserTemplate(USER_TEMPLATE_OID); - - addObject(ROLE_PIRATE_SITUATION_ONLY_FILE); - addObject(ROLE_MUTINIER_FILE); - addObject(ROLE_JUDGE_SITUATION_ONLY_FILE); - addObject(ROLE_CONSTABLE_FILE); - addObject(ROLE_THIEF_FILE); - - addObjects(ROLE_CORP_FILES); - - assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); - - InternalMonitor.reset(); - - DebugUtil.setPrettyPrintBeansAs(PrismContext.LANG_YAML); - } - - @Test - public void test100JackAssignRoleJudge() throws Exception { - final String TEST_NAME = "test100JackAssignRoleJudge"; - TestUtil.displayTestTitle(this, TEST_NAME); - - // GIVEN - Task task = taskManager.createTaskInstance(TestPolicyState.class.getName() + "." + TEST_NAME); - OperationResult result = task.getResult(); - - // WHEN - TestUtil.displayWhen(TEST_NAME); - assignRole(USER_JACK_OID, ROLE_JUDGE_OID, task, result); - - // THEN - TestUtil.displayThen(TEST_NAME); - UserType jack = getUser(USER_JACK_OID).asObjectable(); - display("jack", jack); - result.computeStatus(); - TestUtil.assertSuccess(result); - - assertAssignedRole(USER_JACK_OID, ROLE_JUDGE_OID, task, result); - assertEquals("Wrong # of assignments", 1, jack.getAssignment().size()); - assertEquals("Wrong policy situations", - Collections.emptyList(), - jack.getAssignment().get(0).getPolicySituation()); - } - - @Test - public void test110JackAssignRolePirate() throws Exception { - final String TEST_NAME = "test110JackAssignRolePirate"; - TestUtil.displayTestTitle(this, TEST_NAME); - - // GIVEN - Task task = taskManager.createTaskInstance(TestPolicyState.class.getName() + "." + TEST_NAME); - OperationResult result = task.getResult(); - - // WHEN - TestUtil.displayWhen(TEST_NAME); - assignRole(USER_JACK_OID, ROLE_PIRATE_OID, task, result); - - // THEN - TestUtil.displayThen(TEST_NAME); - UserType jack = getUser(USER_JACK_OID).asObjectable(); - display("jack", jack); - result.computeStatus(); - TestUtil.assertSuccess(result); - - assertAssignedRole(USER_JACK_OID, ROLE_PIRATE_OID, task, result); - assertEquals("Wrong # of assignments", 2, jack.getAssignment().size()); - for (AssignmentType assignment : jack.getAssignment()) { - assertEquals("Wrong policy situations", - Collections.singletonList(SchemaConstants.MODEL_POLICY_SITUATION_EXCLUSION_VIOLATION), - assignment.getPolicySituation()); - } - } - - // should keep the situation for both assignments - @Test - public void test120RecomputeJack() throws Exception { - final String TEST_NAME = "test120RecomputeJack"; - TestUtil.displayTestTitle(this, TEST_NAME); - - // GIVEN - Task task = taskManager.createTaskInstance(TestPolicyState.class.getName() + "." + TEST_NAME); - OperationResult result = task.getResult(); - - // WHEN - TestUtil.displayWhen(TEST_NAME); - recomputeUser(USER_JACK_OID, task, result); - - // THEN - TestUtil.displayThen(TEST_NAME); - UserType jack = getUser(USER_JACK_OID).asObjectable(); - display("jack", jack); - result.computeStatus(); - TestUtil.assertSuccess(result); - - assertEquals("Wrong # of assignments", 2, jack.getAssignment().size()); - for (AssignmentType assignment : jack.getAssignment()) { - assertEquals("Wrong policy situations", - Collections.singletonList(SchemaConstants.MODEL_POLICY_SITUATION_EXCLUSION_VIOLATION), - assignment.getPolicySituation()); - } - } - - - - -} diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java new file mode 100644 index 00000000000..062fddae56b --- /dev/null +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.model.impl.lens; + +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder; +import com.evolveum.midpoint.schema.constants.ObjectTypes; +import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.schema.internals.InternalMonitor; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.test.util.TestUtil; +import com.evolveum.midpoint.util.DebugUtil; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentPolicyEnforcementType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.context.ContextConfiguration; +import org.testng.annotations.Test; + +import java.io.File; +import java.util.Collections; + +import static com.evolveum.midpoint.schema.util.ObjectTypeUtil.createAssignmentTo; +import static org.testng.AssertJUnit.assertEquals; + +/** + * Tests recording of policy situations into objects and assignments. + * + * @author mederly + * + */ +@ContextConfiguration(locations = {"classpath:ctx-model-test-main.xml"}) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) +public class TestPolicyStateRecording extends AbstractLensTest { + + private static final String ROLE_JUDGE_POLICY_RULE_EXCLUSION_NAME = "criminal exclusion"; + + protected static final File TEST_DIR = new File(AbstractLensTest.TEST_DIR, "policy/state"); + + private static final File USER_BOB_FILE = new File(TEST_DIR, "user-bob.xml"); + private static String userBobOid; + private static final File ROLE_A_TEST_2A_FILE = new File(TEST_DIR, "a-test-2a.xml"); + private static String roleATest2aOid; + private static final File ROLE_A_TEST_2B_FILE = new File(TEST_DIR, "a-test-2b.xml"); + private static String roleATest2bOid; + private static final File ROLE_A_TEST_2C_FILE = new File(TEST_DIR, "a-test-2c.xml"); + private static String roleATest2cOid; + private static final File ROLE_A_TEST_3A_FILE = new File(TEST_DIR, "a-test-3a.xml"); + private static String roleATest3aOid; + private static final File ROLE_A_TEST_3B_FILE = new File(TEST_DIR, "a-test-3b.xml"); + private static String roleATest3bOid; + private static final File ROLE_A_TEST_3X_FILE = new File(TEST_DIR, "a-test-3x.xml"); + private static String roleATest3xOid; + private static final File ROLE_A_TEST_3Y_FILE = new File(TEST_DIR, "a-test-3y.xml"); + private static String roleATest3yOid; + private static final File METAROLE_COMMON_RULES_FILE = new File(TEST_DIR, "metarole-common-rules.xml"); + private static String metaroleCommonRulesOid; + + @Override + public void initSystem(Task initTask, OperationResult initResult) throws Exception { + super.initSystem(initTask, initResult); + setDefaultUserTemplate(USER_TEMPLATE_OID); + + addObject(ROLE_PIRATE_SITUATION_ONLY_FILE); + addObject(ROLE_JUDGE_SITUATION_ONLY_FILE); + + assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); + + metaroleCommonRulesOid = addAndRecompute(METAROLE_COMMON_RULES_FILE, initTask, initResult); + roleATest2aOid = addAndRecompute(ROLE_A_TEST_2A_FILE, initTask, initResult); + roleATest2bOid = addAndRecompute(ROLE_A_TEST_2B_FILE, initTask, initResult); + roleATest2cOid = addAndRecompute(ROLE_A_TEST_2C_FILE, initTask, initResult); + roleATest3xOid = addAndRecompute(ROLE_A_TEST_3X_FILE, initTask, initResult); + roleATest3yOid = addAndRecompute(ROLE_A_TEST_3Y_FILE, initTask, initResult); + roleATest3aOid = addAndRecompute(ROLE_A_TEST_3A_FILE, initTask, initResult); + roleATest3bOid = addAndRecompute(ROLE_A_TEST_3B_FILE, initTask, initResult); + + userBobOid = addAndRecompute(USER_BOB_FILE, initTask, initResult); + + InternalMonitor.reset(); + + DebugUtil.setPrettyPrintBeansAs(PrismContext.LANG_YAML); + } + + @Test + public void test100JackAssignRoleJudge() throws Exception { + final String TEST_NAME = "test100JackAssignRoleJudge"; + TestUtil.displayTestTitle(this, TEST_NAME); + + // GIVEN + Task task = taskManager.createTaskInstance(TestPolicyStateRecording.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + assignRole(USER_JACK_OID, ROLE_JUDGE_OID, task, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + UserType jack = getUser(USER_JACK_OID).asObjectable(); + display("jack", jack); + result.computeStatus(); + TestUtil.assertSuccess(result); + + assertAssignedRole(USER_JACK_OID, ROLE_JUDGE_OID, task, result); + assertEquals("Wrong # of assignments", 1, jack.getAssignment().size()); + assertEquals("Wrong policy situations", + Collections.emptyList(), + jack.getAssignment().get(0).getPolicySituation()); + } + + @Test + public void test110JackAssignRolePirate() throws Exception { + final String TEST_NAME = "test110JackAssignRolePirate"; + TestUtil.displayTestTitle(this, TEST_NAME); + + // GIVEN + Task task = taskManager.createTaskInstance(TestPolicyStateRecording.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + assignRole(USER_JACK_OID, ROLE_PIRATE_OID, task, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + UserType jack = getUser(USER_JACK_OID).asObjectable(); + display("jack", jack); + result.computeStatus(); + TestUtil.assertSuccess(result); + + assertAssignedRole(USER_JACK_OID, ROLE_PIRATE_OID, task, result); + assertEquals("Wrong # of assignments", 2, jack.getAssignment().size()); + for (AssignmentType assignment : jack.getAssignment()) { + assertEquals("Wrong policy situations", + Collections.singletonList(SchemaConstants.MODEL_POLICY_SITUATION_EXCLUSION_VIOLATION), + assignment.getPolicySituation()); + } + } + + // should keep the situation for both assignments + @Test + public void test120RecomputeJack() throws Exception { + final String TEST_NAME = "test120RecomputeJack"; + TestUtil.displayTestTitle(this, TEST_NAME); + + // GIVEN + Task task = taskManager.createTaskInstance(TestPolicyStateRecording.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + recomputeUser(USER_JACK_OID, task, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + UserType jack = getUser(USER_JACK_OID).asObjectable(); + display("jack", jack); + result.computeStatus(); + TestUtil.assertSuccess(result); + + // TODO test that assignment IDs are filled in correctly (currently they are not) + assertEquals("Wrong # of assignments", 2, jack.getAssignment().size()); + for (AssignmentType assignment : jack.getAssignment()) { + assertEquals("Wrong policy situations", + Collections.singletonList(SchemaConstants.MODEL_POLICY_SITUATION_EXCLUSION_VIOLATION), + assignment.getPolicySituation()); + } + } + + @Test + public void test200BobAssign2a3a() throws Exception { + final String TEST_NAME = "test200BobAssign2a3a"; + TestUtil.displayTestTitle(this, TEST_NAME); + + // GIVEN + Task task = taskManager.createTaskInstance(TestPolicyStateRecording.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + ObjectDelta delta = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT) + .add(createAssignmentTo(roleATest2aOid, ObjectTypes.ROLE, prismContext), + createAssignmentTo(roleATest3aOid, ObjectTypes.ROLE, prismContext)) + .asObjectDeltaCast(userBobOid); + executeChangesAssertSuccess(delta, null, task, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + UserType bob = getUser(userBobOid).asObjectable(); + display("bob", bob); + result.computeStatus(); + TestUtil.assertSuccess(result); + + assertAssignedRole(userBobOid, roleATest2aOid, task, result); + assertAssignedRole(userBobOid, roleATest3aOid, task, result); + assertEquals("Wrong # of assignments", 2, bob.getAssignment().size()); + assertEquals("Wrong policy situations for assignment 1", + Collections.emptyList(), + bob.getAssignment().get(0).getPolicySituation()); + assertEquals("Wrong policy situations for assignment 2", + Collections.emptyList(), + bob.getAssignment().get(1).getPolicySituation()); + } + + @Test + public void test200BobAssign2b3b() throws Exception { + final String TEST_NAME = "test200BobAssign2b3b"; + TestUtil.displayTestTitle(this, TEST_NAME); + + // GIVEN + Task task = taskManager.createTaskInstance(TestPolicyStateRecording.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + ObjectDelta delta = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT) + .add(createAssignmentTo(roleATest2bOid, ObjectTypes.ROLE, prismContext), + createAssignmentTo(roleATest3bOid, ObjectTypes.ROLE, prismContext)) + .asObjectDeltaCast(userBobOid); + executeChangesAssertSuccess(delta, null, task, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + UserType bob = getUser(userBobOid).asObjectable(); + display("bob", bob); + result.computeStatus(); + TestUtil.assertSuccess(result); + + assertAssignedRole(userBobOid, roleATest2aOid, task, result); + assertAssignedRole(userBobOid, roleATest2bOid, task, result); + assertAssignedRole(userBobOid, roleATest3aOid, task, result); + assertAssignedRole(userBobOid, roleATest3bOid, task, result); + assertEquals("Wrong # of assignments", 4, bob.getAssignment().size()); + + // TODO policy state + } + + + +} diff --git a/model/model-impl/src/test/resources/lens/policy/state/a-test-2a.xml b/model/model-impl/src/test/resources/lens/policy/state/a-test-2a.xml new file mode 100644 index 00000000000..4890bdcca79 --- /dev/null +++ b/model/model-impl/src/test/resources/lens/policy/state/a-test-2a.xml @@ -0,0 +1,44 @@ + + + + a-test-2a + Exclusive with test-2b/2c + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/model/model-impl/src/test/resources/lens/policy/state/a-test-2b.xml b/model/model-impl/src/test/resources/lens/policy/state/a-test-2b.xml new file mode 100644 index 00000000000..7d810e87a69 --- /dev/null +++ b/model/model-impl/src/test/resources/lens/policy/state/a-test-2b.xml @@ -0,0 +1,44 @@ + + + + a-test-2b + Exclusive with test-2a/2c + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/model/model-impl/src/test/resources/lens/policy/state/a-test-2c.xml b/model/model-impl/src/test/resources/lens/policy/state/a-test-2c.xml new file mode 100644 index 00000000000..740b763c6cd --- /dev/null +++ b/model/model-impl/src/test/resources/lens/policy/state/a-test-2c.xml @@ -0,0 +1,44 @@ + + + + a-test-2c + Exclusive with test-2a/2b + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/model/model-impl/src/test/resources/lens/policy/state/a-test-3a.xml b/model/model-impl/src/test/resources/lens/policy/state/a-test-3a.xml new file mode 100644 index 00000000000..fac95988ee0 --- /dev/null +++ b/model/model-impl/src/test/resources/lens/policy/state/a-test-3a.xml @@ -0,0 +1,29 @@ + + + + a-test-3a + Testing SoD with induced role (test-3x) + + + + + + + \ No newline at end of file diff --git a/model/model-impl/src/test/resources/lens/policy/state/a-test-3b.xml b/model/model-impl/src/test/resources/lens/policy/state/a-test-3b.xml new file mode 100644 index 00000000000..9dea26df089 --- /dev/null +++ b/model/model-impl/src/test/resources/lens/policy/state/a-test-3b.xml @@ -0,0 +1,29 @@ + + + + a-test-3b + Testing SoD with induced role (test-3y) + + + + + + + \ No newline at end of file diff --git a/model/model-impl/src/test/resources/lens/policy/state/a-test-3x.xml b/model/model-impl/src/test/resources/lens/policy/state/a-test-3x.xml new file mode 100644 index 00000000000..26a15f21532 --- /dev/null +++ b/model/model-impl/src/test/resources/lens/policy/state/a-test-3x.xml @@ -0,0 +1,35 @@ + + + + a-test-3x + Embedded role, conflicting with 3y + + + + + + + + + + + + + \ No newline at end of file diff --git a/model/model-impl/src/test/resources/lens/policy/state/a-test-3y.xml b/model/model-impl/src/test/resources/lens/policy/state/a-test-3y.xml new file mode 100644 index 00000000000..f7bce8db1d0 --- /dev/null +++ b/model/model-impl/src/test/resources/lens/policy/state/a-test-3y.xml @@ -0,0 +1,35 @@ + + + + a-test-3y + Embedded role, conflicting with 3x + + + + + + + + + + + + + \ No newline at end of file diff --git a/model/model-impl/src/test/resources/lens/policy/state/metarole-common-rules.xml b/model/model-impl/src/test/resources/lens/policy/state/metarole-common-rules.xml new file mode 100644 index 00000000000..1bf5c1f09b2 --- /dev/null +++ b/model/model-impl/src/test/resources/lens/policy/state/metarole-common-rules.xml @@ -0,0 +1,34 @@ + + + + common-rules + + + + + http://midpoint.evolveum.com/xml/ns/public/model/policy/situation#exclusionViolation + + + + + + + + \ No newline at end of file diff --git a/model/model-impl/src/test/resources/lens/policy/state/user-bob.xml b/model/model-impl/src/test/resources/lens/policy/state/user-bob.xml new file mode 100644 index 00000000000..1fb0475364f --- /dev/null +++ b/model/model-impl/src/test/resources/lens/policy/state/user-bob.xml @@ -0,0 +1,23 @@ + + + + + bob + Bob + Bobovic + diff --git a/model/model-impl/testng-unit.xml b/model/model-impl/testng-unit.xml index b6c29d43ecc..90f316133bd 100644 --- a/model/model-impl/testng-unit.xml +++ b/model/model-impl/testng-unit.xml @@ -72,7 +72,7 @@ - + From aab94cd4c83174f4dddcf377ca9c3741c9d1a08e Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 26 Sep 2017 12:34:02 +0200 Subject: [PATCH 62/97] Fixed storing policy state. --- .../util/xml/DomAwareEqualsStrategy.java | 41 +++++++-- .../model/impl/lens/AssignmentSpec.java | 2 +- .../model/impl/lens/ChangeExecutor.java | 84 +++++++++---------- .../impl/lens/EvaluatedAssignmentImpl.java | 16 ++-- .../model/impl/lens/LensElementContext.java | 14 +++- .../projector/policy/PolicyStateUpdater.java | 5 +- .../model/impl/lens/AbstractLensTest.java | 4 +- .../impl/lens/TestPolicyStateRecording.java | 4 +- ...on-only.xml => role-judge-record-only.xml} | 0 ...n-only.xml => role-pirate-record-only.xml} | 0 10 files changed, 106 insertions(+), 64 deletions(-) rename model/model-impl/src/test/resources/lens/{role-judge-situation-only.xml => role-judge-record-only.xml} (100%) rename model/model-impl/src/test/resources/lens/{role-pirate-situation-only.xml => role-pirate-record-only.xml} (100%) diff --git a/infra/util/src/main/java/com/evolveum/midpoint/util/xml/DomAwareEqualsStrategy.java b/infra/util/src/main/java/com/evolveum/midpoint/util/xml/DomAwareEqualsStrategy.java index 45adb915377..358e6cb2a7a 100644 --- a/infra/util/src/main/java/com/evolveum/midpoint/util/xml/DomAwareEqualsStrategy.java +++ b/infra/util/src/main/java/com/evolveum/midpoint/util/xml/DomAwareEqualsStrategy.java @@ -15,7 +15,7 @@ */ package com.evolveum.midpoint.util.xml; -import org.jvnet.jaxb2_commons.lang.EqualsStrategy; +import com.evolveum.midpoint.util.PrettyPrinter; import org.jvnet.jaxb2_commons.lang.JAXBEqualsStrategy; import org.jvnet.jaxb2_commons.locator.ObjectLocator; import org.w3c.dom.Element; @@ -31,23 +31,48 @@ */ public class DomAwareEqualsStrategy extends JAXBEqualsStrategy { - public static EqualsStrategy INSTANCE = new DomAwareEqualsStrategy(); + public static DomAwareEqualsStrategy INSTANCE = new DomAwareEqualsStrategy(); + + private static final boolean ENABLE_BRUTAL_DEBUGGING = false; // keep false to avoid unnecessary code execution + private boolean traceAll = false; + private boolean traceNotEqual = false; + + public boolean isTraceAll() { + return traceAll; + } + + public void setTraceAll(boolean traceAll) { + this.traceAll = traceAll; + } + + public boolean isTraceNotEqual() { + return traceNotEqual; + } + + public void setTraceNotEqual(boolean traceNotEqual) { + this.traceNotEqual = traceNotEqual; + } @Override protected boolean equalsInternal(ObjectLocator leftLocator, ObjectLocator rightLocator, Object lhs, Object rhs) { -// System.out.println("DomAwareEqualsStrategy: "+PrettyPrinter.prettyPrint(lhs)+"<=>"+PrettyPrinter.prettyPrint(rhs)); + if (ENABLE_BRUTAL_DEBUGGING && traceAll) { + System.out.println("DomAwareEqualsStrategy: "+ PrettyPrinter.prettyPrint(lhs)+"<=>"+PrettyPrinter.prettyPrint(rhs)); + } + boolean result; if (lhs instanceof String && rhs instanceof String) { - return DOMUtil.compareTextNodeValues((String)lhs, (String)rhs); + result = DOMUtil.compareTextNodeValues((String)lhs, (String)rhs); } else if (lhs instanceof Element && rhs instanceof Element) { final Element left = (Element) lhs; final Element right = (Element) rhs; - boolean result = DOMUtil.compareElement(left, right, false); -// System.out.println("cmp: "+PrettyPrinter.prettyPrint(left)+"<=>"+PrettyPrinter.prettyPrint(right)+": "+result); - return result; + result = DOMUtil.compareElement(left, right, false); } else { - return super.equalsInternal(leftLocator, rightLocator, lhs, rhs); + result = super.equalsInternal(leftLocator, rightLocator, lhs, rhs); + } + if (ENABLE_BRUTAL_DEBUGGING && (traceAll || traceNotEqual && !result)) { + System.out.println("cmp: "+PrettyPrinter.prettyPrint(lhs)+"<=>"+PrettyPrinter.prettyPrint(rhs)+": "+result); } + return result; } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentSpec.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentSpec.java index 713c04f4d3e..b9e384541bd 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentSpec.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentSpec.java @@ -31,7 +31,7 @@ public class AssignmentSpec implements Serializable { @NotNull public final AssignmentType assignment; - @NotNull public final PlusMinusZero mode; + @NotNull public final PlusMinusZero mode; // regarding the current object state (not the old one) public AssignmentSpec(@NotNull AssignmentType assignment, @NotNull PlusMinusZero mode) { this.assignment = assignment; 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 64123a26558..4f146c66c70 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 @@ -148,7 +148,7 @@ public boolean executeChanges(LensContext context, Tas ObjectDelta focusDelta = focusContext.getWaveExecutableDelta(context.getExecutionWave()); focusDelta = applyPendingObjectPolicyStateModifications(focusContext, focusDelta); - applyPendingAssignmentPolicyStateModifications(focusContext, focusDelta); + focusDelta = applyPendingAssignmentPolicyStateModifications(focusContext, focusDelta); if (focusDelta != null) { @@ -375,57 +375,57 @@ private ObjectDelta applyPendingObjectPolicyStateModif return focusDelta; } - private void applyPendingAssignmentPolicyStateModifications(LensFocusContext focusContext, ObjectDelta focusDelta) + private ObjectDelta applyPendingAssignmentPolicyStateModifications(LensFocusContext focusContext, ObjectDelta focusDelta) throws SchemaException { - if (focusDelta != null) { - for (Map.Entry>> entry : focusContext - .getPendingAssignmentPolicyStateModifications().entrySet()) { - PlusMinusZero mode = entry.getKey().mode; - if (mode == PlusMinusZero.MINUS) { - continue; // this assignment is being thrown out anyway, so let's ignore it + for (Map.Entry>> entry : focusContext + .getPendingAssignmentPolicyStateModifications().entrySet()) { + PlusMinusZero mode = entry.getKey().mode; + if (mode == PlusMinusZero.MINUS) { + continue; // this assignment is being thrown out anyway, so let's ignore it + } + AssignmentType assignmentToFind = entry.getKey().assignment; + List> modifications = entry.getValue(); + if (modifications.isEmpty()) { + continue; + } + LOGGER.trace("Applying policy state modifications for {} ({}):\n{}", assignmentToFind, mode, + DebugUtil.debugDumpLazily(modifications)); + if (mode == PlusMinusZero.ZERO) { + if (assignmentToFind.getId() == null) { + throw new IllegalStateException("Existing assignment with null id: " + assignmentToFind); } - AssignmentType assignmentToFind = entry.getKey().assignment; - List> modifications = entry.getValue(); - if (modifications.isEmpty()) { - continue; + for (ItemDelta modification : modifications) { + focusDelta = focusContext.swallowToDelta(focusDelta, modification); } - LOGGER.trace("Applying policy state modifications for {} ({}):\n{}", assignmentToFind, mode, - DebugUtil.debugDumpLazily(modifications)); - if (mode == PlusMinusZero.ZERO) { - if (assignmentToFind.getId() == null) { - throw new IllegalStateException("Existing assignment with null id: " + assignmentToFind); - } - for (ItemDelta modification : modifications) { - focusContext.swallowToDelta(focusDelta, modification); - } + } else { + assert mode == PlusMinusZero.PLUS; + if (focusDelta != null && focusDelta.isAdd()) { + swallowIntoValues(((FocusType) focusDelta.getObjectToAdd().asObjectable()).getAssignment(), + assignmentToFind, modifications); } else { - assert mode == PlusMinusZero.PLUS; - if (focusDelta.isAdd()) { - swallowIntoValues(((FocusType) focusDelta.getObjectToAdd().asObjectable()).getAssignment(), - assignmentToFind, modifications); + ContainerDelta assignmentDelta = focusDelta != null ? + focusDelta.findContainerDelta(FocusType.F_ASSIGNMENT) : null; + if (assignmentDelta == null) { + throw new IllegalStateException( + "We have 'plus' assignment to modify but there's no assignment delta. Assignment=" + + assignmentToFind + ", objectDelta=" + focusDelta); + } + if (assignmentDelta.isReplace()) { + swallowIntoValues(asContainerables(assignmentDelta.getValuesToReplace()), assignmentToFind, + modifications); + } else if (assignmentDelta.isAdd()) { + swallowIntoValues(asContainerables(assignmentDelta.getValuesToAdd()), assignmentToFind, + modifications); } else { - ContainerDelta assignmentDelta = focusDelta.findContainerDelta(FocusType.F_ASSIGNMENT); - if (assignmentDelta == null) { - throw new IllegalStateException( - "We have 'plus' assignment to modify but there's no assignment delta. Assignment=" - + assignmentToFind + ", objectDelta=" + focusDelta); - } - if (assignmentDelta.isReplace()) { - swallowIntoValues(asContainerables(assignmentDelta.getValuesToReplace()), assignmentToFind, - modifications); - } else if (assignmentDelta.isAdd()) { - swallowIntoValues(asContainerables(assignmentDelta.getValuesToAdd()), assignmentToFind, - modifications); - } else { - throw new IllegalStateException( - "We have 'plus' assignment to modify but there're no values to add or replace in assignment delta. Assignment=" - + assignmentToFind + ", objectDelta=" + focusDelta); - } + throw new IllegalStateException( + "We have 'plus' assignment to modify but there're no values to add or replace in assignment delta. Assignment=" + + assignmentToFind + ", objectDelta=" + focusDelta); } } } } focusContext.clearPendingAssignmentPolicyStateModifications(); + return focusDelta; } private void swallowIntoValues(Collection assignments, AssignmentType assignmentToFind, List> modifications) diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java index 0f2193aaeee..3f6d751d075 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java @@ -44,6 +44,9 @@ import org.jetbrains.annotations.NotNull; import static com.evolveum.midpoint.prism.PrismContainerValue.asContainerable; +import static com.evolveum.midpoint.prism.delta.PlusMinusZero.MINUS; +import static com.evolveum.midpoint.prism.delta.PlusMinusZero.PLUS; +import static com.evolveum.midpoint.prism.delta.PlusMinusZero.ZERO; /** * Evaluated assignment that contains all constructions and authorizations from the assignment @@ -528,14 +531,17 @@ public List getNonNegativeTargets() { return rv; } + /** + * @return mode (adding, deleting, keeping) with respect to the *current* object (not the old one) + */ @NotNull public PlusMinusZero getMode() { - if (assignmentIdi.getItemOld() == null) { - return PlusMinusZero.PLUS; - } else if (assignmentIdi.getItemNew() == null) { - return PlusMinusZero.MINUS; + if (assignmentIdi.getItemNew() == null) { + return MINUS; + } else if (presentInCurrentObject) { + return ZERO; } else { - return PlusMinusZero.ZERO; + return PLUS; } } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java index ad8ea5e5071..e06c9609b68 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java @@ -73,15 +73,23 @@ public abstract class LensElementContext implements ModelE private String iterationToken; /** - * These are policy state modifications that should be applied regardless of how the clockwork is exited - * (e.g. in primary state, in final state, with an exception). + * These are policy state modifications that should be applied. + * Currently we apply them in ChangeExecutor.executeChanges only. * - * Currently implemented only for focus, not for projections. + * In the future we plan to be able to apply some state modifications even + * if the clockwork is exited in non-standard way (e.g. in primary state or with an exception). + * But we must be sure what policy state to store, because some constraints might be triggered + * because of expectation of future state (like conflicting assignment is added etc.) + * --- + * Although placed in LensElementContext, support for this data is currently implemented only for focus, not for projections. */ @NotNull private transient final List> pendingObjectPolicyStateModifications = new ArrayList<>(); /** * Policy state modifications for assignments. + * + * Although we put here also deltas for assignments that are to be deleted, we do not execute these + * (because we implement execution only for the standard exit-path from the clockwork). */ @NotNull private transient final Map>> pendingAssignmentPolicyStateModifications = new HashMap<>(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateUpdater.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateUpdater.java index 63330d650e5..91490dc2f5b 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateUpdater.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateUpdater.java @@ -24,6 +24,7 @@ import com.evolveum.midpoint.prism.delta.PlusMinusZero; import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder; import com.evolveum.midpoint.prism.path.IdItemPathSegment; +import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; @@ -116,7 +117,9 @@ private ComputationResult compute(@NotNull List rulesToReco cr.oldPolicySituations.addAll(existingPolicySituation); cr.oldTriggeredRules.addAll(existingTriggeredPolicyRule); cr.situationsNeedUpdate = !Objects.equals(cr.oldPolicySituations, cr.newPolicySituations); - cr.rulesNeedUpdate = !Objects.equals(cr.oldTriggeredRules, cr.newTriggeredRules); + // we do not use this, because it uses hashCode, that is (for some reason) wrongly computed + //cr.rulesNeedUpdate = !Objects.equals(cr.oldTriggeredRules, cr.newTriggeredRules); + cr.rulesNeedUpdate = !MiscUtil.unorderedCollectionEquals(cr.oldTriggeredRules, cr.newTriggeredRules); return cr; } diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/AbstractLensTest.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/AbstractLensTest.java index b64dbade95e..b9a9432adf2 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/AbstractLensTest.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/AbstractLensTest.java @@ -92,14 +92,14 @@ public abstract class AbstractLensTest extends AbstractInternalModelIntegrationT "user-barbossa-modify-delete-assignment-account-dummy-attr.xml"); protected static final File ROLE_PIRATE_FILE = new File(TEST_DIR, "role-pirate.xml"); - protected static final File ROLE_PIRATE_SITUATION_ONLY_FILE = new File(TEST_DIR, "role-pirate-situation-only.xml"); + protected static final File ROLE_PIRATE_RECORD_ONLY_FILE = new File(TEST_DIR, "role-pirate-record-only.xml"); protected static final String ROLE_PIRATE_OID = "12345678-d34d-b33f-f00d-555555556666"; protected static final File ROLE_MUTINIER_FILE = new File(TEST_DIR, "role-mutinier.xml"); protected static final String ROLE_MUTINIER_OID = "12345678-d34d-b33f-f00d-555555556668"; protected static final File ROLE_JUDGE_FILE = new File(TEST_DIR, "role-judge.xml"); - protected static final File ROLE_JUDGE_SITUATION_ONLY_FILE = new File(TEST_DIR, "role-judge-situation-only.xml"); + protected static final File ROLE_JUDGE_RECORD_ONLY_FILE = new File(TEST_DIR, "role-judge-record-only.xml"); protected static final String ROLE_JUDGE_OID = "12345111-1111-2222-1111-121212111111"; protected static final File ROLE_CONSTABLE_FILE = new File(TEST_DIR, "role-constable.xml"); diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java index 062fddae56b..0a126381e4d 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java @@ -77,8 +77,8 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti super.initSystem(initTask, initResult); setDefaultUserTemplate(USER_TEMPLATE_OID); - addObject(ROLE_PIRATE_SITUATION_ONLY_FILE); - addObject(ROLE_JUDGE_SITUATION_ONLY_FILE); + addObject(ROLE_PIRATE_RECORD_ONLY_FILE); + addObject(ROLE_JUDGE_RECORD_ONLY_FILE); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); diff --git a/model/model-impl/src/test/resources/lens/role-judge-situation-only.xml b/model/model-impl/src/test/resources/lens/role-judge-record-only.xml similarity index 100% rename from model/model-impl/src/test/resources/lens/role-judge-situation-only.xml rename to model/model-impl/src/test/resources/lens/role-judge-record-only.xml diff --git a/model/model-impl/src/test/resources/lens/role-pirate-situation-only.xml b/model/model-impl/src/test/resources/lens/role-pirate-record-only.xml similarity index 100% rename from model/model-impl/src/test/resources/lens/role-pirate-situation-only.xml rename to model/model-impl/src/test/resources/lens/role-pirate-record-only.xml From 5fe57aa2ae88f8d3f1a1ee57eab94362954066ac Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 26 Sep 2017 14:30:56 +0200 Subject: [PATCH 63/97] Support for multi-word full text queries. --- .../repo/sql/QueryInterpreter2Test.java | 34 +++++++++++++++++++ .../restriction/FullTextRestriction.java | 31 ++++++++++++++--- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java index 48c51d43a51..65a4a6d694e 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java @@ -3654,6 +3654,40 @@ public void test940FullTextSimple() throws Exception { } } + @Test + public void test945FullTextMulti() throws Exception { + Session session = open(); + + try { + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .fullText("\t\nPeter\t\tMravec\t") + .build(); + + String real = getInterpretedQuery2(session, UserType.class, query); + String expected = "select\n" + + " u.oid,\n" + + " u.fullObject,\n" + + " u.stringsCount,\n" + + " u.longsCount,\n" + + " u.datesCount,\n" + + " u.referencesCount,\n" + + " u.polysCount,\n" + + " u.booleansCount\n" + + "from\n" + + " RUser u\n" + + " left join u.textInfoItems t\n" + + " left join u.textInfoItems t2\n" + + "where\n" + + " (\n" + + " t.text like :text and\n" + + " t2.text like :text2\n" + + " )"; + assertEqualsIgnoreWhitespace(expected, real); + } finally { + close(session); + } + } + @Test public void testAdHoc100ProcessStartTimestamp() throws Exception { Session session = open(); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/FullTextRestriction.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/FullTextRestriction.java index 304d7c8cc0a..f4773519cbf 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/FullTextRestriction.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/FullTextRestriction.java @@ -25,6 +25,13 @@ import org.apache.commons.lang3.StringUtils; import org.hibernate.criterion.MatchMode; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import static java.util.stream.Collectors.toList; + /** * @author mederly */ @@ -37,16 +44,30 @@ public FullTextRestriction(InterpretationContext context, FullTextFilter filter, @Override public Condition interpret() throws QueryException { - String textInfoItemsAlias = getItemPathResolver().addTextInfoJoin(getBaseHqlEntity().getHqlPath()); - String textPath = textInfoItemsAlias + "." + RObjectTextInfo.F_TEXT; - // TODO implement multiple values if (filter.getValues().size() != 1) { throw new QueryException("FullText filter currently supports only a single string"); } String text = filter.getValues().iterator().next(); String normalized = getContext().getPrismContext().getDefaultPolyStringNormalizer().normalize(text); - normalized = StringUtils.normalizeSpace(normalized); - return getContext().getHibernateQuery().createLike(textPath, normalized, MatchMode.ANYWHERE, false); + String[] words = StringUtils.split(normalized); + if (words.length == 0) { + throw new QueryException("No words to query for using full-text search filter"); + } + List conditions = new ArrayList<>(words.length); + for (String word : words) { + conditions.add(createWordQuery(word)); + } + if (conditions.size() == 1) { + return conditions.get(0); + } else { + return getContext().getHibernateQuery().createAnd(conditions); + } } + + private Condition createWordQuery(String word) throws QueryException { + String textInfoItemsAlias = getItemPathResolver().addTextInfoJoin(getBaseHqlEntity().getHqlPath()); + String textPath = textInfoItemsAlias + "." + RObjectTextInfo.F_TEXT; + return getContext().getHibernateQuery().createLike(textPath, word, MatchMode.ANYWHERE, false); + } } From 8044097fd252271beead0229f354eb85e77e4f4a Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 26 Sep 2017 14:30:56 +0200 Subject: [PATCH 64/97] Support for multi-word full text queries. (cherry picked from commit 5fe57aa) --- .../repo/sql/QueryInterpreter2Test.java | 34 +++++++++++++++++++ .../restriction/FullTextRestriction.java | 31 ++++++++++++++--- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java index 48c51d43a51..65a4a6d694e 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java @@ -3654,6 +3654,40 @@ public void test940FullTextSimple() throws Exception { } } + @Test + public void test945FullTextMulti() throws Exception { + Session session = open(); + + try { + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .fullText("\t\nPeter\t\tMravec\t") + .build(); + + String real = getInterpretedQuery2(session, UserType.class, query); + String expected = "select\n" + + " u.oid,\n" + + " u.fullObject,\n" + + " u.stringsCount,\n" + + " u.longsCount,\n" + + " u.datesCount,\n" + + " u.referencesCount,\n" + + " u.polysCount,\n" + + " u.booleansCount\n" + + "from\n" + + " RUser u\n" + + " left join u.textInfoItems t\n" + + " left join u.textInfoItems t2\n" + + "where\n" + + " (\n" + + " t.text like :text and\n" + + " t2.text like :text2\n" + + " )"; + assertEqualsIgnoreWhitespace(expected, real); + } finally { + close(session); + } + } + @Test public void testAdHoc100ProcessStartTimestamp() throws Exception { Session session = open(); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/FullTextRestriction.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/FullTextRestriction.java index 304d7c8cc0a..f4773519cbf 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/FullTextRestriction.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/FullTextRestriction.java @@ -25,6 +25,13 @@ import org.apache.commons.lang3.StringUtils; import org.hibernate.criterion.MatchMode; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import static java.util.stream.Collectors.toList; + /** * @author mederly */ @@ -37,16 +44,30 @@ public FullTextRestriction(InterpretationContext context, FullTextFilter filter, @Override public Condition interpret() throws QueryException { - String textInfoItemsAlias = getItemPathResolver().addTextInfoJoin(getBaseHqlEntity().getHqlPath()); - String textPath = textInfoItemsAlias + "." + RObjectTextInfo.F_TEXT; - // TODO implement multiple values if (filter.getValues().size() != 1) { throw new QueryException("FullText filter currently supports only a single string"); } String text = filter.getValues().iterator().next(); String normalized = getContext().getPrismContext().getDefaultPolyStringNormalizer().normalize(text); - normalized = StringUtils.normalizeSpace(normalized); - return getContext().getHibernateQuery().createLike(textPath, normalized, MatchMode.ANYWHERE, false); + String[] words = StringUtils.split(normalized); + if (words.length == 0) { + throw new QueryException("No words to query for using full-text search filter"); + } + List conditions = new ArrayList<>(words.length); + for (String word : words) { + conditions.add(createWordQuery(word)); + } + if (conditions.size() == 1) { + return conditions.get(0); + } else { + return getContext().getHibernateQuery().createAnd(conditions); + } } + + private Condition createWordQuery(String word) throws QueryException { + String textInfoItemsAlias = getItemPathResolver().addTextInfoJoin(getBaseHqlEntity().getHqlPath()); + String textPath = textInfoItemsAlias + "." + RObjectTextInfo.F_TEXT; + return getContext().getHibernateQuery().createLike(textPath, word, MatchMode.ANYWHERE, false); + } } From 3241d5d89cd7bd53778dd7fc5a97fe3d098e44bd Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 26 Sep 2017 14:41:42 +0200 Subject: [PATCH 65/97] Removed exception when doing full-text search for no words. --- .../repo/sql/QueryInterpreter2Test.java | 30 +++++++++++++++++++ .../restriction/FullTextRestriction.java | 7 ++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java index 65a4a6d694e..6931a4aa462 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java @@ -3654,6 +3654,36 @@ public void test940FullTextSimple() throws Exception { } } + // adapt the test after query interpreter is optimized (when searching for empty text) + @Test + public void test941FullTextEmpty() throws Exception { + Session session = open(); + + try { + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .fullText("\t\t\t") + .build(); + + String real = getInterpretedQuery2(session, UserType.class, query); + String expected = "select\n" + + " u.oid, u.fullObject,\n" + + " u.stringsCount,\n" + + " u.longsCount,\n" + + " u.datesCount,\n" + + " u.referencesCount,\n" + + " u.polysCount,\n" + + " u.booleansCount\n" + + "from\n" + + " RUser u\n" + + " left join u.textInfoItems t\n" + + "where\n" + + " t.text like :text"; + assertEqualsIgnoreWhitespace(expected, real); + } finally { + close(session); + } + } + @Test public void test945FullTextMulti() throws Exception { Session session = open(); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/FullTextRestriction.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/FullTextRestriction.java index f4773519cbf..63a1fc0072e 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/FullTextRestriction.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/FullTextRestriction.java @@ -51,14 +51,13 @@ public Condition interpret() throws QueryException { String text = filter.getValues().iterator().next(); String normalized = getContext().getPrismContext().getDefaultPolyStringNormalizer().normalize(text); String[] words = StringUtils.split(normalized); - if (words.length == 0) { - throw new QueryException("No words to query for using full-text search filter"); - } List conditions = new ArrayList<>(words.length); for (String word : words) { conditions.add(createWordQuery(word)); } - if (conditions.size() == 1) { + if (conditions.isEmpty()) { + return createWordQuery(""); // original behavior -> match all records (TODO return something like 'empty condition') + } else if (conditions.size() == 1) { return conditions.get(0); } else { return getContext().getHibernateQuery().createAnd(conditions); From eeec5d944e86bbc1b055d41b0e84523f1bcf0d2b Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 26 Sep 2017 14:41:42 +0200 Subject: [PATCH 66/97] Removed exception when doing full-text search for no words. (cherry picked from commit 3241d5d) --- .../repo/sql/QueryInterpreter2Test.java | 30 +++++++++++++++++++ .../restriction/FullTextRestriction.java | 7 ++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java index 65a4a6d694e..6931a4aa462 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java @@ -3654,6 +3654,36 @@ public void test940FullTextSimple() throws Exception { } } + // adapt the test after query interpreter is optimized (when searching for empty text) + @Test + public void test941FullTextEmpty() throws Exception { + Session session = open(); + + try { + ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) + .fullText("\t\t\t") + .build(); + + String real = getInterpretedQuery2(session, UserType.class, query); + String expected = "select\n" + + " u.oid, u.fullObject,\n" + + " u.stringsCount,\n" + + " u.longsCount,\n" + + " u.datesCount,\n" + + " u.referencesCount,\n" + + " u.polysCount,\n" + + " u.booleansCount\n" + + "from\n" + + " RUser u\n" + + " left join u.textInfoItems t\n" + + "where\n" + + " t.text like :text"; + assertEqualsIgnoreWhitespace(expected, real); + } finally { + close(session); + } + } + @Test public void test945FullTextMulti() throws Exception { Session session = open(); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/FullTextRestriction.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/FullTextRestriction.java index f4773519cbf..63a1fc0072e 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/FullTextRestriction.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/FullTextRestriction.java @@ -51,14 +51,13 @@ public Condition interpret() throws QueryException { String text = filter.getValues().iterator().next(); String normalized = getContext().getPrismContext().getDefaultPolyStringNormalizer().normalize(text); String[] words = StringUtils.split(normalized); - if (words.length == 0) { - throw new QueryException("No words to query for using full-text search filter"); - } List conditions = new ArrayList<>(words.length); for (String word : words) { conditions.add(createWordQuery(word)); } - if (conditions.size() == 1) { + if (conditions.isEmpty()) { + return createWordQuery(""); // original behavior -> match all records (TODO return something like 'empty condition') + } else if (conditions.size() == 1) { return conditions.get(0); } else { return getContext().getHibernateQuery().createAnd(conditions); From 1dbcc039519f65b18c3755927d6c51fe85bccf8b Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 26 Sep 2017 15:34:39 +0200 Subject: [PATCH 67/97] Fixed storing policy state, including situation triggers. --- .../xml/ns/public/common/common-policy-3.xsd | 60 ++++++++-- .../complex/system-configuration.xml | 4 +- .../context/EvaluatedExclusionTrigger.java | 4 +- .../api/context/EvaluatedPolicyRule.java | 2 +- .../context/EvaluatedSituationTrigger.java | 2 +- .../PolicyRuleExternalizationOptions.java | 14 +-- .../impl/hooks/PolicyRuleEnforcerHook.java | 4 +- .../model/impl/lens/ChangeExecutor.java | 3 +- .../impl/lens/EvaluatedPolicyRuleImpl.java | 33 ++++-- .../projector/policy/PolicyRuleProcessor.java | 6 +- ...eUpdater.java => PolicyStateRecorder.java} | 12 +- .../impl/lens/TestPolicyStateRecording.java | 112 +++++++++--------- .../policy/state/metarole-common-rules.xml | 3 + .../lens/role-pirate-record-only.xml | 2 +- .../test/AbstractModelIntegrationTest.java | 29 +++++ .../primary/policy/ApprovalSchemaBuilder.java | 17 ++- .../midpoint/test/DummyAuditService.java | 5 + 17 files changed, 205 insertions(+), 107 deletions(-) rename model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/{PolicyStateUpdater.java => PolicyStateRecorder.java} (93%) diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd index 25810227239..e90e0ff0231 100644 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd @@ -412,10 +412,10 @@ - + - If triggers are to be stored, what level of details should be preserved? + How much information about triggered policy rules should be stored? EXPERIMENTAL @@ -427,7 +427,7 @@ - Triggers will not be stored. + Triggered policy rules will not be stored. @@ -447,7 +447,8 @@ - The triggers for the rule will be stored (including subtriggers). Hidden and final presentation settings are respected. + The triggers and other information for the rule will be stored (including subtriggers). + Hidden and final presentation settings are respected. @@ -457,6 +458,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1389,18 +1425,22 @@ - + - How should be triggers stored? + How much information about triggered policy rules should be stored? EXPERIMENTAL - - 3.7 - true - + + + + + + + + diff --git a/model/certification-impl/src/test/resources/complex/system-configuration.xml b/model/certification-impl/src/test/resources/complex/system-configuration.xml index ac1cbdb3a3d..1292597db67 100644 --- a/model/certification-impl/src/test/resources/complex/system-configuration.xml +++ b/model/certification-impl/src/test/resources/complex/system-configuration.xml @@ -395,7 +395,7 @@ http://sample.org/situations#incomplete-role-c1-to-c4 - full + full @@ -413,7 +413,7 @@ http://sample.org/situations#active-role-with-no-identifier - none + none diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedExclusionTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedExclusionTrigger.java index 1b364bd9f94..80202a6d0c4 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedExclusionTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedExclusionTrigger.java @@ -24,7 +24,7 @@ import java.util.Objects; -import static com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyTriggerStorageStrategyType.FULL; +import static com.evolveum.midpoint.xml.ns._public.common.common_3.TriggeredPolicyRulesStorageStrategyType.FULL; /** * @author mederly @@ -82,7 +82,7 @@ protected void debugDumpSpecific(StringBuilder sb, int indent) { public EvaluatedExclusionTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { EvaluatedExclusionTriggerType rv = new EvaluatedExclusionTriggerType(); fillCommonContent(rv); - if (options.getTriggerStorageStrategy() == FULL) { + if (options.getTriggeredRulesStorageStrategy() == FULL) { rv.setConflictingObjectRef(ObjectTypeUtil.createObjectRef(conflictingTarget)); rv.setConflictingObjectDisplayName(ObjectTypeUtil.getDisplayName(conflictingTarget)); if (conflictingPath != null) { diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRule.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRule.java index 8ef51b2759d..183fd74bead 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRule.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRule.java @@ -66,7 +66,7 @@ default boolean isTriggered() { Collection getPolicyExceptions(); - EvaluatedPolicyRuleType toEvaluatedPolicyRuleType(PolicyRuleExternalizationOptions options); + void addToEvaluatedPolicyRuleTypes(Collection rules, PolicyRuleExternalizationOptions options); boolean isGlobal(); diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedSituationTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedSituationTrigger.java index 063c358ec05..f9f6d78190b 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedSituationTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedSituationTrigger.java @@ -107,7 +107,7 @@ public EvaluatedSituationTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRule EvaluatedSituationTriggerType rv = new EvaluatedSituationTriggerType(); fillCommonContent(rv); if (!options.isRespectFinalFlag() || !isFinal()) { - sourceRules.forEach(r -> rv.getSourceRule().add(r.toEvaluatedPolicyRuleType(options))); + sourceRules.forEach(r -> r.addToEvaluatedPolicyRuleTypes(rv.getSourceRule(), options)); } return rv; } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/PolicyRuleExternalizationOptions.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/PolicyRuleExternalizationOptions.java index 2e8ac2a4f47..91b172afdfb 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/PolicyRuleExternalizationOptions.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/PolicyRuleExternalizationOptions.java @@ -16,19 +16,19 @@ package com.evolveum.midpoint.model.api.context; -import com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyTriggerStorageStrategyType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.TriggeredPolicyRulesStorageStrategyType; import org.jetbrains.annotations.NotNull; import java.io.Serializable; -import static com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyTriggerStorageStrategyType.FULL; +import static com.evolveum.midpoint.xml.ns._public.common.common_3.TriggeredPolicyRulesStorageStrategyType.FULL; /** * @author mederly */ public class PolicyRuleExternalizationOptions implements Serializable { - @NotNull private PolicyTriggerStorageStrategyType triggerStorageStrategy; + @NotNull private TriggeredPolicyRulesStorageStrategyType triggeredRulesStorageStrategy; private boolean includeAssignmentsContent; private boolean respectFinalFlag; @@ -36,16 +36,16 @@ public PolicyRuleExternalizationOptions() { this(FULL, false, true); } - public PolicyRuleExternalizationOptions(PolicyTriggerStorageStrategyType triggerStorageStrategy, + public PolicyRuleExternalizationOptions(TriggeredPolicyRulesStorageStrategyType triggeredRulesStorageStrategy, boolean includeAssignmentsContent, boolean respectFinalFlag) { - this.triggerStorageStrategy = triggerStorageStrategy != null ? triggerStorageStrategy : FULL; + this.triggeredRulesStorageStrategy = triggeredRulesStorageStrategy != null ? triggeredRulesStorageStrategy : FULL; this.includeAssignmentsContent = includeAssignmentsContent; this.respectFinalFlag = respectFinalFlag; } @NotNull - public PolicyTriggerStorageStrategyType getTriggerStorageStrategy() { - return triggerStorageStrategy; + public TriggeredPolicyRulesStorageStrategyType getTriggeredRulesStorageStrategy() { + return triggeredRulesStorageStrategy; } public boolean isIncludeAssignmentsContent() { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/hooks/PolicyRuleEnforcerHook.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/hooks/PolicyRuleEnforcerHook.java index e9f4e234f8f..9e364c29b89 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/hooks/PolicyRuleEnforcerHook.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/hooks/PolicyRuleEnforcerHook.java @@ -40,7 +40,7 @@ import java.util.Collections; import java.util.List; -import static com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyTriggerStorageStrategyType.FULL; +import static com.evolveum.midpoint.xml.ns._public.common.common_3.TriggeredPolicyRulesStorageStrategyType.FULL; /** * Hook used to enforce the policy rules that have the enforce action. @@ -138,7 +138,7 @@ private void enforceTriggeredRules(EvaluationContext evalC } // TODO really include assignments content? - evalCtx.rules.add(policyRule.toEvaluatedPolicyRuleType(new PolicyRuleExternalizationOptions(FULL, true, true))); + policyRule.addToEvaluatedPolicyRuleTypes(evalCtx.rules, new PolicyRuleExternalizationOptions(FULL, true, true)); for (EvaluatedPolicyRuleTrigger trigger: triggers) { if (trigger.getMessage() != null) { 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 4f146c66c70..74c755af85e 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 @@ -24,7 +24,7 @@ import com.evolveum.midpoint.common.Clock; import com.evolveum.midpoint.common.SynchronizationUtils; -import com.evolveum.midpoint.model.impl.lens.projector.policy.PolicyStateUpdater; +import com.evolveum.midpoint.model.impl.lens.projector.policy.PolicyStateRecorder; import com.evolveum.midpoint.prism.delta.*; import com.evolveum.midpoint.repo.api.ConflictWatcher; import com.evolveum.midpoint.repo.common.expression.Expression; @@ -116,7 +116,6 @@ public class ChangeExecutor { @Autowired private Clock clock; @Autowired private ModelObjectResolver objectResolver; @Autowired private OperationalDataManager metadataManager; - @Autowired private PolicyStateUpdater policyStateUpdater; @Autowired private CredentialsProcessor credentialsProcessor; private PrismObjectDefinition userDefinition = null; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedPolicyRuleImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedPolicyRuleImpl.java index 40308f52e06..5b0f14a1e0d 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedPolicyRuleImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedPolicyRuleImpl.java @@ -15,10 +15,6 @@ */ package com.evolveum.midpoint.model.impl.lens; -import java.util.*; -import java.util.Objects; -import java.util.stream.Collectors; - import com.evolveum.midpoint.model.api.context.*; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.util.PrismPrettyPrinter; @@ -31,7 +27,13 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import static com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyTriggerStorageStrategyType.FULL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import static com.evolveum.midpoint.xml.ns._public.common.common_3.TriggeredPolicyRulesStorageStrategyType.FULL; /** * @author semancik @@ -315,10 +317,10 @@ private void createMessageTreeNode(TreeNode root, EvaluatedP */ @Override - public EvaluatedPolicyRuleType toEvaluatedPolicyRuleType(PolicyRuleExternalizationOptions options) { + public void addToEvaluatedPolicyRuleTypes(Collection rules, PolicyRuleExternalizationOptions options) { EvaluatedPolicyRuleType rv = new EvaluatedPolicyRuleType(); rv.setRuleName(getName()); - boolean isFull = options.getTriggerStorageStrategy() == FULL; + boolean isFull = options.getTriggeredRulesStorageStrategy() == FULL; if (isFull && assignmentPath != null) { rv.setAssignmentPath(assignmentPath.toAssignmentPathType(options.isIncludeAssignmentsContent())); } @@ -326,8 +328,19 @@ public EvaluatedPolicyRuleType toEvaluatedPolicyRuleType(PolicyRuleExternalizati rv.setDirectOwnerRef(ObjectTypeUtil.createObjectRef(directOwner)); rv.setDirectOwnerDisplayName(ObjectTypeUtil.getDisplayName(directOwner)); } - triggers.forEach(t -> rv.getTrigger().add(t.toEvaluatedPolicyRuleTriggerType(options))); - return rv; + for (EvaluatedPolicyRuleTrigger trigger : triggers) { + if (trigger instanceof EvaluatedSituationTrigger && trigger.isHidden()) { + for (EvaluatedPolicyRule sourceRule : ((EvaluatedSituationTrigger) trigger).getSourceRules()) { + sourceRule.addToEvaluatedPolicyRuleTypes(rules, options); + } + } else { + rv.getTrigger().add(trigger.toEvaluatedPolicyRuleTriggerType(options)); + } + } + if (rv.getTrigger().isEmpty()) { + // skip empty situation rule + } else { + rules.add(rv); + } } - } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java index 5fb0be2dc03..040d7475c0f 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java @@ -69,7 +69,7 @@ public class PolicyRuleProcessor { @Autowired @Qualifier("cacheRepositoryService") private RepositoryService repositoryService; @Autowired private MappingFactory mappingFactory; @Autowired private MappingEvaluator mappingEvaluator; - @Autowired private PolicyStateUpdater policyStateUpdater; + @Autowired private PolicyStateRecorder policyStateRecorder; @Autowired private AssignmentConstraintEvaluator assignmentConstraintEvaluator; @Autowired private HasAssignmentConstraintEvaluator hasAssignmentConstraintEvaluator; @@ -149,7 +149,7 @@ public void evaluateAssignmentPolicyRules(LensContext c } } } - policyStateUpdater.applyAssignmentState(context, evaluatedAssignment, globalCtx.rulesToRecord); + policyStateRecorder.applyAssignmentState(context, evaluatedAssignment, globalCtx.rulesToRecord); } exclusionConstraintEvaluator.checkExclusionsLegacy(context, evaluatedAssignmentTriple.getPlusSet(), @@ -214,7 +214,7 @@ public void evaluateObjectPolicyRules(LensContext conte for (EvaluatedPolicyRule rule : situationRules) { evaluateFocusRule(rule, context, globalCtx, task, result); } - policyStateUpdater.applyObjectState(context, globalCtx.rulesToRecord); + policyStateRecorder.applyObjectState(context, globalCtx.rulesToRecord); } private Collection getAllGlobalRules(LensContext context) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateUpdater.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java similarity index 93% rename from model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateUpdater.java rename to model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java index 91490dc2f5b..cb6e7ced2f1 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateUpdater.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java @@ -43,9 +43,9 @@ * @author mederly */ @Component -public class PolicyStateUpdater { +public class PolicyStateRecorder { - private static final Trace LOGGER = TraceManager.getTrace(PolicyStateUpdater.class); + private static final Trace LOGGER = TraceManager.getTrace(PolicyStateRecorder.class); @Autowired private PrismContext prismContext; @@ -110,14 +110,16 @@ private ComputationResult compute(@NotNull List rulesToReco for (EvaluatedPolicyRule rule : rulesToRecord) { cr.newPolicySituations.add(rule.getPolicySituation()); RecordPolicyActionType recordAction = rule.getActions().getRecord(); - if (recordAction.getTriggerStorageStrategy() != PolicyTriggerStorageStrategyType.NONE) { - cr.newTriggeredRules.add(rule.toEvaluatedPolicyRuleType(new PolicyRuleExternalizationOptions(recordAction.getTriggerStorageStrategy(), false, true))); + if (recordAction.getPolicyRules() != TriggeredPolicyRulesStorageStrategyType.NONE) { + PolicyRuleExternalizationOptions externalizationOptions = new PolicyRuleExternalizationOptions( + recordAction.getPolicyRules(), false, true); + rule.addToEvaluatedPolicyRuleTypes(cr.newTriggeredRules, externalizationOptions); } } cr.oldPolicySituations.addAll(existingPolicySituation); cr.oldTriggeredRules.addAll(existingTriggeredPolicyRule); cr.situationsNeedUpdate = !Objects.equals(cr.oldPolicySituations, cr.newPolicySituations); - // we do not use this, because it uses hashCode, that is (for some reason) wrongly computed + // we do not use Objects.equal, because it uses hashCode, that is (for some reason) wrongly computed //cr.rulesNeedUpdate = !Objects.equals(cr.oldTriggeredRules, cr.newTriggeredRules); cr.rulesNeedUpdate = !MiscUtil.unorderedCollectionEquals(cr.oldTriggeredRules, cr.newTriggeredRules); return cr; diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java index 0a126381e4d..90bdfd958c5 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java @@ -36,6 +36,8 @@ import java.io.File; import java.util.Collections; +import static com.evolveum.midpoint.model.api.ModelExecuteOptions.createReconcile; +import static com.evolveum.midpoint.prism.delta.ObjectDelta.createEmptyModifyDelta; import static com.evolveum.midpoint.schema.util.ObjectTypeUtil.createAssignmentTo; import static org.testng.AssertJUnit.assertEquals; @@ -98,82 +100,79 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti DebugUtil.setPrettyPrintBeansAs(PrismContext.LANG_YAML); } + @Test public void test100JackAssignRoleJudge() throws Exception { - final String TEST_NAME = "test100JackAssignRoleJudge"; - TestUtil.displayTestTitle(this, TEST_NAME); + TestCtx t = createContext(this, "test100JackAssignRoleJudge"); // GIVEN - Task task = taskManager.createTaskInstance(TestPolicyStateRecording.class.getName() + "." + TEST_NAME); - OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); - assignRole(USER_JACK_OID, ROLE_JUDGE_OID, task, result); + t.displayWhen(); + assignRole(USER_JACK_OID, ROLE_JUDGE_OID, t.task, t.result); // THEN - TestUtil.displayThen(TEST_NAME); + t.displayThen(); UserType jack = getUser(USER_JACK_OID).asObjectable(); display("jack", jack); - result.computeStatus(); - TestUtil.assertSuccess(result); + t.result.computeStatus(); + TestUtil.assertSuccess(t.result); - assertAssignedRole(USER_JACK_OID, ROLE_JUDGE_OID, task, result); + assertAssignedRole(USER_JACK_OID, ROLE_JUDGE_OID, t.task, t.result); assertEquals("Wrong # of assignments", 1, jack.getAssignment().size()); assertEquals("Wrong policy situations", Collections.emptyList(), jack.getAssignment().get(0).getPolicySituation()); + + display("Audit", dummyAuditService); + dummyAuditService.assertExecutionRecords(1); } @Test public void test110JackAssignRolePirate() throws Exception { - final String TEST_NAME = "test110JackAssignRolePirate"; - TestUtil.displayTestTitle(this, TEST_NAME); - - // GIVEN - Task task = taskManager.createTaskInstance(TestPolicyStateRecording.class.getName() + "." + TEST_NAME); - OperationResult result = task.getResult(); + TestCtx t = createContext(this, "test110JackAssignRolePirate"); // WHEN - TestUtil.displayWhen(TEST_NAME); - assignRole(USER_JACK_OID, ROLE_PIRATE_OID, task, result); + t.displayWhen(); + assignRole(USER_JACK_OID, ROLE_PIRATE_OID, t.task, t.result); // THEN - TestUtil.displayThen(TEST_NAME); + t.displayThen(); UserType jack = getUser(USER_JACK_OID).asObjectable(); display("jack", jack); - result.computeStatus(); - TestUtil.assertSuccess(result); + t.result.computeStatus(); + TestUtil.assertSuccess(t.result); - assertAssignedRole(USER_JACK_OID, ROLE_PIRATE_OID, task, result); + assertAssignedRole(USER_JACK_OID, ROLE_PIRATE_OID, t.task, t.result); assertEquals("Wrong # of assignments", 2, jack.getAssignment().size()); for (AssignmentType assignment : jack.getAssignment()) { assertEquals("Wrong policy situations", Collections.singletonList(SchemaConstants.MODEL_POLICY_SITUATION_EXCLUSION_VIOLATION), assignment.getPolicySituation()); } + + display("Audit", dummyAuditService); + dummyAuditService.assertExecutionRecords(2); // rules without IDs, with IDs } // should keep the situation for both assignments @Test public void test120RecomputeJack() throws Exception { - final String TEST_NAME = "test120RecomputeJack"; - TestUtil.displayTestTitle(this, TEST_NAME); + TestCtx t = createContext(this, "test120RecomputeJack"); // GIVEN - Task task = taskManager.createTaskInstance(TestPolicyStateRecording.class.getName() + "." + TEST_NAME); - OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); - recomputeUser(USER_JACK_OID, task, result); + t.displayWhen(); + executeChanges(createEmptyModifyDelta(UserType.class, USER_JACK_OID, prismContext), createReconcile(), t.task, t.result); + //recomputeUser(USER_JACK_OID, t.task, t.result); // THEN - TestUtil.displayThen(TEST_NAME); + t.displayThen(); UserType jack = getUser(USER_JACK_OID).asObjectable(); display("jack", jack); - result.computeStatus(); - TestUtil.assertSuccess(result); + t.result.computeStatus(); + TestUtil.assertSuccess(t.result); // TODO test that assignment IDs are filled in correctly (currently they are not) assertEquals("Wrong # of assignments", 2, jack.getAssignment().size()); @@ -182,35 +181,36 @@ public void test120RecomputeJack() throws Exception { Collections.singletonList(SchemaConstants.MODEL_POLICY_SITUATION_EXCLUSION_VIOLATION), assignment.getPolicySituation()); } + + display("Audit", dummyAuditService); + dummyAuditService.assertExecutionRecords(1); + dummyAuditService.assertExecutionDeltas(0); } @Test public void test200BobAssign2a3a() throws Exception { - final String TEST_NAME = "test200BobAssign2a3a"; - TestUtil.displayTestTitle(this, TEST_NAME); + TestCtx t = createContext(this, "test200BobAssign2a3a"); // GIVEN - Task task = taskManager.createTaskInstance(TestPolicyStateRecording.class.getName() + "." + TEST_NAME); - OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + t.displayWhen(); ObjectDelta delta = DeltaBuilder.deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT) .add(createAssignmentTo(roleATest2aOid, ObjectTypes.ROLE, prismContext), createAssignmentTo(roleATest3aOid, ObjectTypes.ROLE, prismContext)) .asObjectDeltaCast(userBobOid); - executeChangesAssertSuccess(delta, null, task, result); + executeChangesAssertSuccess(delta, null, t.task, t.result); // THEN - TestUtil.displayThen(TEST_NAME); + t.displayThen(); UserType bob = getUser(userBobOid).asObjectable(); display("bob", bob); - result.computeStatus(); - TestUtil.assertSuccess(result); + t.result.computeStatus(); + TestUtil.assertSuccess(t.result); - assertAssignedRole(userBobOid, roleATest2aOid, task, result); - assertAssignedRole(userBobOid, roleATest3aOid, task, result); + assertAssignedRole(userBobOid, roleATest2aOid, t.task, t.result); + assertAssignedRole(userBobOid, roleATest3aOid, t.task, t.result); assertEquals("Wrong # of assignments", 2, bob.getAssignment().size()); assertEquals("Wrong policy situations for assignment 1", Collections.emptyList(), @@ -218,39 +218,41 @@ public void test200BobAssign2a3a() throws Exception { assertEquals("Wrong policy situations for assignment 2", Collections.emptyList(), bob.getAssignment().get(1).getPolicySituation()); + + display("Audit", dummyAuditService); + dummyAuditService.assertExecutionRecords(1); // no policy state update } @Test public void test200BobAssign2b3b() throws Exception { - final String TEST_NAME = "test200BobAssign2b3b"; - TestUtil.displayTestTitle(this, TEST_NAME); + TestCtx t = createContext(this, "test200BobAssign2b3b"); // GIVEN - Task task = taskManager.createTaskInstance(TestPolicyStateRecording.class.getName() + "." + TEST_NAME); - OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + t.displayWhen(); ObjectDelta delta = DeltaBuilder.deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT) .add(createAssignmentTo(roleATest2bOid, ObjectTypes.ROLE, prismContext), createAssignmentTo(roleATest3bOid, ObjectTypes.ROLE, prismContext)) .asObjectDeltaCast(userBobOid); - executeChangesAssertSuccess(delta, null, task, result); + executeChangesAssertSuccess(delta, null, t.task, t.result); // THEN - TestUtil.displayThen(TEST_NAME); + t.displayThen(); UserType bob = getUser(userBobOid).asObjectable(); display("bob", bob); - result.computeStatus(); - TestUtil.assertSuccess(result); + t.result.computeStatus(); + TestUtil.assertSuccess(t.result); - assertAssignedRole(userBobOid, roleATest2aOid, task, result); - assertAssignedRole(userBobOid, roleATest2bOid, task, result); - assertAssignedRole(userBobOid, roleATest3aOid, task, result); - assertAssignedRole(userBobOid, roleATest3bOid, task, result); + assertAssignedRole(userBobOid, roleATest2aOid, t.task, t.result); + assertAssignedRole(userBobOid, roleATest2bOid, t.task, t.result); + assertAssignedRole(userBobOid, roleATest3aOid, t.task, t.result); + assertAssignedRole(userBobOid, roleATest3bOid, t.task, t.result); assertEquals("Wrong # of assignments", 4, bob.getAssignment().size()); + display("Audit", dummyAuditService); + dummyAuditService.assertExecutionRecords(2); // rules without IDs, with IDs // TODO policy state } diff --git a/model/model-impl/src/test/resources/lens/policy/state/metarole-common-rules.xml b/model/model-impl/src/test/resources/lens/policy/state/metarole-common-rules.xml index 1bf5c1f09b2..415c3aaa9c8 100644 --- a/model/model-impl/src/test/resources/lens/policy/state/metarole-common-rules.xml +++ b/model/model-impl/src/test/resources/lens/policy/state/metarole-common-rules.xml @@ -23,6 +23,9 @@ + + true + http://midpoint.evolveum.com/xml/ns/public/model/policy/situation#exclusionViolation diff --git a/model/model-impl/src/test/resources/lens/role-pirate-record-only.xml b/model/model-impl/src/test/resources/lens/role-pirate-record-only.xml index b936eeab0e2..46dd5419bf4 100644 --- a/model/model-impl/src/test/resources/lens/role-pirate-record-only.xml +++ b/model/model-impl/src/test/resources/lens/role-pirate-record-only.xml @@ -32,7 +32,7 @@ - messageOnly + messageOnly diff --git a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java index b1d88eeb8ee..772e3fdbc65 100644 --- a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java +++ b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java @@ -4551,4 +4551,33 @@ protected TaskType getRootTask(List> tasks) { return rv.get(0); } } + + // highly experimental + public class TestCtx { + public final String name; + + public final Task task; + public final OperationResult result; + + TestCtx(Object testCase, String name) { + this.name = name; + TestUtil.displayTestTitle(testCase, name); + task = taskManager.createTaskInstance(testCase.getClass().getName() + "." + name); + result = task.getResult(); + dummyAuditService.clear(); + } + + public void displayWhen() { + TestUtil.displayWhen(name); + } + + public void displayThen() { + TestUtil.displayThen(name); + } + } + + protected TestCtx createContext(Object testCase, String testName) { + return new TestCtx(testCase, testName); + } + } diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java index 14a86b8f7a6..828fa662bf5 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java @@ -34,7 +34,7 @@ import javax.xml.namespace.QName; import java.util.*; -import static com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyTriggerStorageStrategyType.FULL; +import static com.evolveum.midpoint.xml.ns._public.common.common_3.TriggeredPolicyRulesStorageStrategyType.FULL; import static java.util.Comparator.naturalOrder; /** @@ -207,11 +207,16 @@ private void processFragmentGroup(List fragments, ApprovalSchemaType r resultingSchemaType.getStage().add(stageDef); } if (firstFragment.policyRule != null) { - SchemaAttachedPolicyRuleType attachedRule = new SchemaAttachedPolicyRuleType(); - attachedRule.setStageMin(from); - attachedRule.setStageMax(i - 1); - attachedRule.setRule(firstFragment.policyRule.toEvaluatedPolicyRuleType(new PolicyRuleExternalizationOptions(FULL, false, true))); - attachedRules.getEntry().add(attachedRule); + List rules = new ArrayList<>(); + firstFragment.policyRule.addToEvaluatedPolicyRuleTypes(rules, new PolicyRuleExternalizationOptions(FULL, + false, true)); + for (EvaluatedPolicyRuleType rule : rules) { + SchemaAttachedPolicyRuleType attachedRule = new SchemaAttachedPolicyRuleType(); + attachedRule.setStageMin(from); + attachedRule.setStageMax(i - 1); + attachedRule.setRule(rule); + attachedRules.getEntry().add(attachedRule); + } } } diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/DummyAuditService.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/DummyAuditService.java index 9c6cb6326f3..9b4554eedf1 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/DummyAuditService.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/DummyAuditService.java @@ -148,6 +148,11 @@ public void assertRecords(int expectedNumber) { " but was "+records.size(); } + public void assertExecutionRecords(int expectedNumber) { + List executionRecords = getExecutionRecords(); + assertEquals("Wrong # of execution records", expectedNumber, executionRecords.size()); + } + public List getRecordsOfType(AuditEventType type) { List retval = new ArrayList(); for (AuditEventRecord record : records) { From c23e474690dfadb934df2e562a89d5fa7fe0a8af Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 26 Sep 2017 16:28:11 +0200 Subject: [PATCH 68/97] A couple more tests for policy state. --- .../impl/lens/TestPolicyStateRecording.java | 278 ++++++++++++++++-- .../lens/policy/state/a-test-wrong.xml | 25 ++ .../policy/state/metarole-common-rules.xml | 23 ++ .../resources/lens/policy/state/user-eve.xml | 24 ++ 4 files changed, 332 insertions(+), 18 deletions(-) create mode 100644 model/model-impl/src/test/resources/lens/policy/state/a-test-wrong.xml create mode 100644 model/model-impl/src/test/resources/lens/policy/state/user-eve.xml diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java index 90bdfd958c5..d26a66ee4cb 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java @@ -25,9 +25,7 @@ import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.test.util.TestUtil; import com.evolveum.midpoint.util.DebugUtil; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentPolicyEnforcementType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +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; @@ -35,6 +33,7 @@ import java.io.File; import java.util.Collections; +import java.util.List; import static com.evolveum.midpoint.model.api.ModelExecuteOptions.createReconcile; import static com.evolveum.midpoint.prism.delta.ObjectDelta.createEmptyModifyDelta; @@ -56,7 +55,10 @@ public class TestPolicyStateRecording extends AbstractLensTest { protected static final File TEST_DIR = new File(AbstractLensTest.TEST_DIR, "policy/state"); private static final File USER_BOB_FILE = new File(TEST_DIR, "user-bob.xml"); + private static final String WRONG_URI = "http://test.org/wrong"; private static String userBobOid; + private static final File USER_EVE_FILE = new File(TEST_DIR, "user-eve.xml"); + private static String userEveOid; private static final File ROLE_A_TEST_2A_FILE = new File(TEST_DIR, "a-test-2a.xml"); private static String roleATest2aOid; private static final File ROLE_A_TEST_2B_FILE = new File(TEST_DIR, "a-test-2b.xml"); @@ -71,6 +73,8 @@ public class TestPolicyStateRecording extends AbstractLensTest { private static String roleATest3xOid; private static final File ROLE_A_TEST_3Y_FILE = new File(TEST_DIR, "a-test-3y.xml"); private static String roleATest3yOid; + private static final File ROLE_A_TEST_WRONG_FILE = new File(TEST_DIR, "a-test-wrong.xml"); + private static String roleATestWrongOid; private static final File METAROLE_COMMON_RULES_FILE = new File(TEST_DIR, "metarole-common-rules.xml"); private static String metaroleCommonRulesOid; @@ -92,15 +96,16 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti roleATest3yOid = addAndRecompute(ROLE_A_TEST_3Y_FILE, initTask, initResult); roleATest3aOid = addAndRecompute(ROLE_A_TEST_3A_FILE, initTask, initResult); roleATest3bOid = addAndRecompute(ROLE_A_TEST_3B_FILE, initTask, initResult); + roleATestWrongOid = addAndRecompute(ROLE_A_TEST_WRONG_FILE, initTask, initResult); userBobOid = addAndRecompute(USER_BOB_FILE, initTask, initResult); + userEveOid = addAndRecompute(USER_EVE_FILE, initTask, initResult); InternalMonitor.reset(); DebugUtil.setPrettyPrintBeansAs(PrismContext.LANG_YAML); } - @Test public void test100JackAssignRoleJudge() throws Exception { TestCtx t = createContext(this, "test100JackAssignRoleJudge"); @@ -118,7 +123,7 @@ public void test100JackAssignRoleJudge() throws Exception { t.result.computeStatus(); TestUtil.assertSuccess(t.result); - assertAssignedRole(USER_JACK_OID, ROLE_JUDGE_OID, t.task, t.result); + assertAssignedRole(jack.asPrismObject(), ROLE_JUDGE_OID); assertEquals("Wrong # of assignments", 1, jack.getAssignment().size()); assertEquals("Wrong policy situations", Collections.emptyList(), @@ -143,12 +148,10 @@ public void test110JackAssignRolePirate() throws Exception { t.result.computeStatus(); TestUtil.assertSuccess(t.result); - assertAssignedRole(USER_JACK_OID, ROLE_PIRATE_OID, t.task, t.result); + assertAssignedRole(jack.asPrismObject(), ROLE_PIRATE_OID); assertEquals("Wrong # of assignments", 2, jack.getAssignment().size()); for (AssignmentType assignment : jack.getAssignment()) { - assertEquals("Wrong policy situations", - Collections.singletonList(SchemaConstants.MODEL_POLICY_SITUATION_EXCLUSION_VIOLATION), - assignment.getPolicySituation()); + assertExclusionViolationState(assignment); } display("Audit", dummyAuditService); @@ -209,8 +212,8 @@ public void test200BobAssign2a3a() throws Exception { t.result.computeStatus(); TestUtil.assertSuccess(t.result); - assertAssignedRole(userBobOid, roleATest2aOid, t.task, t.result); - assertAssignedRole(userBobOid, roleATest3aOid, t.task, t.result); + assertAssignedRole(bob.asPrismObject(), roleATest2aOid); + assertAssignedRole(bob.asPrismObject(), roleATest3aOid); assertEquals("Wrong # of assignments", 2, bob.getAssignment().size()); assertEquals("Wrong policy situations for assignment 1", Collections.emptyList(), @@ -224,8 +227,8 @@ public void test200BobAssign2a3a() throws Exception { } @Test - public void test200BobAssign2b3b() throws Exception { - TestCtx t = createContext(this, "test200BobAssign2b3b"); + public void test210BobAssign2b3b() throws Exception { + TestCtx t = createContext(this, "test210BobAssign2b3b"); // GIVEN @@ -245,17 +248,256 @@ public void test200BobAssign2b3b() throws Exception { t.result.computeStatus(); TestUtil.assertSuccess(t.result); - assertAssignedRole(userBobOid, roleATest2aOid, t.task, t.result); - assertAssignedRole(userBobOid, roleATest2bOid, t.task, t.result); - assertAssignedRole(userBobOid, roleATest3aOid, t.task, t.result); - assertAssignedRole(userBobOid, roleATest3bOid, t.task, t.result); + assertAssignedRole(bob.asPrismObject(), roleATest2aOid); + assertAssignedRole(bob.asPrismObject(), roleATest2bOid); + assertAssignedRole(bob.asPrismObject(), roleATest3aOid); + assertAssignedRole(bob.asPrismObject(), roleATest3bOid); assertEquals("Wrong # of assignments", 4, bob.getAssignment().size()); display("Audit", dummyAuditService); dummyAuditService.assertExecutionRecords(2); // rules without IDs, with IDs - // TODO policy state + + for (AssignmentType assignment : bob.getAssignment()) { + assertExclusionViolationState(assignment); + } + } + + private void assertExclusionViolationState(AssignmentType assignment) { + assertEquals("Wrong policy situations", + Collections.singletonList(SchemaConstants.MODEL_POLICY_SITUATION_EXCLUSION_VIOLATION), + assignment.getPolicySituation()); + assertEquals("Wrong # of triggered policy rules in assignment " + assignment, 1, assignment.getTriggeredPolicyRule().size()); + List triggers = assignment.getTriggeredPolicyRule().get(0).getTrigger(); + assertEquals("Wrong # of triggers in triggered policy rule in assignment " + assignment, 1, triggers.size()); + assertEquals("Wrong type of trigger in " + assignment, PolicyConstraintKindType.EXCLUSION, triggers.get(0).getConstraintKind()); + } + + // new user, new assignments (no IDs) + @Test + public void test220AliceAssign2a2b() throws Exception { + TestCtx t = createContext(this, "test220AliceAssign2a2b"); + + // GIVEN + UserType alice = prismContext.createObjectable(UserType.class) + .name("alice") + .assignment(createAssignmentTo(roleATest2aOid, ObjectTypes.ROLE, prismContext)) + .assignment(createAssignmentTo(roleATest2bOid, ObjectTypes.ROLE, prismContext)); + + // WHEN + t.displayWhen(); + addObject(alice.asPrismObject(), t.task, t.result); + + // THEN + t.displayThen(); + alice = getUser(alice.getOid()).asObjectable(); + display("alice", alice); + t.result.computeStatus(); + TestUtil.assertSuccess(t.result); + + assertAssignedRole(alice.asPrismObject(), roleATest2aOid); + assertAssignedRole(alice.asPrismObject(), roleATest2bOid); + assertEquals("Wrong # of assignments", 2, alice.getAssignment().size()); + + display("Audit", dummyAuditService); + dummyAuditService.assertExecutionRecords(2); // rules without IDs, with IDs ? + + for (AssignmentType assignment : alice.getAssignment()) { + assertExclusionViolationState(assignment); + } + } + + // new user, new assignments (explicit IDs) + @Test + public void test230ChuckAssign2a2b() throws Exception { + TestCtx t = createContext(this, "test230ChuckAssign2a2b"); + + // GIVEN + AssignmentType assignment2a = createAssignmentTo(roleATest2aOid, ObjectTypes.ROLE, prismContext); + assignment2a.setId(100L); + AssignmentType assignment2b = createAssignmentTo(roleATest2bOid, ObjectTypes.ROLE, prismContext); + assignment2b.setId(101L); + UserType chuck = prismContext.createObjectable(UserType.class) + .name("chuck") + .assignment(assignment2a) + .assignment(assignment2b); + + // WHEN + t.displayWhen(); + addObject(chuck.asPrismObject(), t.task, t.result); + + // THEN + t.displayThen(); + chuck = getUser(chuck.getOid()).asObjectable(); + display("chuck", chuck); + t.result.computeStatus(); + TestUtil.assertSuccess(t.result); + + assertAssignedRole(chuck.asPrismObject(), roleATest2aOid); + assertAssignedRole(chuck.asPrismObject(), roleATest2bOid); + assertEquals("Wrong # of assignments", 2, chuck.getAssignment().size()); + + display("Audit", dummyAuditService); + dummyAuditService.assertExecutionRecords(2); // sourceRef.oid is null on the first iteration (object OID is unknown before actual creation in repo) + + for (AssignmentType assignment : chuck.getAssignment()) { + assertExclusionViolationState(assignment); + } } + // new user, new assignments (explicit IDs, explicit OID) + @Test + public void test240DanAssign2a2b() throws Exception { + TestCtx t = createContext(this, "test240DanAssign2a2b"); + + // GIVEN + AssignmentType assignment2a = createAssignmentTo(roleATest2aOid, ObjectTypes.ROLE, prismContext); + assignment2a.setId(100L); + AssignmentType assignment2b = createAssignmentTo(roleATest2bOid, ObjectTypes.ROLE, prismContext); + assignment2b.setId(101L); + UserType dan = prismContext.createObjectable(UserType.class) + .oid("207752fa-9559-496c-b04d-42b5e9af2779") + .name("dan") + .assignment(assignment2a) + .assignment(assignment2b); + // WHEN + t.displayWhen(); + addObject(dan.asPrismObject(), t.task, t.result); + + // THEN + t.displayThen(); + dan = getUser(dan.getOid()).asObjectable(); + display("dan", dan); + t.result.computeStatus(); + TestUtil.assertSuccess(t.result); + + assertAssignedRole(dan.asPrismObject(), roleATest2aOid); + assertAssignedRole(dan.asPrismObject(), roleATest2bOid); + assertEquals("Wrong # of assignments", 2, dan.getAssignment().size()); + + display("Audit", dummyAuditService); + dummyAuditService.assertExecutionRecords(1); + + for (AssignmentType assignment : dan.getAssignment()) { + assertExclusionViolationState(assignment); + } + } + + // modified user, new assignment (with ID) + @Test + public void test250EveAssign2b() throws Exception { + TestCtx t = createContext(this, "test220AliceAssign2a2b"); + + // WHEN + t.displayWhen(); + AssignmentType assignment2b = createAssignmentTo(roleATest2bOid, ObjectTypes.ROLE, prismContext); + assignment2b.setId(200L); + ObjectDelta delta = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT) + .add(assignment2b) + .asObjectDeltaCast(userEveOid); + executeChangesAssertSuccess(delta, null, t.task, t.result); + + // THEN + t.displayThen(); + UserType eve = getUser(userEveOid).asObjectable(); + display("alice", eve); + t.result.computeStatus(); + TestUtil.assertSuccess(t.result); + + assertAssignedRole(eve.asPrismObject(), roleATest2aOid); + assertAssignedRole(eve.asPrismObject(), roleATest2bOid); + assertEquals("Wrong # of assignments", 2, eve.getAssignment().size()); + + display("Audit", dummyAuditService); + dummyAuditService.assertExecutionRecords(1); + + for (AssignmentType assignment : eve.getAssignment()) { + assertExclusionViolationState(assignment); + } + } + + @Test + public void test300MakeRoleWrong() throws Exception { + TestCtx t = createContext(this, "test300MakeRoleWrong"); + + // GIVEN + + // WHEN + t.displayWhen(); + ObjectDelta delta = DeltaBuilder.deltaFor(RoleType.class, prismContext) + .item(RoleType.F_DESCRIPTION).replace("wrong") + .asObjectDeltaCast(roleATestWrongOid); + executeChangesAssertSuccess(delta, null, t.task, t.result); + + // THEN + t.displayThen(); + RoleType wrong = getRole(roleATestWrongOid).asObjectable(); + display("role 'wrong'", wrong); + t.result.computeStatus(); + TestUtil.assertSuccess(t.result); + + assertEquals("Wrong policy situations for role", Collections.singletonList(WRONG_URI), wrong.getPolicySituation()); + + display("Audit", dummyAuditService); + dummyAuditService.assertExecutionRecords(1); // no extra policy state update + } + + @Test + public void test310CreateWrongRole() throws Exception { + TestCtx t = createContext(this, "test310CreateWrongRole"); + + // GIVEN + RoleType wrong2 = prismContext.createObjectable(RoleType.class) + .name("wrong-2") + .description("wrong") + .assignment(createAssignmentTo(metaroleCommonRulesOid, ObjectTypes.ROLE, prismContext)); + + // WHEN + t.displayWhen(); + addObject(wrong2.asPrismObject(), t.task, t.result); + + // THEN + t.displayThen(); + wrong2 = getRole(wrong2.getOid()).asObjectable(); + display("role 'wrong-2'", wrong2); + t.result.computeStatus(); + TestUtil.assertSuccess(t.result); + + assertEquals("Wrong policy situations for role", Collections.singletonList(WRONG_URI), wrong2.getPolicySituation()); + + display("Audit", dummyAuditService); + dummyAuditService.assertExecutionRecords(2); // extra policy state update because of OID + } + + @Test + public void test320CreateWrongRoleKnownOid() throws Exception { + TestCtx t = createContext(this, "test320CreateWrongRoleKnownOid"); + + // GIVEN + AssignmentType assignmentCommon = createAssignmentTo(metaroleCommonRulesOid, ObjectTypes.ROLE, prismContext); + assignmentCommon.setId(300L); + RoleType wrong3 = prismContext.createObjectable(RoleType.class) + .name("wrong-3") + .oid("df6c6bdc-f938-4afc-98f3-10d18ceda274") + .description("wrong") + .assignment(assignmentCommon); + + // WHEN + t.displayWhen(); + addObject(wrong3.asPrismObject(), t.task, t.result); + + // THEN + t.displayThen(); + wrong3 = getRole(wrong3.getOid()).asObjectable(); + display("role 'wrong-3'", wrong3); + t.result.computeStatus(); + TestUtil.assertSuccess(t.result); + + assertEquals("Wrong policy situations for role", Collections.singletonList(WRONG_URI), wrong3.getPolicySituation()); + + display("Audit", dummyAuditService); + dummyAuditService.assertExecutionRecords(1); // no extra policy state update + } } diff --git a/model/model-impl/src/test/resources/lens/policy/state/a-test-wrong.xml b/model/model-impl/src/test/resources/lens/policy/state/a-test-wrong.xml new file mode 100644 index 00000000000..dc3231f4df1 --- /dev/null +++ b/model/model-impl/src/test/resources/lens/policy/state/a-test-wrong.xml @@ -0,0 +1,25 @@ + + + + a-test-wrong + + + + \ No newline at end of file diff --git a/model/model-impl/src/test/resources/lens/policy/state/metarole-common-rules.xml b/model/model-impl/src/test/resources/lens/policy/state/metarole-common-rules.xml index 415c3aaa9c8..35f0486a21d 100644 --- a/model/model-impl/src/test/resources/lens/policy/state/metarole-common-rules.xml +++ b/model/model-impl/src/test/resources/lens/policy/state/metarole-common-rules.xml @@ -34,4 +34,27 @@ + + + + + + + The role is in wrong state. + + + + + description + wrong + + + + + http://test.org/wrong + + + + + \ No newline at end of file diff --git a/model/model-impl/src/test/resources/lens/policy/state/user-eve.xml b/model/model-impl/src/test/resources/lens/policy/state/user-eve.xml new file mode 100644 index 00000000000..6f1a8eabc67 --- /dev/null +++ b/model/model-impl/src/test/resources/lens/policy/state/user-eve.xml @@ -0,0 +1,24 @@ + + + + + eve + + + + From 12cd6be3bdb3266f12d9ae8ba91d87bbb1b326ca Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Tue, 26 Sep 2017 17:45:15 +0200 Subject: [PATCH 69/97] Added policy state checking to TestPolicyDrivenRoleLifecycle (with a couple of workarounds). --- .../impl/AccCertCaseOperationsHelper.java | 2 + .../TestPolicyDrivenRoleLifecycle.java | 100 ++++++++++-------- 2 files changed, 59 insertions(+), 43 deletions(-) diff --git a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertCaseOperationsHelper.java b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertCaseOperationsHelper.java index edc1e051d5e..e5eec2cb4ea 100644 --- a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertCaseOperationsHelper.java +++ b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertCaseOperationsHelper.java @@ -171,6 +171,8 @@ List> getDeltasToCreateCases( throw new IllegalStateException("Object class not found for object type " + objectType + " in campaign " + campaignShortName); } + // TODO derive search filter from certification handler (e.g. select only objects having assignments with the proper policySituation) + // It is only an optimization but potentially a very strong one. Workaround: enter query filter manually into scope definition. final SearchFilterType searchFilter = objectBasedScope != null ? objectBasedScope.getSearchFilter() : null; if (searchFilter != null) { ObjectFilter filter = QueryConvertor.parseFilter(searchFilter, objectClass, prismContext); diff --git a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/complex/TestPolicyDrivenRoleLifecycle.java b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/complex/TestPolicyDrivenRoleLifecycle.java index 0a73d2140aa..0e32ff9ebe4 100644 --- a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/complex/TestPolicyDrivenRoleLifecycle.java +++ b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/complex/TestPolicyDrivenRoleLifecycle.java @@ -48,7 +48,9 @@ import static com.evolveum.midpoint.model.api.ModelExecuteOptions.createPartialProcessing; import static com.evolveum.midpoint.xml.ns._public.common.common_3.PartialProcessingTypeType.SKIP; +import static java.util.Collections.emptyList; import static java.util.Collections.singleton; +import static java.util.Collections.singletonList; import static org.testng.AssertJUnit.assertEquals; /** @@ -68,6 +70,9 @@ public class TestPolicyDrivenRoleLifecycle extends AbstractUninitializedCertific protected static final File ROLE_CORRECT_FILE = new File(TEST_DIR, "role-correct.xml"); protected static final File ROLE_CORRECT_HIGH_RISK_FILE = new File(TEST_DIR, "role-correct-high-risk.xml"); + protected static final String SITUATION_INCOMPLETE_ROLE = "http://sample.org/situations#incomplete-role-c1-to-c4"; + protected static final String SITUATION_ACTIVE_ROLE_WITH_NO_IDENTIFIER = "http://sample.org/situations#active-role-with-no-identifier"; + protected static String roleEmptyOid; protected static String roleHighRiskEmptyOid; protected static String roleCorrectOid; @@ -99,11 +104,11 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti DebugUtil.setPrettyPrintBeansAs(PrismContext.LANG_YAML); - userJackOid = repoAddObjectFromFile(USER_JACK_FILE, initResult).getOid(); - roleEmptyOid = repoAddObjectFromFile(ROLE_EMPTY_FILE, initResult).getOid(); - roleHighRiskEmptyOid = repoAddObjectFromFile(ROLE_HIGH_RISK_EMPTY_FILE, initResult).getOid(); - roleCorrectOid = repoAddObjectFromFile(ROLE_CORRECT_FILE, initResult).getOid(); - roleCorrectHighRiskOid = repoAddObjectFromFile(ROLE_CORRECT_HIGH_RISK_FILE, initResult).getOid(); + userJackOid = addAndRecompute(USER_JACK_FILE, initTask, initResult); + roleEmptyOid = addAndRecompute(ROLE_EMPTY_FILE, initTask, initResult); + roleHighRiskEmptyOid = addAndRecompute(ROLE_HIGH_RISK_EMPTY_FILE, initTask, initResult); + roleCorrectOid = addAndRecompute(ROLE_CORRECT_FILE, initTask, initResult); + roleCorrectHighRiskOid = addAndRecompute(ROLE_CORRECT_HIGH_RISK_FILE, initTask, initResult); } @NotNull @@ -126,19 +131,25 @@ public void test010AttemptToActivateIncompleteRoleC1345() throws Exception { TestUtil.displayWhen(TEST_NAME); TestUtil.displayThen(TEST_NAME); Holder> contextHolder = new Holder<>(); + activateRoleAssertFailure(roleEmptyOid, contextHolder, result, task); + + PrismObject role = getRole(roleEmptyOid); + display("role after", role); + + dumpRules(contextHolder); + assertEquals("Wrong policy situation", singletonList(SITUATION_INCOMPLETE_ROLE), role.asObjectable().getPolicySituation()); + } + + private void activateRoleAssertFailure(String roleOid, Holder> contextHolder, OperationResult result, Task task) + throws SchemaException, CommunicationException, ObjectAlreadyExistsException, ExpressionEvaluationException, + SecurityViolationException, ConfigurationException, ObjectNotFoundException { try { - activateRole(roleEmptyOid, contextHolder, task, result); + activateRole(roleOid, contextHolder, task, result); fail("unexpected success"); } catch (PolicyViolationException e) { System.out.println("Got expected exception:"); e.printStackTrace(System.out); } - - PrismObject role = getRole(roleEmptyOid); - display("role after", role); - // TODO check policy situation - - dumpRules(contextHolder); } @Test @@ -155,19 +166,13 @@ public void test020AttemptToActivateIncompleteRoleC234() throws Exception { TestUtil.displayWhen(TEST_NAME); TestUtil.displayThen(TEST_NAME); Holder> contextHolder = new Holder<>(); - try { - activateRole(roleHighRiskEmptyOid, contextHolder, task, result); - fail("unexpected success"); - } catch (PolicyViolationException e) { - System.out.println("Got expected exception:"); - e.printStackTrace(System.out); - } + activateRoleAssertFailure(roleHighRiskEmptyOid, contextHolder, result, task); PrismObject role = getRole(roleHighRiskEmptyOid); display("role after", role); - // TODO check policy situation dumpRules(contextHolder); + assertEquals("Wrong policy situation", singletonList(SITUATION_INCOMPLETE_ROLE), role.asObjectable().getPolicySituation()); } @Test @@ -184,19 +189,13 @@ public void test030AttemptToActivateCorrectRoleC34() throws Exception { TestUtil.displayWhen(TEST_NAME); TestUtil.displayThen(TEST_NAME); Holder> contextHolder = new Holder<>(); - try { - activateRole(roleCorrectOid, contextHolder, task, result); - fail("unexpected success"); - } catch (PolicyViolationException e) { - System.out.println("Got expected exception:"); - e.printStackTrace(System.out); - } + activateRoleAssertFailure(roleCorrectOid, contextHolder, result, task); PrismObject role = getRole(roleCorrectOid); display("role after", role); - // TODO check policy situation dumpRules(contextHolder); + assertEquals("Wrong policy situation", singletonList(SITUATION_INCOMPLETE_ROLE), role.asObjectable().getPolicySituation()); } private void dumpRules(Holder> contextHolder) { @@ -219,6 +218,9 @@ public void test040AssignOwnerAndApproverToCorrectRole() throws Exception { ModelExecuteOptions noApprovals = createPartialProcessing(new PartialProcessingOptionsType().approvals(SKIP)); assignRole(USER_ADMINISTRATOR_OID, roleCorrectOid, SchemaConstants.ORG_APPROVER, noApprovals, task, result); assignRole(USER_ADMINISTRATOR_OID, roleCorrectOid, SchemaConstants.ORG_OWNER, noApprovals, task, result); + + // recompute the role to set correct policy situation + recomputeFocus(RoleType.class, roleCorrectOid, task, result); } @Test @@ -242,9 +244,10 @@ public void test050ActivateCorrectRole() throws Exception { PrismObject roleAfter = getRole(roleCorrectOid); display("role after", roleAfter); assertEquals("Wrong (changed) lifecycle state", SchemaConstants.LIFECYCLE_DRAFT, roleAfter.asObjectable().getLifecycleState()); - // TODO check policy situation dumpRules(contextHolder); + assertEquals("Wrong policy situation", emptyList(), roleAfter.asObjectable().getPolicySituation()); + assertEquals("Wrong triggered policy rules", emptyList(), roleAfter.asObjectable().getTriggeredPolicyRule()); Collection> options = GetOperationOptions.retrieveItemsNamed(TaskType.F_WORKFLOW_CONTEXT, WfContextType.F_WORK_ITEM); @@ -272,6 +275,9 @@ public void test050ActivateCorrectRole() throws Exception { PrismObject roleAfterApproval = getRole(roleCorrectOid); display("role after approval", roleAfterApproval); assertEquals("Wrong (unchanged) lifecycle state", SchemaConstants.LIFECYCLE_ACTIVE, roleAfterApproval.asObjectable().getLifecycleState()); + + assertEquals("Wrong policy situation", emptyList(), roleAfter.asObjectable().getPolicySituation()); + assertEquals("Wrong triggered policy rules", emptyList(), roleAfter.asObjectable().getTriggeredPolicyRule()); } @Test @@ -291,6 +297,9 @@ public void test060AssignOwnerAndApproverToCorrectHighRiskRole() throws Exceptio assignRole(USER_ADMINISTRATOR_OID, roleCorrectHighRiskOid, SchemaConstants.ORG_APPROVER, noApprovals, task, result); assignRole(userJackOid, roleCorrectHighRiskOid, SchemaConstants.ORG_APPROVER, noApprovals, task, result); assignRole(USER_ADMINISTRATOR_OID, roleCorrectHighRiskOid, SchemaConstants.ORG_OWNER, noApprovals, task, result); + + // recompute the role to set correct policy situation + recomputeFocus(RoleType.class, roleCorrectHighRiskOid, task, result); } @Test @@ -314,10 +323,12 @@ public void test070ActivateCorrectHighRiskRole() throws Exception { PrismObject roleAfter = getRole(roleCorrectHighRiskOid); display("role after", roleAfter); assertEquals("Wrong (changed) lifecycle state", SchemaConstants.LIFECYCLE_DRAFT, roleAfter.asObjectable().getLifecycleState()); - // TODO check policy situation dumpRules(contextHolder); + assertEquals("Wrong policy situation", emptyList(), roleAfter.asObjectable().getPolicySituation()); + assertEquals("Wrong triggered policy rules", emptyList(), roleAfter.asObjectable().getTriggeredPolicyRule()); + Collection> options = GetOperationOptions.retrieveItemsNamed(TaskType.F_WORKFLOW_CONTEXT, WfContextType.F_WORK_ITEM); List> tasks = getTasksForObject(roleCorrectHighRiskOid, RoleType.COMPLEX_TYPE, options, task, result); @@ -325,7 +336,6 @@ public void test070ActivateCorrectHighRiskRole() throws Exception { assertEquals("Wrong # of approval tasks for role", 2, tasks.size()); TaskType approvalTask = getApprovalTask(tasks); - TaskType rootTask = getRootTask(tasks); WfContextType wfc = approvalTask.getWorkflowContext(); assertEquals("Modification of correct-high-risk", wfc.getProcessInstanceName()); assertEquals("wrong # of work items", 1, wfc.getWorkItem().size()); @@ -333,21 +343,25 @@ public void test070ActivateCorrectHighRiskRole() throws Exception { ItemApprovalProcessStateType info = WfContextUtil.getItemApprovalProcessInfo(wfc); assertEquals("wrong # of approval stages", 2, info.getApprovalSchema().getStage().size()); assertEquals("wrong # of attached policy rules", 2, info.getPolicyRules().getEntry().size()); -// EvaluatedPolicyRuleType rule = info.getPolicyRules().getEntry().get(0).getRule(); -// List triggers = rule.getTrigger(); -// -// // TODO check trigger -// -// workflowService.completeWorkItem(workItem.getExternalId(), true, null, null, result); -// waitForTaskFinish(rootTask.getOid(), false); -// -// PrismObject roleAfterApproval = getRole(roleCorrectHighRiskOid); -// display("role after approval", roleAfterApproval); -// assertEquals("Wrong (unchanged) lifecycle state", SchemaConstants.LIFECYCLE_ACTIVE, roleAfterApproval.asObjectable().getLifecycleState()); - } + workflowService.completeWorkItem(workItem.getExternalId(), true, null, null, result); + approvalTask = modelService.getObject(TaskType.class, approvalTask.getOid(), options, task, result).asObjectable(); + wfc = approvalTask.getWorkflowContext(); + assertEquals("wrong # of work items", 1, wfc.getWorkItem().size()); + workItem = wfc.getWorkItem().get(0); + workflowService.completeWorkItem(workItem.getExternalId(), true, null, null, result); + TaskType rootTask = getRootTask(tasks); + waitForTaskFinish(rootTask.getOid(), false); + + PrismObject roleAfterApproval = getRole(roleCorrectHighRiskOid); + display("role after approval", roleAfterApproval); + assertEquals("Wrong (unchanged) lifecycle state", SchemaConstants.LIFECYCLE_ACTIVE, roleAfterApproval.asObjectable().getLifecycleState()); + + assertEquals("Wrong policy situation", singletonList(SITUATION_ACTIVE_ROLE_WITH_NO_IDENTIFIER), roleAfterApproval.asObjectable().getPolicySituation()); + assertEquals("Wrong triggered policy rules", emptyList(), roleAfterApproval.asObjectable().getTriggeredPolicyRule()); // recording rules = none + } private void activateRole(String oid, Holder> contextHolder, Task task, OperationResult result) throws SchemaException, CommunicationException, ObjectAlreadyExistsException, ExpressionEvaluationException, From 68c9a53f7a476085fba030b6a087a1f9ef338ce6 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Wed, 27 Sep 2017 06:20:42 +0200 Subject: [PATCH 70/97] Fixed setting assignment policy state on assignment deletion. --- .../midpoint/prism/delta/ContainerDelta.java | 27 ++++----------- .../test/TestSoDCertification.java | 1 - .../model/impl/lens/ChangeExecutor.java | 2 +- .../impl/lens/EvaluatedAssignmentImpl.java | 2 +- .../projector/policy/PolicyRuleProcessor.java | 5 ++- .../projector/policy/PolicyStateRecorder.java | 15 ++++++--- .../impl/lens/TestPolicyStateRecording.java | 33 +++++++++++++++++++ 7 files changed, 56 insertions(+), 29 deletions(-) diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ContainerDelta.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ContainerDelta.java index eb092c43e75..e9eb76d18f5 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ContainerDelta.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ContainerDelta.java @@ -186,16 +186,14 @@ private Collection findItemValues(Long id, ItemPath path, Collection void expand(PrismObject object, Trace logger) throws SchemaException { - PrismContainer container = null; - ItemPath path = this.getPath(); - if (object != null) { - container = object.findContainer(path); - } if (valuesToDelete != null) { + ItemPath path = this.getPath(); + PrismContainer container = null; + if (object != null) { + container = object.findContainer(path); + } Iterator> iterator = valuesToDelete.iterator(); while (iterator.hasNext()) { PrismContainerValue deltaCVal = iterator.next(); @@ -210,24 +208,11 @@ public void expand(PrismObject object, Trace logger) t for (Item containerItem: containerCVal.getItems()) { deltaCVal.add(containerItem.clone()); } + continue; } } // id-only value with ID that is not in the object any more: delete the value from delta iterator.remove(); - } else if (deltaCVal.getId() == null) { - if (container != null) { - @SuppressWarnings("unchecked") - List> containerCVals = - (List>) - container.findValuesIgnoreMetadata(deltaCVal); - if (containerCVals.size() > 1) { - logger.warn("More values to be deleted are matched by a single value in delete delta: values={}, delta value={}", - containerCVals, deltaCVal); - } else if (containerCVals.size() == 1) { - deltaCVal.setId(containerCVals.get(0).getId()); - } - // for the time being let's keep non-existent values in the delta - } } } } diff --git a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestSoDCertification.java b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestSoDCertification.java index b7eb388b72d..f0abb077fc1 100644 --- a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestSoDCertification.java +++ b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestSoDCertification.java @@ -99,7 +99,6 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti DebugUtil.setPrettyPrintBeansAs(PrismContext.LANG_YAML); } - // TODO move a test like this into model-intest @Test public void test001Triggers() throws Exception { final String TEST_NAME = "test001Triggers"; 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 74c755af85e..a2e651d32b8 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 @@ -380,7 +380,7 @@ private ObjectDelta applyPendingAssignmentPolicyStateM .getPendingAssignmentPolicyStateModifications().entrySet()) { PlusMinusZero mode = entry.getKey().mode; if (mode == PlusMinusZero.MINUS) { - continue; // this assignment is being thrown out anyway, so let's ignore it + continue; // this assignment is being thrown out anyway, so let's ignore it (at least for now) } AssignmentType assignmentToFind = entry.getKey().assignment; List> modifications = entry.getValue(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java index 3f6d751d075..c86cea8a7a2 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java @@ -536,7 +536,7 @@ public List getNonNegativeTargets() { */ @NotNull public PlusMinusZero getMode() { - if (assignmentIdi.getItemNew() == null) { + if (assignmentIdi.getItemNew() == null || assignmentIdi.getItemNew().isEmpty()) { return MINUS; } else if (presentInCurrentObject) { return ZERO; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java index 040d7475c0f..8947e15abd3 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleProcessor.java @@ -24,6 +24,7 @@ import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.delta.ContainerDelta; import com.evolveum.midpoint.prism.delta.DeltaSetTriple; +import com.evolveum.midpoint.prism.delta.PlusMinusZero; import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.repo.common.expression.ExpressionUtil; @@ -149,7 +150,9 @@ public void evaluateAssignmentPolicyRules(LensContext c } } } - policyStateRecorder.applyAssignmentState(context, evaluatedAssignment, globalCtx.rulesToRecord); + // a bit of hack, but hopefully it will work + PlusMinusZero mode = inMinus ? PlusMinusZero.MINUS : evaluatedAssignment.getMode(); + policyStateRecorder.applyAssignmentState(context, evaluatedAssignment, mode, globalCtx.rulesToRecord); } exclusionConstraintEvaluator.checkExclusionsLegacy(context, evaluatedAssignmentTriple.getPlusSet(), diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java index cb6e7ced2f1..b9f0fee8833 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java @@ -53,6 +53,9 @@ public void applyObjectState(LensContext context, List< // compute policySituation and triggeredPolicyRules and compare it with the expected state // note that we use the new state for the comparison, because if values match we do not need to do anything LensFocusContext focusContext = context.getFocusContext(); + if (focusContext.isDelete()) { + return; + } F objectNew = focusContext.getObjectNew().asObjectable(); ComputationResult cr = compute(rulesToRecord, objectNew.getPolicySituation(), objectNew.getTriggeredPolicyRule()); if (cr.situationsNeedUpdate) { @@ -72,8 +75,11 @@ public void applyObjectState(LensContext context, List< } public void applyAssignmentState(LensContext context, - EvaluatedAssignmentImpl evaluatedAssignment, List rulesToRecord) throws SchemaException { + EvaluatedAssignmentImpl evaluatedAssignment, PlusMinusZero mode, List rulesToRecord) throws SchemaException { LensFocusContext focusContext = context.getFocusContext(); + if (focusContext.isDelete()) { + return; + } AssignmentType assignmentNew = evaluatedAssignment.getAssignmentType(false); AssignmentType assignmentOld = evaluatedAssignment.getAssignmentType(true); if (assignmentOld == null && assignmentNew == null) { @@ -84,19 +90,20 @@ public void applyAssignmentState(LensContext context, @NotNull AssignmentType assignmentToMatch = assignmentOld != null ? assignmentOld : assignmentNew; // this value is used to compute policy situation/rules modifications @NotNull AssignmentType assignmentToCompute = assignmentNew != null ? assignmentNew : assignmentOld; - @NotNull PlusMinusZero mode = evaluatedAssignment.getMode(); Long id = assignmentToMatch.getId(); ComputationResult cr = compute(rulesToRecord, assignmentToCompute.getPolicySituation(), assignmentToCompute.getTriggeredPolicyRule()); if (cr.situationsNeedUpdate) { - focusContext.addToPendingAssignmentPolicyStateModifications(assignmentToMatch, mode, DeltaBuilder.deltaFor(FocusType.class, prismContext) + focusContext.addToPendingAssignmentPolicyStateModifications(assignmentToMatch, + mode, DeltaBuilder.deltaFor(FocusType.class, prismContext) .item(FocusType.F_ASSIGNMENT, new IdItemPathSegment(id), AssignmentType.F_POLICY_SITUATION) .oldRealValues(cr.oldPolicySituations) .replaceRealValues(cr.newPolicySituations) .asItemDelta()); } if (cr.rulesNeedUpdate) { - focusContext.addToPendingAssignmentPolicyStateModifications(assignmentToMatch, mode, DeltaBuilder.deltaFor(FocusType.class, prismContext) + focusContext.addToPendingAssignmentPolicyStateModifications(assignmentToMatch, + mode, DeltaBuilder.deltaFor(FocusType.class, prismContext) .item(FocusType.F_ASSIGNMENT, new IdItemPathSegment(id), AssignmentType.F_TRIGGERED_POLICY_RULE) .oldRealValues(cr.oldTriggeredRules) .replaceRealValues(cr.newTriggeredRules) diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java index d26a66ee4cb..0b929ac732a 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java @@ -190,6 +190,39 @@ public void test120RecomputeJack() throws Exception { dummyAuditService.assertExecutionDeltas(0); } + @Test + public void test130JackUnassignRolePirate() throws Exception { + TestCtx t = createContext(this, "test130JackUnassignRolePirate"); + + // GIVEN + UserType jack = getUser(USER_JACK_OID).asObjectable(); + AssignmentType pirateAssignment = findAssignmentByTarget(jack.asPrismObject(), ROLE_PIRATE_OID).get(); + + // WHEN + t.displayWhen(); + ObjectDelta delta = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT) + .delete(pirateAssignment.clone()) + .asObjectDeltaCast(USER_JACK_OID); + executeChangesAssertSuccess(delta, null, t.task, t.result); + + // THEN + t.displayThen(); + jack = getUser(USER_JACK_OID).asObjectable(); + display("jack", jack); + t.result.computeStatus(); + TestUtil.assertSuccess(t.result); + + assertNotAssignedRole(jack.asPrismObject(), ROLE_PIRATE_OID); + assertEquals("Wrong # of assignments", 1, jack.getAssignment().size()); + assertEquals("Wrong policy situations", + Collections.emptyList(), + jack.getAssignment().get(0).getPolicySituation()); + + display("Audit", dummyAuditService); + dummyAuditService.assertExecutionRecords(1); // executed in one shot + } + @Test public void test200BobAssign2a3a() throws Exception { TestCtx t = createContext(this, "test200BobAssign2a3a"); From b17e252932f54d23d86b5bef66403092e5981f78 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Wed, 27 Sep 2017 06:33:02 +0200 Subject: [PATCH 71/97] Minor change. --- .../midpoint/model/impl/lens/TestPolicyStateRecording.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java index 0b929ac732a..07ae1dd23e4 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyStateRecording.java @@ -196,7 +196,7 @@ public void test130JackUnassignRolePirate() throws Exception { // GIVEN UserType jack = getUser(USER_JACK_OID).asObjectable(); - AssignmentType pirateAssignment = findAssignmentByTarget(jack.asPrismObject(), ROLE_PIRATE_OID).get(); + AssignmentType pirateAssignment = findAssignmentByTargetRequired(jack.asPrismObject(), ROLE_PIRATE_OID); // WHEN t.displayWhen(); From c57f27842beec7933accd9d544c755696538349e Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Wed, 27 Sep 2017 13:31:54 +0200 Subject: [PATCH 72/97] string policy type - containerable --- .../main/resources/xml/ns/public/common/common-core-3.xsd | 7 +++++++ 1 file changed, 7 insertions(+) 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 3cc847b530d..0c79be7dc93 100644 --- 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 @@ -256,6 +256,7 @@ tns:OrgType OrgType.parentOrganization 240 + @@ -10667,6 +10668,12 @@ + + + + + + From 56489a83782a7da48995907f2d804a4d6dd43f71 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Wed, 27 Sep 2017 22:07:17 +0200 Subject: [PATCH 73/97] Many fixes to activation, parallelism, test improvements. Work in progress. (MID-4154) --- .../com/evolveum/midpoint/common/Clock.java | 44 ++- .../midpoint/prism/delta/ItemDelta.java | 2 +- .../xml/ns/public/common/common-core-3.xsd | 62 ++++ .../evolveum/midpoint/test/util/TestUtil.java | 5 + .../model/api/ModelExecuteOptions.java | 38 ++ .../model/impl/lens/ChangeExecutor.java | 120 ++++-- .../midpoint/model/impl/lens/Clockwork.java | 22 +- .../model/impl/lens/LensElementContext.java | 15 +- .../impl/lens/LensProjectionContext.java | 6 +- .../lens/projector/ActivationProcessor.java | 116 +++++- .../impl/lens/projector/MappingEvaluator.java | 24 +- .../lens/projector/MappingOutputStruct.java | 13 +- .../projector/ProjectionValuesProcessor.java | 46 ++- .../midpoint/model/intest/TestActivation.java | 343 +++++++++++++----- .../intest/TestModelServiceContract.java | 181 +++++---- .../manual/AbstractManualResourceTest.java | 294 +++++++++++++-- .../TestSemiManualDisableSlowProposed.java | 179 +++++++++ .../manual/TestSemiManualSlowProposed.java | 167 +-------- .../src/test/resources/logback-test.xml | 8 +- ...urce-semi-manual-disable-slow-proposed.xml | 216 +++++++++++ ...-one-semi-manual-disable-slow-proposed.xml | 35 ++ ...-two-semi-manual-disable-slow-proposed.xml | 36 ++ model/model-intest/testng-integration.xml | 1 + .../test/AbstractModelIntegrationTest.java | 8 + .../provisioning/impl/ConstraintsChecker.java | 2 +- .../provisioning/impl/ShadowCache.java | 24 +- .../provisioning/impl/ShadowManager.java | 34 +- .../test/AbstractIntegrationTest.java | 28 +- 28 files changed, 1606 insertions(+), 463 deletions(-) create mode 100644 model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/TestSemiManualDisableSlowProposed.java create mode 100644 model/model-intest/src/test/resources/manual/resource-semi-manual-disable-slow-proposed.xml create mode 100644 model/model-intest/src/test/resources/manual/role-one-semi-manual-disable-slow-proposed.xml create mode 100644 model/model-intest/src/test/resources/manual/role-two-semi-manual-disable-slow-proposed.xml diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/Clock.java b/infra/common/src/main/java/com/evolveum/midpoint/common/Clock.java index e90cf1c27f0..bc0579e90ac 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/Clock.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/Clock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2014 Evolveum + * Copyright (c) 2010-2017 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,13 +37,19 @@ public class Clock { private static final Trace LOGGER = TraceManager.getTrace(Clock.class); private Long override = null; - // TODO: more sophisticated functions + private Long overrideOffset = null; public long currentTimeMillis() { - if (override != null) { - return override; + long time; + if (override == null) { + time = System.currentTimeMillis(); + } else { + time = override; } - return System.currentTimeMillis(); + if (overrideOffset != null) { + time = time + overrideOffset; + } + return time; } public XMLGregorianCalendar currentTimeXMLGregorianCalendar() { @@ -80,19 +86,43 @@ public void override(XMLGregorianCalendar overrideTimestamp) { override(XmlTypeConverter.toMillis(overrideTimestamp)); } + /** + * Extends offset on top of existing offset. + */ public void overrideDuration(String durationString) { overrideDuration(XmlTypeConverter.createDuration(durationString)); } + /** + * Extends offset on top of existing offset. + */ public void overrideDuration(Duration duration) { - XMLGregorianCalendar time = currentTimeXMLGregorianCalendar(); + long millis = currentTimeMillis(); + XMLGregorianCalendar time = XmlTypeConverter.createXMLGregorianCalendar(millis); time.add(duration); - override(time); + long offset = XmlTypeConverter.toMillis(time) - millis; + overrideDuration(offset); + } + + /** + * Extends offset on top of existing offset. + */ + public void overrideDuration(Long offsetMillis) { + if (overrideOffset == null) { + overrideOffset = offsetMillis; + } else { + overrideOffset = overrideOffset + offsetMillis; + } + } + + public void overrideOffset(Long offsetMillis) { + this.overrideOffset = offsetMillis; } public void resetOverride() { LOGGER.info("Clock override reset"); this.override = null; + this.overrideOffset = null; if (LOGGER.isDebugEnabled()) { LOGGER.debug("Clock current time: {}", currentTimeXMLGregorianCalendar()); } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ItemDelta.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ItemDelta.java index 2d74a08b5b2..9f0144768ac 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ItemDelta.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ItemDelta.java @@ -1293,7 +1293,7 @@ public static void applyTo(Collection deltas, PrismContaine delta.applyTo(propertyContainerValue); } } - + public static void applyToMatchingPath(Collection deltas, PrismContainer propertyContainer) throws SchemaException { for (ItemDelta delta : deltas) { 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 3cc847b530d..11254bad103 100644 --- 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 @@ -880,6 +880,30 @@ + + + +

+ The timestamp last provisioning operation that was based on this object. + E.g. the timestamp of last modificaiton od any account based on the + data from the user. This valus is only updated if there was any + real change in the resource. +

+

+ This meta-datum is used as an informational property that tells when + the data were last synchronized in outbound direction. But it has another + imporatant role. It is used indirectly to trigger optimistic locking + conflicts that are used to detect a "clean" recompute (i.e. recompute + that is processing data without any outside interaction). +

+
+ + true + 3.6.1 + +
+
+ + + + + Semi-Manual disable-on-delete slow proposed CSV Resource + + + + + c:connectorType + ManualConnector + + + + + + administrator + + + + csv + + + + c:connectorType + com.evolveum.polygon.connector.csv.CsvConnector + + + + + + target/semi-manual.csv + utf-8 + , + ; + username + password + + + + + + false + + + false + + + false + + + false + + + false + + + + ri:disabled + false + true + + + + + + + + + + + + account + default + true + ri:AccountObjectClass + + ri:username + + strong + + name + + + + + ri:fullname + + + fullName + + + + + + + + + default existence + weak + + $focusExists + + + + + + strong + true + + + + + + + + + + + + + + + + + + + + + ri:disabled + false + true + + + + + + + true + light + true + all + true + PT15M + + + + + ri:AccountObjectClass + account + default + true + + + name + + $projection/attributes/username + + + + + linked + true + + + deleted + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink + + + + unlinked + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#link + + + + + + diff --git a/model/model-intest/src/test/resources/manual/role-one-semi-manual-disable-slow-proposed.xml b/model/model-intest/src/test/resources/manual/role-one-semi-manual-disable-slow-proposed.xml new file mode 100644 index 00000000000..58ea88f1042 --- /dev/null +++ b/model/model-intest/src/test/resources/manual/role-one-semi-manual-disable-slow-proposed.xml @@ -0,0 +1,35 @@ + + + One: Semi Manual Disable Slow Proposed + + + + account + + ri:interests + + + one + + + + + + diff --git a/model/model-intest/src/test/resources/manual/role-two-semi-manual-disable-slow-proposed.xml b/model/model-intest/src/test/resources/manual/role-two-semi-manual-disable-slow-proposed.xml new file mode 100644 index 00000000000..0650abc8cec --- /dev/null +++ b/model/model-intest/src/test/resources/manual/role-two-semi-manual-disable-slow-proposed.xml @@ -0,0 +1,36 @@ + + + Two: Semi Manual Disable Slow proposed + + + + account + + ri:interests + + strong + + two + + + + + + diff --git a/model/model-intest/testng-integration.xml b/model/model-intest/testng-integration.xml index cdfd75f677b..8b31c226ace 100644 --- a/model/model-intest/testng-integration.xml +++ b/model/model-intest/testng-integration.xml @@ -122,6 +122,7 @@ + diff --git a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java index b1d88eeb8ee..8ac9ec68d38 100644 --- a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java +++ b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java @@ -191,6 +191,7 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationDecisionType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationPhaseType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ConflictResolutionActionType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ConflictResolutionType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ConstructionType; import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsPolicyType; @@ -2411,6 +2412,13 @@ protected void setConflictResolution(QName objectType, String subType, ConflictR SystemObjectsType.SYSTEM_CONFIGURATION.value(), modifications, parentResult); } + + protected void setConflictResolutionAction(QName objectType, String subType, ConflictResolutionActionType conflictResolutionAction, OperationResult parentResult) + throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { + ConflictResolutionType conflictResolutionType = new ConflictResolutionType(); + conflictResolutionType.action(conflictResolutionAction); + setConflictResolution(objectType, subType, conflictResolutionType, parentResult); + } protected void setGlobalSecurityPolicy(String securityPolicyOid, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConstraintsChecker.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConstraintsChecker.java index 06659ed7083..d40c61bee9f 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConstraintsChecker.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConstraintsChecker.java @@ -204,8 +204,8 @@ private boolean checkUniqueness(String oid, PrismProperty identifier, ObjectQuer return true; } if (foundObjects.size() > 1) { + LOGGER.error("Found {} objects with attribute {}:\n{}", foundObjects.size() ,identifier.toHumanReadableString(), foundObjects); if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Found {} objects with attribute {}", foundObjects.size() ,identifier.toHumanReadableString()); for (PrismObject foundObject: foundObjects) { LOGGER.debug("Conflicting object:\n{}", foundObject.debugDump()); } diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java index 966aea8422b..c26c477170d 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java @@ -895,19 +895,18 @@ public PrismObject refreshShadow(PrismObject repoShadow, for (PendingOperationType pendingOperation: sortedOperations) { ItemPath containerPath = pendingOperation.asPrismContainerValue().getPath(); - OperationResultStatusType statusType = pendingOperation.getResultStatus(); - XMLGregorianCalendar completionTimestamp = pendingOperation.getCompletionTimestamp(); - XMLGregorianCalendar now = null; + + if (!OperationResultStatusType.IN_PROGRESS.equals(pendingOperation.getResultStatus())) { + continue; + } String asyncRef = pendingOperation.getAsynchronousOperationReference(); if (asyncRef != null) { - OperationResultStatus newStaus = resouceObjectConverter.refreshOperationStatus(ctx, repoShadow, asyncRef, parentResult); - - now = clock.currentTimeXMLGregorianCalendar(); + OperationResultStatus newStatus = resouceObjectConverter.refreshOperationStatus(ctx, repoShadow, asyncRef, parentResult); - if (newStaus != null) { - OperationResultStatusType newStatusType = newStaus.createStatusType(); + if (newStatus != null) { + OperationResultStatusType newStatusType = newStatus.createStatusType(); if (!newStatusType.equals(pendingOperation.getResultStatus())) { @@ -924,14 +923,11 @@ public PrismObject refreshShadow(PrismObject repoShadow, shadowDelta.addModification(statusDelta); } - statusType = newStatusType; - if (operationCompleted) { // Operation completed PropertyDelta timestampDelta = shadowDelta.createPropertyModification(containerPath.subPath(PendingOperationType.F_COMPLETION_TIMESTAMP)); - timestampDelta.setValuesToReplace(new PrismPropertyValue<>(now)); + timestampDelta.setValuesToReplace(new PrismPropertyValue<>(clock.currentTimeXMLGregorianCalendar())); shadowDelta.addModification(timestampDelta); - completionTimestamp = now; ObjectDeltaType pendingDeltaType = pendingOperation.getDelta(); ObjectDelta pendingDelta = DeltaConvertor.createObjectDelta(pendingDeltaType, prismContext); @@ -975,10 +971,6 @@ public PrismObject refreshShadow(PrismObject repoShadow, } } } - - if (now == null) { - now = clock.currentTimeXMLGregorianCalendar(); - } } if (shadowDelta.isDelete()) { diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java index 01f09052515..1da42514288 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java @@ -778,11 +778,11 @@ public String addNewProposedShadow(ProvisioningContext ctx, PrismObject repoShadow = createRepositoryShadow(ctx, shadow); repoShadow.asObjectable().setLifecycleState(SchemaConstants.LIFECYCLE_PROPOSED); - addPendingOperationAdd(repoShadow, shadow, task.getTaskIdentifier()); + addPendingOperationAdd(repoShadow, shadow, null, task.getTaskIdentifier()); ConstraintsChecker.onShadowAddOperation(repoShadow.asObjectable()); String oid = repositoryService.addObject(repoShadow, null, result); - LOGGER.trace("Draft shadow added to the repository: {}", repoShadow); + LOGGER.trace("Proposed shadow added to the repository: {}", repoShadow); return oid; } @@ -805,13 +805,13 @@ public void handlePropesedShadowError(ProvisioningContext ctx, PrismObject> addResult, OperationResult parentResult) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException, ObjectAlreadyExistsException, ExpressionEvaluationException { if (existingShadowOid != null) { - // We know that we have draft shadow + // We know that we have proposed shadow updateProposedShadowAfterAdd(ctx, existingShadowOid, addResult, parentResult); return existingShadowOid; } - // TODO: check for proposed Shadow. There may be a draft shadow even if we do not have explicit draft shadow OID - // (e.g. in case that the add operation failed). If draft shadow is present do modify instead of add. + // TODO: check for proposed Shadow. There may be a proposed shadow even if we do not have explicit proposed shadow OID + // (e.g. in case that the add operation failed). If proposed shadow is present do modify instead of add. PrismObject resourceShadow = addResult.getReturnValue(); @@ -858,16 +858,14 @@ public String addNewActiveRepositoryShadow(ProvisioningContext ctx, String exist @SuppressWarnings("unchecked") private void updateProposedShadowAfterAdd(ProvisioningContext ctx, String existingShadowOid, AsynchronousOperationReturnValue> addResult, OperationResult parentResult) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException, ObjectAlreadyExistsException, ExpressionEvaluationException { PrismObject resourceShadow = addResult.getReturnValue(); - LOGGER.info("AAAAA resource:\n{}", resourceShadow.debugDumpLazily(1)); PrismObject proposedShadow = repositoryService.getObject(ShadowType.class, existingShadowOid, null, parentResult); - LOGGER.info("AAAAA repo:\n{}", proposedShadow.debugDumpLazily(1)); if (proposedShadow == null) { parentResult - .recordFatalError("Error while creating account shadow object to save in the reposiotory. Draft shadow is gone."); + .recordFatalError("Error while creating account shadow object to save in the reposiotory. Proposed shadow is gone."); throw new IllegalStateException( - "Error while creating account shadow object to save in the reposiotory. Draft shadow is gone."); + "Error while creating account shadow object to save in the reposiotory. Proposed shadow is gone."); } Collection shadowChanges = new ArrayList<>(); @@ -886,7 +884,8 @@ private void updateProposedShadowAfterAdd(ProvisioningContext ctx, String existi PrismContainerDefinition containerDefinition = proposedShadow.getDefinition().findContainerDefinition(ShadowType.F_PENDING_OPERATION); ContainerDelta pendingOperationDelta =containerDefinition.createEmptyDelta(new ItemPath(ShadowType.F_PENDING_OPERATION)); - pendingOperationDelta.addValuesToAdd(createPendingOperationAdd(proposedShadow, resourceShadow, addResult.getOperationResult().getAsynchronousOperationReference()).asPrismContainerValue()); + pendingOperationDelta.addValuesToAdd(createPendingOperationAdd(proposedShadow, resourceShadow, + OperationResultStatusType.IN_PROGRESS, addResult.getOperationResult().getAsynchronousOperationReference()).asPrismContainerValue()); shadowChanges.add(pendingOperationDelta); } @@ -899,12 +898,12 @@ private void updateProposedShadowAfterAdd(ProvisioningContext ctx, String existi computeUpdateShadowAttributeChanges(ctx, shadowChanges, resourceShadow, proposedShadow); if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Updading draft repository shadow\n{}", DebugUtil.debugDump(shadowChanges, 1)); + LOGGER.trace("Updading proposed repository shadow\n{}", DebugUtil.debugDump(shadowChanges, 1)); } repositoryService.modifyObject(ShadowType.class, proposedShadow.getOid(), shadowChanges, parentResult); - LOGGER.trace("Draft shadow updated"); + LOGGER.trace("Proposed shadow updated"); parentResult.recordSuccess(); } @@ -915,22 +914,23 @@ private void addPendingOperationAdd(PrismObject repoShadow, return; } PrismObject resourceShadow = addResult.getReturnValue(); - addPendingOperationAdd(repoShadow, resourceShadow, addResult.getOperationResult().getAsynchronousOperationReference()); + addPendingOperationAdd(repoShadow, resourceShadow, + OperationResultStatusType.IN_PROGRESS, addResult.getOperationResult().getAsynchronousOperationReference()); } - private void addPendingOperationAdd(PrismObject repoShadow, PrismObject resourceShadow, String asyncOperationReference) throws SchemaException { + private void addPendingOperationAdd(PrismObject repoShadow, PrismObject resourceShadow, OperationResultStatusType status, String asyncOperationReference) throws SchemaException { ShadowType repoShadowType = repoShadow.asObjectable(); - repoShadowType.getPendingOperation().add(createPendingOperationAdd(repoShadow, resourceShadow, asyncOperationReference)); + repoShadowType.getPendingOperation().add(createPendingOperationAdd(repoShadow, resourceShadow, status, asyncOperationReference)); repoShadowType.setExists(false); } - private PendingOperationType createPendingOperationAdd(PrismObject repoShadow, PrismObject resourceShadow, String asyncOperationReference) throws SchemaException { + private PendingOperationType createPendingOperationAdd(PrismObject repoShadow, PrismObject resourceShadow, OperationResultStatusType status, String asyncOperationReference) throws SchemaException { ObjectDelta addDelta = resourceShadow.createAddDelta(); ObjectDeltaType addDeltaType = DeltaConvertor.toObjectDeltaType(addDelta); PendingOperationType pendingOperation = new PendingOperationType(); pendingOperation.setDelta(addDeltaType); pendingOperation.setRequestTimestamp(clock.currentTimeXMLGregorianCalendar()); - pendingOperation.setResultStatus(OperationResultStatusType.IN_PROGRESS); + pendingOperation.setResultStatus(status); if (asyncOperationReference != null) { pendingOperation.setAsynchronousOperationReference(asyncOperationReference); } diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java index 275ecc1dc9d..7625b1dff50 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java @@ -1558,13 +1558,13 @@ protected void assertMetadata(String message, MetadataType metadataType, boolean XMLGregorianCalendar start, XMLGregorianCalendar end, String actorOid, String channel) { assertNotNull("No metadata in " + message, metadataType); if (create) { - TestUtil.assertBetween("Wrong create timestamp in " + message, start, end, metadataType.getCreateTimestamp()); + assertBetween("Wrong create timestamp in " + message, start, end, metadataType.getCreateTimestamp()); if (actorOid != null) { ObjectReferenceType creatorRef = metadataType.getCreatorRef(); assertNotNull("No creatorRef in " + message, creatorRef); assertEquals("Wrong creatorRef OID in " + message, actorOid, creatorRef.getOid()); if (assertRequest) { - TestUtil.assertBetween("Wrong request timestamp in " + message, start, end, metadataType.getRequestTimestamp()); + assertBetween("Wrong request timestamp in " + message, start, end, metadataType.getRequestTimestamp()); ObjectReferenceType requestorRef = metadataType.getRequestorRef(); assertNotNull("No requestorRef in " + message, requestorRef); assertEquals("Wrong requestorRef OID in " + message, actorOid, requestorRef.getOid()); @@ -1577,7 +1577,7 @@ protected void assertMetadata(String message, MetadataType metadataType, boolean assertNotNull("No modifierRef in " + message, modifierRef); assertEquals("Wrong modifierRef OID in " + message, actorOid, modifierRef.getOid()); } - TestUtil.assertBetween("Wrong password modify timestamp in " + message, start, end, metadataType.getModifyTimestamp()); + assertBetween("Wrong password modify timestamp in " + message, start, end, metadataType.getModifyTimestamp()); assertEquals("Wrong modification channel in " + message, channel, metadataType.getModifyChannel()); } } @@ -1592,6 +1592,13 @@ protected void assertShadowPasswordMetadata(PrismObject shadow, bool assertNotNull("No metadata in shadow "+shadow, metadata); assertMetadata("Password metadata in "+shadow, metadata, passwordCreated, false, startCal, endCal, actorOid, channel); } + + protected void assertLastProvisioningTimestamp(PrismObject object, + XMLGregorianCalendar start, XMLGregorianCalendar end) { + MetadataType metadata = object.asObjectable().getMetadata(); + assertNotNull("No metadata in " + object); + assertBetween("Wrong last provisioning timestamp in " + object, start, end, metadata.getLastProvisioningTimestamp()); + } // Convenience @@ -1602,7 +1609,7 @@ protected PrismObject parseObject(File file) throws Sc protected void displayTestTitle(String testName) { TestUtil.displayTestTitle(this, testName); } - + protected void displayWhen(String testName) { TestUtil.displayWhen(testName); } @@ -1615,6 +1622,10 @@ protected void displayCleanup(String testName) { TestUtil.displayCleanup(testName); } + protected void displaySkip(String testName) { + TestUtil.displaySkip(testName); + } + protected void display(String str) { IntegrationTestTools.display(str); } @@ -1699,6 +1710,15 @@ public static void displayObjectTypeCollection(String message, Collection Date: Wed, 27 Sep 2017 22:55:48 +0200 Subject: [PATCH 74/97] Added "task" variable for bulk actions. Fixed /rpc/executeScript?asynchronous=true. --- .../admin/configuration/PageBulkAction.java | 4 +- .../prism/schema/SchemaRegistryImpl.java | 5 +- .../schema/constants/ExpressionConstants.java | 1 + .../midpoint/model/api/PipelineItem.java | 22 ++--- .../midpoint/model/api/ScriptingService.java | 5 +- .../midpoint/model/impl/ModelRestService.java | 7 +- .../impl/controller/ModelController.java | 5 +- .../impl/scripting/ExecutionContext.java | 4 +- .../model/impl/scripting/PipelineData.java | 11 +-- .../scripting/ScriptExecutionTaskHandler.java | 7 +- .../ScriptingExpressionEvaluator.java | 12 ++- .../model/impl/scripting/VariablesUtil.java | 95 +++++++++++++++++++ .../scripting/actions/ScriptExecutor.java | 22 +++-- .../expressions/SearchEvaluator.java | 7 +- .../intest/scripting/TestScriptingBasic.java | 39 +++++++- .../src/test/resources/schema/piracy.xsd | 19 ++++ .../scripting-users-in-background.xml | 59 ++++++++++++ 17 files changed, 275 insertions(+), 49 deletions(-) create mode 100644 model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/VariablesUtil.java create mode 100644 model/model-intest/src/test/resources/scripting/scripting-users-in-background.xml diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageBulkAction.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageBulkAction.java index 70c4388cd78..71bc2d7e254 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageBulkAction.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageBulkAction.java @@ -42,6 +42,8 @@ import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; +import java.util.Collections; + /** * @author lazyman */ @@ -138,7 +140,7 @@ private void startPerformed(AjaxRequestTarget target) { //noinspection ConstantConditions ScriptExecutionResult executionResult = parsed instanceof ExecuteScriptType ? - getScriptingService().evaluateExpression((ExecuteScriptType) parsed, task, result) : + getScriptingService().evaluateExpression((ExecuteScriptType) parsed, Collections.emptyMap(), task, result) : getScriptingService().evaluateExpression((ScriptingExpressionType) parsed, task, result); result.recordStatus(OperationResultStatus.SUCCESS, "Action executed. Returned " + executionResult.getDataOutput().size() + " item(s). Console and data output available via 'Export to XML' function."); result.addReturn("console", executionResult.getConsoleOutput()); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistryImpl.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistryImpl.java index 892b5fd1ffe..ad882628331 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistryImpl.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/schema/SchemaRegistryImpl.java @@ -105,7 +105,7 @@ public class SchemaRegistryImpl implements DebugDumpable, SchemaRegistry { @Autowired // TODO does this work? private PrismContext prismContext; - private static final Trace LOGGER = TraceManager.getTrace(SchemaRegistry.class); + private static final Trace LOGGER = TraceManager.getTrace(SchemaRegistryImpl.class); @Override public DynamicNamespacePrefixMapper getNamespacePrefixMapper() { @@ -985,7 +985,8 @@ public ItemDefinition locateItemDefinition(@NotNull QN return def; } } - if (complexTypeDefinition == null || complexTypeDefinition.isXsdAnyMarker()) { + // not sure about this: shouldn't extension schemas have xsdAnyMarker set? + if (complexTypeDefinition == null || complexTypeDefinition.isXsdAnyMarker() || complexTypeDefinition.getExtensionForType() != null) { def = resolveGlobalItemDefinition(itemName, complexTypeDefinition); if (def != null) { return def; diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/ExpressionConstants.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/ExpressionConstants.java index 8f222b35522..ad098ab5242 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/ExpressionConstants.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/ExpressionConstants.java @@ -92,4 +92,5 @@ public class ExpressionConstants { public static final QName VAR_CHANNEL = new QName(SchemaConstants.NS_C, "channel"); public static final QName VAR_WORKFLOW_CONTEXT = new QName(SchemaConstants.NS_C, "workflowContext"); + public static final QName VAR_TASK = new QName(SchemaConstants.NS_C, "task"); } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/PipelineItem.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/PipelineItem.java index edb1bf0da06..1930695fc54 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/PipelineItem.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/PipelineItem.java @@ -17,7 +17,6 @@ package com.evolveum.midpoint.model.api; import com.evolveum.midpoint.prism.PrismValue; -import com.evolveum.midpoint.prism.util.CloneUtil; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.DebugUtil; @@ -34,6 +33,7 @@ public class PipelineItem implements DebugDumpable, Serializable { @NotNull private PrismValue value; @NotNull private OperationResult result; + // variables here are to be cloned-on-use (if they are not immutable) @NotNull private final Map variables = new HashMap<>(); public PipelineItem(@NotNull PrismValue value, @NotNull OperationResult result) { @@ -44,7 +44,7 @@ public PipelineItem(@NotNull PrismValue value, @NotNull OperationResult result) public PipelineItem(@NotNull PrismValue value, @NotNull OperationResult result, @NotNull Map variables) { this.value = value; this.result = result; - copyClonedVariables(variables, this.variables); + this.variables.putAll(variables); } @NotNull @@ -70,10 +70,11 @@ public Map getVariables() { return variables; } - @SuppressWarnings("unchecked") - public X getVariable(String name) { - return (X) variables.get(name); - } + // don't forget to clone on use +// @SuppressWarnings("unchecked") +// public X getVariable(String name) { +// return (X) variables.get(name); +// } @Override public String debugDump(int indent) { @@ -89,12 +90,7 @@ public void computeResult() { } public PipelineItem cloneMutableState() { - PipelineItem rv = new PipelineItem(value, result.clone()); - copyClonedVariables(variables, rv.getVariables()); - return rv; - } - - public static void copyClonedVariables(Map sourceMap, Map targetMap) { - sourceMap.forEach((key, value) -> targetMap.put(key, CloneUtil.clone(value))); + // note that variables are cloned on use + return new PipelineItem(value, result.clone(), variables); } } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/ScriptingService.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/ScriptingService.java index 35ce5d1a0c5..b47842e3f7c 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/ScriptingService.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/ScriptingService.java @@ -23,8 +23,10 @@ import com.evolveum.midpoint.util.exception.SecurityViolationException; import com.evolveum.midpoint.xml.ns._public.model.scripting_3.ExecuteScriptType; import com.evolveum.midpoint.xml.ns._public.model.scripting_3.ScriptingExpressionType; +import org.jetbrains.annotations.NotNull; import javax.xml.namespace.QName; +import java.util.Map; /** * Interface of the Model subsystem that provides scripting (bulk actions) operations. @@ -79,7 +81,8 @@ void evaluateExpressionInBackground(QName objectType, ObjectFilter filter, Strin ScriptExecutionResult evaluateExpression(ScriptingExpressionType expression, Task task, OperationResult result) throws ScriptExecutionException, SchemaException, SecurityViolationException; - ScriptExecutionResult evaluateExpression(ExecuteScriptType executeScriptCommand, Task task, OperationResult result) + ScriptExecutionResult evaluateExpression(@NotNull ExecuteScriptType executeScriptCommand, + @NotNull Map initialVariables, @NotNull Task task, @NotNull OperationResult result) throws ScriptExecutionException, SchemaException, SecurityViolationException; } \ No newline at end of file diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelRestService.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelRestService.java index 3709757743d..45ef2ac9c4a 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelRestService.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/ModelRestService.java @@ -26,7 +26,6 @@ import com.evolveum.midpoint.model.impl.scripting.ScriptingExpressionEvaluator; import com.evolveum.midpoint.model.impl.security.SecurityHelper; import com.evolveum.midpoint.model.impl.util.RestServiceUtil; -import com.evolveum.midpoint.prism.Item; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.crypto.Protector; @@ -66,10 +65,10 @@ import javax.ws.rs.core.*; import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.Response.Status; -import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; import java.net.URI; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -843,11 +842,11 @@ public Response executeScript(@Convertor(ExecuteScriptConvertor.class) ExecuteSc Response response; try { if (Boolean.TRUE.equals(asynchronous)) { - scriptingService.evaluateExpression(command, task, result); + scriptingService.evaluateExpressionInBackground(command, task, result); URI resourceUri = uriInfo.getAbsolutePathBuilder().path(task.getOid()).build(task.getOid()); response = RestServiceUtil.createResponse(Response.Status.CREATED, resourceUri, result); } else { - ScriptExecutionResult executionResult = scriptingService.evaluateExpression(command, task, result); + ScriptExecutionResult executionResult = scriptingService.evaluateExpression(command, Collections.emptyMap(), task, result); ExecuteScriptResponseType responseData = new ExecuteScriptResponseType() .result(result.createOperationResultType()) .output(new ExecuteScriptOutputType() diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java index a886c39bbc5..a6852844d57 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java @@ -2026,10 +2026,11 @@ public ScriptExecutionResult evaluateExpression(ScriptingExpressionType expressi } @Override - public ScriptExecutionResult evaluateExpression(ExecuteScriptType scriptExecutionCommand, Task task, OperationResult result) + public ScriptExecutionResult evaluateExpression(@NotNull ExecuteScriptType scriptExecutionCommand, + @NotNull Map initialVariables, @NotNull Task task, @NotNull OperationResult result) throws ScriptExecutionException, SchemaException, SecurityViolationException { checkScriptingAuthorization(result); - ExecutionContext executionContext = scriptingExpressionEvaluator.evaluateExpression(scriptExecutionCommand, task, result); + ExecutionContext executionContext = scriptingExpressionEvaluator.evaluateExpression(scriptExecutionCommand, initialVariables, task, result); return executionContext.toExecutionResult(); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java index 314f3dc1709..50b11343690 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ExecutionContext.java @@ -44,7 +44,7 @@ public class ExecutionContext { private final ScriptingExpressionEvaluator scriptingExpressionEvaluator; private final StringBuilder consoleOutput = new StringBuilder(); private final Map globalVariables = new HashMap<>(); // will probably remain unused - private final Map initialVariables; // used e.g. when there are no data in a pipeline + private final Map initialVariables; // used e.g. when there are no data in a pipeline; these are frozen - i.e. made immutable if possible; to be cloned-on-use private PipelineData finalOutput; // used only when passing result to external clients (TODO do this more cleanly) public ExecutionContext(ScriptingExpressionEvaluationOptionsType options, Task task, @@ -57,7 +57,7 @@ public ExecutionContext(ScriptingExpressionEvaluationOptionsType options, Task t this.initialVariables = initialVariables; } - public Task getTask() { + public Task getTask() { return task; } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/PipelineData.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/PipelineData.java index cd7b613825e..1989c332131 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/PipelineData.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/PipelineData.java @@ -181,8 +181,7 @@ private Collection resolveQuery(Class return objects.stream().map(o -> ObjectTypeUtil.createObjectRef(o)).collect(Collectors.toList()); } - static PipelineData parseFrom(ValueListType input, Map initialVariables, - PrismContext prismContext) { + static PipelineData parseFrom(ValueListType input, Map frozenInitialVariables, PrismContext prismContext) { PipelineData rv = new PipelineData(); if (input != null) { for (Object o : input.getValue()) { @@ -191,18 +190,18 @@ static PipelineData parseFrom(ValueListType input, Map initialVa RawType raw = (RawType) o; PrismValue prismValue = raw.getAlreadyParsedValue(); if (prismValue != null) { - rv.addValue(prismValue, initialVariables); + rv.addValue(prismValue, frozenInitialVariables); } else { throw new IllegalArgumentException("Raw value in the input data: " + DebugUtil.debugDump(raw.getXnode())); // TODO attempt to parse it somehow (e.g. by passing to the pipeline and then parsing based on expected type) } } else { if (o instanceof Containerable) { - rv.addValue(((Containerable) o).asPrismContainerValue(), initialVariables); + rv.addValue(((Containerable) o).asPrismContainerValue(), frozenInitialVariables); } else if (o instanceof Referencable) { - rv.addValue(((Referencable) o).asReferenceValue(), initialVariables); + rv.addValue(((Referencable) o).asReferenceValue(), frozenInitialVariables); } else { - rv.addValue(new PrismPropertyValue<>(o, prismContext), initialVariables); + rv.addValue(new PrismPropertyValue<>(o, prismContext), frozenInitialVariables); } } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptExecutionTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptExecutionTaskHandler.java index 3f073a2ff8f..6e49094425e 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptExecutionTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptExecutionTaskHandler.java @@ -20,6 +20,7 @@ import com.evolveum.midpoint.model.api.ScriptExecutionResult; import com.evolveum.midpoint.model.api.ScriptingService; import com.evolveum.midpoint.prism.PrismProperty; +import com.evolveum.midpoint.schema.constants.ExpressionConstants; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.Task; @@ -37,7 +38,9 @@ import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @author mederly @@ -73,7 +76,9 @@ public TaskRunResult run(Task task) { try { task.startCollectingOperationStatsFromZero(true, false, true); task.setProgress(0); - ScriptExecutionResult executionResult = scriptingService.evaluateExpression(executeScriptProperty.getRealValue(), task, result); + Map initialVariables = new HashMap<>(); + initialVariables.put(ExpressionConstants.VAR_TASK.getLocalPart(), task.getTaskPrismObject().asObjectable()); + ScriptExecutionResult executionResult = scriptingService.evaluateExpression(executeScriptProperty.getRealValue(), initialVariables, task, result); LOGGER.debug("Execution output: {} item(s)", executionResult.getDataOutput().size()); LOGGER.debug("Execution result:\n", executionResult.getConsoleOutput()); result.computeStatus(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java index 18fe3454a20..0aa74e9e369 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/ScriptingExpressionEvaluator.java @@ -152,10 +152,11 @@ public ExecutionContext evaluateExpression(@NotNull ExecuteScriptType executeScr } // TEMPORARY! - public ExecutionContext evaluateExpression(@NotNull ExecuteScriptType executeScript, @NotNull Map initialVariables, Task task, OperationResult result) throws ScriptExecutionException { + public ExecutionContext evaluateExpression(@NotNull ExecuteScriptType executeScript, Map initialVariables, Task task, OperationResult result) throws ScriptExecutionException { Validate.notNull(executeScript.getScriptingExpression(), "Scripting expression must be present"); + Map frozenVariables = VariablesUtil.initialPreparation(initialVariables); ExecutionContext context = evaluateExpression(executeScript.getScriptingExpression().getValue(), - PipelineData.parseFrom(executeScript.getInput(), initialVariables, prismContext), executeScript.getOptions(), initialVariables, false, task, result); + PipelineData.parseFrom(executeScript.getInput(), frozenVariables, prismContext), executeScript.getOptions(), frozenVariables, false, task, result); context.computeResults(); return context; } @@ -163,17 +164,18 @@ public ExecutionContext evaluateExpression(@NotNull ExecuteScriptType executeScr // VERY TEMPORARY! public ExecutionContext evaluateExpressionPrivileged(@NotNull ExecuteScriptType executeScript, @NotNull Map initialVariables, Task task, OperationResult result) throws ScriptExecutionException { Validate.notNull(executeScript.getScriptingExpression(), "Scripting expression must be present"); + Map frozenVariables = VariablesUtil.initialPreparation(initialVariables); ExecutionContext context = evaluateExpression(executeScript.getScriptingExpression().getValue(), - PipelineData.parseFrom(executeScript.getInput(), initialVariables, prismContext), executeScript.getOptions(), initialVariables, true, task, result); + PipelineData.parseFrom(executeScript.getInput(), frozenVariables, prismContext), executeScript.getOptions(), frozenVariables, true, task, result); context.computeResults(); return context; } // main entry point from the outside private ExecutionContext evaluateExpression(ScriptingExpressionType expression, PipelineData data, - ScriptingExpressionEvaluationOptionsType options, Map initialVariables, + ScriptingExpressionEvaluationOptionsType options, Map frozenInitialVariables, boolean privileged, Task task, OperationResult result) throws ScriptExecutionException { - ExecutionContext context = new ExecutionContext(options, task, this, privileged, initialVariables); + ExecutionContext context = new ExecutionContext(options, task, this, privileged, frozenInitialVariables); PipelineData output; try { output = evaluateExpression(expression, data, context, result); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/VariablesUtil.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/VariablesUtil.java new file mode 100644 index 00000000000..da4e7435161 --- /dev/null +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/VariablesUtil.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.model.impl.scripting; + +import com.evolveum.midpoint.prism.Item; +import com.evolveum.midpoint.prism.PrismValue; +import com.evolveum.midpoint.prism.util.CloneUtil; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author mederly + */ +public class VariablesUtil { + + private static final Trace LOGGER = TraceManager.getTrace(VariablesUtil.class); + + // We create immutable versions of prism variables to avoid unnecessary downstream cloning + @NotNull + static Map initialPreparation(Map initialVariables) { + HashMap rv = new HashMap<>(); + if (initialVariables != null) { + for (Map.Entry entry : initialVariables.entrySet()) { + rv.put(entry.getKey(), makeImmutable(entry.getValue())); + } + } + return rv; + } + + @NotNull + public static Map cloneIfNecessary(@NotNull Map variables) { + HashMap rv = new HashMap<>(); + variables.forEach((key, value) -> rv.put(key, cloneIfNecessary(key, value))); + return rv; + } + + @Nullable + public static Object cloneIfNecessary(String name, Object value) { + if (value instanceof PrismValue || value instanceof Item) { + return makeImmutable(value); + } else { + try { + return CloneUtil.clone(value); + } catch (Throwable t) { + LOGGER.warn("Scripting variable value {} of type {} couldn't be cloned. Using original.", name, value.getClass()); + return value; + } + } + } + + @Nullable + public static Object makeImmutable(Object value) { + if (value instanceof PrismValue) { + PrismValue pval = (PrismValue) value; + if (!pval.isImmutable()) { + PrismValue clone = pval.clone(); + clone.setImmutable(true); + return clone; + } else { + return pval; + } + } else if (value instanceof Item) { + Item item = (Item) value; + if (!item.isImmutable()) { + Item clone = item.clone(); + clone.setImmutable(true); + return clone; + } else { + return item; + } + } else { + return value; + } + } + +} diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/ScriptExecutor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/ScriptExecutor.java index d5061df292a..612f44e8576 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/ScriptExecutor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/actions/ScriptExecutor.java @@ -16,17 +16,17 @@ package com.evolveum.midpoint.model.impl.scripting.actions; -import com.evolveum.midpoint.repo.common.expression.ExpressionSyntaxException; -import com.evolveum.midpoint.repo.common.expression.ExpressionUtil; -import com.evolveum.midpoint.repo.common.expression.ExpressionVariables; +import com.evolveum.midpoint.model.api.PipelineItem; import com.evolveum.midpoint.model.api.ScriptExecutionException; import com.evolveum.midpoint.model.common.expression.script.ScriptExpression; import com.evolveum.midpoint.model.common.expression.script.ScriptExpressionFactory; -import com.evolveum.midpoint.model.impl.scripting.PipelineData; import com.evolveum.midpoint.model.impl.scripting.ExecutionContext; -import com.evolveum.midpoint.model.api.PipelineItem; +import com.evolveum.midpoint.model.impl.scripting.PipelineData; import com.evolveum.midpoint.model.impl.util.Utils; import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.repo.common.expression.ExpressionSyntaxException; +import com.evolveum.midpoint.repo.common.expression.ExpressionUtil; +import com.evolveum.midpoint.repo.common.expression.ExpressionVariables; import com.evolveum.midpoint.schema.constants.ExpressionConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.util.QNameUtil; @@ -45,6 +45,10 @@ import javax.xml.namespace.QName; import java.util.Collection; import java.util.List; +import java.util.Map; + +import static com.evolveum.midpoint.model.impl.scripting.VariablesUtil.cloneIfNecessary; +import static com.evolveum.midpoint.schema.constants.SchemaConstants.NS_C; /** * @author mederly @@ -94,7 +98,7 @@ public PipelineData execute(ActionExpressionType expression, PipelineData input, context.checkTaskStop(); Throwable exception = null; try { - Object outObject = executeScript(scriptExpression, input, context, result); + Object outObject = executeScript(scriptExpression, input, context.getInitialVariables(), context, result); if (outObject != null) { addToData(outObject, PipelineData.newOperationResult(), output); } else { @@ -127,7 +131,7 @@ public PipelineData execute(ActionExpressionType expression, PipelineData input, } Throwable exception = null; try { - Object outObject = executeScript(scriptExpression, value, context, result); + Object outObject = executeScript(scriptExpression, value, item.getVariables(), context, result); if (outObject != null) { addToData(outObject, item.getResult(), output); } else { @@ -191,12 +195,14 @@ private ItemDefinition getItemDefinition(String itemUri) throws ScriptExecuti throw new ScriptExecutionException("Supplied item identification " + itemUri + " corresponds neither to item name nor type name"); } - private Object executeScript(ScriptExpression scriptExpression, Object input, ExecutionContext context, OperationResult result) + private Object executeScript(ScriptExpression scriptExpression, Object input, + Map externalVariables, ExecutionContext context, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { ExpressionVariables variables = new ExpressionVariables(); variables.addVariableDefinition(ExpressionConstants.VAR_INPUT, input); variables.addVariableDefinition(ExpressionConstants.VAR_PRISM_CONTEXT, prismContext); ExpressionUtil.addActorVariable(variables, securityEnforcer); + externalVariables.forEach((k, v) -> variables.addVariableDefinition(new QName(NS_C, k), cloneIfNecessary(k, v))); List rv = Utils.evaluateScript(scriptExpression, null, variables, true, "in '"+NAME+"' action", context.getTask(), result); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/expressions/SearchEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/expressions/SearchEvaluator.java index 5a9896296e2..545c8a3a67f 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/expressions/SearchEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/expressions/SearchEvaluator.java @@ -53,6 +53,8 @@ import java.util.Collections; import java.util.List; +import static com.evolveum.midpoint.model.impl.scripting.VariablesUtil.cloneIfNecessary; + /** * @author mederly */ @@ -76,8 +78,7 @@ public PipelineData evaluate(SearchExpressionType searchE if (data.isEmpty()) { // TODO fix this brutal hack (with dummyValue) PrismContainerValue dummyValue = new PrismContainerValue<>(prismContext); - PipelineItem dummyItem = new PipelineItem(dummyValue, PipelineData.newOperationResult()); - PipelineItem.copyClonedVariables(context.getInitialVariables(), dummyItem.getVariables()); + PipelineItem dummyItem = new PipelineItem(dummyValue, PipelineData.newOperationResult(), context.getInitialVariables()); data = Collections.singletonList(dummyItem); } @@ -112,7 +113,7 @@ public PipelineData evaluate(SearchExpressionType searchE ObjectQuery objectQuery; if (unresolvedObjectQuery != null) { ExpressionVariables variables = new ExpressionVariables(); - item.getVariables().forEach((name, value) -> variables.addVariableDefinition(new QName(name), value)); + item.getVariables().forEach((name, value) -> variables.addVariableDefinition(new QName(name), cloneIfNecessary(name, value))); try { objectQuery = ExpressionUtil .evaluateQueryExpressions(unresolvedObjectQuery, variables, expressionFactory, prismContext, diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/scripting/TestScriptingBasic.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/scripting/TestScriptingBasic.java index a2d98ae25ef..cf55112e412 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/scripting/TestScriptingBasic.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/scripting/TestScriptingBasic.java @@ -20,6 +20,7 @@ import com.evolveum.midpoint.model.impl.ModelWebService; import com.evolveum.midpoint.model.impl.scripting.ExecutionContext; import com.evolveum.midpoint.model.impl.scripting.PipelineData; +import com.evolveum.midpoint.model.impl.scripting.ScriptExecutionTaskHandler; import com.evolveum.midpoint.model.impl.scripting.ScriptingExpressionEvaluator; import com.evolveum.midpoint.model.intest.AbstractInitializedModelIntegrationTest; import com.evolveum.midpoint.notifications.api.transports.Message; @@ -48,6 +49,7 @@ import org.testng.annotations.Test; import org.testng.collections.Sets; +import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.namespace.QName; import java.io.File; @@ -91,12 +93,14 @@ public class TestScriptingBasic extends AbstractInitializedModelIntegrationTest private static final File NOTIFICATION_ABOUT_JACK_FILE = new File(TEST_DIR, "notification-about-jack.xml"); private static final File NOTIFICATION_ABOUT_JACK_TYPE2_FILE = new File(TEST_DIR, "notification-about-jack-type2.xml"); private static final File SCRIPTING_USERS_FILE = new File(TEST_DIR, "scripting-users.xml"); + private static final File SCRIPTING_USERS_IN_BACKGROUND_FILE = new File(TEST_DIR, "scripting-users-in-background.xml"); private static final File GENERATE_PASSWORDS_FILE = new File(TEST_DIR, "generate-passwords.xml"); private static final File GENERATE_PASSWORDS_2_FILE = new File(TEST_DIR, "generate-passwords-2.xml"); private static final File GENERATE_PASSWORDS_3_FILE = new File(TEST_DIR, "generate-passwords-3.xml"); private static final File ECHO_FILE = new File(TEST_DIR, "echo.xml"); + private static final QName USER_NAME_TASK_EXTENSION_PROPERTY = new QName("http://midpoint.evolveum.com/xml/ns/samples/piracy", "userName"); - @Autowired + @Autowired private ScriptingExpressionEvaluator scriptingExpressionEvaluator; @Override @@ -736,6 +740,39 @@ public void test500ScriptingUsers() throws Exception { realOids); } + @Test + public void test505ScriptingUsersInBackground() throws Exception { + final String TEST_NAME = "test505ScriptingUsersInBackground"; + TestUtil.displayTestTitle(this, TEST_NAME); + + // GIVEN + Task task = createTask(DOT_CLASS + TEST_NAME); + task.setOwner(getUser(USER_ADMINISTRATOR_OID)); + OperationResult result = task.getResult(); + JAXBElement expression = prismContext.parserFor(SCRIPTING_USERS_IN_BACKGROUND_FILE).parseRealValueToJaxbElement(); + + // WHEN + + ExecuteScriptType exec = new ExecuteScriptType().scriptingExpression(expression); + task.setExtensionPropertyValue(SchemaConstants.SE_EXECUTE_SCRIPT, exec); + task.getTaskPrismObject() + .findContainer(TaskType.F_EXTENSION) + .findOrCreateProperty(USER_NAME_TASK_EXTENSION_PROPERTY) + .addRealValue("jack"); + task.setHandlerUri(ScriptExecutionTaskHandler.HANDLER_URI); + taskManager.switchToBackground(task, result); + + waitForTaskFinish(task.getOid(), false); + task.refresh(result); + + // THEN + display(task.getResult()); + TestUtil.assertSuccess(task.getResult()); + PrismObject jack = getUser(USER_JACK_OID); + display("jack after creation", jack); + assertEquals("Wrong description", task.getName().getOrig(), jack.asObjectable().getDescription()); + } + @Test public void test510GeneratePasswords() throws Exception { final String TEST_NAME = "test510GeneratePasswords"; diff --git a/model/model-intest/src/test/resources/schema/piracy.xsd b/model/model-intest/src/test/resources/schema/piracy.xsd index f9cc1461049..566051f905b 100644 --- a/model/model-intest/src/test/resources/schema/piracy.xsd +++ b/model/model-intest/src/test/resources/schema/piracy.xsd @@ -159,4 +159,23 @@
+ + + + + + + + + + + + + false + + + + + + diff --git a/model/model-intest/src/test/resources/scripting/scripting-users-in-background.xml b/model/model-intest/src/test/resources/scripting/scripting-users-in-background.xml new file mode 100644 index 00000000000..98d4c3c7a20 --- /dev/null +++ b/model/model-intest/src/test/resources/scripting/scripting-users-in-background.xml @@ -0,0 +1,59 @@ + + + + + + c:UserType + + + + name + + + + basic.getExtensionPropertyValue(task, "", "userName") + + + + + + + + + execute-script + + script + + + import com.evolveum.midpoint.xml.ns._public.common.common_3.* + import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder + + log.info('Modifying user {}', input) + def deltas = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_DESCRIPTION) + .replace(basic.stringify(task.name)) + .asObjectDeltas(input.oid) + log.info('Change:\n{}', deltas.iterator().next().debugDump()) + midpoint.executeChanges(deltas, null) + + + + + From 1e170b1e8e812f491392f3530a92839d40c457af Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Thu, 28 Sep 2017 10:45:33 +0200 Subject: [PATCH 75/97] Fixing bug in matchesForRecursion. --- .../evaluator/AssociationFromLinkExpressionEvaluator.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationFromLinkExpressionEvaluator.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationFromLinkExpressionEvaluator.java index fdc62bf87d3..be3b7eefd8e 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationFromLinkExpressionEvaluator.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationFromLinkExpressionEvaluator.java @@ -164,8 +164,9 @@ private void gatherAssociationsFromAbstractRoleRecurse(OrgType thisOrg, private boolean matchesForRecursion(OrgType thisOrg) { for (String recurseUpOrgType: evaluatorType.getRecurseUpOrgType()) { - thisOrg.getOrgType().contains(recurseUpOrgType); - return true; + if (thisOrg.getOrgType().contains(recurseUpOrgType)) { + return true; + } } return false; } From 50e8c675546df683fc25a66c54a76759d57ce687 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Thu, 28 Sep 2017 14:41:25 +0200 Subject: [PATCH 76/97] Fixed PolyStringType.hashCode bug. --- .../evolveum/prism/xml/ns/_public/types_3/PolyStringType.java | 2 +- .../model/impl/lens/projector/policy/PolicyStateRecorder.java | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/types_3/PolyStringType.java b/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/types_3/PolyStringType.java index 26106c9baa9..2ee74aedbb2 100644 --- a/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/types_3/PolyStringType.java +++ b/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/types_3/PolyStringType.java @@ -494,7 +494,7 @@ private static JAXBElement copyOfStringElement(final JAXBElement public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((any == null) ? 0 : any.hashCode()); + result = prime * result + ((any == null || any.isEmpty()) ? 0 : any.hashCode()); result = prime * result + ((norm == null) ? 0 : norm.hashCode()); result = prime * result + ((orig == null) ? 0 : orig.hashCode()); return result; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java index b9f0fee8833..7bf10737576 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java @@ -126,9 +126,7 @@ private ComputationResult compute(@NotNull List rulesToReco cr.oldPolicySituations.addAll(existingPolicySituation); cr.oldTriggeredRules.addAll(existingTriggeredPolicyRule); cr.situationsNeedUpdate = !Objects.equals(cr.oldPolicySituations, cr.newPolicySituations); - // we do not use Objects.equal, because it uses hashCode, that is (for some reason) wrongly computed - //cr.rulesNeedUpdate = !Objects.equals(cr.oldTriggeredRules, cr.newTriggeredRules); - cr.rulesNeedUpdate = !MiscUtil.unorderedCollectionEquals(cr.oldTriggeredRules, cr.newTriggeredRules); + cr.rulesNeedUpdate = !Objects.equals(cr.oldTriggeredRules, cr.newTriggeredRules); // hope hashCode is computed well return cr; } From e3b79c0ba6518e7dfa3ba969d4ff46c116bddf80 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Fri, 29 Sep 2017 00:01:08 +0200 Subject: [PATCH 77/97] More parallelism improvements, bugfixies and test improvements (MID-4154) ... but still work in progress --- .../xml/ns/public/common/common-core-3.xsd | 14 + .../midpoint/schema/util/SchemaTestUtil.java | 2 +- .../impl/controller/ModelController.java | 45 +- .../ModelInteractionServiceImpl.java | 10 + .../controller/ModelOperationTaskHandler.java | 3 +- .../model/impl/lens/ChangeExecutor.java | 70 ++- .../midpoint/model/impl/lens/Clockwork.java | 98 ++-- .../midpoint/model/impl/lens/LensContext.java | 18 + .../model/impl/lens/LensElementContext.java | 9 +- .../midpoint/model/impl/lens/LensUtil.java | 7 +- .../model/impl/lens/PersonaProcessor.java | 24 +- .../impl/lens/ProjectorComponentRunnable.java | 3 +- .../lens/projector/ActivationProcessor.java | 17 +- .../impl/lens/projector/ContextLoader.java | 2 +- .../impl/lens/projector/FocusProcessor.java | 13 +- .../impl/lens/projector/MappingEvaluator.java | 4 +- .../projector/ProjectionMappingLoader.java | 15 +- .../projector/ProjectionValuesProcessor.java | 2 + .../model/impl/lens/projector/Projector.java | 19 +- .../sync/FocusValidityScannerTaskHandler.java | 5 +- .../model/impl/sync/RecomputeTaskHandler.java | 5 +- .../impl/sync/SynchronizationServiceImpl.java | 3 +- .../impl/trigger/RecomputeTriggerHandler.java | 18 +- .../AbstractSearchIterativeResultHandler.java | 7 +- .../model/impl/lens/TestClockwork.java | 3 +- .../midpoint/model/intest/TestActivation.java | 13 +- .../midpoint/model/intest/TestAudit.java | 135 +++--- .../midpoint/model/intest/TestDeputy.java | 230 +++++---- .../midpoint/model/intest/TestIntent.java | 23 +- .../midpoint/model/intest/TestMapping.java | 20 +- .../intest/TestModelServiceContract.java | 45 +- .../model/intest/TestMultiResource.java | 442 +++++++++--------- .../model/intest/TestUserTemplate.java | 4 +- .../src/test/resources/logback-test.xml | 8 +- .../mapping/resource-dummy-crimson.xml | 4 +- .../mapping/resource-dummy-light-crimson.xml | 4 +- .../provisioning/impl/ShadowManager.java | 2 +- .../manual/AbstractManualResourceTest.java | 16 +- 38 files changed, 712 insertions(+), 650 deletions(-) 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 11254bad103..9c422b482e1 100644 --- 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 @@ -11880,6 +11880,18 @@ + + + + Operation should be end with an error. + This is a recoverable error (precondition failed). + TODO: align with "fail" + + + + + + @@ -11915,6 +11927,8 @@ The whole operation should fail. This is to be used mainly for testing purposes, to check if conflict detection algorithm does not yield false positive results. + This fails with a system error. This is a definitive, non-recoverable fauilure. + TODO: align with "error" diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/util/SchemaTestUtil.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/util/SchemaTestUtil.java index 5b108c5c15e..c7589a1e1d5 100644 --- a/infra/schema/src/test/java/com/evolveum/midpoint/schema/util/SchemaTestUtil.java +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/util/SchemaTestUtil.java @@ -101,7 +101,7 @@ public static void assertFocusDefinition(ComplexTypeDefinition complexTypeDefini assertFalse("Metadata is runtime", metadataContainer.isRuntimeSchema()); assertFalse("Metadata is dynamic", metadataContainer.isDynamic()); assertTrue("Metadata is NOT operational", metadataContainer.isOperational()); - assertEquals("Metadata size", 12, metadataContainer.getDefinitions().size()); + assertEquals("Metadata size", 13, metadataContainer.getDefinitions().size()); PrismReferenceDefinition tenantRefDef = complexTypeDefinition.findItemDefinition(UserType.F_TENANT_REF, PrismReferenceDefinition.class); PrismAsserts.assertDefinition(tenantRefDef, UserType.F_TENANT_REF, ObjectReferenceType.COMPLEX_TYPE, 0, 1); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java index a886c39bbc5..c76cb0ec510 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java @@ -47,6 +47,7 @@ import com.evolveum.midpoint.prism.util.CloneUtil; import com.evolveum.midpoint.provisioning.api.ProvisioningOperationOptions; import com.evolveum.midpoint.provisioning.api.ProvisioningService; +import com.evolveum.midpoint.repo.api.PreconditionViolationException; import com.evolveum.midpoint.repo.api.RepoAddOptions; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.repo.cache.RepositoryCache; @@ -604,6 +605,15 @@ public Collection> executeChanges(fin CommunicationException|ConfigurationException|PolicyViolationException|SecurityViolationException|RuntimeException e) { ModelUtils.recordFatalError(result, e); throw e; + + } catch (PreconditionViolationException e) { + ModelUtils.recordFatalError(result, e); + // TODO: Temporary fix for 3.6.1 + // We do not want to propagate PreconditionViolationException to model API as that might break compatiblity + // ... and we do not really need that in 3.6.1 + // TODO: expose PreconditionViolationException in 3.7 + throw new SystemException(e); + } finally { task.markObjectActionExecutedBoundary(); } @@ -720,33 +730,20 @@ public void recompute(Class type, String oid, ModelExe result.cleanupResult(); - } catch (ExpressionEvaluationException e) { - ModelUtils.recordFatalError(result, e); - throw e; - } catch (SchemaException e) { - ModelUtils.recordFatalError(result, e); - throw e; - } catch (PolicyViolationException e) { - ModelUtils.recordFatalError(result, e); - throw e; - } catch (ObjectNotFoundException e) { + } catch (ExpressionEvaluationException | SchemaException | PolicyViolationException | ObjectNotFoundException | + ObjectAlreadyExistsException | CommunicationException | ConfigurationException | SecurityViolationException | + RuntimeException | Error e) { ModelUtils.recordFatalError(result, e); throw e; - } catch (ObjectAlreadyExistsException e) { + + } catch (PreconditionViolationException e) { ModelUtils.recordFatalError(result, e); - throw e; - } catch (CommunicationException e) { - ModelUtils.recordFatalError(result, e); - throw e; - } catch (ConfigurationException e) { - ModelUtils.recordFatalError(result, e); - throw e; - } catch (SecurityViolationException e) { - ModelUtils.recordFatalError(result, e); - throw e; - } catch (RuntimeException e) { - ModelUtils.recordFatalError(result, e); - throw e; + // TODO: Temporary fix for 3.6.1 + // We do not want to propagate PreconditionViolationException to model API as that might break compatiblity + // ... and we do not really need that in 3.6.1 + // TODO: expose PreconditionViolationException in 3.7 + throw new SystemException(e); + } finally { RepositoryCache.exit(); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java index 8f90e6d3580..d9613f16c32 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java @@ -87,6 +87,7 @@ import com.evolveum.midpoint.prism.query.RefFilter; import com.evolveum.midpoint.prism.query.TypeFilter; import com.evolveum.midpoint.provisioning.api.ProvisioningService; +import com.evolveum.midpoint.repo.api.PreconditionViolationException; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.result.OperationResultStatus; @@ -195,6 +196,15 @@ public ModelContext previewChanges( ExpressionEvaluationException e) { ModelUtils.recordFatalError(result, e); throw e; + + } catch (PreconditionViolationException e) { + ModelUtils.recordFatalError(result, e); + // TODO: Temporary fix for 3.6.1 + // We do not want to propagate PreconditionViolationException to model API as that might break compatiblity + // ... and we do not really need that in 3.6.1 + // TODO: expose PreconditionViolationException in 3.7 + throw new SystemException(e); + } finally { RepositoryCache.exit(); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelOperationTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelOperationTaskHandler.java index 5a3c795beb6..7fb45b0d3a6 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelOperationTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelOperationTaskHandler.java @@ -23,6 +23,7 @@ import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.provisioning.api.ProvisioningService; +import com.evolveum.midpoint.repo.api.PreconditionViolationException; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.task.api.TaskCategory; @@ -122,7 +123,7 @@ public TaskRunResult run(Task task) { result.computeStatus(); } runResult.setRunResultStatus(TaskRunResult.TaskRunResultStatus.FINISHED); - } catch (RuntimeException|CommonException e) { + } catch (CommonException | PreconditionViolationException | RuntimeException | Error e) { String message = "An exception occurred within model operation, in task " + task; LoggingUtils.logUnexpectedException(LOGGER, message, e); result.recordPartialError(message, e); 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 733c26d5c0d..b6898e4ceb0 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 @@ -181,7 +181,13 @@ public boolean executeChanges(LensContext context, Tas policySituationUpdater.storeFocusPolicySituation(context); } - if (focusDelta != null) { + if (focusDelta == null && !context.hasProjectionChange()) { + LOGGER.trace("Skipping focus change execute, because user delta is null"); + } else { + + if (focusDelta == null) { + focusDelta = focusContext.getObjectAny().createModifyDelta(); + } ObjectPolicyConfigurationType objectPolicyConfigurationType = focusContext .getObjectPolicyConfigurationType(); @@ -221,6 +227,9 @@ public boolean executeChanges(LensContext context, Tas } catch (PreconditionViolationException e) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Modification precondition failed for {}: {}", focusContext.getHumanReadableName(), e.getMessage()); + } // TODO: fatal error if the conflict resolution is "error" (later) result.recordHandledError(e); throw e; @@ -235,8 +244,6 @@ public boolean executeChanges(LensContext context, Tas } finally { context.reportProgress(new ProgressInformation(FOCUS_OPERATION, subResult)); } - } else { - LOGGER.trace("Skipping focus change execute, because user delta is null"); } } @@ -254,7 +261,7 @@ public boolean executeChanges(LensContext context, Tas if (!projCtx.isCanProject()) { continue; } - + // we should not get here, but just to be sure if (projCtx.getSynchronizationPolicyDecision() == SynchronizationPolicyDecision.IGNORE) { LOGGER.trace("Skipping ignored projection context {}", projCtx.toHumanReadableString()); @@ -318,7 +325,7 @@ public boolean executeChanges(LensContext context, Tas subResult.computeStatus(); subResult.recordNotApplicableIfUnknown(); continue; - + } else if (projDelta.isDelete() && projCtx.getResourceShadowDiscriminator() != null && projCtx.getResourceShadowDiscriminator().getOrder() > 0) { // HACK ... for higher-order context check if this was @@ -377,26 +384,12 @@ public boolean executeChanges(LensContext context, Tas restartRequested = true; break; // we will process remaining projections when retrying // the wave - } catch (CommunicationException e) { - recordProjectionExecutionException(e, projCtx, subResult, - SynchronizationPolicyDecision.BROKEN); - continue; - } catch (ConfigurationException e) { - recordProjectionExecutionException(e, projCtx, subResult, - SynchronizationPolicyDecision.BROKEN); - continue; - } catch (SecurityViolationException e) { - recordProjectionExecutionException(e, projCtx, subResult, - SynchronizationPolicyDecision.BROKEN); - continue; - } catch (ExpressionEvaluationException e) { - recordProjectionExecutionException(e, projCtx, subResult, - SynchronizationPolicyDecision.BROKEN); - continue; - } catch (RuntimeException e) { + + } catch (CommunicationException | ConfigurationException | SecurityViolationException | ExpressionEvaluationException | RuntimeException | Error e) { recordProjectionExecutionException(e, projCtx, subResult, SynchronizationPolicyDecision.BROKEN); continue; + } finally { context.reportProgress(new ProgressInformation(RESOURCE_OBJECT_OPERATION, projCtx.getResourceShadowDiscriminator(), subResult)); @@ -410,18 +403,7 @@ public boolean executeChanges(LensContext context, Tas } private void applyLastProvisioningTimestamp(LensContext context, ObjectDelta focusDelta) throws SchemaException { - Collection projectionContexts = context.getProjectionContexts(); - if (projectionContexts == null) { - return; - } - boolean hasProjectionChange = false; - for (LensProjectionContext projectionContext: projectionContexts) { - if (projectionContext.hasPrimaryDelta() || projectionContext.hasSecondaryDelta()) { - hasProjectionChange = true; - break; - } - } - if (!hasProjectionChange) { + if (!context.hasProjectionChange()) { return; } if (focusDelta.isAdd()) { @@ -520,7 +502,7 @@ private void applyObjectPolicy(LensFocusContext focusC } } - private

void recordProjectionExecutionException(Exception e, + private

void recordProjectionExecutionException(Throwable e, LensProjectionContext accCtx, OperationResult subResult, SynchronizationPolicyDecision decision) { subResult.recordFatalError(e); LOGGER.error("Error executing changes for {}: {}", @@ -584,7 +566,7 @@ private void updateLinks( // Already linked, nothing to do, only be sure, the // situation is set with the good value LOGGER.trace("Updating situation in already linked shadow."); - updateSituationInShadow(task, SynchronizationSituationType.LINKED, focusObjectContext, + updateSituationInShadow(task, SynchronizationSituationType.LINKED, null, focusObjectContext, projCtx, result); return; } @@ -594,7 +576,7 @@ private void updateLinks( linkShadow(focusContext.getOid(), projOid, focusObjectContext, projCtx, task, result); // be sure, that the situation is set correctly LOGGER.trace("Updating situation after shadow was linked."); - updateSituationInShadow(task, SynchronizationSituationType.LINKED, focusObjectContext, projCtx, + updateSituationInShadow(task, SynchronizationSituationType.LINKED, null, focusObjectContext, projCtx, result); } else { // Link should NOT exist @@ -621,7 +603,7 @@ private void updateLinks( LOGGER.trace("Resource object {} deleted, updating also situation in shadow.", projOid); // HACK HACK? try { - updateSituationInShadow(task, SynchronizationSituationType.DELETED, focusObjectContext, + updateSituationInShadow(task, SynchronizationSituationType.DELETED, true, focusObjectContext, projCtx, result); } catch (ObjectNotFoundException e) { // HACK HACK? @@ -635,7 +617,7 @@ private void updateLinks( // situation here. Reflect that in the shadow. LOGGER.trace("Resource object {} unlinked from the user, updating also situation in shadow.", projOid); - updateSituationInShadow(task, null, focusObjectContext, projCtx, result); + updateSituationInShadow(task, null, null, focusObjectContext, projCtx, result); } // Not linked, that's OK } @@ -760,7 +742,7 @@ private void unlinkShadow(String focusOid, PrismReference } private void updateSituationInShadow(Task task, - SynchronizationSituationType situation, LensFocusContext focusContext, + SynchronizationSituationType situation, Boolean dead, LensFocusContext focusContext, LensProjectionContext projectionCtx, OperationResult parentResult) throws ObjectNotFoundException, SchemaException { @@ -783,6 +765,11 @@ private void updateSituationInShadow(Task task, List> syncSituationDeltas = SynchronizationUtils .createSynchronizationSituationAndDescriptionDelta(account, situation, task.getChannel(), projectionCtx.hasFullShadow()); + + if (dead != null) { + PropertyDelta deadDelta = PropertyDelta.createModificationReplaceProperty(ShadowType.F_DEAD, account.getDefinition(), dead); + syncSituationDeltas.add(deadDelta); + } try { Utils.setRequestee(task, focusContext); @@ -1337,7 +1324,8 @@ private void executeModification(Ob if (conflictResolution != null) { String readVersion = objectContext.getObjectReadVersion(); if (readVersion != null) { - precondition = new VersionPrecondition<>(readVersion); + LOGGER.trace("Modification with precondition, readVersion={}", readVersion); + precondition = new VersionPrecondition<>(readVersion); } else { LOGGER.warn("Requested careful modification of {}, but there is no read version", objectContext.getHumanReadableName()); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java index b873986cba0..33d5e75a273 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java @@ -122,6 +122,7 @@ public class Clockwork { private static final int DEFAULT_MAX_CONFLICT_RESOLUTION_ATTEMPTS = 1; // synchronize with common-core-3.xsd private static final int DEFAULT_CONFLICT_RESOLUTION_DELAY_UNIT = 5000; // synchronize with common-core-3.xsd + private static final int MAX_PRECONDITION_CONFLICT_RESOLUTION_ATTEMPTS = 3; private static final Trace LOGGER = TraceManager.getTrace(Clockwork.class); @@ -163,7 +164,9 @@ public void setDebugListener(LensDebugListener debugListener) { private static final int DEFAULT_MAX_CLICKS = 200; - public HookOperationMode run(LensContext context, Task task, OperationResult result) throws SchemaException, PolicyViolationException, ExpressionEvaluationException, ObjectNotFoundException, ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException { + public HookOperationMode run(LensContext context, Task task, OperationResult result) + throws SchemaException, PolicyViolationException, ExpressionEvaluationException, ObjectNotFoundException, + ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException, PreconditionViolationException { LOGGER.trace("Running clockwork for context {}", context); if (InternalsConfig.consistencyChecks) { context.checkConsistence(); @@ -257,7 +260,7 @@ private HookOperationMode resolveFocusConflict(LensContex } // so, recompute is the action - LOGGER.debug("Conflict detected while updating {}, recomputing (options={})", focusObject, options); + LOGGER.debug("CONFLICT: Conflict detected while updating {}, recomputing (options={})", focusObject, options); if (context.getFocusContext() == null) { LOGGER.warn("No focus context, not possible to resolve conflict by focus recomputation"); // should really never occur @@ -282,37 +285,69 @@ private HookOperationMode resolveFocusConflict(LensContex } ConflictResolutionType focusConflictResolution = new ConflictResolutionType(); - focusConflictResolution.setAction(ConflictResolutionActionType.RESTART); + focusConflictResolution.setAction(ConflictResolutionActionType.ERROR); options.setFocusConflictResolution(focusConflictResolution); - PrismObject focus = repositoryService.getObject(focusClass, oid, null, result); - LensContext contextNew = contextFactory.createRecomputeContext(focus, options, task, result); - contextNew.setProgressListeners(new ArrayList<>(emptyIfNull(context.getProgressListeners()))); - int attemptOld = context.getConflictResolutionAttemptNumber(); - int attemptNew = attemptOld + 1; - boolean shouldExecuteAttempt = shouldExecuteAttempt(resolutionPolicy, attemptNew, context); - if (shouldExecuteAttempt) { + int preconditionAttempts = 0; + while (true) { + + PrismObject focus = repositoryService.getObject(focusClass, oid, null, result); + LensContext contextNew = contextFactory.createRecomputeContext(focus, options, task, result); + contextNew.setProgressListeners(new ArrayList<>(emptyIfNull(context.getProgressListeners()))); + + int attemptOld = context.getConflictResolutionAttemptNumber(); + int attemptNew = attemptOld + 1; + boolean shouldExecuteAttempt = shouldExecuteAttempt(context, resolutionPolicy, attemptNew); + if (!shouldExecuteAttempt) { + LOGGER.warn("CONFLICT: Couldn't resolve conflict even after {} resolution attempt(s), giving up.", attemptOld); + return HookOperationMode.FOREGROUND; + } contextNew.setConflictResolutionAttemptNumber(attemptNew); // this is a recursion; but limited to max attempts which should not be a large number - return run(contextNew, task, result); - } else { - LOGGER.warn("Couldn't resolve conflict even after {} resolution attempt(s), giving up.", attemptOld); - return HookOperationMode.FOREGROUND; + + delay(context, resolutionPolicy, attemptNew + preconditionAttempts); + + LOGGER.debug("CONFLICT: Recomputing {} as reaction to conflict (options={}, attempts={},{})", + context.getFocusContext().getHumanReadableName(), attemptNew, preconditionAttempts); + + try { + + HookOperationMode hookOperationMode = run(contextNew, task, result); + + // This may be in fact a giveup after recompute that was not able to cleanly proceed. + LOGGER.debug("CONFLICT: Clean recompute (or giveup) of {} achieved (options={}, attempts={},{})", + context.getFocusContext().getHumanReadableName(), options, attemptNew, preconditionAttempts); + + return hookOperationMode; + + } catch (PreconditionViolationException e) { + preconditionAttempts++; + LOGGER.debug("CONFLICT: Recompute precondition failed (attempt {}, precondition attempt {}), trying again", attemptNew, preconditionAttempts); + if (preconditionAttempts < MAX_PRECONDITION_CONFLICT_RESOLUTION_ATTEMPTS) { + continue; + } + LOGGER.warn("CONFLICT: Couldn't resolve conflict even after {} resolution attempt(s) and {} precondition attempts, giving up.", + attemptOld, preconditionAttempts); + return HookOperationMode.FOREGROUND; + } } } - private boolean shouldExecuteAttempt(@NotNull ConflictResolutionType resolutionPolicy, int attemptNew, - LensContext context) { + private boolean shouldExecuteAttempt(LensContext context, @NotNull ConflictResolutionType resolutionPolicy, int attemptNew) { int maxAttempts = defaultIfNull(resolutionPolicy.getMaxAttempts(), DEFAULT_MAX_CONFLICT_RESOLUTION_ATTEMPTS); if (attemptNew > maxAttempts) { return false; } + return true; + } + + private void delay(LensContext context, @NotNull ConflictResolutionType resolutionPolicy, int attempts) { long delayUnit = defaultIfNull(resolutionPolicy.getDelayUnit(), DEFAULT_CONFLICT_RESOLUTION_DELAY_UNIT); - for (int i = 0; i < attemptNew; i++) { + for (int i = 0; i < attempts; i++) { delayUnit *= 2; } long delay = (long) (Math.random() * delayUnit); - String message = "Waiting "+delay+" milliseconds before starting conflict resolution attempt "+attemptNew+" of "+maxAttempts; + String message = "CONFLICT: Waiting "+delay+" milliseconds before starting conflict resolution (delay exponent: "+attempts+")"; // TODO convey information about waiting time after some GUI mechanism for displaying it is available // (showing text messages is currently really ugly) context.reportProgress(new ProgressInformation(WAITING, EXITING)); @@ -323,7 +358,6 @@ private boolean shouldExecuteAttempt(@NotNull ConflictRes // ignore } context.reportProgress(new ProgressInformation(WAITING, EXITING)); - return true; } private void enterAssociationSearchExpressionEvaluatorCache() { @@ -357,7 +391,9 @@ private int getMaxClicks(LensContext context, Operatio } } - public HookOperationMode click(LensContext context, Task task, OperationResult result) throws SchemaException, PolicyViolationException, ExpressionEvaluationException, ObjectNotFoundException, ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException { + public HookOperationMode click(LensContext context, Task task, OperationResult result) + throws SchemaException, PolicyViolationException, ExpressionEvaluationException, ObjectNotFoundException, + ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException, PreconditionViolationException { // DO NOT CHECK CONSISTENCY of the context here. The context may not be fresh and consistent yet. Project will fix // that. Check consistency afterwards (and it is also checked inside projector several times). @@ -450,7 +486,7 @@ public HookOperationMode click(LensContext context, Ta } catch (CommunicationException | ConfigurationException | ExpressionEvaluationException | ObjectNotFoundException | PolicyViolationException | SchemaException | SecurityViolationException | RuntimeException | - ObjectAlreadyExistsException e) { + ObjectAlreadyExistsException | PreconditionViolationException e) { processClockworkException(context, e, task, result); throw e; } @@ -579,7 +615,9 @@ private void processPrimaryToSecondary(LensContext con context.setState(ModelState.SECONDARY); } - private void processSecondary(LensContext context, Task task, OperationResult result) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException, PolicyViolationException { + private void processSecondary(LensContext context, Task task, OperationResult result) + throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, + SecurityViolationException, ExpressionEvaluationException, PolicyViolationException, PreconditionViolationException { if (context.getExecutionWave() > context.getMaxWave() + 1) { context.setState(ModelState.FINAL); return; @@ -588,16 +626,8 @@ private void processSecondary(LensContext context, Tas Holder restartRequestedHolder = new Holder<>(); LensUtil.partialExecute("execution", - () -> { - boolean restartRequested; - try { - - restartRequested = changeExecutor.executeChanges(context, task, result); - - } catch (PreconditionViolationException e) { - LOGGER.debug("Precondition violation, will restart"); - restartRequested = true; - } + () -> { + boolean restartRequested = changeExecutor.executeChanges(context, task, result); restartRequestedHolder.setValue(restartRequested); }, context.getPartialProcessingOptions()::getExecution); @@ -697,7 +727,9 @@ private

boolean isShadowDeltaSignificant(ObjectDelta

d return false; } - private HookOperationMode processFinal(LensContext context, Task task, OperationResult result) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException, PolicyViolationException { + private HookOperationMode processFinal(LensContext context, Task task, OperationResult result) + throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, + SecurityViolationException, ExpressionEvaluationException, PolicyViolationException, PreconditionViolationException { auditFinalExecution(context, task, result); logFinalReadable(context, task, result); recordOperationExecution(context, null, task, result); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensContext.java index e438a685e99..a43259ecccc 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensContext.java @@ -1368,4 +1368,22 @@ public void unregisterConflictWatchers(RepositoryService repositoryService) { conflictWatchers.forEach(w -> repositoryService.unregisterConflictWatcher(w)); conflictWatchers.clear(); } + + public boolean hasProjectionChange() { + for (LensProjectionContext projectionContext: getProjectionContexts()) { + if (projectionContext.getWave() != getExecutionWave()) { + continue; + } + if (!projectionContext.isCanProject()) { + continue; + } + if (projectionContext.isThombstone()) { + continue; + } + if (projectionContext.hasPrimaryDelta() || projectionContext.hasSecondaryDelta()) { + return true; + } + } + return false; + } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java index e806d0b7880..c0decff2e84 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java @@ -709,9 +709,12 @@ protected String getDebugDumpTitle(String suffix) { public abstract String getHumanReadableName(); public String getObjectReadVersion() { - if (getObjectCurrent() != null) { - return getObjectCurrent().getVersion(); - } + // Do NOT use version from object current. + // Current object may be re-read, but the computation + // might be based on older data (objectOld). +// if (getObjectCurrent() != null) { +// return getObjectCurrent().getVersion(); +// } if (getObjectOld() != null) { return getObjectOld().getVersion(); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java index 37ba88f412a..d01439351d8 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java @@ -63,6 +63,7 @@ import com.evolveum.midpoint.prism.delta.PropertyDelta; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.provisioning.api.ProvisioningService; +import com.evolveum.midpoint.repo.api.PreconditionViolationException; import com.evolveum.midpoint.repo.common.expression.Expression; import com.evolveum.midpoint.repo.common.expression.ExpressionEvaluationContext; import com.evolveum.midpoint.repo.common.expression.ExpressionFactory; @@ -1231,14 +1232,14 @@ public static void processRuleWithException(@NotNull EvaluatedPolicyRule rule, C public static void partialExecute(String componentName, ProjectorComponentRunnable runnable, Supplier optionSupplier) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, - PolicyViolationException, ExpressionEvaluationException, ObjectAlreadyExistsException { + PolicyViolationException, ExpressionEvaluationException, ObjectAlreadyExistsException, PreconditionViolationException { partialExecute(componentName, runnable, optionSupplier, null); } public static void partialExecute(String componentName, ProjectorComponentRunnable runnable, Supplier optionSupplier, OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, - PolicyViolationException, ExpressionEvaluationException, ObjectAlreadyExistsException { + PolicyViolationException, ExpressionEvaluationException, ObjectAlreadyExistsException, PreconditionViolationException { PartialProcessingTypeType option = optionSupplier.get(); if (option == PartialProcessingTypeType.SKIP) { LOGGER.debug("Skipping projector component {} because partial execution option is set to {}", componentName, option); @@ -1248,7 +1249,7 @@ public static void partialExecute(String componentName, ProjectorComponentRunnab runnable.run(); LOGGER.trace("Projector component finished: {}", componentName); } catch (SchemaException | ObjectNotFoundException | CommunicationException | ConfigurationException | SecurityViolationException - | PolicyViolationException | ExpressionEvaluationException | ObjectAlreadyExistsException | RuntimeException | Error e) { + | PolicyViolationException | ExpressionEvaluationException | ObjectAlreadyExistsException | PreconditionViolationException | RuntimeException | Error e) { LOGGER.trace("Projector component error: {}: {}: {}", componentName, e.getClass().getSimpleName(), e.getMessage()); if (result != null) { result.recordFatalError(e); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/PersonaProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/PersonaProcessor.java index acfecb83250..b5563a21c32 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/PersonaProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/PersonaProcessor.java @@ -41,6 +41,7 @@ import com.evolveum.midpoint.prism.delta.DeltaSetTriple; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.repo.api.PreconditionViolationException; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.FocusTypeUtil; @@ -105,7 +106,9 @@ public class PersonaProcessor { private PrismContext prismContext; @SuppressWarnings({ "unchecked", "rawtypes" }) - public HookOperationMode processPersonaChanges(LensContext context, Task task, OperationResult result) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException, PolicyViolationException { + public HookOperationMode processPersonaChanges(LensContext context, Task task, OperationResult result) + throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, CommunicationException, + ConfigurationException, SecurityViolationException, ExpressionEvaluationException, PolicyViolationException, PreconditionViolationException { LensFocusContext focusContext = context.getFocusContext(); if (focusContext == null) { @@ -127,7 +130,9 @@ public HookOperationMode processPersonaChanges(LensContex return processPersonaChangesFocus((LensContext) context, task, result); } - public HookOperationMode processPersonaChangesFocus(LensContext context, Task task, OperationResult result) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException, PolicyViolationException { + public HookOperationMode processPersonaChangesFocus(LensContext context, Task task, OperationResult result) + throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, CommunicationException, + ConfigurationException, SecurityViolationException, ExpressionEvaluationException, PolicyViolationException, PreconditionViolationException { DeltaSetTriple> evaluatedAssignmentTriple = (DeltaSetTriple)context.getEvaluatedAssignmentTriple(); if (evaluatedAssignmentTriple == null || evaluatedAssignmentTriple.isEmpty()) { return HookOperationMode.FOREGROUND; @@ -262,7 +267,8 @@ private boolean personaMatches(FocusType persona, PersonaKey key) { public void personaAdd(LensContext context, PersonaKey key, PersonaConstruction construction, Task task, OperationResult result) - throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, PolicyViolationException, ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException { + throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, PolicyViolationException, ObjectAlreadyExistsException, + CommunicationException, ConfigurationException, SecurityViolationException, PreconditionViolationException { PrismObject focus = context.getFocusContext().getObjectNew(); LOGGER.debug("Adding persona {} for {} using construction {}", key, focus, construction); PersonaConstructionType constructionType = construction.getConstructionType(); @@ -302,7 +308,8 @@ public void personaAdd(LensContext public void personaModify(LensContext context, PersonaKey key, PersonaConstruction construction, PrismObject existingPersona, Task task, OperationResult result) - throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, PolicyViolationException, ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException { + throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, PolicyViolationException, + ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException, PreconditionViolationException { PrismObject focus = context.getFocusContext().getObjectNew(); LOGGER.debug("Modifying persona {} for {} using construction {}", key, focus, construction); PersonaConstructionType constructionType = construction.getConstructionType(); @@ -328,7 +335,10 @@ public void personaModify(LensContext executePersonaDelta(targetDelta, task, result); } - public void personaDelete(LensContext context, PersonaKey key, FocusType existingPersona, Task task, OperationResult result) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException { + public void personaDelete(LensContext context, PersonaKey key, FocusType existingPersona, + Task task, OperationResult result) + throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException, + CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException, PreconditionViolationException { PrismObject focus = context.getFocusContext().getObjectOld(); LOGGER.debug("Deleting persona {} for {}: ", key, focus, existingPersona); ObjectDelta targetDelta = existingPersona.asPrismObject().createDeleteDelta(); @@ -358,7 +368,9 @@ private void unlink(LensContext context, FocusType per repositoryService.modifyObject(delta.getObjectTypeClass(), delta.getOid(), delta.getModifications(), result); } - private void executePersonaDelta(ObjectDelta delta, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, PolicyViolationException, ExpressionEvaluationException, ObjectAlreadyExistsException, SecurityViolationException { + private void executePersonaDelta(ObjectDelta delta, Task task, OperationResult result) + throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, + PolicyViolationException, ExpressionEvaluationException, ObjectAlreadyExistsException, SecurityViolationException, PreconditionViolationException { Collection> deltas = MiscSchemaUtil.createCollection(delta); LensContext context = contextFactory.createContext(deltas, null, task, result); // Persona changes are all "secondary" changes, trigerred by roles and policies. We do not want to authorize diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ProjectorComponentRunnable.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ProjectorComponentRunnable.java index a20226a39ae..65898c787d7 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ProjectorComponentRunnable.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ProjectorComponentRunnable.java @@ -15,6 +15,7 @@ */ package com.evolveum.midpoint.model.impl.lens; +import com.evolveum.midpoint.repo.api.PreconditionViolationException; import com.evolveum.midpoint.util.exception.CommunicationException; import com.evolveum.midpoint.util.exception.ConfigurationException; import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; @@ -33,6 +34,6 @@ public interface ProjectorComponentRunnable { void run() throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, - SecurityViolationException, PolicyViolationException, ExpressionEvaluationException, ObjectAlreadyExistsException; + SecurityViolationException, PolicyViolationException, ExpressionEvaluationException, ObjectAlreadyExistsException, PreconditionViolationException; } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ActivationProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ActivationProcessor.java index 345d1ef1e15..dc383c1d266 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ActivationProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ActivationProcessor.java @@ -122,9 +122,20 @@ private void processActivationFocal(LensContext context processActivationMetadata(context, projectionContext, now, result); return; } - processActivationUserCurrent(context, projectionContext, now, task, result); - processActivationMetadata(context, projectionContext, now, result); - processActivationUserFuture(context, projectionContext, now, task, result); + try { + + processActivationUserCurrent(context, projectionContext, now, task, result); + processActivationMetadata(context, projectionContext, now, result); + processActivationUserFuture(context, projectionContext, now, task, result); + + } catch (ObjectNotFoundException e) { + if (projectionContext.isThombstone()) { + // This is not critical. The projection is marked as thombstone and we can go on with processing + // No extra action is needed. + } else { + throw e; + } + } } public void processActivationUserCurrent(LensContext context, LensProjectionContext projCtx, diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ContextLoader.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ContextLoader.java index 32653c97e11..7e56d7f5793 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ContextLoader.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ContextLoader.java @@ -1277,7 +1277,7 @@ public void loadFullShadow(LensContext context, LensPr projCtx.setOid(objectCurrent.getOid()); } catch (ObjectNotFoundException ex) { - LOGGER.trace("Load of full resource object {} ended with ObjectNotFoundException (options={})", projCtx, getOptions); + LOGGER.debug("Load of full resource object {} ended with ObjectNotFoundException (options={})", projCtx, getOptions); if (projCtx.isDelete()){ //this is OK, shadow was deleted, but we will continue in processing with old shadow..and set it as full so prevent from other full loading projCtx.setFullShadow(true); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java index 2416410aede..ce28de1e9b7 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java @@ -57,6 +57,7 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.path.NameItemPathSegment; import com.evolveum.midpoint.prism.polystring.PolyString; +import com.evolveum.midpoint.repo.api.PreconditionViolationException; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; @@ -113,9 +114,6 @@ public class FocusProcessor { @Autowired private ObjectTemplateProcessor objectTemplateProcessor; - @Autowired - private MappingFactory mappingFactory; - @Autowired private PrismContext prismContext; @@ -145,8 +143,9 @@ public class FocusProcessor { private PolicyRuleProcessor policyRuleProcessor; void processFocus(LensContext context, String activityDescription, - XMLGregorianCalendar now, Task task, OperationResult result) throws ObjectNotFoundException, - SchemaException, ExpressionEvaluationException, PolicyViolationException, ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException { + XMLGregorianCalendar now, Task task, OperationResult result) + throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, PolicyViolationException, + ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException, PreconditionViolationException { LensFocusContext focusContext = context.getFocusContext(); if (focusContext == null) { @@ -163,8 +162,8 @@ void processFocus(LensContext con private void processFocusFocus(LensContext context, String activityDescription, XMLGregorianCalendar now, Task task, OperationResult result) - throws ObjectNotFoundException, - SchemaException, ExpressionEvaluationException, PolicyViolationException, ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException { + throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, PolicyViolationException, + ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException, PreconditionViolationException { LensFocusContext focusContext = context.getFocusContext(); ObjectTemplateType objectTemplate = context.getFocusTemplate(); PartialProcessingOptionsType partialProcessingOptions = context.getPartialProcessingOptions(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/MappingEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/MappingEvaluator.java index 00082e2ba0d..57d1dd758bb 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/MappingEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/MappingEvaluator.java @@ -303,7 +303,7 @@ public implements MappingLoader { + + private static final Trace LOGGER = TraceManager.getTrace(ProjectionMappingLoader.class); private LensProjectionContext projectionContext; private ContextLoader contextLoader; @@ -55,9 +59,14 @@ public boolean isLoaded() { @Override public PrismObject load(String loadReason, Task task, OperationResult result) throws ObjectNotFoundException, CommunicationException, SchemaException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { contextLoader.loadFullShadow(context, projectionContext, loadReason, task, result); - if (projectionContext.getSynchronizationPolicyDecision() == SynchronizationPolicyDecision.BROKEN) { - // TODO - } + if (SynchronizationPolicyDecision.BROKEN.equals(projectionContext.getSynchronizationPolicyDecision())) { + LOGGER.debug("Attempt to load full object for {} failed, projection context is broken", projectionContext.getHumanReadableName()); + throw new ObjectNotFoundException("Projection loading failed, projection broken"); + } + if (projectionContext.isThombstone()) { + LOGGER.debug("Projection {} got thombstoned", projectionContext.getHumanReadableName()); + throw new ObjectNotFoundException("Projection loading failed, projection thombstoned"); + } return projectionContext.getObjectCurrent(); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ProjectionValuesProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ProjectionValuesProcessor.java index 14762911fb3..c45afe99b16 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ProjectionValuesProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ProjectionValuesProcessor.java @@ -313,6 +313,7 @@ private void processProjections(LensContext context, projContext.setSynchronizationPolicyDecision(SynchronizationPolicyDecision.KEEP); projContext.setObjectOld(fullConflictingShadow.clone()); projContext.setObjectCurrent(fullConflictingShadow); + projContext.setOid(fullConflictingShadow.getOid()); projContext.setFullShadow(true); ObjectDelta secondaryDelta = projContext.getSecondaryDelta(); if (secondaryDelta != null && projContext.getOid() != null) { @@ -381,6 +382,7 @@ private void processProjections(LensContext context, cleanupContext(projContext, fullConflictingShadow); projContext.setObjectOld(fullConflictingShadow.clone()); projContext.setObjectCurrent(fullConflictingShadow); + projContext.setOid(fullConflictingShadow.getOid()); projContext.setFullShadow(true); projContext.setSynchronizationPolicyDecision(SynchronizationPolicyDecision.KEEP); ObjectDelta secondaryDelta = projContext.getSecondaryDelta(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/Projector.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/Projector.java index 17d4e7ecb11..f2a611ea237 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/Projector.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/Projector.java @@ -36,6 +36,7 @@ import com.evolveum.midpoint.model.impl.lens.LensUtil; import com.evolveum.midpoint.model.impl.lens.projector.credentials.ProjectionCredentialsProcessor; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; +import com.evolveum.midpoint.repo.api.PreconditionViolationException; import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; import com.evolveum.midpoint.schema.internals.InternalCounters; import com.evolveum.midpoint.schema.internals.InternalMonitor; @@ -109,7 +110,7 @@ public class Projector { public void project(LensContext context, String activityDescription, Task task, OperationResult parentResult) throws SchemaException, PolicyViolationException, ExpressionEvaluationException, ObjectNotFoundException, - ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException { + ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException, PreconditionViolationException { projectInternal(context, activityDescription, true, false, task, parentResult); } @@ -119,7 +120,7 @@ public void project(LensContext context, String activi public void resume(LensContext context, String activityDescription, Task task, OperationResult parentResult) throws SchemaException, PolicyViolationException, ExpressionEvaluationException, ObjectNotFoundException, - ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException { + ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException, PreconditionViolationException { if (context.getProjectionWave() != context.getExecutionWave()) { throw new IllegalStateException("Projector.resume called in illegal wave state: execution wave = " + context.getExecutionWave() + @@ -139,14 +140,14 @@ public void resume(LensContext context, String activit public void projectAllWaves(LensContext context, String activityDescription, Task task, OperationResult parentResult) throws SchemaException, PolicyViolationException, ExpressionEvaluationException, ObjectNotFoundException, - ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException { + ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException, PreconditionViolationException { projectInternal(context, activityDescription, true, true, task, parentResult); } private void projectInternal(LensContext context, String activityDescription, boolean fromStart, boolean allWaves, Task task, OperationResult parentResult) throws SchemaException, PolicyViolationException, ExpressionEvaluationException, ObjectNotFoundException, - ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException { + ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException, PreconditionViolationException { context.checkAbortRequested(); @@ -290,7 +291,7 @@ private void projectInternal(LensContext context, Stri computeResultStatus(now, result); } catch (SchemaException | PolicyViolationException | ExpressionEvaluationException | ObjectAlreadyExistsException | - ObjectNotFoundException | CommunicationException | ConfigurationException | SecurityViolationException e) { + ObjectNotFoundException | CommunicationException | ConfigurationException | SecurityViolationException | PreconditionViolationException e) { recordFatalError(e, now, result); throw e; } catch (RuntimeException e) { @@ -310,7 +311,9 @@ private void projectInternal(LensContext context, Stri private void projectProjection(LensContext context, LensProjectionContext projectionContext, PartialProcessingOptionsType partialProcessingOptions, - XMLGregorianCalendar now, String activityDescription, Task task, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, SchemaException, ConfigurationException, SecurityViolationException, PolicyViolationException, ExpressionEvaluationException, ObjectAlreadyExistsException { + XMLGregorianCalendar now, String activityDescription, Task task, OperationResult parentResult) + throws ObjectNotFoundException, CommunicationException, SchemaException, ConfigurationException, + SecurityViolationException, PolicyViolationException, ExpressionEvaluationException, ObjectAlreadyExistsException, PreconditionViolationException { if (projectionContext.getWave() != context.getProjectionWave()) { // Let's skip accounts that do not belong into this wave. @@ -364,6 +367,10 @@ private void projectProjection(LensContext context, Le }, partialProcessingOptions::getProjectionValues); + if (projectionContext.isThombstone()) { + result.recordStatus(OperationResultStatus.NOT_APPLICABLE, "Skipping projection because it is a thombstone"); + return; + } LensUtil.partialExecute("projectionCredentials", () -> { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/FocusValidityScannerTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/FocusValidityScannerTaskHandler.java index 6e9b2fadc8f..01e87efbe80 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/FocusValidityScannerTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/FocusValidityScannerTaskHandler.java @@ -31,6 +31,7 @@ import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.repo.api.PreconditionViolationException; import com.evolveum.midpoint.schema.result.OperationConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; @@ -238,7 +239,7 @@ protected AbstractScannerResultHandler createHandler(TaskRunResult run AbstractScannerResultHandler handler = new AbstractScannerResultHandler( coordinatorTask, FocusValidityScannerTaskHandler.class.getName(), "recompute", "recompute task", taskManager) { @Override - protected boolean handleObject(PrismObject object, Task workerTask, OperationResult result) throws CommonException { + protected boolean handleObject(PrismObject object, Task workerTask, OperationResult result) throws CommonException, PreconditionViolationException { if (oidAlreadySeen(coordinatorTask, object.getOid())) { LOGGER.trace("Recomputation already executed for {}", ObjectTypeUtil.toShortString(object)); } else { @@ -253,7 +254,7 @@ protected boolean handleObject(PrismObject object, Task workerTask, Op private void reconcileUser(PrismObject user, Task workerTask, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ObjectAlreadyExistsException, - ConfigurationException, PolicyViolationException, SecurityViolationException { + ConfigurationException, PolicyViolationException, SecurityViolationException, PreconditionViolationException { LOGGER.trace("Recomputing user {}", user); // We want reconcile option here. There may be accounts that are in wrong activation state. // We will not notice that unless we go with reconcile. diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/RecomputeTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/RecomputeTaskHandler.java index b4f4a4d6698..9e7cc220a15 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/RecomputeTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/RecomputeTaskHandler.java @@ -36,6 +36,7 @@ import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.repo.api.PreconditionViolationException; import com.evolveum.midpoint.schema.result.OperationConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.Task; @@ -111,7 +112,7 @@ protected AbstractSearchIterativeResultHandler createHandler(TaskRunR AbstractSearchIterativeResultHandler handler = new AbstractSearchIterativeResultHandler( coordinatorTask, RecomputeTaskHandler.class.getName(), "recompute", "recompute task", taskManager) { @Override - protected boolean handleObject(PrismObject object, Task workerTask, OperationResult result) throws CommonException { + protected boolean handleObject(PrismObject object, Task workerTask, OperationResult result) throws CommonException, PreconditionViolationException { recompute(object, getOptions(coordinatorTask), workerTask, result); return true; } @@ -134,7 +135,7 @@ private ModelExecuteOptions getOptions(Task coordinatorTask) throws SchemaExcept private void recompute(PrismObject focalObject, ModelExecuteOptions options, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ObjectAlreadyExistsException, - ConfigurationException, PolicyViolationException, SecurityViolationException { + ConfigurationException, PolicyViolationException, SecurityViolationException, PreconditionViolationException { LOGGER.trace("Recomputing object {}", focalObject); LensContext syncContext = contextFactory.createRecomputeContext(focalObject, options, task, result); 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 a793f87b584..0e74029c857 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 @@ -56,6 +56,7 @@ import com.evolveum.midpoint.prism.delta.PropertyDelta; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.provisioning.api.ResourceObjectShadowChangeDescription; +import com.evolveum.midpoint.repo.api.PreconditionViolationException; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; @@ -781,7 +782,7 @@ private SynchronizationSituationType reactToChange(Class void handle(PrismObject object, TriggerType tri clockwork.run(lensContext, task, result); LOGGER.trace("Recomputing of {}: {}", object, result.getStatus()); - } catch (SchemaException e) { - LOGGER.error(e.getMessage(), e); - } catch (ObjectNotFoundException e) { - LOGGER.error(e.getMessage(), e); - } catch (ExpressionEvaluationException e) { - LOGGER.error(e.getMessage(), e); - } catch (CommunicationException e) { - LOGGER.error(e.getMessage(), e); - } catch (ObjectAlreadyExistsException e) { - LOGGER.error(e.getMessage(), e); - } catch (ConfigurationException e) { - LOGGER.error(e.getMessage(), e); - } catch (PolicyViolationException e) { - LOGGER.error(e.getMessage(), e); - } catch (SecurityViolationException e) { + } catch (CommonException | PreconditionViolationException | RuntimeException | Error e) { LOGGER.error(e.getMessage(), e); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractSearchIterativeResultHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractSearchIterativeResultHandler.java index ef2de0be915..58d1308cc8f 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractSearchIterativeResultHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/util/AbstractSearchIterativeResultHandler.java @@ -17,6 +17,7 @@ import com.evolveum.midpoint.prism.PrismProperty; import com.evolveum.midpoint.prism.polystring.PolyString; +import com.evolveum.midpoint.repo.api.PreconditionViolationException; import com.evolveum.midpoint.repo.cache.RepositoryCache; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResultStatus; @@ -353,7 +354,7 @@ private void processRequest(ProcessingRequest request, Task workerTask, Operatio } } - } catch (CommonException|RuntimeException e) { + } catch (CommonException | PreconditionViolationException | Error | RuntimeException e) { if (isRecordIterationStatistics()) { workerTask.recordIterativeOperationEnd(objectName, objectDisplayName, null /* TODO */, object.getOid(), startTime, e); @@ -430,7 +431,7 @@ private boolean shouldReportProgress() { } } - private boolean processError(PrismObject object, Exception ex, OperationResult result) { + private boolean processError(PrismObject object, Throwable ex, OperationResult result) { int errorsCount = errors.incrementAndGet(); LOGGER.trace("Processing error, count: {}", errorsCount); @@ -480,7 +481,7 @@ public void setLogErrors(boolean logErrors) { this.logErrors = logErrors; } - protected abstract boolean handleObject(PrismObject object, Task workerTask, OperationResult result) throws CommonException; + protected abstract boolean handleObject(PrismObject object, Task workerTask, OperationResult result) throws CommonException, PreconditionViolationException; public class ProcessingRequest { public PrismObject object; diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestClockwork.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestClockwork.java index 8fec5f5df04..2f17ae28ff3 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestClockwork.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestClockwork.java @@ -60,6 +60,7 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; +import com.evolveum.midpoint.repo.api.PreconditionViolationException; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ResourceTypeUtil; import com.evolveum.midpoint.schema.util.SchemaTestConstants; @@ -402,7 +403,7 @@ private LensContext createJackAssignAccountContext(OperationResult res return context; } - private void unassignJackAccount() throws SchemaException, ObjectNotFoundException, IOException, JAXBException, PolicyViolationException, ExpressionEvaluationException, ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException { + private void unassignJackAccount() throws SchemaException, ObjectNotFoundException, IOException, JAXBException, PolicyViolationException, ExpressionEvaluationException, ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException, PreconditionViolationException { Task task = taskManager.createTaskInstance(TestClockwork.class.getName() + ".unassignJackAccount"); LensContext context = createUserLensContext(); OperationResult result = task.getResult(); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestActivation.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestActivation.java index b8a4def6458..48883376cfd 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestActivation.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestActivation.java @@ -1913,8 +1913,8 @@ public void test217ModifyLargoRemoveValidFrom() throws Exception { /** * Delete assignment from repo. Model should not notice. - * The change should be NOT applied after recompute. - * Accounts are not retrieved, therefore the change is not noticed. + * The change should be applied after recompute, because RED resource has + * strong mappings, which trigger account to be loaded. */ @Test public void test230JackUnassignRepoRecompute() throws Exception { @@ -1940,14 +1940,12 @@ public void test230JackUnassignRepoRecompute() throws Exception { // THEN displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + assertSuccess(result); - assertDummyAccount(RESOURCE_DUMMY_RED_NAME, ACCOUNT_JACK_DUMMY_USERNAME, "Jack Sparrow", true); + assertDummyAccount(RESOURCE_DUMMY_RED_NAME, ACCOUNT_JACK_DUMMY_USERNAME, "Jack Sparrow", false); } /** - * Deleted assignment from the repo (previous test). Model haven't noticed. * Now recompute with reconcile. The change should be applied after recompute. */ @Test @@ -1965,8 +1963,7 @@ public void test231JackRecomputeReconcile() throws Exception { // THEN displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + assertSuccess(result); assertDummyAccount(RESOURCE_DUMMY_RED_NAME, ACCOUNT_JACK_DUMMY_USERNAME, "Jack Sparrow", false); } diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestAudit.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestAudit.java index 65143b6b44d..3a1e9f9c3c0 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestAudit.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestAudit.java @@ -105,7 +105,7 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti @Test public void test000Sanity() throws Exception { final String TEST_NAME = "test000Sanity"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); assertTrue(modelAuditService.supportsRetrieval()); @@ -122,7 +122,7 @@ public void test000Sanity() throws Exception { @Test public void test010SanityJack() throws Exception { final String TEST_NAME = "test010SanityJack"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // WHEN List auditRecords = getObjectAuditRecords(USER_JACK_OID); @@ -136,20 +136,20 @@ public void test010SanityJack() throws Exception { @Test public void test100ModifyUserJackKid() throws Exception { final String TEST_NAME = "test100ModifyUserJackKid"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestAudit.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); initialTs = getTimeSafely(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modifyUserReplace(USER_JACK_OID, UserType.F_TITLE, task, result, createPolyString("Kid")); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -165,9 +165,9 @@ public void test100ModifyUserJackKid() throws Exception { @Test public void test105CreateUserHerman() throws Exception { final String TEST_NAME = "test105CreateUserHerman"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestAudit.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userHermanBefore = PrismTestUtil.parseObject(USER_HERMAN_FILE); @@ -177,12 +177,12 @@ public void test105CreateUserHerman() throws Exception { hermanInitialTs = getTimeSafely(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); addObject(userHermanBefore, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -197,9 +197,9 @@ public void test105CreateUserHerman() throws Exception { @Test public void test110ModifyUserJackSailor() throws Exception { final String TEST_NAME = "test110ModifyUserJackSailor"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestAudit.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); @@ -210,12 +210,12 @@ public void test110ModifyUserJackSailor() throws Exception { ActivationStatusType.DISABLED); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(objectDelta), null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -230,9 +230,9 @@ public void test110ModifyUserJackSailor() throws Exception { @Test public void test115ModifyUserHermanMarooned() throws Exception { final String TEST_NAME = "test115ModifyUserHermanMarooned"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestAudit.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta objectDelta = createModifyUserReplaceDelta(USER_HERMAN_OID, UserType.F_TITLE, @@ -241,14 +241,13 @@ public void test115ModifyUserHermanMarooned() throws Exception { objectDelta.addModification(createAssignmentModification(RESOURCE_DUMMY_OID, ShadowKindType.ACCOUNT, null, true)); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(objectDelta), null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); PrismObject user = getUser(USER_HERMAN_OID); display("Herman (marooned)", user); @@ -262,9 +261,9 @@ public void test115ModifyUserHermanMarooned() throws Exception { @Test public void test120ModifyUserJackCaptain() throws Exception { final String TEST_NAME = "test120ModifyUserJackCaptain"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestAudit.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta objectDelta = createModifyUserReplaceDelta(USER_JACK_OID, UserType.F_TITLE, @@ -274,14 +273,13 @@ public void test120ModifyUserJackCaptain() throws Exception { ActivationStatusType.ENABLED); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(objectDelta), null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); jackCaptainTs = getTimeSafely(); jackCaptainEid = assertObjectAuditRecords(USER_JACK_OID, 6); @@ -294,9 +292,9 @@ public void test120ModifyUserJackCaptain() throws Exception { @Test public void test125ModifyUserHermanHermit() throws Exception { final String TEST_NAME = "test125ModifyUserHermanHermit"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestAudit.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta objectDelta = createModifyUserReplaceDelta(USER_HERMAN_OID, UserType.F_TITLE, @@ -311,15 +309,14 @@ public void test125ModifyUserHermanHermit() throws Exception { null, null, null, true)); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(objectDelta), null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); PrismObject user = getUser(USER_HERMAN_OID); display("Herman (hermit)", user); @@ -332,9 +329,9 @@ public void test125ModifyUserHermanHermit() throws Exception { @Test public void test135ModifyUserHermanCivilisedHermit() throws Exception { final String TEST_NAME = "test135ModifyUserHermanCivilisedHermit"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestAudit.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta objectDelta = createModifyUserReplaceDelta(USER_HERMAN_OID, UserType.F_TITLE, @@ -344,30 +341,29 @@ public void test135ModifyUserHermanCivilisedHermit() throws Exception { null, null, null, false)); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(objectDelta), null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); PrismObject user = getUser(USER_HERMAN_OID); display("Herman (civilised hermit)", user); hermanCivilisedHermitTs = getTimeSafely(); - hermanCivilisedHermitEid = assertObjectAuditRecords(USER_HERMAN_OID, 8); - assertRecordsFromInitial(hermanCivilisedHermitTs, 14); + hermanCivilisedHermitEid = assertObjectAuditRecords(USER_HERMAN_OID, 9); + assertRecordsFromInitial(hermanCivilisedHermitTs, 15); } @Test public void test200ReconstructJackSailor() throws Exception { final String TEST_NAME = "test200ReconstructJackSailor"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestAudit.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userBefore = getUser(USER_JACK_OID); @@ -376,15 +372,14 @@ public void test200ReconstructJackSailor() throws Exception { PrismAsserts.assertPropertyValue(userBefore, UserType.F_TITLE, createPolyString("Captain")); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); PrismObject jackReconstructed = modelAuditService.reconstructObject(UserType.class, USER_JACK_OID, jackSailorEid, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); display("Reconstructed jack", jackReconstructed); @@ -397,9 +392,9 @@ public void test200ReconstructJackSailor() throws Exception { @Test public void test210ReconstructJackKid() throws Exception { final String TEST_NAME = "test210ReconstructJackKid"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestAudit.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userBefore = getUser(USER_JACK_OID); @@ -408,15 +403,14 @@ public void test210ReconstructJackKid() throws Exception { PrismAsserts.assertPropertyValue(userBefore, UserType.F_TITLE, createPolyString("Captain")); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); PrismObject jackReconstructed = modelAuditService.reconstructObject(UserType.class, USER_JACK_OID, jackKidEid, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); display("Reconstructed jack", jackReconstructed); @@ -431,9 +425,9 @@ public void test210ReconstructJackKid() throws Exception { @Test public void test250ReconstructHermanCreated() throws Exception { final String TEST_NAME = "test250ReconstructHermanCreated"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestAudit.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userBefore = getUser(USER_HERMAN_OID); @@ -445,15 +439,14 @@ public void test250ReconstructHermanCreated() throws Exception { assertAssignments(userBefore, 1); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); PrismObject hermanReconstructed = modelAuditService.reconstructObject(UserType.class, USER_HERMAN_OID, hermanCreatedEid, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); display("Reconstructed herman", hermanReconstructed); @@ -472,21 +465,20 @@ public void test250ReconstructHermanCreated() throws Exception { @Test public void test252ReconstructHermanMarooned() throws Exception { final String TEST_NAME = "test252ReconstructHermanMarooned"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestAudit.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); PrismObject hermanReconstructed = modelAuditService.reconstructObject(UserType.class, USER_HERMAN_OID, hermanMaroonedEid, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); display("Reconstructed herman", hermanReconstructed); @@ -506,21 +498,20 @@ public void test252ReconstructHermanMarooned() throws Exception { @Test public void test254ReconstructHermanHermit() throws Exception { final String TEST_NAME = "test254ReconstructHermanHermit"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestAudit.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); PrismObject hermanReconstructed = modelAuditService.reconstructObject(UserType.class, USER_HERMAN_OID, hermanHermitEid, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); display("Reconstructed herman", hermanReconstructed); @@ -588,7 +579,7 @@ public void test300ConcurrentAudits() throws Exception { Thread thread = new Thread(() -> { try { login(userAdministrator); - Task threadTask = taskManager.createTaskInstance(TestAudit.class.getName() + "." + TEST_NAME); + Task threadTask = createTask(TEST_NAME); OperationResult threadResult = threadTask.getResult(); for (int iteration = 0; iteration < ITERATIONS; iteration++) { display("Executing iteration " + iteration + " on user " + index); @@ -659,7 +650,7 @@ public void test310ConcurrentAuditsRaw() throws Exception { Thread thread = new Thread(() -> { try { login(userAdministrator); - Task threadTask = taskManager.createTaskInstance(TestAudit.class.getName() + "." + TEST_NAME); + Task threadTask = createTask(TEST_NAME); OperationResult threadResult = threadTask.getResult(); for (int iteration = 0; iteration < ITERATIONS; iteration++) { display("Executing iteration " + iteration + " in worker " + index); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestDeputy.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestDeputy.java index 87909e3b786..ca24db2d83c 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestDeputy.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestDeputy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Evolveum + * Copyright (c) 2016-2017 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -71,7 +71,7 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti @Test public void test000Sanity() throws Exception { final String TEST_NAME = "test000Sanity"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); PrismObject userJack = getUser(USER_JACK_OID); display("User Jack", userJack); @@ -93,18 +93,18 @@ public void test000Sanity() throws Exception { @Test public void test100AssignDeputyNoBigDeal() throws Exception { final String TEST_NAME = "test100AssignDeputyNoBigDeal"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignDeputy(USER_BARBOSSA_OID, USER_JACK_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -130,18 +130,18 @@ public void test100AssignDeputyNoBigDeal() throws Exception { @Test public void test109UnassignDeputyNoBigDeal() throws Exception { final String TEST_NAME = "test109UnassignDeputyNoBigDeal"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); unassignDeputy(USER_BARBOSSA_OID, USER_JACK_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -166,18 +166,18 @@ public void test109UnassignDeputyNoBigDeal() throws Exception { @Test public void test110AssignJackPirate() throws Exception { final String TEST_NAME = "test110AssignJackPirate"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignRole(USER_JACK_OID, ROLE_PIRATE_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -204,18 +204,18 @@ public void test110AssignJackPirate() throws Exception { @Test public void test112AssignDeputyPirate() throws Exception { final String TEST_NAME = "test112AssignDeputyPirate"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignDeputy(USER_BARBOSSA_OID, USER_JACK_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -247,18 +247,18 @@ public void test112AssignDeputyPirate() throws Exception { @Test public void test119UnassignDeputyPirate() throws Exception { final String TEST_NAME = "test119UnassignDeputyPirate"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); unassignDeputy(USER_BARBOSSA_OID, USER_JACK_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -285,9 +285,9 @@ public void test119UnassignDeputyPirate() throws Exception { @Test public void test120AssignbarbossaDeputyOfGuybrush() throws Exception { final String TEST_NAME = "test120AssignbarbossaDeputyOfGuybrush"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userGuybrushBefore = getUser(USER_GUYBRUSH_OID); @@ -295,12 +295,12 @@ public void test120AssignbarbossaDeputyOfGuybrush() throws Exception { assertLinks(userGuybrushBefore, 1); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignDeputy(USER_BARBOSSA_OID, USER_GUYBRUSH_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -328,18 +328,18 @@ public void test120AssignbarbossaDeputyOfGuybrush() throws Exception { @Test public void test122AssignGuybrushPirate() throws Exception { final String TEST_NAME = "test122AssignGuybrushPirate"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignRole(USER_GUYBRUSH_OID, ROLE_PIRATE_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -367,18 +367,18 @@ public void test122AssignGuybrushPirate() throws Exception { @Test public void test124RecomputeBarbossa() throws Exception { final String TEST_NAME = "test124RecomputeBarbossa"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); recomputeUser(USER_BARBOSSA_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -408,18 +408,18 @@ public void test124RecomputeBarbossa() throws Exception { @Test public void test126UnassignGuybrushPirate() throws Exception { final String TEST_NAME = "test126UnassignGuybrushPirate"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); unassignRole(USER_GUYBRUSH_OID, ROLE_PIRATE_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -446,19 +446,19 @@ public void test126UnassignGuybrushPirate() throws Exception { @Test public void test128RecomputeBarbossa() throws Exception { final String TEST_NAME = "test128RecomputeBarbossa"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); recomputeUser(USER_BARBOSSA_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -480,18 +480,18 @@ public void test128RecomputeBarbossa() throws Exception { @Test public void test129UnassignBarbossaDeputyOfGuybrush() throws Exception { final String TEST_NAME = "test129UnassignBarbossaDeputyOfGuybrush"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); unassignDeputy(USER_BARBOSSA_OID, USER_GUYBRUSH_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -516,9 +516,9 @@ public void test129UnassignBarbossaDeputyOfGuybrush() throws Exception { @Test public void test150AssignJackMoreRoles() throws Exception { final String TEST_NAME = "test150AssignJackMoreRoles"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta userDelta = createAssignmentUserDelta(USER_JACK_OID, ROLE_PIRATE_OID, RoleType.COMPLEX_TYPE, @@ -538,12 +538,12 @@ public void test150AssignJackMoreRoles() throws Exception { null, null, (ActivationType) null, true))); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(userDelta), null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -570,20 +570,20 @@ public void test150AssignJackMoreRoles() throws Exception { @Test public void test152AssignbarbossaDeputyLimitedDeputy() throws Exception { final String TEST_NAME = "test152AssignbarbossaDeputyLimitedDeputy"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignDeputyLimits(USER_BARBOSSA_OID, USER_JACK_OID, task, result, createRoleReference(ROLE_PIRATE_OID), createOrgReference(ORG_MINISTRY_OF_RUM_OID, SchemaConstants.ORG_MANAGER)); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -607,20 +607,20 @@ public void test152AssignbarbossaDeputyLimitedDeputy() throws Exception { @Test public void test154UnassignbarbossaDeputyLimitedDeputy() throws Exception { final String TEST_NAME = "test154UnassignbarbossaDeputyLimitedDeputy"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); unassignDeputyLimits(USER_BARBOSSA_OID, USER_JACK_OID, task, result, createRoleReference(ROLE_PIRATE_OID), createOrgReference(ORG_MINISTRY_OF_RUM_OID, SchemaConstants.ORG_MANAGER)); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -641,13 +641,13 @@ public void test154UnassignbarbossaDeputyLimitedDeputy() throws Exception { @Test public void test156AssignbarbossaDeputyLimitedDeputyRed() throws Exception { final String TEST_NAME = "test156AssignbarbossaDeputyLimitedDeputyRed"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignDeputyLimits(USER_BARBOSSA_OID, USER_JACK_OID, task, result, createRoleReference(ROLE_RED_SAILOR_OID), @@ -655,7 +655,7 @@ public void test156AssignbarbossaDeputyLimitedDeputyRed() throws Exception { ); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -679,16 +679,16 @@ public void test156AssignbarbossaDeputyLimitedDeputyRed() throws Exception { @Test public void test159UnassignbarbossaDeputyLimitedDeputyRed() throws Exception { final String TEST_NAME = "test159UnassignbarbossaDeputyLimitedDeputyRed"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); unassignDeputyLimits(USER_BARBOSSA_OID, USER_JACK_OID, task, result, createRoleReference(ROLE_RED_SAILOR_OID), @@ -696,7 +696,7 @@ public void test159UnassignbarbossaDeputyLimitedDeputyRed() throws Exception { ); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -721,20 +721,20 @@ public void test159UnassignbarbossaDeputyLimitedDeputyRed() throws Exception { @Test public void test160AssignbarbossaDeputyLimitedDeputyEmpty() throws Exception { final String TEST_NAME = "test160AssignbarbossaDeputyLimitedDeputyEmpty"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignDeputyLimits(USER_BARBOSSA_OID, USER_JACK_OID, task, result, createRoleReference(ROLE_EMPTY_OID) ); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -758,23 +758,23 @@ public void test160AssignbarbossaDeputyLimitedDeputyEmpty() throws Exception { @Test public void test162UnassignbarbossaDeputyLimitedDeputyEmpty() throws Exception { final String TEST_NAME = "test162UnassignbarbossaDeputyLimitedDeputyEmpty"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); unassignDeputyLimits(USER_BARBOSSA_OID, USER_JACK_OID, task, result, createRoleReference(ROLE_EMPTY_OID) ); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -799,20 +799,20 @@ public void test162UnassignbarbossaDeputyLimitedDeputyEmpty() throws Exception { @Test public void test170AddRoleDrinker() throws Exception { final String TEST_NAME = "test170AssignJackRoleDrinker"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject role = PrismTestUtil.parseObject(ROLE_DRINKER_FILE); display("Adding role", role); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); addObject(role, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -825,17 +825,17 @@ public void test170AddRoleDrinker() throws Exception { @Test public void test172AssignJackRoleDrinker() throws Exception { final String TEST_NAME = "test170AssignJackRoleDrinker"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignRole(USER_JACK_OID, ROLE_DRINKER_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -856,20 +856,20 @@ public void test172AssignJackRoleDrinker() throws Exception { @Test public void test172AssignbarbossaDeputyLimitedDeputyDrinker() throws Exception { final String TEST_NAME = "test172AssignbarbossaDeputyLimitedDeputyDrinker"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignDeputyLimits(USER_BARBOSSA_OID, USER_JACK_OID, task, result, createRoleReference(ROLE_DRINKER_OID) ); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -885,23 +885,23 @@ public void test172AssignbarbossaDeputyLimitedDeputyDrinker() throws Exception { @Test public void test178UnassignbarbossaDeputyLimitedDeputyDrinker() throws Exception { final String TEST_NAME = "test178UnassignbarbossaDeputyLimitedDeputyDrinker"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); unassignDeputyLimits(USER_BARBOSSA_OID, USER_JACK_OID, task, result, createRoleReference(ROLE_DRINKER_OID) ); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -926,13 +926,13 @@ public void test178UnassignbarbossaDeputyLimitedDeputyDrinker() throws Exception @Test public void test180AssignbarbossaDeputyLimitedDeputyEmptyDrinker() throws Exception { final String TEST_NAME = "test180AssignbarbossaDeputyLimitedDeputyEmptyDrinker"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignDeputyLimits(USER_BARBOSSA_OID, USER_JACK_OID, task, result, createRoleReference(ROLE_EMPTY_OID), @@ -940,7 +940,7 @@ public void test180AssignbarbossaDeputyLimitedDeputyEmptyDrinker() throws Except ); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -964,16 +964,16 @@ public void test180AssignbarbossaDeputyLimitedDeputyEmptyDrinker() throws Except @Test public void test182UnassignbarbossaDeputyLimitedDeputyEmptyDrinker() throws Exception { final String TEST_NAME = "test182UnassignbarbossaDeputyLimitedDeputyEmptyDrinker"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); unassignDeputyLimits(USER_BARBOSSA_OID, USER_JACK_OID, task, result, createRoleReference(ROLE_EMPTY_OID), @@ -981,9 +981,8 @@ public void test182UnassignbarbossaDeputyLimitedDeputyEmptyDrinker() throws Exce ); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); @@ -1007,7 +1006,7 @@ public void test182UnassignbarbossaDeputyLimitedDeputyEmptyDrinker() throws Exce @Test public void test800ImportValidityScannerTask() throws Exception { final String TEST_NAME = "test800ImportValidityScannerTask"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN Task task = createTask(TestValidityRecomputeTask.class.getName() + "." + TEST_NAME); @@ -1016,14 +1015,14 @@ public void test800ImportValidityScannerTask() throws Exception { XMLGregorianCalendar startCal = clock.currentTimeXMLGregorianCalendar(); /// WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); importObjectFromFile(TASK_VALIDITY_SCANNER_FILENAME); waitForTaskStart(TASK_VALIDITY_SCANNER_OID, false); waitForTaskFinish(TASK_VALIDITY_SCANNER_OID, true); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); XMLGregorianCalendar endCal = clock.currentTimeXMLGregorianCalendar(); assertLastRecomputeTimestamp(TASK_VALIDITY_SCANNER_OID, startCal, endCal); } @@ -1035,9 +1034,9 @@ public void test800ImportValidityScannerTask() throws Exception { @Test public void test802AssignBarbossaDeputyOfJack() throws Exception { final String TEST_NAME = "test802AssignBarbossaDeputyOfJack"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userJackBefore = getUser(USER_JACK_OID); @@ -1052,15 +1051,14 @@ public void test802AssignBarbossaDeputyOfJack() throws Exception { activationType.setValidTo(XmlTypeConverter.addDuration(startTs, "PT2H")); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignDeputy(USER_BARBOSSA_OID, USER_JACK_OID, assignment -> assignment.setActivation(activationType), task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); @@ -1085,15 +1083,14 @@ public void test802AssignBarbossaDeputyOfJack() throws Exception { } /** - * Assign Barbossa as Jack's deputy. Barbossa should have all the privileges now. - * But they will expire soon ... + * Assign Barbossa as Jack's deputy. Barbossa privileges are about to expire. */ @Test public void test804BarbosaThreeHoursLater() throws Exception { final String TEST_NAME = "test804BarbosaThreeHoursLater"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestDeputy.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); clock.overrideDuration("PT3H"); @@ -1101,14 +1098,13 @@ public void test804BarbosaThreeHoursLater() throws Exception { XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); waitForTaskNextRunAssertSuccess(TASK_VALIDITY_SCANNER_OID, true); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIntent.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIntent.java index 00c3aeaf7f1..64cf9f33acd 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIntent.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIntent.java @@ -67,10 +67,10 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti @Test public void test131ModifyUserJackAssignAccountDefault() throws Exception { final String TEST_NAME="test131ModifyUserJackAssignAccountDefault"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestIntent.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); preTestCleanup(AssignmentPolicyEnforcementType.RELATIVE); @@ -128,10 +128,10 @@ public void test131ModifyUserJackAssignAccountDefault() throws Exception { @Test public void test132ModifyUserJackAssignAccountTest() throws Exception { final String TEST_NAME="test132ModifyUserJackAssignAccountTest"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestIntent.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); preTestCleanup(AssignmentPolicyEnforcementType.RELATIVE); @@ -202,10 +202,10 @@ public void test132ModifyUserJackAssignAccountTest() throws Exception { @Test public void test135ModifyUserJackFullName() throws Exception { final String TEST_NAME="test135ModifyUserJackFullName"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestIntent.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); preTestCleanup(AssignmentPolicyEnforcementType.RELATIVE); @@ -265,10 +265,10 @@ public void test135ModifyUserJackFullName() throws Exception { @Test public void test147ModifyUserJackUnAssignAccountDefault() throws Exception { final String TEST_NAME="test147ModifyUserJackUnAssignAccountDefault"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestIntent.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); preTestCleanup(AssignmentPolicyEnforcementType.RELATIVE); @@ -326,10 +326,10 @@ public void test147ModifyUserJackUnAssignAccountDefault() throws Exception { @Test public void test149ModifyUserJackUnassignAccountTest() throws Exception { final String TEST_NAME = "test149ModifyUserJackUnassignAccountTest"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestIntent.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); preTestCleanup(AssignmentPolicyEnforcementType.RELATIVE); @@ -342,8 +342,7 @@ public void test149ModifyUserJackUnassignAccountTest() throws Exception { modelService.executeChanges(deltas, null, task, result); // THEN - result.computeStatus(); - TestUtil.assertSuccess("executeChanges result", result); + assertSuccess(result); assertCounterIncrement(InternalCounters.SHADOW_FETCH_OPERATION_COUNT, 0); PrismObject userJack = getUser(USER_JACK_OID); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMapping.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMapping.java index 0565e5318de..a454e33ee2d 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMapping.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMapping.java @@ -326,7 +326,8 @@ accountOid, getDummyResourceController(RESOURCE_DUMMY_BLUE_NAME).getAttributePat dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertRecords(2); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(1); + dummyAuditService.assertExecutionDeltas(2); + dummyAuditService.assertHasDelta(ChangeType.MODIFY, UserType.class); dummyAuditService.assertHasDelta(ChangeType.MODIFY, ShadowType.class); dummyAuditService.assertExecutionSuccess(); } @@ -371,7 +372,8 @@ accountOid, getDummyResourceController(RESOURCE_DUMMY_BLUE_NAME).getAttributePat dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertRecords(2); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(1); + dummyAuditService.assertExecutionDeltas(2); + dummyAuditService.assertHasDelta(ChangeType.MODIFY, UserType.class); dummyAuditService.assertHasDelta(ChangeType.MODIFY, ShadowType.class); dummyAuditService.assertExecutionSuccess(); } @@ -412,7 +414,8 @@ accountOid, getDummyResourceController(RESOURCE_DUMMY_BLUE_NAME).getAttributePat dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertRecords(2); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(1); + dummyAuditService.assertExecutionDeltas(2); + dummyAuditService.assertHasDelta(ChangeType.MODIFY, UserType.class); dummyAuditService.assertHasDelta(ChangeType.MODIFY, ShadowType.class); dummyAuditService.assertExecutionSuccess(); } @@ -457,7 +460,8 @@ accountOid, getDummyResourceController(RESOURCE_DUMMY_BLUE_NAME).getAttributePat dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertRecords(2); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(1); + dummyAuditService.assertExecutionDeltas(2); + dummyAuditService.assertHasDelta(ChangeType.MODIFY, UserType.class); dummyAuditService.assertHasDelta(ChangeType.MODIFY, ShadowType.class); dummyAuditService.assertExecutionSuccess(); } @@ -717,7 +721,8 @@ accountOid, getDummyResourceController(RESOURCE_DUMMY_RED_NAME).getAttributePath dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertRecords(2); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(1); + dummyAuditService.assertExecutionDeltas(2); + dummyAuditService.assertHasDelta(ChangeType.MODIFY, UserType.class); dummyAuditService.assertHasDelta(ChangeType.MODIFY, ShadowType.class); dummyAuditService.assertExecutionSuccess(); } @@ -907,7 +912,7 @@ public void test139DeleteAccountRed() throws Exception { dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertRecords(2); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(2); + dummyAuditService.assertExecutionDeltas(3); dummyAuditService.assertHasDelta(ChangeType.MODIFY, UserType.class); dummyAuditService.assertHasDelta(ChangeType.DELETE, ShadowType.class); dummyAuditService.assertExecutionSuccess(); @@ -1130,7 +1135,8 @@ public void test144ModifyAccountLocationReplaceEmpty() throws Exception { dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertRecords(2); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(1); + dummyAuditService.assertExecutionDeltas(2); + dummyAuditService.assertHasDelta(ChangeType.MODIFY, UserType.class); dummyAuditService.assertHasDelta(ChangeType.MODIFY, ShadowType.class); dummyAuditService.assertExecutionSuccess(); } diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContract.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContract.java index 6f24030504b..798190b5eae 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContract.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContract.java @@ -258,8 +258,7 @@ public void test100ModifyUserAddAccount() throws Exception { // THEN displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + assertSuccess(result); XMLGregorianCalendar endTime = clock.currentTimeXMLGregorianCalendar(); assertCounterIncrement(InternalCounters.SHADOW_FETCH_OPERATION_COUNT, 0); @@ -295,7 +294,7 @@ public void test100ModifyUserAddAccount() throws Exception { dummyAuditService.assertRecords(2); dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(2); + dummyAuditService.assertExecutionDeltas(3); // lastProvisioningTimestamp, add account, link dummyAuditService.assertHasDelta(ChangeType.MODIFY, UserType.class); dummyAuditService.assertHasDelta(ChangeType.ADD, ShadowType.class); dummyAuditService.assertTarget(USER_JACK_OID); @@ -358,8 +357,7 @@ public void test101GetAccount() throws Exception { display("Account attributes def complex type def", accountContainer.getDefinition().getComplexTypeDefinition()); assertDummyAccountShadowModel(account, accountJackOid, "jack", "Jack Sparrow"); - result.computeStatus(); - TestUtil.assertSuccess("getObject result", result); + assertSuccess("getObject result", result); account.checkConsistence(true, true, ConsistencyCheckScope.THOROUGH); @@ -414,8 +412,7 @@ public void test102GetAccountNoFetch() throws Exception { display("Account attributes def complex type def", accountContainer.getDefinition().getComplexTypeDefinition()); assertDummyAccountShadowRepo(account, accountJackOid, "jack"); - result.computeStatus(); - TestUtil.assertSuccess("getObject result", result); + assertSuccess("getObject result", result); assertSteadyResources(); } @@ -442,8 +439,7 @@ public void test103GetAccountRaw() throws Exception { display("Account attributes def complex type def", accountContainer.getDefinition().getComplexTypeDefinition()); assertDummyAccountShadowRepo(account, accountJackOid, "jack"); - result.computeStatus(); - TestUtil.assertSuccess("getObject result", result); + assertSuccess("getObject result", result); assertSteadyResources(); } @@ -785,7 +781,7 @@ public void test119ModifyUserDeleteAccount() throws Exception { dummyAuditService.assertRecords(2); dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(2); + dummyAuditService.assertExecutionDeltas(3); // lastProvisioningTimestamp, delete account, unlink dummyAuditService.assertHasDelta(ChangeType.MODIFY, UserType.class); dummyAuditService.assertHasDelta(ChangeType.DELETE, ShadowType.class); dummyAuditService.assertTarget(USER_JACK_OID); @@ -898,8 +894,7 @@ public void test121ModifyUserAddAccountRef() throws Exception { modelService.executeChanges(deltas, null, task, result); // THEN - result.computeStatus(); - TestUtil.assertSuccess("executeChanges result", result); + assertSuccess(result); // There is strong mapping. Complete account is fetched. assertCounterIncrement(InternalCounters.SHADOW_FETCH_OPERATION_COUNT, 1); @@ -924,7 +919,7 @@ public void test121ModifyUserAddAccountRef() throws Exception { dummyAuditService.assertRecords(2); dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(2); + dummyAuditService.assertExecutionDeltas(3); // lastProvisioningTimestamp, modify account, link dummyAuditService.assertHasDelta(ChangeType.MODIFY, UserType.class); dummyAuditService.assertHasDelta(ChangeType.MODIFY, ShadowType.class); dummyAuditService.assertTarget(USER_JACK_OID); @@ -1256,7 +1251,8 @@ public void test132ModifyAccountJackDummy() throws Exception { dummyAuditService.assertRecords(3); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(0, 1); + dummyAuditService.assertExecutionDeltas(0, 2); // lastProvisioningTimestamp, modify account + dummyAuditService.assertHasDelta(0, ChangeType.MODIFY, UserType.class); dummyAuditService.assertHasDelta(0, ChangeType.MODIFY, ShadowType.class); dummyAuditService.assertOldValue(0, ChangeType.MODIFY, ShadowType.class, dummyResourceCtl.getAttributeFullnamePath(), "Jack Sparrow"); @@ -1669,8 +1665,7 @@ public void test149ModifyUserJackDeleteAccount() throws Exception { modelService.executeChanges(deltas, null, task, result); // THEN - result.computeStatus(); - TestUtil.assertSuccess("executeChanges result", result); + assertSuccess(result); assertCounterIncrement(InternalCounters.SHADOW_FETCH_OPERATION_COUNT, 0); PrismObject userJack = getUser(USER_JACK_OID); @@ -1691,7 +1686,7 @@ public void test149ModifyUserJackDeleteAccount() throws Exception { dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertRecords(2); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(2); + dummyAuditService.assertExecutionDeltas(3); // lastProvisioningTimestamp, delete account, unlink dummyAuditService.assertHasDelta(ChangeType.MODIFY, UserType.class); dummyAuditService.assertHasDelta(ChangeType.DELETE, ShadowType.class); dummyAuditService.assertTarget(USER_JACK_OID); @@ -1949,8 +1944,7 @@ public void test163ModifyUserJackAddAccountNoneEnforcement() throws Exception { modelService.executeChanges(deltas, null, task, result); // THEN - result.computeStatus(); - TestUtil.assertSuccess("executeChanges result", result); + assertSuccess(result); XMLGregorianCalendar endTime = clock.currentTimeXMLGregorianCalendar(); assertCounterIncrement(InternalCounters.SHADOW_FETCH_OPERATION_COUNT, 0); @@ -1979,7 +1973,7 @@ public void test163ModifyUserJackAddAccountNoneEnforcement() throws Exception { dummyAuditService.assertRecords(2); dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(2); + dummyAuditService.assertExecutionDeltas(3); // lastProvisioningTimestamp, add account, link dummyAuditService.assertHasDelta(ChangeType.MODIFY, UserType.class); dummyAuditService.assertHasDelta(ChangeType.ADD, ShadowType.class); dummyAuditService.assertTarget(USER_JACK_OID); @@ -2091,8 +2085,7 @@ public void test169ModifyUserJackDeleteAccountNoneEnforcement() throws Exception modelService.executeChanges(deltas, null, task, result); // THEN - result.computeStatus(); - TestUtil.assertSuccess("executeChanges result", result); + assertSuccess(result); assertCounterIncrement(InternalCounters.SHADOW_FETCH_OPERATION_COUNT, 0); PrismObject userJack = getUser(USER_JACK_OID); @@ -2113,7 +2106,7 @@ public void test169ModifyUserJackDeleteAccountNoneEnforcement() throws Exception dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertRecords(2); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(2); + dummyAuditService.assertExecutionDeltas(3); // lastProvisioningTimestamp, delete account, unlink dummyAuditService.assertHasDelta(ChangeType.MODIFY, UserType.class); dummyAuditService.assertHasDelta(ChangeType.DELETE, ShadowType.class); dummyAuditService.assertTarget(USER_JACK_OID); @@ -3242,8 +3235,7 @@ accountJackBlueOid, getDummyResourceController(RESOURCE_DUMMY_BLUE_NAME).getAttr modelService.executeChanges(deltas, options, task, result); // THEN - result.computeStatus(); - TestUtil.assertSuccess("executeChanges result", result); + assertSuccess(result); // Not sure why 2 ... but this is not a big problem now assertCounterIncrement(InternalCounters.SHADOW_FETCH_OPERATION_COUNT, 2); @@ -3271,7 +3263,8 @@ accountJackBlueOid, getDummyResourceController(RESOURCE_DUMMY_BLUE_NAME).getAttr dummyAuditService.assertRecords(2); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(0, 1); + dummyAuditService.assertExecutionDeltas(0, 2); // lastProvisioningTimestamp, modify account + dummyAuditService.assertHasDelta(0, ChangeType.MODIFY, UserType.class); dummyAuditService.assertHasDelta(0, ChangeType.MODIFY, ShadowType.class); dummyAuditService.assertOldValue(0, ChangeType.MODIFY, ShadowType.class, getDummyResourceController(RESOURCE_DUMMY_BLUE_NAME).getAttributeFullnamePath(), "Jack Sparrow"); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMultiResource.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMultiResource.java index 687578046c2..367371e8017 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMultiResource.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMultiResource.java @@ -273,7 +273,7 @@ public void test120JackAssignRoleDummiesRelative() throws Exception { getDummyResource().resetBreakMode(); // Clean up user - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); modifyUserReplace(USER_JACK_OID, UserType.F_ORGANIZATIONAL_UNIT, task, result); @@ -292,7 +292,7 @@ public void test121JackTryDeleteAccount() throws Exception { getDummyResource().resetBreakMode(); // Clean up user - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userJack = getUser(USER_JACK_OID); String accountJackDummyOid = getLinkRefOid(userJack, RESOURCE_DUMMY_OID); @@ -333,7 +333,7 @@ public void test200JackAssignDummyIvory() throws Exception { final String TEST_NAME = "test200JackAssignDummyIvory"; // GIVEN - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); @@ -367,7 +367,7 @@ public void test209JackUnAssignDummyIvory() throws Exception { final String TEST_NAME = "test209JackUnAssignDummyIvory"; // GIVEN - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); @@ -397,10 +397,10 @@ public void test209JackUnAssignDummyIvory() throws Exception { @Test public void test210JackAssignDummyBeige() throws Exception { final String TEST_NAME = "test210JackAssignDummyBeige"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); @@ -408,11 +408,11 @@ public void test210JackAssignDummyBeige() throws Exception { modifyUserReplace(USER_JACK_OID, UserType.F_ORGANIZATIONAL_UNIT, task, result); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignAccount(USER_JACK_OID, RESOURCE_DUMMY_BEIGE_OID, null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -435,10 +435,10 @@ public void test210JackAssignDummyBeige() throws Exception { @Test public void test219JackUnAssignDummyBeige() throws Exception { final String TEST_NAME = "test219JackUnAssignDummyBeige"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); @@ -446,11 +446,11 @@ public void test219JackUnAssignDummyBeige() throws Exception { modifyUserReplace(USER_JACK_OID, UserType.F_ORGANIZATIONAL_UNIT, task, result); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); unassignAccount(USER_JACK_OID, RESOURCE_DUMMY_BEIGE_OID, null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -470,10 +470,10 @@ public void test219JackUnAssignDummyBeige() throws Exception { @Test public void test220JackAssignDummyBeigeAndDefault() throws Exception { final String TEST_NAME = "test220JackAssignDummyBeigeAndDefault"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); @@ -484,11 +484,11 @@ public void test220JackAssignDummyBeigeAndDefault() throws Exception { userDelta.addModification(createAssignmentModification(RESOURCE_DUMMY_OID, ShadowKindType.ACCOUNT, null, true)); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); executeChanges(userDelta, null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -510,18 +510,18 @@ public void test220JackAssignDummyBeigeAndDefault() throws Exception { @Test public void test221JackRecompute() throws Exception { final String TEST_NAME = "test221JackRecompute"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); recomputeUser(USER_JACK_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -539,27 +539,27 @@ public void test221JackRecompute() throws Exception { /** * Delete account on default dummy resource (but keep it assigned and keep the shadow). - * The recompute the user. The account should be re-created. + * Then recompute the user. The account should be re-created. * MID-2134, MID-3093 */ @Test public void test223JackKillDefaultDummyAccounAndRecompute() throws Exception { final String TEST_NAME = "test223JackKillDefaultDummyAccounAndRecompute"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); getDummyResource().deleteAccountByName(ACCOUNT_JACK_DUMMY_USERNAME); display("dummy resource before", getDummyResource()); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); recomputeUser(USER_JACK_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -586,21 +586,21 @@ public void test223JackKillDefaultDummyAccounAndRecompute() throws Exception { @Test public void test224JackKillBeigeAccounAndRecompute() throws Exception { final String TEST_NAME = "test224JackKillBeigeAccounAndRecompute"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); dummyResourceBeige.deleteAccountByName(ACCOUNT_JACK_DUMMY_USERNAME); display("beige dummy resource before", dummyResourceBeige); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); recomputeUser(USER_JACK_OID, ModelExecuteOptions.createReconcile(), task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -620,16 +620,16 @@ public void test224JackKillBeigeAccounAndRecompute() throws Exception { /** * Delete both accounts on beige and default dummy resource (but keep it assigned and keep the shadows). - * The recompute the user. The accounts should be re-created. + * Then recompute the user. The accounts should be re-created. * MID-2134, MID-3093 */ @Test public void test225JackKillBothAccounsAndRecompute() throws Exception { final String TEST_NAME = "test225JackKillBothAccounsAndRecompute"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); getDummyResource().deleteAccountByName(ACCOUNT_JACK_DUMMY_USERNAME); @@ -639,13 +639,12 @@ public void test225JackKillBothAccounsAndRecompute() throws Exception { display("beige dummy resource before", dummyResourceBeige); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); recomputeUser(USER_JACK_OID, ModelExecuteOptions.createReconcile(), task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); PrismObject userJack = getUser(USER_JACK_OID); assertLinks(userJack, 2); @@ -671,7 +670,7 @@ public void test225JackKillBothAccounsAndRecompute() throws Exception { @Test public void test227ModifyUserJackDefaultDummyBrokenSchemaViolation() throws Exception { final String TEST_NAME = "test227ModifyUserJackDefaultDummyBrokenSchemaViolation"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestMultiResource.class.getName() + "." + TEST_NAME); @@ -681,12 +680,12 @@ public void test227ModifyUserJackDefaultDummyBrokenSchemaViolation() throws Exce getDummyResource().setModifyBreakMode(BreakMode.SCHEMA); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modifyUserReplace(USER_JACK_OID, UserType.F_FULL_NAME, task, result, new PolyString("Cpt. Jack Sparrow", null)); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); display("Result", result); TestUtil.assertPartialError(result); @@ -715,7 +714,7 @@ public void test227ModifyUserJackDefaultDummyBrokenSchemaViolation() throws Exce @Test public void test228ModifyUserJackDefaultDummyNoError() throws Exception { final String TEST_NAME = "test228ModifyUserJackDefaultDummyNoError"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestMultiResource.class.getName() + "." + TEST_NAME); @@ -724,12 +723,12 @@ public void test228ModifyUserJackDefaultDummyNoError() throws Exception { getDummyResource().resetBreakMode(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modifyUserReplace(USER_JACK_OID, UserType.F_FULL_NAME, task, result, new PolyString(USER_JACK_FULL_NAME, null)); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); display("Result", result); TestUtil.assertSuccess(result); @@ -756,10 +755,10 @@ public void test228ModifyUserJackDefaultDummyNoError() throws Exception { @Test public void test229JackUnassignDummyBeigeAndDefault() throws Exception { final String TEST_NAME = "test229JackUnassignDummyBeigeAndDefault"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); getDummyResource().resetBreakMode(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); @@ -768,11 +767,11 @@ public void test229JackUnassignDummyBeigeAndDefault() throws Exception { userDelta.addModification(createAssignmentModification(RESOURCE_DUMMY_OID, ShadowKindType.ACCOUNT, null, false)); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); executeChanges(userDelta, null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -792,10 +791,10 @@ public void test229JackUnassignDummyBeigeAndDefault() throws Exception { @Test public void test250JackAssignDummyLavender() throws Exception { final String TEST_NAME = "test250JackAssignDummyLavender"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); @@ -829,9 +828,9 @@ public void test250JackAssignDummyLavender() throws Exception { * resource through the user to the other resource. If dependency does not work then no value is propagated. */ public void jackAssignRoleDummies(final String TEST_NAME) throws Exception { - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); clearJackOrganizationalUnit(task, result); @@ -874,9 +873,9 @@ public void jackAssignRoleDummies(final String TEST_NAME) throws Exception { } public void jackRename(final String TEST_NAME) throws Exception { - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); jackRename(TEST_NAME, "jackie", "Jackie Sparrow", task, result); @@ -891,11 +890,11 @@ public void jackRename(final String TEST_NAME, String toName, String toFullName, Collection> deltas = MiscSchemaUtil.createCollection(objectDelta); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(deltas, null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -932,9 +931,9 @@ public void jackRename(final String TEST_NAME, String toName, String toFullName, } public void jackUnAssignRoleDummies(final String TEST_NAME) throws Exception { - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -962,9 +961,9 @@ public void jackUnAssignRoleDummies(final String TEST_NAME) throws Exception { */ public void jackAssignRoleDummiesError(final String TEST_NAME, String roleOid, String dummyResourceName, boolean expectAccount) throws Exception { - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); clearJackOrganizationalUnit(task, result); @@ -1003,17 +1002,17 @@ private void clearJackOrganizationalUnit(Task task, OperationResult result) thro } public void jackUnAssignRoleDummiesError(final String TEST_NAME, String roleOid) throws Exception { - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); unassignRole(USER_JACK_OID, roleOid, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); display(result); // there is a failure while reading dummy account - it was not created @@ -1038,10 +1037,10 @@ public void jackUnAssignRoleDummiesError(final String TEST_NAME, String roleOid) @Test public void test300AddAndAssignRelative() throws Exception { final String TEST_NAME = "test300AddAndAssignRelative"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // Add default dummy account to jack without assigning it. @@ -1064,11 +1063,11 @@ public void test300AddAndAssignRelative() throws Exception { assertDefaultDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignAccount(USER_JACK_OID, RESOURCE_DUMMY_BLUE_OID, null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -1096,18 +1095,18 @@ public void test300AddAndAssignRelative() throws Exception { @Test public void test310AddedAccountAndUnassignRelative() throws Exception { final String TEST_NAME = "test310AddedAccountAndUnassignRelative"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); unassignAccount(USER_JACK_OID, RESOURCE_DUMMY_BLUE_OID, null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -1137,18 +1136,18 @@ public void test310AddedAccountAndUnassignRelative() throws Exception { @Test public void test319UnassignDummyRelative() throws Exception { final String TEST_NAME = "test319UnassignDummyRelative"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); unassignAccount(USER_JACK_OID, RESOURCE_DUMMY_OID, null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -1173,17 +1172,17 @@ public void test319UnassignDummyRelative() throws Exception { @Test public void test350AddAccountLavender() throws Exception { final String TEST_NAME = "test350AddAccountLavender"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta userDelta = createModifyUserAddAccount(USER_JACK_OID, resourceDummyLavender); // WHEN try { - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(userDelta), null, task, result); AssertJUnit.fail("Unexpected success"); @@ -1193,7 +1192,7 @@ public void test350AddAccountLavender() throws Exception { } // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertFailure(result); @@ -1204,20 +1203,20 @@ public void test350AddAccountLavender() throws Exception { @Test public void test352AddAccountIvory() throws Exception { final String TEST_NAME = "test352AddAccountIvory"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta userDelta = createModifyUserAddAccount(USER_JACK_OID, resourceDummyIvory); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(userDelta), null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -1228,20 +1227,20 @@ public void test352AddAccountIvory() throws Exception { @Test public void test354AddAccountBeige() throws Exception { final String TEST_NAME = "test354AddAccountBeige"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta userDelta = createModifyUserAddAccount(USER_JACK_OID, resourceDummyBeige); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(userDelta), null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -1252,20 +1251,20 @@ public void test354AddAccountBeige() throws Exception { @Test public void test360AddAccountDummy() throws Exception { final String TEST_NAME = "test360AddAccountDummy"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta userDelta = createModifyUserAddAccount(USER_JACK_OID, getDummyResourceObject()); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(userDelta), null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -1279,20 +1278,20 @@ public void test360AddAccountDummy() throws Exception { @Test public void test362AddAccountLavender() throws Exception { final String TEST_NAME = "test362AddAccountLavender"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta userDelta = createModifyUserAddAccount(USER_JACK_OID, resourceDummyLavender); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(userDelta), null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -1306,17 +1305,17 @@ public void test362AddAccountLavender() throws Exception { @Test public void test370DeleteAccountDummy() throws Exception { final String TEST_NAME = "test370DeleteAccountDummy"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta userDelta = createModifyUserDeleteAccount(USER_JACK_OID, getDummyResourceObject()); // WHEN try { - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(userDelta), null, task, result); AssertJUnit.fail("Unexpected success"); @@ -1326,7 +1325,7 @@ public void test370DeleteAccountDummy() throws Exception { } // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertFailure(result); @@ -1343,17 +1342,17 @@ public void test370DeleteAccountDummy() throws Exception { @Test public void test372UnlinkAccountDummy() throws Exception { final String TEST_NAME = "test372UnlinkAccountDummy"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta userDelta = createModifyUserUnlinkAccount(USER_JACK_OID, getDummyResourceObject()); // WHEN try { - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(userDelta), null, task, result); AssertJUnit.fail("Unexpected success"); @@ -1363,9 +1362,8 @@ public void test372UnlinkAccountDummy() throws Exception { } // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertFailure(result); + displayThen(TEST_NAME); + assertFailure(result); PrismObject user = getUser(USER_JACK_OID); assertAccount(user, RESOURCE_DUMMY_OID); @@ -1377,21 +1375,20 @@ public void test372UnlinkAccountDummy() throws Exception { @Test public void test374DeleteAccountLavender() throws Exception { final String TEST_NAME = "test374DeleteAccountLavender"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta userDelta = createModifyUserDeleteAccount(USER_JACK_OID, resourceDummyLavender); - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(userDelta), null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); PrismObject user = getUser(USER_JACK_OID); assertAccount(user, RESOURCE_DUMMY_OID); @@ -1407,21 +1404,20 @@ public void test374DeleteAccountLavender() throws Exception { @Test public void test376DeleteAccountDummy() throws Exception { final String TEST_NAME = "test376DeleteAccountDummy"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta userDelta = createModifyUserDeleteAccount(USER_JACK_OID, getDummyResourceObject()); - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(userDelta), null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); assertNoDummyAccount(RESOURCE_DUMMY_LAVENDER_NAME, ACCOUNT_JACK_DUMMY_USERNAME); assertNoDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME); @@ -1434,21 +1430,20 @@ public void test376DeleteAccountDummy() throws Exception { @Test public void test378DeleteAccountBeige() throws Exception { final String TEST_NAME = "test378DeleteAccountBeige"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta userDelta = createModifyUserDeleteAccount(USER_JACK_OID, resourceDummyBeige); - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(userDelta), null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); assertNoDummyAccount(RESOURCE_DUMMY_LAVENDER_NAME, ACCOUNT_JACK_DUMMY_USERNAME); assertNoDummyAccount(RESOURCE_DUMMY_BEIGE_NAME, ACCOUNT_JACK_DUMMY_USERNAME); @@ -1462,21 +1457,20 @@ public void test378DeleteAccountBeige() throws Exception { @Test public void test379DeleteAccountIvory() throws Exception { final String TEST_NAME = "test379DeleteAccountIvory"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta userDelta = createModifyUserDeleteAccount(USER_JACK_OID, resourceDummyIvory); - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(userDelta), null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); assertNoDummyAccount(RESOURCE_DUMMY_LAVENDER_NAME, ACCOUNT_JACK_DUMMY_USERNAME); assertNoDummyAccount(RESOURCE_DUMMY_BEIGE_NAME, ACCOUNT_JACK_DUMMY_USERNAME); @@ -1491,26 +1485,25 @@ public void test379DeleteAccountIvory() throws Exception { @Test public void test380AddAccountPeru() throws Exception { final String TEST_NAME = "test380AddAccountPeru"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); getDummyResource().resetBreakMode(); // precondition assertEncryptedUserPassword(USER_JACK_OID, USER_JACK_PASSWORD); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta userDelta = createModifyUserAddAccount(USER_JACK_OID, resourceDummyPeru); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(userDelta), null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); assertDummyAccount(RESOURCE_DUMMY_PERU_NAME, ACCOUNT_JACK_DUMMY_USERNAME, ACCOUNT_JACK_DUMMY_FULLNAME, true); assertDummyPassword(RESOURCE_DUMMY_PERU_NAME, ACCOUNT_JACK_DUMMY_USERNAME, USER_JACK_PASSWORD); @@ -1519,22 +1512,21 @@ public void test380AddAccountPeru() throws Exception { @Test public void test382AddAccountYellow() throws Exception { final String TEST_NAME = "test382AddAccountYellow"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta userDelta = createModifyUserAddAccount(USER_JACK_OID, getDummyResourceObject(RESOURCE_DUMMY_YELLOW_NAME)); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(userDelta), null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); PrismObject userJack = getUser(USER_JACK_OID); display("User after change execution", userJack); @@ -1556,7 +1548,7 @@ public void test382AddAccountYellow() throws Exception { @Test public void test385ModifyUserJackPasswordA() throws Exception { final String TEST_NAME = "test385ModifyUserJackPasswordA"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(AbstractPasswordTest.class.getName() + "." + TEST_NAME); @@ -1567,8 +1559,7 @@ public void test385ModifyUserJackPasswordA() throws Exception { modifyUserChangePassword(USER_JACK_OID, USER_PASSWORD_A_CLEAR, task, result); // THEN - result.computeStatus(); - TestUtil.assertPartialError(result); + assertPartialError(result); PrismObject userJack = getUser(USER_JACK_OID); display("User after change execution", userJack); @@ -1590,21 +1581,20 @@ public void test385ModifyUserJackPasswordA() throws Exception { @Test public void test389DeleteAccountPeru() throws Exception { final String TEST_NAME = "test389DeleteAccountPeru"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); ObjectDelta userDelta = createModifyUserDeleteAccount(USER_JACK_OID, resourceDummyPeru); - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(MiscSchemaUtil.createCollection(userDelta), null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); assertNoDummyAccount(RESOURCE_DUMMY_PERU_NAME, ACCOUNT_JACK_DUMMY_USERNAME); @@ -1618,12 +1608,12 @@ public void test389DeleteAccountPeru() throws Exception { @Test public void test400DavidAndGoliathAssignRole() throws Exception { final String TEST_NAME = "test400DavidAndGoliathAssignRole"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userBefore = createUser(USER_WORLD_NAME, USER_WORLD_FULL_NAME, true); @@ -1633,13 +1623,12 @@ public void test400DavidAndGoliathAssignRole() throws Exception { dummyAuditService.clear(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignRole(userBefore.getOid(), ROLE_FIGHT_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); assertDavidGoliath(userBefore.getOid(), "stone", USER_WORLD_NAME, true, true, true); @@ -1663,7 +1652,7 @@ public void test400DavidAndGoliathAssignRole() throws Exception { ObjectDeltaOperation executionDeltaOp = dummyAuditService.getExecutionDelta(2, ChangeType.MODIFY, ShadowType.class); ObjectDelta executionDelta = executionDeltaOp.getObjectDelta(); display("Last execution delta", executionDelta); - PrismAsserts.assertModifications("Phantom changes in last delta:", executionDelta, 2); + PrismAsserts.assertModifications("Phantom changes in last delta:", executionDelta, 4); } private void assertDavidGoliath(String userOid, String ou, String name, boolean userEnabled, boolean davidEnabled, boolean goliathEnabled) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, SchemaViolationException, ConflictException, ExpressionEvaluationException { @@ -1705,25 +1694,24 @@ private void assertDavidGoliath(String userOid, String ou, String name, boolean @Test public void test401DavidAndGoliathModifyOu() throws Exception { final String TEST_NAME = "test401DavidAndGoliathModifyOu"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userBefore = findUserByUsername(USER_WORLD_NAME); dummyAuditService.clear(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modifyUserReplace(userBefore.getOid(), UserType.F_ORGANIZATIONAL_UNIT, task, result, PrismTestUtil.createPolyString("rock")); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); assertDavidGoliath(userBefore.getOid(), "rock", USER_WORLD_NAME, true, true, true); @@ -1747,18 +1735,18 @@ public void test401DavidAndGoliathModifyOu() throws Exception { ObjectDeltaOperation executionDeltaOp = dummyAuditService.getExecutionDelta(2, ChangeType.MODIFY, ShadowType.class); ObjectDelta executionDelta = executionDeltaOp.getObjectDelta(); display("Last execution delta", executionDelta); - PrismAsserts.assertModifications("Phantom changes in last delta:", executionDelta, 2); + PrismAsserts.assertModifications("Phantom changes in last delta:", executionDelta, 4); } @Test public void test403DavidAndGoliathDisableUser() throws Exception { final String TEST_NAME = "test403DavidAndGoliathDisableUser"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userBefore = findUserByUsername(USER_WORLD_NAME); @@ -1766,13 +1754,12 @@ public void test403DavidAndGoliathDisableUser() throws Exception { dummyAuditService.clear(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modifyUserReplace(userBefore.getOid(), ACTIVATION_ADMINISTRATIVE_STATUS_PATH, task, result, ActivationStatusType.DISABLED); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); assertDavidGoliath(userBefore.getOid(), "rock", USER_WORLD_NAME, false, false, false); @@ -1784,7 +1771,8 @@ public void test403DavidAndGoliathDisableUser() throws Exception { dummyAuditService.assertExecutionDeltas(0,2); dummyAuditService.assertHasDelta(0,ChangeType.MODIFY, UserType.class); dummyAuditService.assertHasDelta(0,ChangeType.MODIFY, ShadowType.class); - dummyAuditService.assertExecutionDeltas(1,1); // user is again disabled here + dummyAuditService.assertExecutionDeltas(1,2); // user is again disabled here + dummyAuditService.assertHasDelta(1,ChangeType.MODIFY, UserType.class); // lastProvisioningTimestamp dummyAuditService.assertHasDelta(1,ChangeType.MODIFY, ShadowType.class); dummyAuditService.assertExecutionSuccess(); } @@ -1792,25 +1780,24 @@ public void test403DavidAndGoliathDisableUser() throws Exception { @Test public void test404DavidAndGoliathEnableUser() throws Exception { final String TEST_NAME = "test404DavidAndGoliathEnableUser"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userBefore = findUserByUsername(USER_WORLD_NAME); dummyAuditService.clear(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modifyUserReplace(userBefore.getOid(), ACTIVATION_ADMINISTRATIVE_STATUS_PATH, task, result, ActivationStatusType.ENABLED); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); assertDavidGoliath(userBefore.getOid(), "rock", USER_WORLD_NAME, true, true, true); @@ -1822,7 +1809,8 @@ public void test404DavidAndGoliathEnableUser() throws Exception { dummyAuditService.assertExecutionDeltas(0,2); dummyAuditService.assertHasDelta(0,ChangeType.MODIFY, UserType.class); dummyAuditService.assertHasDelta(0,ChangeType.MODIFY, ShadowType.class); - dummyAuditService.assertExecutionDeltas(1,1); // user is again disabled here + dummyAuditService.assertExecutionDeltas(1,2); // user is again disabled here + dummyAuditService.assertHasDelta(1,ChangeType.MODIFY, UserType.class); // lastProvisioningTimestamp dummyAuditService.assertHasDelta(1,ChangeType.MODIFY, ShadowType.class); dummyAuditService.assertExecutionSuccess(); } @@ -1830,12 +1818,12 @@ public void test404DavidAndGoliathEnableUser() throws Exception { @Test public void test405DavidAndGoliathDisableAccountDavid() throws Exception { final String TEST_NAME = "test405DavidAndGoliathDisableAccountDavid"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userBefore = findUserByUsername(USER_WORLD_NAME); @@ -1844,13 +1832,12 @@ public void test405DavidAndGoliathDisableAccountDavid() throws Exception { dummyAuditService.clear(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modifyAccountShadowReplace(accountDavidOid, ACTIVATION_ADMINISTRATIVE_STATUS_PATH, task, result, ActivationStatusType.DISABLED); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); assertDavidGoliath(userBefore.getOid(), "rock", USER_WORLD_NAME, true, false, true); @@ -1859,7 +1846,8 @@ public void test405DavidAndGoliathDisableAccountDavid() throws Exception { dummyAuditService.assertRecords(2); dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(0,1); + dummyAuditService.assertExecutionDeltas(0,2); + dummyAuditService.assertHasDelta(0,ChangeType.MODIFY, UserType.class); // lastProvisioningTimestamp dummyAuditService.assertHasDelta(0,ChangeType.MODIFY, ShadowType.class); dummyAuditService.assertExecutionSuccess(); } @@ -1870,12 +1858,12 @@ public void test405DavidAndGoliathDisableAccountDavid() throws Exception { @Test public void test406DavidAndGoliathRecompute() throws Exception { final String TEST_NAME = "test406DavidAndGoliathRecompute"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userBefore = findUserByUsername(USER_WORLD_NAME); @@ -1883,13 +1871,12 @@ public void test406DavidAndGoliathRecompute() throws Exception { dummyAuditService.clear(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); recomputeUser(userBefore.getOid(), task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); assertDavidGoliath(userBefore.getOid(), "rock", USER_WORLD_NAME, true, false, true); @@ -1901,12 +1888,12 @@ public void test406DavidAndGoliathRecompute() throws Exception { @Test public void test408DavidAndGoliathEnableAccountDavid() throws Exception { final String TEST_NAME = "test408DavidAndGoliathEnableAccountDavid"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userBefore = findUserByUsername(USER_WORLD_NAME); @@ -1915,13 +1902,12 @@ public void test408DavidAndGoliathEnableAccountDavid() throws Exception { dummyAuditService.clear(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modifyAccountShadowReplace(accountDavidOid, ACTIVATION_ADMINISTRATIVE_STATUS_PATH, task, result, ActivationStatusType.ENABLED); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); assertDavidGoliath(userBefore.getOid(), "rock", USER_WORLD_NAME, true, true, true); @@ -1930,7 +1916,8 @@ public void test408DavidAndGoliathEnableAccountDavid() throws Exception { dummyAuditService.assertRecords(2); dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(0,1); + dummyAuditService.assertExecutionDeltas(0,2); + dummyAuditService.assertHasDelta(0,ChangeType.MODIFY, UserType.class); // lastProvisioningTimestamp dummyAuditService.assertHasDelta(0,ChangeType.MODIFY, ShadowType.class); dummyAuditService.assertExecutionSuccess(); } @@ -1938,25 +1925,24 @@ public void test408DavidAndGoliathEnableAccountDavid() throws Exception { @Test public void test410DavidAndGoliathRename() throws Exception { final String TEST_NAME = "test410DavidAndGoliathRename"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userBefore = findUserByUsername(USER_WORLD_NAME); dummyAuditService.clear(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modifyUserReplace(userBefore.getOid(), UserType.F_NAME, task, result, PrismTestUtil.createPolyString(USER_FIELD_NAME)); - // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + // THEN + displayThen(TEST_NAME); + assertSuccess(result); assertDavidGoliath(userBefore.getOid(), "rock", USER_FIELD_NAME, true, true, true); @@ -1980,29 +1966,29 @@ public void test410DavidAndGoliathRename() throws Exception { ObjectDeltaOperation executionDeltaOp = dummyAuditService.getExecutionDelta(2, ChangeType.MODIFY, ShadowType.class); ObjectDelta executionDelta = executionDeltaOp.getObjectDelta(); display("Last execution delta", executionDelta); - PrismAsserts.assertModifications("Phantom changes in last delta:", executionDelta, 2); + PrismAsserts.assertModifications("Phantom changes in last delta:", executionDelta, 4); } @Test public void test419DavidAndGoliathUnassignRole() throws Exception { final String TEST_NAME = "test419DavidAndGoliathUnassignRole"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userBefore = findUserByUsername(USER_FIELD_NAME); dummyAuditService.clear(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); unassignRole(userBefore.getOid(), ROLE_FIGHT_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result, 2); @@ -2032,12 +2018,12 @@ public void test419DavidAndGoliathUnassignRole() throws Exception { @Test public void test420DavidAndGoliathAssignRoleGoliathDown() throws Exception { final String TEST_NAME = "test420DavidAndGoliathAssignRoleGoliathDown"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userBefore = findUserByUsername(USER_FIELD_NAME); @@ -2056,11 +2042,11 @@ public void test420DavidAndGoliathAssignRoleGoliathDown() throws Exception { dummyAuditService.clear(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignRole(userBefore.getOid(), ROLE_FIGHT_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); // Inner errors are expected TestUtil.assertPartialError(result); @@ -2100,12 +2086,12 @@ public void test420DavidAndGoliathAssignRoleGoliathDown() throws Exception { @Test(enabled=false) public void test422DavidAndGoliathAssignRoleGoliathUpRecompute() throws Exception { final String TEST_NAME = "test422DavidAndGoliathAssignRoleGoliathUpRecompute"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userBefore = findUserByUsername(USER_FIELD_NAME); @@ -2116,7 +2102,7 @@ public void test422DavidAndGoliathAssignRoleGoliathUpRecompute() throws Exceptio recomputeUser(userBefore.getOid(), task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -2143,23 +2129,23 @@ public void test422DavidAndGoliathAssignRoleGoliathUpRecompute() throws Exceptio @Test public void test429DavidAndGoliathUnassignRole() throws Exception { final String TEST_NAME = "test429DavidAndGoliathUnassignRole"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userBefore = findUserByUsername(USER_FIELD_NAME); dummyAuditService.clear(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); unassignRole(userBefore.getOid(), ROLE_FIGHT_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); // TestUtil.assertSuccess(result, 2); @@ -2191,12 +2177,12 @@ public void test429DavidAndGoliathUnassignRole() throws Exception { @Test public void test430DavidAndGoliathAssignRoleDavidDown() throws Exception { final String TEST_NAME = "test430DavidAndGoliathAssignRoleDavidDown"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); PrismObject userBefore = findUserByUsername(USER_FIELD_NAME); @@ -2216,11 +2202,11 @@ public void test430DavidAndGoliathAssignRoleDavidDown() throws Exception { dummyAuditService.clear(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignRole(userBefore.getOid(), ROLE_FIGHT_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); // Inner errors are expected TestUtil.assertPartialError(result); @@ -2256,12 +2242,12 @@ public void test430DavidAndGoliathAssignRoleDavidDown() throws Exception { @Test public void test440DavidAndGoliathAssignRoleAndCreateUserInOneStep() throws Exception { final String TEST_NAME = "test440DavidAndGoliathAssignRoleAndCreateUserInOneStep"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); dummyResourceGoliath.setBreakMode(BreakMode.NONE); dummyResourceDavid.setBreakMode(BreakMode.NONE); try{ - Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); + Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // delete user and his roles which were added before @@ -2306,11 +2292,11 @@ public void test440DavidAndGoliathAssignRoleAndCreateUserInOneStep() throws Exce dummyAuditService.clear(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); // assignRole(userBefore.getOid(), ROLE_FIGHT_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestUserTemplate.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestUserTemplate.java index 7f297aa93d6..10d08ef3d61 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestUserTemplate.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestUserTemplate.java @@ -1019,7 +1019,7 @@ public void test160ModifyUserGivenNameAgain() throws Exception { dummyAuditService.assertTarget(USER_JACK_OID); dummyAuditService.assertExecutionSuccess(); ObjectDeltaOperation objectDeltaOperation = dummyAuditService.getExecutionDelta(0, ChangeType.MODIFY, UserType.class); - assertEquals("unexpected number of modifications in audited delta", 4, objectDeltaOperation.getObjectDelta().getModifications().size()); // givenName + badLuck + modifyTimestamp + assertEquals("unexpected number of modifications in audited delta", 5, objectDeltaOperation.getObjectDelta().getModifications().size()); // givenName + badLuck + modifyTimestamp PropertyDelta badLuckDelta = objectDeltaOperation.getObjectDelta().findPropertyDelta(new ItemPath(UserType.F_EXTENSION, PIRACY_BAD_LUCK)); assertNotNull("badLuck delta was not found", badLuckDelta); List oldValues = (List) badLuckDelta.getEstimatedOldValues(); @@ -1069,7 +1069,7 @@ public void test162ModifyUserGivenNameAgainPhantomChange() throws Exception { dummyAuditService.assertTarget(USER_JACK_OID); dummyAuditService.assertExecutionSuccess(); ObjectDeltaOperation objectDeltaOperation = dummyAuditService.getExecutionDelta(0, ChangeType.MODIFY, UserType.class); - assertEquals("unexpected number of modifications in audited delta", 4, objectDeltaOperation.getObjectDelta().getModifications().size()); // givenName + modifyTimestamp, modifyChannel, modifierRef + assertEquals("unexpected number of modifications in audited delta", 5, objectDeltaOperation.getObjectDelta().getModifications().size()); // givenName + modifyTimestamp, modifyChannel, modifierRef } @Test diff --git a/model/model-intest/src/test/resources/logback-test.xml b/model/model-intest/src/test/resources/logback-test.xml index 28c0a548e7d..90d10261aeb 100644 --- a/model/model-intest/src/test/resources/logback-test.xml +++ b/model/model-intest/src/test/resources/logback-test.xml @@ -47,7 +47,7 @@ - + @@ -57,7 +57,7 @@ - + @@ -67,7 +67,7 @@ - + @@ -80,7 +80,7 @@ - + diff --git a/model/model-intest/src/test/resources/mapping/resource-dummy-crimson.xml b/model/model-intest/src/test/resources/mapping/resource-dummy-crimson.xml index 01b372e3064..393046152f8 100644 --- a/model/model-intest/src/test/resources/mapping/resource-dummy-crimson.xml +++ b/model/model-intest/src/test/resources/mapping/resource-dummy-crimson.xml @@ -190,9 +190,7 @@ - - strong - + diff --git a/model/model-intest/src/test/resources/mapping/resource-dummy-light-crimson.xml b/model/model-intest/src/test/resources/mapping/resource-dummy-light-crimson.xml index f905f957fed..dd4f5f858cf 100644 --- a/model/model-intest/src/test/resources/mapping/resource-dummy-light-crimson.xml +++ b/model/model-intest/src/test/resources/mapping/resource-dummy-light-crimson.xml @@ -181,9 +181,7 @@ - - strong - + diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java index 1da42514288..412c27ead5f 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java @@ -1319,7 +1319,7 @@ public void modifyShadowAttributes(ProvisioningContext ctx, PrismObject shadowChanges = extractRepoShadowChanges(ctx, shadow, modifications); if (shadowChanges != null && !shadowChanges.isEmpty()) { LOGGER.trace( - "Detected shadow changes. Start to modify shadow in the repository, applying modifications {}", + "There are repository shadow changes, applying modifications {}", DebugUtil.debugDump(shadowChanges)); try { ConstraintsChecker.onShadowModifyOperation(shadowChanges); diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/manual/AbstractManualResourceTest.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/manual/AbstractManualResourceTest.java index 3aac919147f..5280e4af290 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/manual/AbstractManualResourceTest.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/manual/AbstractManualResourceTest.java @@ -1342,13 +1342,13 @@ public void test240CloseDisableCaseAndReadAccountWill() throws Exception { OperationResult result = task.getResult(); syncServiceMock.reset(); + accountWillCompletionTimestampStart = clock.currentTimeXMLGregorianCalendar(); + closeCase(willLastCaseOid); PrismObject shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result); display("Shadow before", shadowBefore); - accountWillCompletionTimestampStart = clock.currentTimeXMLGregorianCalendar(); - // WHEN displayWhen(TEST_NAME); PrismObject shadowProvisioning = provisioningService.getObject(ShadowType.class, @@ -1678,18 +1678,18 @@ public void test260ClosePasswordChangeCaseAndRefreshAccountWill() throws Excepti } /** - * ff 10min. Refresh. Oldest delta should expire. + * ff 7min. Refresh. Oldest delta should expire. */ @Test - public void test270RefreshAccountWillAfter10min() throws Exception { - final String TEST_NAME = "test130RefreshAccountWillAfter10min"; + public void test270RefreshAccountWillAfter7min() throws Exception { + final String TEST_NAME = "test130RefreshAccountWillAfter7min"; displayTestTitle(TEST_NAME); // GIVEN Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); syncServiceMock.reset(); - clock.overrideDuration("PT10M"); + clock.overrideDuration("PT7M"); PrismObject shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result); display("Shadow before", shadowBefore); @@ -2128,13 +2128,13 @@ public void test310CloseCaseAndRefreshAccountWill() throws Exception { OperationResult result = task.getResult(); syncServiceMock.reset(); + accountWillCompletionTimestampStart = clock.currentTimeXMLGregorianCalendar(); + closeCase(willLastCaseOid); PrismObject shadowBefore = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result); display("Shadow before", shadowBefore); - accountWillCompletionTimestampStart = clock.currentTimeXMLGregorianCalendar(); - // WHEN displayWhen(TEST_NAME); provisioningService.refreshShadow(shadowBefore, null, task, result); From e5823afc754d851b81a1a5719e67e443fa0043ea Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Fri, 29 Sep 2017 14:59:08 +0200 Subject: [PATCH 78/97] Adjusting and improving tests, fixing conflict detection delay (MID-4154) --- .../midpoint/model/impl/lens/Clockwork.java | 26 +++++++++---------- .../midpoint/model/intest/TestAudit.java | 4 +-- .../intest/gensync/TestRoleEntitlement.java | 6 ++--- .../model/intest/sync/TestImportRecon.java | 2 +- ...self-accounts-partial-control-password.xml | 1 + .../provisioning/impl/ConstraintsChecker.java | 4 +-- .../impl/dummy/TestDummyParallelism.java | 4 +-- 7 files changed, 24 insertions(+), 23 deletions(-) diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java index 33d5e75a273..d3b478a0920 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java @@ -244,7 +244,7 @@ private HookOperationMode resolveFocusConflict(LensContex return HookOperationMode.FOREGROUND; } PrismObject focusObject = context.getFocusContext() != null ? context.getFocusContext().getObjectAny() : null; - ModelExecuteOptions options = null; + ModelExecuteOptions options = new ModelExecuteOptions(); switch (resolutionPolicy.getAction()) { case FAIL: throw new SystemException("Conflict detected while updating " + focusObject); case LOG: @@ -253,7 +253,7 @@ private HookOperationMode resolveFocusConflict(LensContex case RECOMPUTE: break; case RECONCILE: - options = ModelExecuteOptions.createReconcile(); + options.setReconcile(); break; default: throw new IllegalStateException("Unsupported conflict resolution action: " + resolutionPolicy.getAction()); @@ -290,28 +290,28 @@ private HookOperationMode resolveFocusConflict(LensContex int preconditionAttempts = 0; while (true) { - - PrismObject focus = repositoryService.getObject(focusClass, oid, null, result); - LensContext contextNew = contextFactory.createRecomputeContext(focus, options, task, result); - contextNew.setProgressListeners(new ArrayList<>(emptyIfNull(context.getProgressListeners()))); - - int attemptOld = context.getConflictResolutionAttemptNumber(); + + int attemptOld = context.getConflictResolutionAttemptNumber(); int attemptNew = attemptOld + 1; boolean shouldExecuteAttempt = shouldExecuteAttempt(context, resolutionPolicy, attemptNew); if (!shouldExecuteAttempt) { LOGGER.warn("CONFLICT: Couldn't resolve conflict even after {} resolution attempt(s), giving up.", attemptOld); return HookOperationMode.FOREGROUND; } - contextNew.setConflictResolutionAttemptNumber(attemptNew); - // this is a recursion; but limited to max attempts which should not be a large number delay(context, resolutionPolicy, attemptNew + preconditionAttempts); - LOGGER.debug("CONFLICT: Recomputing {} as reaction to conflict (options={}, attempts={},{})", - context.getFocusContext().getHumanReadableName(), attemptNew, preconditionAttempts); + PrismObject focus = repositoryService.getObject(focusClass, oid, null, result); + LensContext contextNew = contextFactory.createRecomputeContext(focus, options, task, result); + contextNew.setProgressListeners(new ArrayList<>(emptyIfNull(context.getProgressListeners()))); + contextNew.setConflictResolutionAttemptNumber(attemptNew); + + LOGGER.debug("CONFLICT: Recomputing {} as reaction to conflict (options={}, attempts={},{}, readVersion={})", + context.getFocusContext().getHumanReadableName(), options, attemptNew, preconditionAttempts, contextNew.getFocusContext().getObjectReadVersion()); try { - + + // this is a recursion; but limited to max attempts which should not be a large number HookOperationMode hookOperationMode = run(contextNew, task, result); // This may be in fact a giveup after recompute that was not able to cleanly proceed. diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestAudit.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestAudit.java index 3a1e9f9c3c0..8876fe371b7 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestAudit.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestAudit.java @@ -354,8 +354,8 @@ public void test135ModifyUserHermanCivilisedHermit() throws Exception { display("Herman (civilised hermit)", user); hermanCivilisedHermitTs = getTimeSafely(); - hermanCivilisedHermitEid = assertObjectAuditRecords(USER_HERMAN_OID, 9); - assertRecordsFromInitial(hermanCivilisedHermitTs, 15); + hermanCivilisedHermitEid = assertObjectAuditRecords(USER_HERMAN_OID, 8); + assertRecordsFromInitial(hermanCivilisedHermitTs, 14); } @Test diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/gensync/TestRoleEntitlement.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/gensync/TestRoleEntitlement.java index 4d88ac79e4d..6d4b60ed91c 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/gensync/TestRoleEntitlement.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/gensync/TestRoleEntitlement.java @@ -434,7 +434,7 @@ public void test119ModifyRoleDeleteEntitlement() throws Exception { dummyAuditService.assertRecords(2); dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(2); + dummyAuditService.assertExecutionDeltas(3); dummyAuditService.assertHasDelta(ChangeType.MODIFY, RoleType.class); dummyAuditService.assertHasDelta(ChangeType.DELETE, ShadowType.class); dummyAuditService.assertTarget(ROLE_PIRATE_OID); @@ -541,7 +541,7 @@ public void test121ModifyRoleLinkEntitlement() throws Exception { dummyAuditService.assertRecords(2); dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(2); + dummyAuditService.assertExecutionDeltas(3); dummyAuditService.assertHasDelta(ChangeType.MODIFY, RoleType.class); dummyAuditService.assertHasDelta(ChangeType.MODIFY, ShadowType.class); dummyAuditService.assertTarget(ROLE_PIRATE_OID); @@ -761,7 +761,7 @@ public void test132ModifyEntitlement() throws Exception { dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertRecords(3); dummyAuditService.assertAnyRequestDeltas(); - dummyAuditService.assertExecutionDeltas(0, 1); + dummyAuditService.assertExecutionDeltas(0, 2); dummyAuditService.assertHasDelta(0, ChangeType.MODIFY, ShadowType.class); dummyAuditService.assertExecutionDeltas(1, 1); dummyAuditService.assertHasDelta(1, ChangeType.MODIFY, RoleType.class); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestImportRecon.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestImportRecon.java index c89e7c1f5c1..28c6441a0b8 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestImportRecon.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/sync/TestImportRecon.java @@ -431,7 +431,7 @@ public void test150ImportFromResourceDummy() throws Exception { displayThen(TEST_NAME); TestUtil.assertSuccess(task.getResult()); - assertCounterIncrement(InternalCounters.SHADOW_FETCH_OPERATION_COUNT, 3); + assertCounterIncrement(InternalCounters.SHADOW_FETCH_OPERATION_COUNT, 5); users = modelService.searchObjects(UserType.class, null, null, task, result); display("Users after import", users); diff --git a/model/model-intest/src/test/resources/security/role-self-accounts-partial-control-password.xml b/model/model-intest/src/test/resources/security/role-self-accounts-partial-control-password.xml index 070d258f667..9d347ba0825 100644 --- a/model/model-intest/src/test/resources/security/role-self-accounts-partial-control-password.xml +++ b/model/model-intest/src/test/resources/security/role-self-accounts-partial-control-password.xml @@ -77,6 +77,7 @@ self

credentials + metadata http://midpoint.evolveum.com/xml/ns/public/security/authorization-model-3#modify diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConstraintsChecker.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConstraintsChecker.java index d40c61bee9f..5e4d44eacfb 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConstraintsChecker.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ConstraintsChecker.java @@ -194,8 +194,8 @@ private boolean checkUniqueness(String oid, PrismProperty identifier, ObjectQuer Collection> options = SelectorOptions.createCollection(GetOperationOptions.createNoFetch()); List> foundObjects = shadowCache.searchObjects(query, options, true, task, result); if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Uniqueness check of {} resulted in {} results, using query:\n{}", - identifier, foundObjects.size(), query.debugDump()); + LOGGER.trace("Uniqueness check of {} resulted in {} results:\n{}\nquery:\n{}", + identifier, foundObjects.size(), foundObjects, query.debugDump(1)); } if (foundObjects.isEmpty()) { if (useCache) { diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyParallelism.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyParallelism.java index c310c824c01..034b4856297 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyParallelism.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyParallelism.java @@ -65,7 +65,7 @@ public class TestDummyParallelism extends AbstractBasicDummyTest { private static final long WAIT_TIMEOUT = 60000L; - private static final int DUMMY_OPERATION_DELAY_RANGE = 1000; + private static final int DUMMY_OPERATION_DELAY_RANGE = 1500; private String accountMorganOid; private String accountElizabethOid; @@ -79,7 +79,7 @@ protected int getConcurrentTestFastRandomStartDelayRange() { } protected int getConcurrentTestSlowRandomStartDelayRange() { - return 1000; + return 150; } @Override From 4769cf0ff0a79ce5b2ea705327143a4c30352a94 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Sat, 30 Sep 2017 08:45:02 +0200 Subject: [PATCH 79/97] Option to serialize wf execution tasks. (cherry picked from commit 4fe7741) --- .../ns/public/common/common-workflows-3.xsd | 43 +++- .../impl/tasks/WfTaskCreationInstruction.java | 21 ++ .../wf/impl/policy/AbstractWfTestPolicy.java | 9 +- .../policy/other/TestParallelApprovals.java | 187 ++++++++++++++++++ .../resources/policy/role-role51a-slow.xml | 43 ++++ .../resources/policy/role-role52a-slow.xml | 43 ++++ .../resources/policy/role-role53a-slow.xml | 43 ++++ model/workflow-impl/testng-integration.xml | 1 + .../quartzimpl/execution/JobExecutor.java | 3 + 9 files changed, 391 insertions(+), 2 deletions(-) create mode 100644 model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestParallelApprovals.java create mode 100644 model/workflow-impl/src/test/resources/policy/role-role51a-slow.xml create mode 100644 model/workflow-impl/src/test/resources/policy/role-role52a-slow.xml create mode 100644 model/workflow-impl/src/test/resources/policy/role-role53a-slow.xml diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd index 6a3dd601cea..864b1bb438c 100644 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd @@ -635,12 +635,53 @@ + + + + Whether and how to serialize execution tasks (if "execute after all approvals" is set to false). + EXPERIMENTAL + + + true + 3.6.1 + + + - + + + + Whether and how to serialize execution tasks (if "execute after all approvals" is set to false). + EXPERIMENTAL + + + true + 3.6.1 + + + + + + + Whether this feature is enabled. Default is true if executionTasksSerialization element is present; false otherwise. + + + + + + + Interval after which the execution task is to be rescheduled in case of conflict. Default is 10 seconds. + + + + + + + How to deal with legacy approvers specifications, i.e. approvalRef, approvalExpression, approvalSchema, diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java index ea43ed10a90..4f735f16c5c 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java @@ -23,6 +23,7 @@ import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.task.api.*; @@ -42,6 +43,7 @@ import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; import org.apache.commons.lang.Validate; +import javax.xml.datatype.Duration; import java.util.*; import static com.evolveum.midpoint.prism.xml.XmlTypeConverter.createXMLGregorianCalendar; @@ -58,6 +60,8 @@ public class WfTaskCreationInstruction sysconfig = prismContext.parseObject(getSystemConfigurationFile()); + updateSystemConfiguration(sysconfig.asObjectable()); + repoAddObject(sysconfig, initResult); + repoAddObjectFromFile(ROLE_SUPERUSER_FILE, initResult); userAdministrator = repoAddObjectFromFile(USER_ADMINISTRATOR_FILE, initResult); login(userAdministrator); @@ -230,6 +233,10 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti userTemplateAssigningRole1aOidAfter = repoAddObjectFromFile(USER_TEMPLATE_ASSIGNING_ROLE_1A_AFTER, initResult).getOid(); } + protected void updateSystemConfiguration(SystemConfigurationType systemConfiguration) { + // nothing to do by default + } + protected File getSystemConfigurationFile() { return SYSTEM_CONFIGURATION_FILE; } diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestParallelApprovals.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestParallelApprovals.java new file mode 100644 index 00000000000..3a61e383c91 --- /dev/null +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestParallelApprovals.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.wf.impl.policy.other; + +import com.evolveum.midpoint.model.impl.controller.ModelOperationTaskHandler; +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder; +import com.evolveum.midpoint.prism.xml.XmlTypeConverter; +import com.evolveum.midpoint.schema.constants.ObjectTypes; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.schema.util.ObjectTypeUtil; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.task.api.TaskListener; +import com.evolveum.midpoint.task.api.TaskManager; +import com.evolveum.midpoint.task.api.TaskRunResult; +import com.evolveum.midpoint.test.util.TestUtil; +import com.evolveum.midpoint.util.DebugUtil; +import com.evolveum.midpoint.wf.impl.policy.AbstractWfTestPolicy; +import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemType; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.testng.annotations.Test; + +import java.io.File; +import java.util.Collections; +import java.util.List; + +import static com.evolveum.midpoint.model.api.ModelExecuteOptions.createExecuteImmediatelyAfterApproval; +import static com.evolveum.midpoint.xml.ns._public.common.common_3.TaskExecutionStatusType.CLOSED; + +/** + * @author mederly + */ +@ContextConfiguration(locations = {"classpath:ctx-workflow-test-main.xml"}) +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) +public class TestParallelApprovals extends AbstractWfTestPolicy { + + private static final File ROLE_ROLE51A_FILE = new File(TEST_RESOURCE_DIR, "role-role51a-slow.xml"); + private static final File ROLE_ROLE52A_FILE = new File(TEST_RESOURCE_DIR, "role-role52a-slow.xml"); + private static final File ROLE_ROLE53A_FILE = new File(TEST_RESOURCE_DIR, "role-role53a-slow.xml"); + + private String roleRole51aOid, roleRole52aOid, roleRole53aOid; + + @Override + protected PrismObject getDefaultActor() { + return userAdministrator; + } + + @Override + public void initSystem(Task initTask, OperationResult initResult) throws Exception { + super.initSystem(initTask, initResult); + + roleRole51aOid = repoAddObjectFromFile(ROLE_ROLE51A_FILE, initResult).getOid(); + roleRole52aOid = repoAddObjectFromFile(ROLE_ROLE52A_FILE, initResult).getOid(); + roleRole53aOid = repoAddObjectFromFile(ROLE_ROLE53A_FILE, initResult).getOid(); + + DebugUtil.setPrettyPrintBeansAs(PrismContext.LANG_YAML); + } + + @Override + protected void updateSystemConfiguration(SystemConfigurationType systemConfiguration) { + super.updateSystemConfiguration(systemConfiguration); + systemConfiguration.getWorkflowConfiguration() + .beginExecutionTasksSerialization() + .retryInterval(XmlTypeConverter.createDuration(1000)); // makes tests run faster + } + + @Test + public void test100ParallelApprovals() throws Exception { + final String TEST_NAME = "test100ParallelApprovals"; + TestUtil.displayTestTitle(this, TEST_NAME); + login(userAdministrator); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + displayWhen(TEST_NAME); + ObjectDelta assignDelta = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT).add( + ObjectTypeUtil.createAssignmentTo(roleRole51aOid, ObjectTypes.ROLE, prismContext), + ObjectTypeUtil.createAssignmentTo(roleRole52aOid, ObjectTypes.ROLE, prismContext), + ObjectTypeUtil.createAssignmentTo(roleRole53aOid, ObjectTypes.ROLE, prismContext)) + .asObjectDeltaCast(userJackOid); + executeChanges(assignDelta, createExecuteImmediatelyAfterApproval(), task, result); // should start approval processes + assertNotAssignedRole(userJackOid, roleRole51aOid, task, result); + assertNotAssignedRole(userJackOid, roleRole52aOid, task, result); + assertNotAssignedRole(userJackOid, roleRole53aOid, task, result); + + display("Task after operation", task); + String rootTaskOid = wfTaskUtil.getRootTaskOid(task); + display("root task", getTask(rootTaskOid)); + + CheckingTaskListener listener = new CheckingTaskListener(rootTaskOid); + taskManager.registerTaskListener(listener); + + List workItems = getWorkItems(task, result); + display("work items", workItems); + display("approving work items"); + for (WorkItemType workItem : workItems) { + workflowManager.completeWorkItem(workItem.getExternalId(), true, null, null, null, result); + } + + waitForTaskCloseOrSuspend(rootTaskOid, 120000, 1000); + + // THEN + + PrismObject rootTask = getTask(rootTaskOid); + if (listener.getException() != null || rootTask.asObjectable().getExecutionStatus() != CLOSED) { + fail("root task has not completed; recorded exception = " + listener.getException()); + } + + PrismObject jack = getUser(userJackOid); + assertAssignedRole(jack, roleRole51aOid); + assertAssignedRole(jack, roleRole52aOid); + assertAssignedRole(jack, roleRole53aOid); + } + + private class CheckingTaskListener implements TaskListener { + + private String rootTaskOid; + private Task executing; + private RuntimeException exception; + + public CheckingTaskListener(String rootTaskOid) { + this.rootTaskOid = rootTaskOid; + } + + public RuntimeException getException() { + return exception; + } + + @Override + public synchronized void onTaskStart(Task task) { + if (!ModelOperationTaskHandler.MODEL_OPERATION_TASK_URI.equals(task.getHandlerUri())) { + return; + } + System.out.println("Starting " + task + ", handler uri " + task.getHandlerUri()); + if (executing != null) { + exception = new IllegalStateException("Started task " + task + " but another one is already executing: " + executing); + System.out.println(exception.getMessage()); + // suspend root task in order to fail faster + taskManager.suspendTasks(Collections.singleton(rootTaskOid), TaskManager.DO_NOT_WAIT, new OperationResult("dummy")); + } + executing = task; + } + + @Override + public synchronized void onTaskFinish(Task task, TaskRunResult runResult) { + if (!ModelOperationTaskHandler.MODEL_OPERATION_TASK_URI.equals(task.getHandlerUri())) { + return; + } + System.out.println("Finishing " + task + ", handler uri " + task.getHandlerUri()); + assert executing.getOid().equals(task.getOid()); + executing = null; + } + + @Override + public void onTaskThreadStart(Task task, boolean isRecovering) { + // ignoring + } + + @Override + public void onTaskThreadFinish(Task task) { + // ignoring + } + } +} diff --git a/model/workflow-impl/src/test/resources/policy/role-role51a-slow.xml b/model/workflow-impl/src/test/resources/policy/role-role51a-slow.xml new file mode 100644 index 00000000000..e69219d918b --- /dev/null +++ b/model/workflow-impl/src/test/resources/policy/role-role51a-slow.xml @@ -0,0 +1,43 @@ + + + + Role51a-slow + + + + + description + + + + + + description + + + + + + diff --git a/model/workflow-impl/src/test/resources/policy/role-role52a-slow.xml b/model/workflow-impl/src/test/resources/policy/role-role52a-slow.xml new file mode 100644 index 00000000000..94e3ddff998 --- /dev/null +++ b/model/workflow-impl/src/test/resources/policy/role-role52a-slow.xml @@ -0,0 +1,43 @@ + + + + Role52a-slow + + + + + description + + + + + + description + + + + + + diff --git a/model/workflow-impl/src/test/resources/policy/role-role53a-slow.xml b/model/workflow-impl/src/test/resources/policy/role-role53a-slow.xml new file mode 100644 index 00000000000..39899cbc74d --- /dev/null +++ b/model/workflow-impl/src/test/resources/policy/role-role53a-slow.xml @@ -0,0 +1,43 @@ + + + + Role53a-slow + + + + + description + + + + + + description + + + + + + diff --git a/model/workflow-impl/testng-integration.xml b/model/workflow-impl/testng-integration.xml index b2466e6419c..40f976a6ab6 100644 --- a/model/workflow-impl/testng-integration.xml +++ b/model/workflow-impl/testng-integration.xml @@ -60,6 +60,7 @@ + diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java index b17ae34a487..562a22f07db 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java @@ -60,6 +60,8 @@ public static void setTaskManagerQuartzImpl(TaskManagerQuartzImpl tmqi) { private static final long WATCHFUL_SLEEP_INCREMENT = 500; private static final int DEFAULT_RESCHEDULE_TIME_FOR_GROUP_LIMIT = 60; + private static final int RESCHEDULE_TIME_RANDOMIZATION_INTERVAL = 3; + private static final int RESCHEDULE_TIME_FOR_NO_SUITABLE_NODE = 60; /* * JobExecutor is instantiated at each execution of the task, so we can store @@ -281,6 +283,7 @@ private RescheduleTime getRescheduleTime(TaskExecutionConstraintsType executionC } else { retryAt = System.currentTimeMillis() + defaultInterval * 1000L; } + retryAt += Math.random() * RESCHEDULE_TIME_RANDOMIZATION_INTERVAL * 1000.0; // to avoid endless collisions if (nextTaskRunTime != null && nextTaskRunTime < retryAt) { return new RescheduleTime(nextTaskRunTime, true); } else { From 4c3e1634a8a64d3e3f4fab6dd6064a4eba12b6e2 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Sun, 1 Oct 2017 00:54:46 +0200 Subject: [PATCH 80/97] Secondary groups in task execution constraints. Options for configuring wf execution tasks constraints and serialization. --- .../xml/ns/public/common/common-core-3.xsd | 38 +++++++ .../ns/public/common/common-workflows-3.xsd | 49 ++++++++- .../impl/tasks/WfTaskCreationInstruction.java | 52 ++++++--- .../policy/other/TestParallelApprovals.java | 5 +- .../repo/sql/util/SimpleTaskAdapter.java | 20 +++- .../com/evolveum/midpoint/task/api/Task.java | 10 +- .../task/quartzimpl/TaskQuartzImpl.java | 36 +++++-- .../quartzimpl/execution/JobExecutor.java | 102 +++++++++++++----- .../TestQuartzTaskManagerContract.java | 49 +++++++++ .../repo/task-108SecondaryGroupLimit-2.xml | 42 ++++++++ .../repo/task-108SecondaryGroupLimit-3.xml | 38 +++++++ .../repo/task-108SecondaryGroupLimit.xml | 38 +++++++ 12 files changed, 416 insertions(+), 63 deletions(-) create mode 100644 repo/task-quartz-impl/src/test/resources/repo/task-108SecondaryGroupLimit-2.xml create mode 100644 repo/task-quartz-impl/src/test/resources/repo/task-108SecondaryGroupLimit-3.xml create mode 100644 repo/task-quartz-impl/src/test/resources/repo/task-108SecondaryGroupLimit.xml 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 b2ad079a93c..8858ef2be64 100644 --- 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 @@ -1771,6 +1771,13 @@ + + + + TODO + + + @@ -1805,6 +1812,37 @@ + + + + + TODO + EXPERIMENTAL. + + + 3.7 + true + + + + + + + TODO + + + + + + + Number of tasks within the group that can be executed at once (clusterwide). Default is "unlimited". + This parameter will be moved into separate task group object in a later version of midPoint. + + + + + + diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd index 864b1bb438c..9a5c77e35f5 100644 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd @@ -635,10 +635,10 @@ - + - Whether and how to serialize execution tasks (if "execute after all approvals" is set to false). + TODO EXPERIMENTAL @@ -652,10 +652,42 @@ + + + + TODO + EXPERIMENTAL + + + true + 3.6.1 + + + + + + + TODO + + + + + + + TODO + + + 3.7 + + + + + + - Whether and how to serialize execution tasks (if "execute after all approvals" is set to false). + TODO EXPERIMENTAL @@ -667,17 +699,24 @@ - Whether this feature is enabled. Default is true if executionTasksSerialization element is present; false otherwise. + Whether this feature is enabled. Default is true if "serialization" element is present; false otherwise. - + Interval after which the execution task is to be rescheduled in case of conflict. Default is 10 seconds. + + + + TODO + + + diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java index 4f735f16c5c..3edb8cb0e57 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java @@ -400,23 +400,45 @@ public Task createTask(WfTaskController taskController, Task parentTask, WfConfi } task.setWorkflowContext(wfContext); - WfExecutionTasksSerializationType serialization = wfConfigurationType != null ? wfConfigurationType.getExecutionTasksSerialization() : null; - if (parentTask != null && executeModelOperationHandler && serialization != null && !Boolean.FALSE.equals(serialization.isEnabled())) { + WfExecutionTasksConfigurationType tasksConfig = wfConfigurationType != null ? wfConfigurationType.getExecutionTasks() : null; + if (executeModelOperationHandler && tasksConfig != null) { TaskType taskBean = task.getTaskPrismObject().asObjectable(); - // TODO think about 3.7 (setting the group influences also the local execution possibilities) -// String groupPrefix = serialization.getExecutionGroupPrefix() != null ? -// serialization.getExecutionGroupPrefix() : DEFAULT_EXECUTION_GROUP_PREFIX_FOR_SERIALIZATION; - String groupName = DEFAULT_EXECUTION_GROUP_PREFIX_FOR_SERIALIZATION + parentTask.getTaskIdentifier(); - Duration retryAfter = serialization.getRetryInterval() != null ? - serialization.getRetryInterval() : XmlTypeConverter.createDuration(DEFAULT_SERIALIZATION_RETRY_TIME); - taskBean.setExecutionConstraints( - new TaskExecutionConstraintsType() - .group(groupName) - .groupTaskLimit(1) - .retryAfter(retryAfter)); - LOGGER.trace("Setting group '{}' with a limit of 1 for task {}", groupName, task); + // execution constraints + TaskExecutionConstraintsType constraints = tasksConfig.getExecutionConstraints(); + if (constraints != null) { + taskBean.setExecutionConstraints(constraints.clone()); + } + // serialization + WfExecutionTasksSerializationType serialization = tasksConfig.getSerialization(); + if (serialization != null && !Boolean.FALSE.equals(serialization.isEnabled()) && parentTask != null) { + String groupPrefix = serialization.getGroupPrefix() != null ? + serialization.getGroupPrefix() : DEFAULT_EXECUTION_GROUP_PREFIX_FOR_SERIALIZATION; + String groupName = groupPrefix + parentTask.getTaskIdentifier(); + Duration retryAfter; + if (serialization.getRetryAfter() != null) { + if (constraints != null && constraints.getRetryAfter() != null && !constraints.getRetryAfter().equals(serialization.getRetryAfter())) { + LOGGER.warn( + "Workflow configuration: task constraints retryAfter ({}) is different from serialization retryAfter ({}) -- using the latter", + constraints.getRetryAfter(), serialization.getRetryAfter()); + } + retryAfter = serialization.getRetryAfter(); + } else if (constraints != null && constraints.getRetryAfter() != null) { + retryAfter = constraints.getRetryAfter(); + } else { + retryAfter = XmlTypeConverter.createDuration(DEFAULT_SERIALIZATION_RETRY_TIME); + } + if (taskBean.getExecutionConstraints() == null) { + taskBean.setExecutionConstraints(new TaskExecutionConstraintsType()); + } + taskBean.getExecutionConstraints() + .beginSecondaryGroup() + .group(groupName) + .groupTaskLimit(1) + .end() + .retryAfter(retryAfter); + LOGGER.trace("Setting group '{}' with a limit of 1 for task {}", groupName, task); + } } - return task; } diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestParallelApprovals.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestParallelApprovals.java index 3a61e383c91..536f4b46869 100644 --- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestParallelApprovals.java +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestParallelApprovals.java @@ -80,8 +80,9 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti protected void updateSystemConfiguration(SystemConfigurationType systemConfiguration) { super.updateSystemConfiguration(systemConfiguration); systemConfiguration.getWorkflowConfiguration() - .beginExecutionTasksSerialization() - .retryInterval(XmlTypeConverter.createDuration(1000)); // makes tests run faster + .beginExecutionTasks() + .beginSerialization() + .retryAfter(XmlTypeConverter.createDuration(1000)); // makes tests run faster } @Test diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/util/SimpleTaskAdapter.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/util/SimpleTaskAdapter.java index 562fdb65f1c..918ef86d985 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/util/SimpleTaskAdapter.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/util/SimpleTaskAdapter.java @@ -45,10 +45,10 @@ import javax.xml.namespace.QName; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Set; +import java.util.*; + +import static java.util.Collections.emptyMap; +import static java.util.Collections.emptySet; /** * @author lazyman @@ -828,6 +828,18 @@ public String getGroup() { return null; } + @NotNull + @Override + public Collection getGroups() { + return emptySet(); + } + + @NotNull + @Override + public Map getGroupsWithLimits() { + return emptyMap(); + } + @NotNull @Override public List getLastFailures() { diff --git a/repo/task-api/src/main/java/com/evolveum/midpoint/task/api/Task.java b/repo/task-api/src/main/java/com/evolveum/midpoint/task/api/Task.java index 50da4cb8e07..9077126c8ed 100644 --- a/repo/task-api/src/main/java/com/evolveum/midpoint/task/api/Task.java +++ b/repo/task-api/src/main/java/com/evolveum/midpoint/task/api/Task.java @@ -17,6 +17,7 @@ import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Set; import javax.xml.namespace.QName; @@ -31,6 +32,7 @@ import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; +import org.jetbrains.annotations.NotNull; /** * Task instance - a logical unit of work that is either done synchronously, asynchronously, it is deferred, scheduled, etc. @@ -312,7 +314,13 @@ public void setNameImmediate(PolyStringType value, OperationResult parentResult) public String getGroup(); - /** + @NotNull + Collection getGroups(); + + @NotNull + Map getGroupsWithLimits(); + + /** * Returns the schedule. */ public ScheduleType getSchedule(); diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskQuartzImpl.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskQuartzImpl.java index 382eb172d70..aa9bea57d17 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskQuartzImpl.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskQuartzImpl.java @@ -79,17 +79,12 @@ import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.concurrent.Future; import static com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType.F_MODEL_OPERATION_CONTEXT; import static com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType.F_WORKFLOW_CONTEXT; +import static java.util.Collections.emptyMap; /** * Implementation of a Task. @@ -1222,7 +1217,32 @@ public String getGroup() { return executionConstraints != null ? executionConstraints.getGroup() : null; } - /* + @NotNull + @Override + public Collection getGroups() { + return getGroupsWithLimits().keySet(); + } + + @NotNull + @Override + public Map getGroupsWithLimits() { + TaskExecutionConstraintsType executionConstraints = getExecutionConstraints(); + if (executionConstraints == null) { + return emptyMap(); + } + Map rv = new HashMap<>(); + if (executionConstraints.getGroup() != null) { + rv.put(executionConstraints.getGroup(), executionConstraints.getGroupTaskLimit()); + } + for (TaskExecutionGroupConstraintType sg : executionConstraints.getSecondaryGroup()) { + if (sg.getGroup() != null) { // shouldn't occur but it's a user configurable field, so be prepared for the worst + rv.put(sg.getGroup(), sg.getGroupTaskLimit()); + } + } + return rv; + } + + /* * Schedule */ diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java index 562a22f07db..1421c410dbb 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/execution/JobExecutor.java @@ -32,15 +32,16 @@ import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskExecutionConstraintsType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ThreadStopActionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import org.apache.commons.lang.Validate; +import org.jetbrains.annotations.NotNull; import org.quartz.*; import org.springframework.security.core.Authentication; import javax.xml.datatype.Duration; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; +import java.util.*; @DisallowConcurrentExecution public class JobExecutor implements InterruptableJob { @@ -208,6 +209,27 @@ public void execute(JobExecutionContext context) throws JobExecutionException { } + class GroupExecInfo { + int limit; + Set tasks = new HashSet<>(); + + GroupExecInfo(Integer l) { + limit = l != null ? l : Integer.MAX_VALUE; + } + + public void accept(Integer limit, Task task) { + if (limit != null && limit < this.limit) { + this.limit = limit; + } + this.tasks.add(task); + } + + @Override + public String toString() { + return "{limit=" + limit + ", tasks=" + tasks + "}"; + } + } + // returns false if constraints are not met (i.e. execution should finish immediately) private boolean checkExecutionConstraints(TaskQuartzImpl task, OperationResult result) throws JobExecutionException { TaskExecutionConstraintsType executionConstraints = task.getExecutionConstraints(); @@ -215,30 +237,13 @@ private boolean checkExecutionConstraints(TaskQuartzImpl task, OperationResult r return true; } - // group limit - String group = executionConstraints.getGroup(); - if (group != null && executionConstraints.getGroupTaskLimit() != null) { - List tasksInGroup = new ArrayList<>(); - ClusterStatusInformation clusterStatusInformation = taskManagerImpl.getExecutionManager() - .getClusterStatusInformation(true, false, result); - for (ClusterStatusInformation.TaskInfo taskInfo : clusterStatusInformation.getTasks()) { - Task runningTask; - try { - runningTask = taskManagerImpl.getTask(taskInfo.getOid(), result); - } catch (ObjectNotFoundException e) { - LOGGER.debug("Couldn't find running task {} when checking execution constraints: {}", taskInfo.getOid(), e.getMessage()); - continue; - } catch (SchemaException e) { - LoggingUtils.logUnexpectedException(LOGGER, - "Couldn't retrieve running task {} when checking execution constraints", e, taskInfo.getOid()); - continue; - } - if (group.equals(runningTask.getGroup()) && !task.getOid().equals(runningTask.getOid())) { - tasksInGroup.add(runningTask); - } - } - int limit = executionConstraints.getGroupTaskLimit(); - LOGGER.trace("Tasks in group {}: {}", group, tasksInGroup); + // group limits + Map groupMap = createGroupMap(task, result); + LOGGER.trace("groupMap = {}", groupMap); + for (Map.Entry entry : groupMap.entrySet()) { + String group = entry.getKey(); + int limit = entry.getValue().limit; + Set tasksInGroup = entry.getValue().tasks; if (tasksInGroup.size() >= limit) { RescheduleTime rescheduleTime = getRescheduleTime(executionConstraints, DEFAULT_RESCHEDULE_TIME_FOR_GROUP_LIMIT, task.getNextRunStartTime(result)); @@ -261,6 +266,47 @@ private boolean checkExecutionConstraints(TaskQuartzImpl task, OperationResult r return true; } + @NotNull + private Map createGroupMap(TaskQuartzImpl task, OperationResult result) { + Map groupMap = new HashMap<>(); + Map groupsWithLimits = task.getGroupsWithLimits(); + if (!groupsWithLimits.isEmpty()) { + groupsWithLimits.forEach((g, l) -> groupMap.put(g, new GroupExecInfo(l))); + ClusterStatusInformation csi = taskManagerImpl.getExecutionManager() + .getClusterStatusInformation(true, false, result); + for (ClusterStatusInformation.TaskInfo taskInfo : csi.getTasks()) { + if (task.getOid().equals(taskInfo.getOid())) { + continue; + } + Task otherTask; + try { + otherTask = taskManagerImpl.getTask(taskInfo.getOid(), result); + } catch (ObjectNotFoundException e) { + LOGGER.debug("Couldn't find running task {} when checking execution constraints: {}", taskInfo.getOid(), + e.getMessage()); + continue; + } catch (SchemaException e) { + LoggingUtils.logUnexpectedException(LOGGER, + "Couldn't retrieve running task {} when checking execution constraints", e, taskInfo.getOid()); + continue; + } + addToGroupMap(groupMap, otherTask); + } + } + return groupMap; + } + + private void addToGroupMap(Map groupMap, Task otherTask) { + for (Map.Entry otherGroupWithLimit : otherTask.getGroupsWithLimits().entrySet()) { + String otherGroup = otherGroupWithLimit.getKey(); + GroupExecInfo groupExecInfo = groupMap.get(otherGroup); + if (groupExecInfo != null) { + Integer otherLimit = otherGroupWithLimit.getValue(); + groupExecInfo.accept(otherLimit, otherTask); + } + } + } + private class RescheduleTime { private final long timestamp; private final boolean regular; diff --git a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestQuartzTaskManagerContract.java b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestQuartzTaskManagerContract.java index f851ba4f16a..f7be988d952 100644 --- a/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestQuartzTaskManagerContract.java +++ b/repo/task-quartz-impl/src/test/java/com/evolveum/midpoint/task/quartzimpl/TestQuartzTaskManagerContract.java @@ -1633,6 +1633,52 @@ public void timeout() { } } + @Test + public void test108SecondaryGroupLimit() throws Exception { + + final String TEST_NAME = "108SecondaryGroupLimit"; + final OperationResult result = createResult(TEST_NAME); + + TaskType task1 = (TaskType) addObjectFromFile(taskFilename(TEST_NAME)).asObjectable(); + waitForTaskStart(task1.getOid(), result); + + // import second task with the same group (expensive) + TaskType task2 = (TaskType) addObjectFromFile(taskFilename(TEST_NAME + "-2")).asObjectable(); + + Thread.sleep(10000); + task1 = getTaskType(task1.getOid(), result); + assertNull("First task should have no retry time", task1.getNextRetryTimestamp()); + + task2 = getTaskType(task2.getOid(), result); + assertNull("Second task was started even if it should not be", task2.getLastRunStartTimestamp()); + assertNotNull("Next retry time is not set for second task", task2.getNextRetryTimestamp()); + + // now finish first task and check the second one is started + boolean stopped = taskManager.suspendTasks(Collections.singleton(task1.getOid()), 20000L, result); + assertTrue("Task 1 was not suspended successfully", stopped); + + waitForTaskStart(task2.getOid(), result); + + // import third task that has another collision (large-ram) with the second one + TaskType task3 = (TaskType) addObjectFromFile(taskFilename(TEST_NAME + "-3")).asObjectable(); + + Thread.sleep(10000); + task2 = getTaskType(task2.getOid(), result); + assertNull("Second task should have no retry time", task2.getNextRetryTimestamp()); + + task3 = getTaskType(task3.getOid(), result); + assertNull("Third task was started even if it should not be", task3.getLastRunStartTimestamp()); + assertNotNull("Next retry time is not set for third task", task3.getNextRetryTimestamp()); + + // now finish second task and check the third one is started + stopped = taskManager.suspendTasks(Collections.singleton(task2.getOid()), 20000L, result); + assertTrue("Task 2 was not suspended successfully", stopped); + + waitForTaskStart(task3.getOid(), result); + + taskManager.suspendTasks(Collections.singleton(task3.getOid()), 20000L, result); + } + @Test public void test110GroupLimit() throws Exception { @@ -1727,6 +1773,9 @@ public void test999CheckingLeftovers() throws Exception { checkLeftover(leftovers, "022", result); checkLeftover(leftovers, "100", result); checkLeftover(leftovers, "105", result); + checkLeftover(leftovers, "108", result); + checkLeftover(leftovers, "108", "a", result); + checkLeftover(leftovers, "108", "b", result); checkLeftover(leftovers, "110", result); checkLeftover(leftovers, "110", "a", result); checkLeftover(leftovers, "120", result); diff --git a/repo/task-quartz-impl/src/test/resources/repo/task-108SecondaryGroupLimit-2.xml b/repo/task-quartz-impl/src/test/resources/repo/task-108SecondaryGroupLimit-2.xml new file mode 100644 index 00000000000..43afd27dd22 --- /dev/null +++ b/repo/task-quartz-impl/src/test/resources/repo/task-108SecondaryGroupLimit-2.xml @@ -0,0 +1,42 @@ + + + + + + Testing task secondary group limit (2) + + 91919191-76e0-59e2-86d6-3d4f02d3a108 + + + runnable + + http://midpoint.evolveum.com/test/long-task-handler + single + + + + expensive + 1 + + + large-ram + 1 + + PT2S + + diff --git a/repo/task-quartz-impl/src/test/resources/repo/task-108SecondaryGroupLimit-3.xml b/repo/task-quartz-impl/src/test/resources/repo/task-108SecondaryGroupLimit-3.xml new file mode 100644 index 00000000000..c6bbe46ad2a --- /dev/null +++ b/repo/task-quartz-impl/src/test/resources/repo/task-108SecondaryGroupLimit-3.xml @@ -0,0 +1,38 @@ + + + + + + Testing task secondary group limit (3) + + 91919191-76e0-59e2-86d6-3d4f02d3b108 + + + runnable + + http://midpoint.evolveum.com/test/long-task-handler + single + + + + large-ram + + + PT2S + + diff --git a/repo/task-quartz-impl/src/test/resources/repo/task-108SecondaryGroupLimit.xml b/repo/task-quartz-impl/src/test/resources/repo/task-108SecondaryGroupLimit.xml new file mode 100644 index 00000000000..cab3b014f5c --- /dev/null +++ b/repo/task-quartz-impl/src/test/resources/repo/task-108SecondaryGroupLimit.xml @@ -0,0 +1,38 @@ + + + + + + Testing task secondary group limit + + 91919191-76e0-59e2-86d6-3d4f02d30108 + + + runnable + + http://midpoint.evolveum.com/test/long-task-handler + single + + + + expensive + 1 + + PT2S + + From 68476c1e0335b921d4984f8d7feac74e274e4fcd Mon Sep 17 00:00:00 2001 From: kate Date: Sun, 1 Oct 2017 13:58:39 +0200 Subject: [PATCH 81/97] model changes for assignments and policy rules tab. still not finished --- .../gui/api/component/DisplayNamePanel.java | 6 + .../AbstractAssignmentDetailsPanel.java | 42 +-- .../AbstractRoleAssignmentDetailsPanel.java | 7 +- .../AbstractRoleAssignmentPanel.java | 133 ++----- .../component/assignment/AssignmentDto.java | 41 --- .../component/assignment/AssignmentPanel.java | 129 ++++--- .../component/assignment/AssignmentsUtil.java | 57 ++- .../assignment/GdprAssignmentPanel.java | 19 +- .../assignment/PolicyRuleDetailsPanel.java | 3 +- .../assignment/PolicyRulesPanel.java | 50 +-- .../assignment/SelfConsentPanel.java | 17 +- .../SimpleParametricRoleSelector.html | 63 ---- .../SimpleParametricRoleSelector.java | 332 ------------------ .../assignment/SimpleRoleSelector.java | 62 ++-- .../objectdetails/AbstractFocusTabPanel.java | 8 +- .../objectdetails/AbstractRoleMainPanel.java | 4 +- .../FocusAssignmentsTabPanel.java | 82 ++--- .../objectdetails/FocusConsentTabPanel.java | 34 +- .../objectdetails/FocusDetailsTabPanel.java | 4 +- .../objectdetails/FocusMainPanel.java | 64 ++-- .../FocusPolicyRulesTabPanel.java | 35 +- .../objectdetails/RoleMainPanel.java | 5 +- .../web/component/prism/ContainerStatus.java | 2 +- .../prism/ContainerValueWrapper.java | 13 + .../web/component/prism/ContainerWrapper.java | 51 ++- .../web/component/prism/ObjectWrapper.java | 9 +- .../sample/SampleFormFocusTabPanel.java | 19 +- .../util/AssignmentListDataProvider.java | 36 +- .../web/page/admin/PageAdminAbstractRole.java | 22 -- .../web/page/admin/PageAdminFocus.java | 201 ++++------- .../web/page/admin/roles/PageRole.java | 2 +- .../web/page/admin/services/PageService.java | 2 +- .../page/admin/users/PageMergeObjects.java | 13 +- .../web/page/admin/users/PageOrgUnit.java | 2 +- .../web/page/admin/users/PageUser.java | 49 +-- .../web/page/admin/users/PageUserHistory.java | 5 +- .../web/page/self/PageSelfConsents.java | 13 +- 37 files changed, 577 insertions(+), 1059 deletions(-) delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SimpleParametricRoleSelector.html delete mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SimpleParametricRoleSelector.java diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/DisplayNamePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/DisplayNamePanel.java index 51678daa82d..c4955d4434b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/DisplayNamePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/DisplayNamePanel.java @@ -60,6 +60,9 @@ private void initLayout() { } private String createImageModel() { + if (getModelObject() == null){ + return ""; + } if (ObjectType.class.isAssignableFrom(getModelObject().getClass())) { return WebComponentUtil.createDefaultIcon((ObjectType) getModelObject()); } @@ -74,6 +77,9 @@ private IModel getAdditionalNameLabelStyleClass() { private IModel createHeaderModel() { // TODO: align with DisplayNameModel + if (getModelObject() == null){ + return Model.of(""); + } if (ObjectType.class.isAssignableFrom(getModelObject().getClass())) { return Model.of(WebComponentUtil.getEffectiveName((ObjectType) getModelObject(), AbstractRoleType.F_DISPLAY_NAME)); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.java index fab2d6fd58f..c69f134d0ce 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentDetailsPanel.java @@ -20,6 +20,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.web.component.prism.*; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; @@ -37,12 +38,6 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.web.component.form.Form; -import com.evolveum.midpoint.web.component.prism.ContainerValuePanel; -import com.evolveum.midpoint.web.component.prism.ContainerWrapper; -import com.evolveum.midpoint.web.component.prism.ItemWrapper; -import com.evolveum.midpoint.web.component.prism.PrismContainerPanel; -import com.evolveum.midpoint.web.component.prism.PrismPanel; -import com.evolveum.midpoint.web.component.prism.PropertyOrReferenceWrapper; import com.evolveum.midpoint.web.model.ContainerValueWrapperFromObjectWrapperModel; import com.evolveum.midpoint.web.model.ContainerWrapperFromObjectWrapperModel; import com.evolveum.midpoint.web.model.ContainerWrapperListFromObjectWrapperModel; @@ -56,17 +51,15 @@ /** * Created by honchar */ -public abstract class AbstractAssignmentDetailsPanel extends BasePanel{ +public abstract class AbstractAssignmentDetailsPanel extends BasePanel>{ private static final long serialVersionUID = 1L; private final static String ID_DISPLAY_NAME = "displayName"; private final static String ID_ACTIVATION_PANEL = "activationPanel"; private final static String ID_CONTAINERS = "otherContainers"; - public AbstractAssignmentDetailsPanel(String id, Form form, IModel assignmentModel){ + public AbstractAssignmentDetailsPanel(String id, Form form, IModel> assignmentModel){ super(id, assignmentModel); - - } @Override @@ -83,19 +76,18 @@ protected void initLayout(){ @Override public C getObject() { - AssignmentDto assignemtn = getModelObject(); - if (assignemtn.isAssignableObject()) { + AssignmentType assignment = getModelObject().getContainerValue().getValue(); + if (AssignmentsUtil.isAssignableObject(assignment)) { Task task = getPageBase().createSimpleTask("Load target"); com.evolveum.midpoint.schema.result.OperationResult result = task.getResult(); - return (C) WebModelServiceUtils.loadObject(getModelObject().getAssignment().getTargetRef(), getPageBase(), task, result).asObjectable(); + return (C) WebModelServiceUtils.loadObject(assignment.getTargetRef(), getPageBase(), task, result).asObjectable(); } - AssignmentType assignmentType = assignemtn.getAssignment(); - if (assignmentType.getConstruction() != null) { - return (C) assignmentType.getConstruction(); - } else if (assignmentType.getPersonaConstruction() != null) { - return (C) assignmentType.getPersonaConstruction(); - } else if (assignmentType.getPolicyRule() !=null) { - return (C) assignmentType.getPolicyRule(); + if (assignment.getConstruction() != null) { + return (C) assignment.getConstruction(); + } else if (assignment.getPersonaConstruction() != null) { + return (C) assignment.getPersonaConstruction(); + } else if (assignment.getPolicyRule() !=null) { + return (C) assignment.getPolicyRule(); } return null; @@ -112,12 +104,12 @@ public C getObject() { PageAdminObjectDetails pageBase = (PageAdminObjectDetails)getPageBase(); ItemPath assignmentPath = getAssignmentPath(); - ContainerValueWrapperFromObjectWrapperModel assignmentModel = - new ContainerValueWrapperFromObjectWrapperModel(pageBase.getObjectModel(), assignmentPath); +// ContainerValueWrapperFromObjectWrapperModel assignmentModel = +// new ContainerValueWrapperFromObjectWrapperModel(pageBase.getObjectModel(), assignmentPath); Form form = new Form<>("form"); - ContainerValuePanel assignmentPanel = new ContainerValuePanel("basic", assignmentModel, true, form, itemWrapper -> getAssignmentBasicTabVisibity(itemWrapper, assignmentPath), pageBase); + ContainerValuePanel assignmentPanel = new ContainerValuePanel("basic", getModel(), true, form, itemWrapper -> getAssignmentBasicTabVisibity(itemWrapper, assignmentPath), pageBase); add(assignmentPanel); @@ -133,13 +125,13 @@ public C getObject() { } protected ItemPath getAssignmentPath() { - return getModel().getObject().getAssignment().asPrismContainerValue().getPath(); + return getModelObject().getContainerValue().getValue().asPrismContainerValue().getPath(); } protected abstract List collectContainersToShow(); private boolean getAssignmentBasicTabVisibity(ItemWrapper itemWrapper, ItemPath parentAssignmentPath) { - AssignmentType assignment = getModelObject().getAssignment(); + AssignmentType assignment = getModelObject().getContainerValue().getValue(); ObjectReferenceType targetRef = assignment.getTargetRef(); List pathsToHide = new ArrayList<>(); QName targetType = null; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentDetailsPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentDetailsPanel.java index 6cf53122e56..37b3334fcc8 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentDetailsPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentDetailsPanel.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.List; +import com.evolveum.midpoint.web.component.prism.ContainerValueWrapper; import org.apache.wicket.model.IModel; import com.evolveum.midpoint.prism.path.ItemPath; @@ -32,7 +33,7 @@ public class AbstractRoleAssignmentDetailsPanel extends Abs hiddenItems.add(AssignmentType.F_POLICY_RULE); }; - public AbstractRoleAssignmentDetailsPanel(String id, Form form, IModel assignmentModel) { + public AbstractRoleAssignmentDetailsPanel(String id, Form form, IModel> assignmentModel) { super(id, form, assignmentModel); } @@ -40,11 +41,11 @@ public AbstractRoleAssignmentDetailsPanel(String id, Form form, IModel collectContainersToShow() { List pathsToShow = new ArrayList<>(); - if (ConstructionType.COMPLEX_TYPE.equals(getModelObject().getTargetType())) { + if (ConstructionType.COMPLEX_TYPE.equals(AssignmentsUtil.getTargetType(getModelObject().getContainerValue().getValue()))) { pathsToShow.add(getAssignmentPath().append(AssignmentType.F_CONSTRUCTION)); } - if (PersonaConstructionType.COMPLEX_TYPE.equals(getModelObject().getTargetType())) { + if (PersonaConstructionType.COMPLEX_TYPE.equals(AssignmentsUtil.getTargetType(getModelObject().getContainerValue().getValue()))) { pathsToShow.add(getAssignmentPath().append(AssignmentType.F_PERSONA_CONSTRUCTION)); } return pathsToShow; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java index b1af8b1b35f..c05507ce74d 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java @@ -21,7 +21,14 @@ import java.util.Map; import javax.xml.namespace.QName; - +import javax.xml.validation.Schema; + +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.web.component.prism.ContainerValueWrapper; +import com.evolveum.midpoint.web.component.prism.ContainerWrapper; +import com.evolveum.midpoint.web.component.prism.ContainerWrapperFactory; +import com.evolveum.midpoint.web.component.prism.ValueStatus; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.lang.StringUtils; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; @@ -56,10 +63,6 @@ import com.evolveum.midpoint.web.page.admin.users.dto.UserDtoStatus; import com.evolveum.midpoint.web.session.UserProfileStorage; import com.evolveum.midpoint.web.session.UserProfileStorage.TableId; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ConstructionType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; /** * Created by honchar. @@ -72,8 +75,9 @@ public class AbstractRoleAssignmentPanel extends AssignmentPanel { private static final String ID_SHOW_ALL_ASSIGNMENTS_BUTTON = "showAllAssignmentsButton"; - public AbstractRoleAssignmentPanel(String id, IModel> assignmentsModel){ - super(id, assignmentsModel); + public AbstractRoleAssignmentPanel(String id, IModel>> assignmentsModel, + ContainerWrapper assignmentContainerWrapper){ + super(id, assignmentsModel, assignmentContainerWrapper); } protected void initCustomLayout(WebMarkupContainer assignmentsContainer){ @@ -149,106 +153,33 @@ protected void addSelectedAssignmentsPerformed(AjaxReques return; } for (T object : assignmentsList){ - AssignmentType assignment = ObjectTypeUtil.createAssignmentTo(object.asPrismObject(), relation); - AssignmentDto dto = new AssignmentDto(assignment, UserDtoStatus.ADD); - getModelObject().add(0, dto); + try { + AssignmentType assignment = ObjectTypeUtil.createAssignmentTo(object.asPrismObject(), relation); + assignment.asPrismContainerValue().applyDefinition(assignmentContainerWrapper.getItem().getDefinition(), false); + ContainerValueWrapper newAssignmentContainerWrapper = assignmentContainerWrapper.createItem(false); + newAssignmentContainerWrapper.setStatus(ValueStatus.ADDED); + newAssignmentContainerWrapper.getContainerValue().getValue().setupContainerValue(assignment.asPrismContainerValue()); + getModelObject().add(0, newAssignmentContainerWrapper); + } catch (SchemaException ex){ + + } } refreshTable(target); } - protected List> initColumns() { - List> columns = new ArrayList<>(); - - columns.add(new PropertyColumn(createStringResource("ObjectReferenceType.relation"), AssignmentDto.F_RELATION_TYPE)); - - //commented since these columns are not used -// columns.add(new DirectlyEditablePropertyColumn(createStringResource("AssignmentDataTablePanel.descriptionColumnName"), AssignmentEditorDto.F_DESCRIPTION){ -// private static final long serialVersionUID = 1L; -// -// @Override -// public void populateItem(Item> cellItem, String componentId, -// final IModel rowModel) { -// super.populateItem(cellItem, componentId, rowModel); -// cellItem.add(AssignmentsUtil.getEnableBehavior(rowModel)); -// } -// }); -// columns.add(new AbstractColumn(createStringResource("AssignmentDataTablePanel.organizationColumnName")){ -// private static final long serialVersionUID = 1L; -// -// @Override -// public void populateItem(Item> cellItem, String componentId, final IModel rowModel) { -// ObjectQuery orgQuery = QueryBuilder.queryFor(OrgType.class, getPageBase().getPrismContext()) -// .item(OrgType.F_TENANT).eq(false) -// .or().item(OrgType.F_TENANT).isNull() -// .build(); -// ChooseTypePanel orgPanel = getChooseOrgPanel(componentId, rowModel, orgQuery); -// orgPanel.add(visibleIfRoleBehavior(rowModel)); -// cellItem.add(orgPanel); -// cellItem.add(AssignmentsUtil.getEnableBehavior(rowModel)); -// } -// -// }); -// columns.add(new AbstractColumn(createStringResource("AssignmentDataTablePanel.tenantColumnName")){ -// private static final long serialVersionUID = 1L; -// -// @Override -// public void populateItem(Item> cellItem, String componentId, final IModel rowModel) { -// ObjectQuery tenantQuery = QueryBuilder.queryFor(OrgType.class, getPageBase().getPrismContext()) -// .item(OrgType.F_TENANT).eq(true) -// .build(); -// ChooseTypePanel tenantPanel = getChooseOrgPanel(componentId, rowModel, tenantQuery); -// tenantPanel.add(visibleIfRoleBehavior(rowModel)); -// cellItem.add(tenantPanel); -// cellItem.add(AssignmentsUtil.getEnableBehavior(rowModel)); -// } -// -// }); -// columns.add(new LinkColumn(createStringResource("AssignmentDataTablePanel.activationColumnName")) { -// private static final long serialVersionUID = 1L; -// -// @Override -// public void populateItem(Item> cellItem, String componentId, -// final IModel rowModel) { -// super.populateItem(cellItem, componentId, rowModel); -// cellItem.setEnabled(false); -//// cellItem.add(AssignmentsUtil.getEnableBehavior(rowModel)); -// } -// -// @Override -// protected IModel createLinkModel(IModel rowModel) { -// IModel activationLabelModel = AssignmentsUtil.createActivationTitleModel(rowModel,"", AssignmentDataTablePanel.this); -// return StringUtils.isEmpty(activationLabelModel.getObject()) ? -// createStringResource("AssignmentEditorPanel.undefined") : activationLabelModel; -// } -// -// @Override -// public void onClick(AjaxRequestTarget target, IModel rowModel) { -// AssignmentActivationPopupablePanel popupPanel = new AssignmentActivationPopupablePanel(pageBase.getMainPopupBodyId(), rowModel){ -// private static final long serialVersionUID = 1L; -// -// @Override -// protected void reloadDateComponent(AjaxRequestTarget target) { -// target.add(getAssignmentsContainer()); -// } -// }; -// pageBase.showMainPopup(popupPanel, target); -// } -// }); -// columns.add(new AbstractColumn(createStringResource("AssignmentDataTablePanel.activationColumnName")) { -// -// private static final long serialVersionUID = 1L; -// -// @Override -// public void populateItem(Item> cellItem, String componentId, -// final IModel rowModel) { -// IModel activationLabelModel = AssignmentsUtil.createActivationTitleModelExperimental(rowModel,"", AbstractRoleAssignmentPanel.this); -// cellItem.add(new Label(componentId, StringUtils.isEmpty(activationLabelModel.getObject()) ? -// createStringResource("AssignmentEditorPanel.undefined") : activationLabelModel)); -// } -// }); + protected List, String>> initColumns() { + List, String>> columns = new ArrayList<>(); + columns.add(new AbstractColumn, String>(createStringResource("ObjectReferenceType.relation")) { + @Override + public void populateItem(Item>> item, String componentId, IModel> assignmentModel) { + String relation = assignmentModel.getObject().getContainerValue().getValue().getTargetRef() != null ? + assignmentModel.getObject().getContainerValue().getValue().getTargetRef().getRelation().getLocalPart() : ""; + item.add(new Label(componentId, relation)); + } + }); return columns; } @@ -309,7 +240,7 @@ private QName getRelation() { } @Override - protected AbstractAssignmentDetailsPanel createDetailsPanel(String idAssignmentDetails, Form form, IModel model) { + protected AbstractAssignmentDetailsPanel createDetailsPanel(String idAssignmentDetails, Form form, IModel> model) { return new AbstractRoleAssignmentDetailsPanel(ID_ASSIGNMENT_DETAILS, form, model); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentDto.java index 1a9853c2361..876ad64c73e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentDto.java @@ -49,28 +49,6 @@ public AssignmentDto(AssignmentType assignment, UserDtoStatus status) { this.status = status; } - /** - * - * @return true if this is an assignment of a RoleType, OrgType, ServiceType or Resource - * @return false if this is an assignment of a User(delegation, deputy) or PolicyRules - */ - public boolean isAssignableObject(){ - if (assignment.getPersonaConstruction() != null) { - return false; - } - - if (assignment.getPolicyRule() != null) { - return false; - } - - //TODO: uncomment when GDPR is in -// if (assignment.getTargetRef() != null && assignment.getTargetRef().getRelation().equals(SchemaConstants.ORG_CONSENT)) { -// return false; -// } - - return true; - } - public Collection computeAssignmentDelta() { Collection deltas = oldAssignment.asPrismContainerValue().diff(assignment.asPrismContainerValue()); return deltas; @@ -96,25 +74,6 @@ public QName getRelation() { } - public QName getTargetType() { - if (assignment.getTarget() != null) { - // object assignment - return assignment.getTarget().asPrismObject().getComplexTypeDefinition().getTypeName(); - } else if (assignment.getTargetRef() != null) { - return assignment.getTargetRef().getType(); - } - if (assignment.getPolicyRule() != null){ - return PolicyRuleType.COMPLEX_TYPE; - } - - if (assignment.getPersonaConstruction() != null) { - return PersonaConstructionType.COMPLEX_TYPE; - } - // account assignment through account construction - return ConstructionType.COMPLEX_TYPE; - - } - public RelationTypes getRelationType() { return RelationTypes.getRelationType(getRelation()); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentPanel.java index 6ab880a0563..d65cd3136ef 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentPanel.java @@ -19,10 +19,17 @@ import java.util.List; import java.util.stream.Collectors; +import com.evolveum.midpoint.prism.PrismContainerValue; +import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.web.component.prism.ContainerValueWrapper; +import com.evolveum.midpoint.web.component.prism.ContainerWrapper; +import com.evolveum.midpoint.web.component.prism.ValueStatus; +import com.evolveum.midpoint.web.component.util.SelectableBean; import org.apache.commons.lang.StringUtils; import org.apache.wicket.AttributeModifier; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; +import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable; import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; @@ -65,7 +72,7 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.TimeIntervalStatusType; -public abstract class AssignmentPanel extends BasePanel> { +public abstract class AssignmentPanel extends BasePanel>> { private static final long serialVersionUID = 1L; @@ -81,10 +88,11 @@ public abstract class AssignmentPanel extends BasePanel> { private final static String ID_CANCEL_BUTTON = "cancelButton"; protected boolean assignmentDetailsVisible; + protected ContainerWrapper assignmentContainerWrapper; - public AssignmentPanel(String id, IModel> assignmentsModel) { + public AssignmentPanel(String id, IModel>> assignmentsModel, ContainerWrapper assignmentContainerWrapper) { super(id, assignmentsModel); - + this.assignmentContainerWrapper = assignmentContainerWrapper; } protected abstract void initPaging(); @@ -111,7 +119,7 @@ private void initListPanel() { assignmentsContainer.setOutputMarkupId(true); add(assignmentsContainer); - BoxedTablePanel assignmentTable = initAssignmentTable(); + BoxedTablePanel> assignmentTable = initAssignmentTable(); assignmentsContainer.add(assignmentTable); AjaxIconButton newObjectIcon = new AjaxIconButton(ID_NEW_ASSIGNMENT_BUTTON, new Model<>("fa fa-plus"), @@ -149,7 +157,7 @@ public boolean isVisible() { } - private BoxedTablePanel initAssignmentTable() { + private BoxedTablePanel> initAssignmentTable() { AssignmentListDataProvider assignmentsProvider = new AssignmentListDataProvider(this, getModel()) { private static final long serialVersionUID = 1L; @@ -166,12 +174,12 @@ public ObjectQuery getQuery() { }; - List> columns = initBasicColumns(); + List, String>> columns = initBasicColumns(); if (WebComponentUtil.isAuthorized(AuthorizationConstants.AUTZ_UI_ADMIN_UNASSIGN_ACTION_URI)) { - columns.add(new InlineMenuButtonColumn(getAssignmentMenuActions(), 2, getPageBase())); + columns.add(new InlineMenuButtonColumn>(getAssignmentMenuActions(), 2, getPageBase())); } - BoxedTablePanel assignmentTable = new BoxedTablePanel(ID_ASSIGNMENTS_TABLE, + BoxedTablePanel> assignmentTable = new BoxedTablePanel>(ID_ASSIGNMENTS_TABLE, assignmentsProvider, columns, getTableId(), getItemsPerPage()) { private static final long serialVersionUID = 1L; @@ -182,8 +190,10 @@ public int getItemsPerPage() { } @Override - protected Item customizeNewRowItem(Item item, IModel model) { - item.add(AttributeModifier.append("class", AssignmentsUtil.createAssignmentStatusClassModel(model))); + protected Item> customizeNewRowItem(Item> item, + IModel> model) { + item.add(AttributeModifier.append("class", + AssignmentsUtil.createAssignmentStatusClassModel(Model.of(model.getObject().getContainerValue().asContainerable())))); return item; } @@ -200,36 +210,43 @@ protected AssignmentsTabStorage getAssignmentsStorage() { protected abstract ObjectQuery createObjectQuery(); - protected List> initBasicColumns() { - List> columns = new ArrayList<>(); + protected List, String>> initBasicColumns() { + List, String>> columns = new ArrayList<>(); - columns.add(new CheckBoxHeaderColumn()); + columns.add(new CheckBoxHeaderColumn>(){ + private static final long serialVersionUID = 1L; - columns.add(new IconColumn(Model.of("")) { + @Override + protected IModel getCheckBoxValueModel(IModel> rowModel) { + return Model.of(rowModel.getObject().isSelected()); + } + }); + + columns.add(new IconColumn>(Model.of("")) { private static final long serialVersionUID = 1L; @Override - protected IModel createIconModel(IModel rowModel) { + protected IModel createIconModel(IModel> rowModel) { return new AbstractReadOnlyModel() { private static final long serialVersionUID = 1L; @Override public String getObject() { - return WebComponentUtil.createDefaultBlackIcon(rowModel.getObject().getTargetType()); + return WebComponentUtil.createDefaultBlackIcon(AssignmentsUtil.getTargetType(rowModel.getObject().getContainerValue().asContainerable())); } }; } }); - columns.add(new LinkColumn(createStringResource("PolicyRulesPanel.nameColumn")){ + columns.add(new LinkColumn>(createStringResource("PolicyRulesPanel.nameColumn")){ private static final long serialVersionUID = 1L; @Override - protected IModel createLinkModel(IModel rowModel) { - String name = AssignmentsUtil.getName(rowModel.getObject().getAssignment(), getParentPage()); + protected IModel createLinkModel(IModel> rowModel) { + String name = AssignmentsUtil.getName(rowModel.getObject().getContainerValue().asContainerable(), getParentPage()); if (StringUtils.isBlank(name)) { return createStringResource("AssignmentPanel.noName"); } @@ -238,23 +255,23 @@ protected IModel createLinkModel(IModel rowModel) { } @Override - public void onClick(AjaxRequestTarget target, IModel rowModel) { + public void onClick(AjaxRequestTarget target, IModel> rowModel) { assignmentDetailsPerformed(target, rowModel); } }); - columns.add(new LinkColumn(createStringResource("AssignmentType.activation")){ + columns.add(new LinkColumn>(createStringResource("AssignmentType.activation")){ private static final long serialVersionUID = 1L; @Override - protected IModel createLinkModel(IModel rowModel) { - return AssignmentsUtil.createActivationTitleModelExperimental(rowModel, AssignmentPanel.this); - + protected IModel createLinkModel(IModel> rowModel) { +// return AssignmentsUtil.createActivationTitleModelExperimental(rowModel, AssignmentPanel.this); +return Model.of(""); } @Override - public void onClick(AjaxRequestTarget target, IModel rowModel) { - updateAssignmnetActivation(target, rowModel); + public void onClick(AjaxRequestTarget target, IModel> rowModel) { +// updateAssignmnetActivation(target, rowModel); } }); @@ -297,7 +314,7 @@ public void onClick(AjaxRequestTarget target, IModel rowModel) { return columns; } - protected abstract List> initColumns(); + protected abstract List, String>> initColumns(); protected abstract void newAssignmentClickPerformed(AjaxRequestTarget target); @@ -320,23 +337,23 @@ public boolean isVisible() { add(details); - IModel> selectedAssignmnetList = new AbstractReadOnlyModel>() { + IModel>> selectedAssignmnetList = new AbstractReadOnlyModel>>() { private static final long serialVersionUID = 1L; @Override - public List getObject() { + public List> getObject() { return getAssignmentListProvider().getSelectedData(); } }; - ListView assignmentDetailsView = new ListView(ID_ASSIGNMENTS_DETAILS, + ListView> assignmentDetailsView = new ListView>(ID_ASSIGNMENTS_DETAILS, selectedAssignmnetList) { private static final long serialVersionUID = 1L; @Override - protected void populateItem(ListItem item) { + protected void populateItem(ListItem> item) { Form form = this.findParent(Form.class); AbstractAssignmentDetailsPanel details = createDetailsPanel(ID_ASSIGNMENT_DETAILS, form, item.getModel()); item.add(details); @@ -369,7 +386,7 @@ public void onClick(AjaxRequestTarget ajaxRequestTarget) { @Override public void onClick(AjaxRequestTarget ajaxRequestTarget) { assignmentDetailsVisible = false; - getSelectedAssignments().stream().forEach(a -> {a.revertChanges(); a.setSelected(false);}); +// getSelectedAssignments().stream().forEach(a -> {a.revertChanges(); a.setSelected(false);}); ajaxRequestTarget.add(AssignmentPanel.this); } }; @@ -380,14 +397,14 @@ protected AssignmentListDataProvider getAssignmentListProvider() { return (AssignmentListDataProvider) getAssignmentTable().getDataTable().getDataProvider(); } - protected BoxedTablePanel getAssignmentTable() { - return (BoxedTablePanel) get(createComponentPath(ID_ASSIGNMENTS, ID_ASSIGNMENTS_TABLE)); + protected BoxedTablePanel> getAssignmentTable() { + return (BoxedTablePanel>) get(createComponentPath(ID_ASSIGNMENTS, ID_ASSIGNMENTS_TABLE)); } - protected abstract AbstractAssignmentDetailsPanel createDetailsPanel(String idAssignmentDetails, Form form, IModel model); + protected abstract AbstractAssignmentDetailsPanel createDetailsPanel(String idAssignmentDetails, Form form, IModel> model); - private List getSelectedAssignments() { - BoxedTablePanel assignemntTable = getAssignmentTable(); + private List> getSelectedAssignments() { + BoxedTablePanel> assignemntTable = getAssignmentTable(); AssignmentListDataProvider assignmentProvider = (AssignmentListDataProvider) assignemntTable.getDataTable() .getDataProvider(); return assignmentProvider.getAvailableData().stream().filter(a -> a.isSelected()).collect(Collectors.toList()); @@ -404,8 +421,8 @@ private List getAssignmentMenuActions() { return menuItems; } - private ColumnMenuAction createDeleteColumnAction() { - return new ColumnMenuAction() { + private ColumnMenuAction> createDeleteColumnAction() { + return new ColumnMenuAction>() { private static final long serialVersionUID = 1L; @Override @@ -413,17 +430,16 @@ public void onClick(AjaxRequestTarget target) { if (getRowModel() == null) { deleteAssignmentPerformed(target, getSelectedAssignments()); } else { - AssignmentDto rowDto = (AssignmentDto) getRowModel().getObject(); - List toDelete = new ArrayList<>(); - toDelete.add(rowDto); + List> toDelete = new ArrayList<>(); + toDelete.add(getRowModel().getObject()); deleteAssignmentPerformed(target, toDelete); } } }; } - private ColumnMenuAction createEditColumnAction() { - return new ColumnMenuAction() { + private ColumnMenuAction> createEditColumnAction() { + return new ColumnMenuAction>() { private static final long serialVersionUID = 1L; @Override @@ -437,28 +453,20 @@ public void onClick(AjaxRequestTarget target) { }; } - protected void assignmentDetailsPerformed(AjaxRequestTarget target, IModel rowModel) { + protected void assignmentDetailsPerformed(AjaxRequestTarget target, IModel> rowModel) { assignmentDetailsVisible = true; getModelObject().forEach(a -> a.setSelected(false)); rowModel.getObject().setSelected(true); target.add(AssignmentPanel.this); } - protected void assignmentDetailsPerformed(AjaxRequestTarget target, List rowModel) { + protected void assignmentDetailsPerformed(AjaxRequestTarget target, List> rowModel) { assignmentDetailsVisible = true; + getModelObject().forEach(a -> a.setSelected(false)); rowModel.stream().forEach(a -> a.setSelected(true)); target.add(AssignmentPanel.this); } - protected void updateAssignmnetActivation(AjaxRequestTarget target, IModel rowModel) { - AssignmentActivationPopupablePanel activationPanel = new AssignmentActivationPopupablePanel( - getPageBase().getMainPopupBodyId(), - new PropertyModel<>(rowModel, AssignmentDto.F_VALUE + "." + AssignmentType.F_ACTIVATION.getLocalPart())); - activationPanel.setOutputMarkupId(true); - - getPageBase().showMainPopup(activationPanel, target); - } - protected abstract TableId getTableId(); protected abstract int getItemsPerPage(); @@ -467,8 +475,15 @@ protected void refreshTable(AjaxRequestTarget target) { target.add(getAssignmentContainer().addOrReplace(initAssignmentTable())); } - protected void deleteAssignmentPerformed(AjaxRequestTarget target, List toDelete) { - toDelete.forEach(a -> a.setStatus(UserDtoStatus.DELETE)); + protected void deleteAssignmentPerformed(AjaxRequestTarget target, List> toDelete) { + if (toDelete == null){ + return; + } + for (ContainerValueWrapper assignmentContainerWrapper : getModelObject()){ + if (toDelete.contains(assignmentContainerWrapper)){ + assignmentContainerWrapper.setStatus(ValueStatus.DELETED); + } + } refreshTable(target); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentsUtil.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentsUtil.java index 29530b3d851..81c890ede1b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentsUtil.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentsUtil.java @@ -4,6 +4,7 @@ import java.util.function.Function; import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.namespace.QName; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.util.QNameUtil; @@ -70,14 +71,14 @@ public String getObject() { }; } - public static IModel createActivationTitleModelExperimental(IModel model, BasePanel basePanel) { + public static IModel createActivationTitleModelExperimental(IModel model, BasePanel basePanel) { return createActivationTitleModelExperimental(model.getObject(), s -> s.value(), basePanel); } - public static IModel createActivationTitleModelExperimental(AssignmentDto model, Function transformStatusLambda, BasePanel basePanel) { + public static IModel createActivationTitleModelExperimental(AssignmentType model, Function transformStatusLambda, BasePanel basePanel) { // AssignmentDto assignmentDto = model.getObject(); - ActivationType activation = model.getAssignment().getActivation(); + ActivationType activation = model.getActivation(); if (activation == null) { return basePanel.createStringResource("lower.ActivationStatusType.null"); } @@ -105,7 +106,7 @@ public static IModel createActivationTitleModelExperimental(AssignmentDt } - public static IModel createConsentActivationTitleModel(IModel model, BasePanel basePanel) { + public static IModel createConsentActivationTitleModel(IModel model, BasePanel basePanel) { return createActivationTitleModelExperimental(model.getObject(), s -> { // TODO: localization @@ -170,14 +171,16 @@ public void setObject(Date object) { // }; // } - public static IModel createAssignmentStatusClassModel(final IModel model) { + public static IModel createAssignmentStatusClassModel(final IModel model) { return new AbstractReadOnlyModel() { private static final long serialVersionUID = 1L; @Override public String getObject() { - AssignmentDto dto = model.getObject(); - return dto.getStatus().name().toLowerCase(); + //TODO fix +// AssignmentType dto = model.getObject(); +// return dto.getStatus().name().toLowerCase(); + return ""; } }; } @@ -327,4 +330,44 @@ public static boolean isConsentAssignment(AssignmentType assignment) { return QNameUtil.match(assignment.getTargetRef().getRelation(), SchemaConstants.ORG_CONSENT); } + /** + * + * @return true if this is an assignment of a RoleType, OrgType, ServiceType or Resource + * @return false if this is an assignment of a User(delegation, deputy) or PolicyRules + */ + public static boolean isAssignableObject(AssignmentType assignment){ + if (assignment.getPersonaConstruction() != null) { + return false; + } + + if (assignment.getPolicyRule() != null) { + return false; + } + + //TODO: uncomment when GDPR is in +// if (assignment.getTargetRef() != null && assignment.getTargetRef().getRelation().equals(SchemaConstants.ORG_CONSENT)) { +// return false; +// } + + return true; + } + + public static QName getTargetType(AssignmentType assignment) { + if (assignment.getTarget() != null) { + // object assignment + return assignment.getTarget().asPrismObject().getComplexTypeDefinition().getTypeName(); + } else if (assignment.getTargetRef() != null) { + return assignment.getTargetRef().getType(); + } + if (assignment.getPolicyRule() != null){ + return PolicyRuleType.COMPLEX_TYPE; + } + + if (assignment.getPersonaConstruction() != null) { + return PersonaConstructionType.COMPLEX_TYPE; + } + // account assignment through account construction + return ConstructionType.COMPLEX_TYPE; + + } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/GdprAssignmentPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/GdprAssignmentPanel.java index f52b3a1be35..602b388f518 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/GdprAssignmentPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/GdprAssignmentPanel.java @@ -20,6 +20,8 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.web.component.prism.ContainerValueWrapper; +import com.evolveum.midpoint.web.component.prism.ContainerWrapper; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn; @@ -41,17 +43,17 @@ public class GdprAssignmentPanel extends AbstractRoleAssignmentPanel { private static final long serialVersionUID = 1L; - public GdprAssignmentPanel(String id, IModel> assignmentsModel) { - super(id, assignmentsModel); + public GdprAssignmentPanel(String id, IModel>> assignmentsModel, ContainerWrapper assignmentContainerWrapper) { + super(id, assignmentsModel, assignmentContainerWrapper); } @Override - protected List> initColumns() { - List> columns = new ArrayList<>(); - columns.add(new PropertyColumn<>(createStringResource("AssignmentType.lifecycleState"), AssignmentDto.F_VALUE + "." + AssignmentType.F_LIFECYCLE_STATE.getLocalPart())); + protected List, String>> initColumns() { + List, String>> columns = new ArrayList<>(); + columns.add(new PropertyColumn<>(createStringResource("AssignmentType.lifecycleState"), AssignmentType.F_LIFECYCLE_STATE.getLocalPart())); - columns.add(new CheckBoxColumn(createStringResource("AssignmnetType.accepted")) { + columns.add(new CheckBoxColumn>(createStringResource("AssignmnetType.accepted")) { private static final long serialVersionUID = 1L; @Override @@ -60,15 +62,14 @@ protected IModel getEnabled() { } @Override - protected IModel getCheckBoxValueModel(IModel rowModel) { + protected IModel getCheckBoxValueModel(IModel> rowModel) { return new AbstractReadOnlyModel() { private static final long serialVersionUID = 1L; @Override public Boolean getObject() { - AssignmentDto assignmentDto = rowModel.getObject(); - AssignmentType assignmentType = assignmentDto.getAssignment(); + AssignmentType assignmentType = rowModel.getObject().getContainerValue().getValue(); if (assignmentType.getLifecycleState() == null) { return Boolean.FALSE; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleDetailsPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleDetailsPanel.java index 8b7c5e55c10..3f78ca28c41 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleDetailsPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRuleDetailsPanel.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.List; +import com.evolveum.midpoint.web.component.prism.ContainerValueWrapper; import org.apache.wicket.model.IModel; import com.evolveum.midpoint.prism.path.ItemPath; @@ -33,7 +34,7 @@ public class PolicyRuleDetailsPanel extends AbstractAssignm - public PolicyRuleDetailsPanel(String id, Form form, IModel model){ + public PolicyRuleDetailsPanel(String id, Form form, IModel> model){ super(id, form, model); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRulesPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRulesPanel.java index fb92e76b9a6..9c04764eed4 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRulesPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/PolicyRulesPanel.java @@ -19,6 +19,9 @@ import java.util.List; import com.evolveum.midpoint.prism.PrismContainerValue; +import com.evolveum.midpoint.web.component.prism.ContainerValueWrapper; +import com.evolveum.midpoint.web.component.prism.ContainerWrapper; +import com.evolveum.midpoint.web.component.prism.ValueStatus; import com.evolveum.midpoint.web.page.admin.users.dto.UserDtoStatus; import org.apache.commons.lang.StringUtils; import org.apache.wicket.ajax.AjaxRequestTarget; @@ -58,54 +61,54 @@ public class PolicyRulesPanel extends AssignmentPanel { private static final long serialVersionUID = 1L; - public PolicyRulesPanel(String id, IModel> policyRulesModel){ - super(id, policyRulesModel); + public PolicyRulesPanel(String id, IModel>> policyRulesModel, ContainerWrapper assignmentContainerWrapper){ + super(id, policyRulesModel, assignmentContainerWrapper); } - protected List> initColumns() { - List> columns = new ArrayList<>(); - columns.add(new AbstractColumn(createStringResource("PolicyRulesPanel.constraintsColumn")){ + protected List, String>> initColumns() { + List, String>> columns = new ArrayList<>(); + columns.add(new AbstractColumn, String>(createStringResource("PolicyRulesPanel.constraintsColumn")){ private static final long serialVersionUID = 1L; @Override - public void populateItem(Item> cellItem, String componentId, - final IModel rowModel) { - PolicyRuleType policyRuleType = rowModel.getObject().getAssignment().getPolicyRule(); + public void populateItem(Item>> cellItem, String componentId, + final IModel> rowModel) { + PolicyRuleType policyRuleType = rowModel.getObject().getContainerValue().getValue().getPolicyRule(); cellItem.add(new MultiLineLabel(componentId, Model.of(PolicyRuleUtil.convertPolicyConstraintsContainerToString(policyRuleType, getParentPage())))); } }); - columns.add(new AbstractColumn(createStringResource("PolicyRulesPanel.situationColumn")){ + columns.add(new AbstractColumn, String>(createStringResource("PolicyRulesPanel.situationColumn")){ private static final long serialVersionUID = 1L; @Override - public void populateItem(Item> cellItem, String componentId, - final IModel rowModel) { - PolicyRuleType policyRuleType = rowModel.getObject().getAssignment().getPolicyRule(); + public void populateItem(Item>> cellItem, String componentId, + final IModel> rowModel) { + PolicyRuleType policyRuleType = rowModel.getObject().getContainerValue().getValue().getPolicyRule(); String situationValue = policyRuleType == null ? "" : policyRuleType.getPolicySituation(); cellItem.add(new Label(componentId, Model.of(situationValue))); } }); - columns.add(new AbstractColumn(createStringResource("PolicyRulesPanel.actionColumn")){ + columns.add(new AbstractColumn, String>(createStringResource("PolicyRulesPanel.actionColumn")){ private static final long serialVersionUID = 1L; @Override - public void populateItem(Item> cellItem, String componentId, - final IModel rowModel) { - PolicyRuleType policyRuleType = rowModel.getObject().getAssignment().getPolicyRule(); + public void populateItem(Item>> cellItem, String componentId, + final IModel> rowModel) { + PolicyRuleType policyRuleType = rowModel.getObject().getContainerValue().getValue().getPolicyRule(); cellItem.add(new MultiLineLabel(componentId, Model.of(PolicyRuleUtil.convertPolicyActionsContainerToString(policyRuleType)))); } }); - columns.add(new AbstractColumn(createStringResource("PolicyRulesPanel.orderColumn")){ + columns.add(new AbstractColumn, String>(createStringResource("PolicyRulesPanel.orderColumn")){ private static final long serialVersionUID = 1L; @Override - public void populateItem(Item> cellItem, String componentId, - final IModel rowModel) { - AssignmentType assignment = rowModel.getObject().getAssignment(); + public void populateItem(Item>> cellItem, String componentId, + final IModel> rowModel) { + AssignmentType assignment = rowModel.getObject().getContainerValue().getValue(); String orderValue; if (assignment == null || assignment.getOrder() == null){ @@ -150,7 +153,10 @@ protected void newAssignmentClickPerformed(AjaxRequestTarget target) { policyRule.setDescription(""); assignment.setPolicyRule(policyRule); - getModelObject().add(new AssignmentDto(assignment, UserDtoStatus.ADD)); + ContainerValueWrapper newAssignmentContainerWrapper = assignmentContainerWrapper.createItem(false); + newAssignmentContainerWrapper.setStatus(ValueStatus.ADDED); + newAssignmentContainerWrapper.getContainerValue().getValue().setupContainerValue(assignment.asPrismContainerValue()); + getModelObject().add(newAssignmentContainerWrapper); target.add(getAssignmentContainer()); } @@ -160,7 +166,7 @@ protected ObjectQuery createObjectQuery() { } @Override - protected AbstractAssignmentDetailsPanel createDetailsPanel(String idAssignmentDetails, Form form, IModel model) { + protected AbstractAssignmentDetailsPanel createDetailsPanel(String idAssignmentDetails, Form form, IModel> model) { return new PolicyRuleDetailsPanel(idAssignmentDetails, form, model); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SelfConsentPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SelfConsentPanel.java index 8e6017a418c..571915b041b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SelfConsentPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SelfConsentPanel.java @@ -46,7 +46,7 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.TimeIntervalStatusType; -public class SelfConsentPanel extends BasePanel { +public class SelfConsentPanel extends BasePanel { private static final long serialVersionUID = 1L; @@ -63,7 +63,7 @@ public class SelfConsentPanel extends BasePanel { private static final String OPERATION_LOAD_TARGET = DOT_CLASS + "loadTargetRef"; // private PageBase parentPage; - public SelfConsentPanel(String id, IModel model, PageBase parentPage) { + public SelfConsentPanel(String id, IModel model, PageBase parentPage) { super(id, model); Task task = parentPage.createSimpleTask(OPERATION_LOAD_TARGET); @@ -73,7 +73,7 @@ public SelfConsentPanel(String id, IModel model, PageBase parentP // ... also, we should use utility method for loading PrismObject abstractRole = WebModelServiceUtils - .loadObject(getModelObject().getAssignment().getTargetRef(), parentPage, task, result); + .loadObject(getModelObject().getTargetRef(), parentPage, task, result); if (abstractRole == null) { getSession().error("Failed to load target ref"); @@ -107,7 +107,7 @@ private void initLayout(final AbstractRoleType abstractRole) { @Override public void onClick(AjaxRequestTarget target) { - SelfConsentPanel.this.getModelObject().getAssignment().setLifecycleState(SchemaConstants.LIFECYCLE_FAILED); + SelfConsentPanel.this.getModelObject().setLifecycleState(SchemaConstants.LIFECYCLE_FAILED); target.add(SelfConsentPanel.this); } }; @@ -120,7 +120,7 @@ public void onClick(AjaxRequestTarget target) { @Override public void onClick(AjaxRequestTarget target) { - SelfConsentPanel.this.getModelObject().getAssignment().setLifecycleState(SchemaConstants.LIFECYCLE_ACTIVE); + SelfConsentPanel.this.getModelObject().setLifecycleState(SchemaConstants.LIFECYCLE_ACTIVE); target.add(SelfConsentPanel.this); } }; @@ -133,7 +133,7 @@ public void onClick(AjaxRequestTarget target) { @Override public void onClick(AjaxRequestTarget target) { - SelfConsentPanel.this.getModelObject().getAssignment().setLifecycleState(SchemaConstants.LIFECYCLE_FAILED); + SelfConsentPanel.this.getModelObject().setLifecycleState(SchemaConstants.LIFECYCLE_FAILED); target.add(SelfConsentPanel.this); } }; @@ -166,8 +166,7 @@ public boolean isVisible() { //TODO move to the WebComponentUtil ??? - private String getIconCssClass(AssignmentDto assignment) { - AssignmentType assignmentType = assignment.getAssignment(); + private String getIconCssClass(AssignmentType assignmentType) { String currentLifecycle = assignmentType.getLifecycleState(); if (StringUtils.isBlank(currentLifecycle)) { return GuiStyleConstants.CLASS_APPROVAL_OUTCOME_ICON_FUTURE_COLORED; @@ -189,7 +188,7 @@ private String getIconCssClass(AssignmentDto assignment) { } private boolean isActiveConsent(){ - String lifecycle = SelfConsentPanel.this.getModelObject().getAssignment().getLifecycleState(); + String lifecycle = SelfConsentPanel.this.getModelObject().getLifecycleState(); if (StringUtils.isBlank(lifecycle)) { return false; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SimpleParametricRoleSelector.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SimpleParametricRoleSelector.html deleted file mode 100644 index 31596add8c4..00000000000 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SimpleParametricRoleSelector.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - - -
-
- - - \ No newline at end of file diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SimpleParametricRoleSelector.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SimpleParametricRoleSelector.java deleted file mode 100644 index 8deacc0cc75..00000000000 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SimpleParametricRoleSelector.java +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright (c) 2016 Evolveum - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.evolveum.midpoint.web.component.assignment; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.apache.commons.lang.StringUtils; -import org.apache.wicket.Component; -import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; -import org.apache.wicket.ajax.markup.html.AjaxLink; -import org.apache.wicket.markup.ComponentTag; -import org.apache.wicket.markup.html.basic.Label; -import org.apache.wicket.markup.html.form.TextField; -import org.apache.wicket.markup.html.list.ListItem; -import org.apache.wicket.markup.html.list.ListView; -import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; - -import com.evolveum.midpoint.gui.api.page.PageBase; -import com.evolveum.midpoint.prism.PrismContainerValue; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.exception.SystemException; -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.web.page.admin.users.dto.UserDtoStatus; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; - -/** - * @author semancik - */ -public class SimpleParametricRoleSelector extends SimpleRoleSelector { - private static final long serialVersionUID = 1L; - - private static final Trace LOGGER = TraceManager.getTrace(SimpleParametricRoleSelector.class); - - private static final String ID_LABEL_ROLE = "labelRole"; - private static final String ID_LABEL_PARAM = "labelParam"; - private static final String ID_LIST_PARAM = "listParam"; - private static final String ID_ITEM_PARAM = "itemParam"; - private static final String ID_ADD_INPUT = "addInput"; - private static final String ID_ADD_LINK = "addLink"; - private static final String ID_DELETE_LINK = "deleteLink"; - - private String labelParam = null; - private String labelRole = null; - private ItemPath parameterPath; - private ListView paramList; - final private IModel> paramListModel; - private String selectedParam = null; - - public SimpleParametricRoleSelector(String id, IModel> assignmentModel, List> availableRoles, ItemPath parameterPath) { - super(id, assignmentModel, availableRoles); - this.parameterPath = parameterPath; - paramListModel = initParamListModel(assignmentModel); - initLayout(); - } - - public String getLabelParam() { - return labelParam; - } - - public void setLabelParam(String labelParam) { - this.labelParam = labelParam; - } - - public String getLabelRole() { - return labelRole; - } - - public void setLabelRole(String labelRole) { - this.labelRole = labelRole; - } - - private IModel> initParamListModel(final IModel> assignmentModel) { - return new IModel>() { - - private List list = null; - - @Override - public void detach() { - } - - @Override - public List getObject() { - if (list == null) { - list = initParamList(assignmentModel.getObject()); - } - return list; - } - - @Override - public void setObject(List list) { - this.list = list; - } - }; - } - - private List initParamList(List assignmentDtos) { - List params = new ArrayList<>(); - for (AssignmentDto assignmentDto: assignmentDtos) { - String paramVal = getParamValue(assignmentDto); - if (paramVal != null) { - if (!params.contains(paramVal)) { - params.add(paramVal); - } - } - } - Collections.sort(params); - return params; - } - - private String getParamValue(AssignmentDto assignmentDto) { - PrismContainerValue newValue = assignmentDto.getAssignment().asPrismContainerValue(); - - if (newValue != null) { - PrismProperty paramProp = newValue.findProperty(parameterPath); - if (paramProp != null) { - return paramProp.getRealValue(); - } - } -// PrismContainerValue oldValue = assignmentDto.getOldValue(); -// if (oldValue != null) { -// PrismProperty paramProp = oldValue.findProperty(parameterPath); -// if (paramProp != null) { -// return paramProp.getRealValue(); -// } -// } - return null; - } - - private void initLayout() { - - IModel labelParamModel = new IModel() { - @Override - public void detach() { - } - - @Override - public String getObject() { - return getLabelParam(); - } - - @Override - public void setObject(String object) { - } - }; - add(new Label(ID_LABEL_PARAM, labelParamModel) { - @Override - protected void onConfigure() { - setVisible(getLabelParam() != null); - super.onConfigure(); - } - }); - - IModel labelRoleModel = new IModel() { - @Override - public void detach() { - } - - @Override - public String getObject() { - return getLabelRole(); - } - - @Override - public void setObject(String object) { - } - }; - add(new Label(ID_LABEL_ROLE, labelRoleModel) { - @Override - protected void onConfigure() { - setVisible(getLabelRole() != null); - super.onConfigure(); - } - }); - - paramList = new ListView(ID_LIST_PARAM, paramListModel) { - @Override - protected void populateItem(ListItem item) { - item.add(createParamLink(ID_ITEM_PARAM, item.getModel())); - } - - }; - paramList.setOutputMarkupId(true); - add(paramList); - - final Model addInputModel = new Model(); - TextField addInput = new TextField<>(ID_ADD_INPUT, addInputModel); - addInput.setOutputMarkupId(true); - addInput.add(new AjaxFormComponentUpdatingBehavior("blur") { - @Override - protected void onUpdate(AjaxRequestTarget target) { - // nothing to do, Ajax behavior is there only to get data to model - } - }); - add(addInput); - - AjaxLink addLink = new AjaxLink(ID_ADD_LINK) { - @Override - public void onClick(AjaxRequestTarget target) { - String newParam = addInputModel.getObject(); - LOGGER.debug("ADD cliked, input field value: {}", newParam); - if (!StringUtils.isBlank(newParam)) { - addParam(newParam); - - } - addInputModel.setObject(null); - target.add(SimpleParametricRoleSelector.this); - } - }; - add(addLink); - - AjaxLink deleteLink = new AjaxLink(ID_DELETE_LINK) { - @Override - public void onClick(AjaxRequestTarget target) { - LOGGER.debug("DELETE cliked, selected param: {}", selectedParam); - deleteParam(selectedParam); - target.add(SimpleParametricRoleSelector.this); - } - }; - add(deleteLink); - } - - - private Component createParamLink(String id, IModel itemModel) { - AjaxLink button = new AjaxLink(id, itemModel) { - - @Override - public IModel getBody() { - return new Model(getModel().getObject()); - } - - @Override - public void onClick(AjaxRequestTarget target) { - LOGGER.trace("{} CLICK param: {}", this, getModel().getObject()); - toggleParam(getModel().getObject()); - target.add(SimpleParametricRoleSelector.this); - } - - @Override - protected void onComponentTag(ComponentTag tag) { - super.onComponentTag(tag); - String param = getModel().getObject(); - if (param.equals(selectedParam)) { - tag.put("class", "list-group-item active"); - } else { - tag.put("class", "list-group-item"); - } - } - }; - button.setOutputMarkupId(true); - return button; - } - - private void toggleParam(String param) { - selectedParam = param; - } - - private void addParam(String newParam) { - List params = paramListModel.getObject(); - if (!params.contains(newParam)) { - params.add(newParam); - } - } - - private void deleteParam(String paramToDelete) { - paramListModel.getObject().remove(paramToDelete); - // make sure that all the assignments with the parameter parameter are also removed from assignement model - Iterator iterator = getAssignmentModel().getObject().iterator(); - while (iterator.hasNext()) { - AssignmentDto dto = iterator.next(); - if (isManagedRole(dto) && paramToDelete.equals(getParamValue(dto))) { - if (dto.getStatus() == UserDtoStatus.ADD) { - iterator.remove(); - } else { - dto.setStatus(UserDtoStatus.DELETE); - } - } - } - } - - @Override - protected AssignmentDto createAddAssignmentDto(PrismObject role, PageBase pageBase) { - AssignmentDto dto = super.createAddAssignmentDto(role, pageBase); - PrismContainerValue newValue; - try { - newValue = dto.getAssignment().asPrismContainerValue(); - PrismProperty prop = newValue.findOrCreateProperty(parameterPath); - prop.setRealValue(selectedParam); - } catch (SchemaException e) { - throw new SystemException(e.getMessage(), e); - } - - return dto; - } - - @Override - protected boolean willProcessAssignment(AssignmentDto dto) { - if (!super.willProcessAssignment(dto)) { - return false; - } - if (selectedParam == null) { - return false; - } - return selectedParam.equals(getParamValue(dto)); - } - - - -} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SimpleRoleSelector.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SimpleRoleSelector.java index a486cfbfe6f..74024525d5c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SimpleRoleSelector.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SimpleRoleSelector.java @@ -18,6 +18,8 @@ import java.util.Iterator; import java.util.List; +import com.evolveum.midpoint.web.component.prism.ContainerValueWrapper; +import com.evolveum.midpoint.web.component.prism.ValueStatus; import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.AjaxLink; @@ -42,7 +44,7 @@ /** * @author semancik */ -public class SimpleRoleSelector extends BasePanel> { +public class SimpleRoleSelector extends BasePanel>> { private static final long serialVersionUID = 1L; private static final Trace LOGGER = TraceManager.getTrace(SimpleRoleSelector.class); @@ -53,7 +55,7 @@ public class SimpleRoleSelector List> availableRoles; - public SimpleRoleSelector(String id, IModel> assignmentModel, List> availableRoles) { + public SimpleRoleSelector(String id, IModel>> assignmentModel, List> availableRoles) { super(id, assignmentModel); this.availableRoles = availableRoles; initLayout(); @@ -67,7 +69,7 @@ public String getExcludeOid() { return null; } - protected IModel> getAssignmentModel() { + protected IModel>> getAssignmentModel() { return getModel(); } @@ -130,11 +132,12 @@ protected void onComponentTag(ComponentTag tag) { private boolean isSelected(PrismObject role) { - for (AssignmentDto dto: getAssignmentModel().getObject()) { - if (willProcessAssignment(dto)) { - ObjectReferenceType targetRef = dto.getAssignment().getTargetRef(); + for (ContainerValueWrapper assignmentContainer: getAssignmentModel().getObject()) { + AssignmentType assignment = assignmentContainer.getContainerValue().getValue(); + if (willProcessAssignment(assignment)) { + ObjectReferenceType targetRef = assignment.getTargetRef(); if (targetRef != null && role.getOid().equals(targetRef.getOid())) { - if (dto.getStatus() != UserDtoStatus.DELETE) { + if (assignmentContainer.getStatus() != ValueStatus.DELETED) { return true; } } @@ -144,52 +147,51 @@ private boolean isSelected(PrismObject role) { } private void toggleRole(PrismObject role) { - Iterator iterator = getAssignmentModel().getObject().iterator(); + Iterator> iterator = getAssignmentModel().getObject().iterator(); while (iterator.hasNext()) { - AssignmentDto dto = iterator.next(); - if (willProcessAssignment(dto)) { - ObjectReferenceType targetRef = dto.getAssignment().getTargetRef(); + ContainerValueWrapper assignmentContainer = iterator.next(); + AssignmentType assignment = assignmentContainer.getContainerValue().getValue(); + if (willProcessAssignment(assignment)) { + ObjectReferenceType targetRef = assignment.getTargetRef(); if (targetRef != null && role.getOid().equals(targetRef.getOid())) { - if (dto.getStatus() == UserDtoStatus.ADD) { + if (assignmentContainer.getStatus() == ValueStatus.ADDED) { iterator.remove(); } else { - dto.setStatus(UserDtoStatus.DELETE); + assignmentContainer.setStatus(ValueStatus.DELETED); } return; } } } - AssignmentDto dto = createAddAssignmentDto(role, getPageBase()); - getAssignmentModel().getObject().add(dto); - } - - protected AssignmentDto createAddAssignmentDto(PrismObject role, PageBase pageBase) { - AssignmentDto dto = new AssignmentDto(ObjectTypeUtil.createAssignmentTo(role), UserDtoStatus.ADD); -// dto.setMinimized(true); - return dto; + AssignmentType newAssignment = ObjectTypeUtil.createAssignmentTo(role); + //TODO + //create ContainerValueWrapper for new assignment +// getAssignmentModel().getObject().add(newAssignment); } private void reset() { - Iterator iterator = getAssignmentModel().getObject().iterator(); + Iterator> iterator = getAssignmentModel().getObject().iterator(); while (iterator.hasNext()) { - AssignmentDto dto = iterator.next(); - if (isManagedRole(dto) && willProcessAssignment(dto)) { - if (dto.getStatus() == UserDtoStatus.ADD) { + ContainerValueWrapper assignmentContainer = iterator.next(); + AssignmentType assignment = assignmentContainer.getContainerValue().getValue(); + if (isManagedRole(assignment) && willProcessAssignment(assignment)) { + if (assignmentContainer.getStatus() == ValueStatus.ADDED) { iterator.remove(); - } else if (dto.getStatus() == UserDtoStatus.DELETE) { - dto.setStatus(UserDtoStatus.MODIFY); + } else if (assignmentContainer.getStatus() == ValueStatus.DELETED) { + //what status to use for container? +// assignmentContainer.setStatus(UserDtoStatus.MODIFY); } } } } - protected boolean willProcessAssignment(AssignmentDto dto) { + protected boolean willProcessAssignment(AssignmentType dto) { return true; } - protected boolean isManagedRole(AssignmentDto dto) { - ObjectReferenceType targetRef = dto.getAssignment().getTargetRef(); + protected boolean isManagedRole(AssignmentType assignment) { + ObjectReferenceType targetRef = assignment.getTargetRef(); if (targetRef == null || targetRef.getOid() == null) { return false; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/AbstractFocusTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/AbstractFocusTabPanel.java index 891accafd2e..f99e7c2d3b0 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/AbstractFocusTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/AbstractFocusTabPanel.java @@ -26,6 +26,7 @@ import com.evolveum.midpoint.web.component.form.Form; import com.evolveum.midpoint.web.component.prism.ObjectWrapper; import com.evolveum.midpoint.web.page.admin.users.dto.FocusSubwrapperDto; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; @@ -37,23 +38,16 @@ public abstract class AbstractFocusTabPanel extends Abstrac private static final Trace LOGGER = TraceManager.getTrace(AbstractFocusTabPanel.class); - private LoadableModel> assignmentsModel; private LoadableModel>> projectionModel; public AbstractFocusTabPanel(String id, Form mainForm, LoadableModel> focusWrapperModel, - LoadableModel> assignmentsModel, LoadableModel>> projectionModel, PageBase pageBase) { super(id, mainForm, focusWrapperModel, pageBase); - this.assignmentsModel = assignmentsModel; this.projectionModel = projectionModel; } - public LoadableModel> getAssignmentsModel() { - return assignmentsModel; - } - public LoadableModel>> getProjectionModel() { return projectionModel; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/AbstractRoleMainPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/AbstractRoleMainPanel.java index 5685fb04434..e85ab1c161b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/AbstractRoleMainPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/AbstractRoleMainPanel.java @@ -85,11 +85,9 @@ public abstract class AbstractRoleMainPanel extends private static final String ID_ITEMS_COUNT = "itemsCount"; public AbstractRoleMainPanel(String id, LoadableModel> objectModel, - CountableLoadableModel assignmentsModel, - CountableLoadableModel policyRulesModel, LoadableModel>> projectionModel, LoadableModel> inducementsModel, PageAdminFocus parentPage) { - super(id, objectModel, assignmentsModel, policyRulesModel, projectionModel, parentPage); + super(id, objectModel, projectionModel, parentPage); this.inducementsModel = inducementsModel; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusAssignmentsTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusAssignmentsTabPanel.java index 314fa5f35c2..63c95707521 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusAssignmentsTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusAssignmentsTabPanel.java @@ -17,28 +17,21 @@ import com.evolveum.midpoint.gui.api.model.LoadableModel; import com.evolveum.midpoint.gui.api.page.PageBase; -import com.evolveum.midpoint.prism.PrismContainer; -import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.schema.util.SystemConfigurationTypeUtil; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.web.component.assignment.AbstractRoleAssignmentPanel; -import com.evolveum.midpoint.web.component.assignment.AssignmentDataTablePanel; -import com.evolveum.midpoint.web.component.assignment.AssignmentDto; -import com.evolveum.midpoint.web.component.assignment.AssignmentEditorDto; -import com.evolveum.midpoint.web.component.assignment.AssignmentTablePanel; +import com.evolveum.midpoint.web.component.assignment.AssignmentsUtil; import com.evolveum.midpoint.web.component.form.Form; import com.evolveum.midpoint.web.component.prism.*; -import com.evolveum.midpoint.web.page.admin.PageAdminFocus; -import com.evolveum.midpoint.web.page.admin.users.component.*; -import com.evolveum.midpoint.web.page.admin.users.dto.UserDtoStatus; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.wicket.Component; -import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.PropertyModel; import java.util.ArrayList; import java.util.List; @@ -58,67 +51,34 @@ public class FocusAssignmentsTabPanel extends AbstractObjec private static final Trace LOGGER = TraceManager.getTrace(FocusAssignmentsTabPanel.class); - private LoadableModel> assignmentsModel; + private LoadableModel> assignmentsModel; - public FocusAssignmentsTabPanel(String id, Form mainForm, LoadableModel> focusWrapperModel, - LoadableModel> assignmentsModel, PageBase page) { + public FocusAssignmentsTabPanel(String id, Form mainForm, LoadableModel> focusWrapperModel, PageBase page) { super(id, mainForm, focusWrapperModel, page); - this.assignmentsModel = assignmentsModel; initLayout(); } private void initLayout() { + ContainerWrapper assignmentsContainerWrapper = getObjectWrapper().findContainerWrapper(new ItemPath(FocusType.F_ASSIGNMENT)); WebMarkupContainer assignments = new WebMarkupContainer(ID_ASSIGNMENTS); assignments.setOutputMarkupId(true); add(assignments); - Component panel; -// if (isEnableExperimentalFeatures()){ - - - - panel = new AbstractRoleAssignmentPanel(ID_ASSIGNMENTS_PANEL, assignmentsModel); -// } else { -// panel = new AssignmentTablePanel(ID_ASSIGNMENTS_PANEL, -// createStringResource("FocusType.assignment"), assignmentsModel, pageBase) { -// -// @Override -// protected boolean getAssignmentMenuVisibility() { -// return !getObjectWrapper().isReadonly(); -// } -// -// @Override -// protected boolean isShowAllAssignmentsVisible() { -// PrismContainer assignmentContainer = getObjectWrapper().getObject().findContainer(new ItemPath(FocusType.F_ASSIGNMENT)); -// return assignmentContainer != null && assignmentContainer.getDefinition() != null ? -// assignmentContainer.getDefinition().canRead() : super.isShowAllAssignmentsVisible(); -// } -// -// @Override -// protected void showAllAssignments(AjaxRequestTarget target) { -// List assignmentsPreviewDtos = ((PageAdminFocus) getPageBase()).recomputeAssignmentsPerformed(target); -// AssignmentPreviewDialog dialog = new AssignmentPreviewDialog(getPageBase().getMainPopupBodyId(), -// assignmentsPreviewDtos, new ArrayList(), getPageBase()); -// getPageBase().showMainPopup(dialog, target); -// } -// -// }; -// } + AbstractRoleAssignmentPanel panel = new AbstractRoleAssignmentPanel(ID_ASSIGNMENTS_PANEL, getAssignmentsListModel(assignmentsContainerWrapper), + assignmentsContainerWrapper); assignments.add(panel); } -// private boolean isEnableExperimentalFeatures(){ -// OperationResult result = new OperationResult(OPERATION_GET_ADMIN_GUI_CONFIGURATION); -// AdminGuiConfigurationType adminGuiConfig = null; -// try{ -// adminGuiConfig = pageBase.getModelInteractionService().getAdminGuiConfiguration(pageBase.createSimpleTask(OPERATION_GET_ADMIN_GUI_CONFIGURATION), result); -// } catch (Exception ex){ -// LOGGER.error("Cannot get admin gui configuration object, ", ex); -// } -// return adminGuiConfig != null && adminGuiConfig.isEnableExperimentalFeatures() != null && -// adminGuiConfig.isEnableExperimentalFeatures(); -// -// } - + private IModel>> getAssignmentsListModel(ContainerWrapper assignmentsContainerWrapper){ + List> assignmentsList = new ArrayList<>(); + assignmentsContainerWrapper.getValues().forEach(a -> { + if (!AssignmentsUtil.isPolicyRuleAssignment(a.getContainerValue().getValue()) && !AssignmentsUtil.isConsentAssignment(a.getContainerValue().getValue()) + && AssignmentsUtil.isAssignmentRelevant(a.getContainerValue().getValue())) { + assignmentsList.add(a); + } + }); +// Collections.sort(consentsList); + return Model.ofList(assignmentsList); + } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusConsentTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusConsentTabPanel.java index b78f7fd5ddf..e346967b42c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusConsentTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusConsentTabPanel.java @@ -1,14 +1,24 @@ package com.evolveum.midpoint.web.component.objectdetails; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import com.evolveum.midpoint.gui.api.model.LoadableModel; import com.evolveum.midpoint.gui.api.page.PageBase; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.web.component.assignment.AssignmentDto; import com.evolveum.midpoint.web.component.assignment.GdprAssignmentPanel; import com.evolveum.midpoint.web.component.form.Form; +import com.evolveum.midpoint.web.component.prism.ContainerValueWrapper; +import com.evolveum.midpoint.web.component.prism.ContainerWrapper; import com.evolveum.midpoint.web.component.prism.ObjectWrapper; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; public class FocusConsentTabPanel extends AbstractObjectTabPanel{ @@ -16,26 +26,36 @@ public class FocusConsentTabPanel extends AbstractObjectTab private static final String ID_ROLES = "roles"; - private LoadableModel> consentsModel; + private LoadableModel> consentsModel; public FocusConsentTabPanel(String id, Form> mainForm, LoadableModel> objectWrapperModel, - LoadableModel> consentsModel, PageBase pageBase) { + PageBase pageBase) { super(id, mainForm, objectWrapperModel, pageBase); - this.consentsModel = consentsModel; initLayout(); } private void initLayout() { + ContainerWrapper assignmentsContainerWrapper = getObjectWrapper().findContainerWrapper(new ItemPath(FocusType.F_ASSIGNMENT)); - GdprAssignmentPanel consentRoles = new GdprAssignmentPanel(ID_ROLES, consentsModel); + GdprAssignmentPanel consentRoles = new GdprAssignmentPanel(ID_ROLES, getConsentsModel(assignmentsContainerWrapper), assignmentsContainerWrapper); add(consentRoles); consentRoles.setOutputMarkupId(true); } + private IModel>> getConsentsModel(ContainerWrapper assignmentsContainerWrapper){ + List> consentsList = new ArrayList<>(); + assignmentsContainerWrapper.getValues().forEach(a -> { + if (isConsentAssignment(a.getContainerValue().getValue())){ + consentsList.add(a); + } + }); +// Collections.sort(consentsList); + return Model.ofList(consentsList); + } - - - + private boolean isConsentAssignment(AssignmentType assignment) { + return assignment.getTargetRef() != null && QNameUtil.match(assignment.getTargetRef().getRelation(), SchemaConstants.ORG_CONSENT); + } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.java index 33117fa6383..784e0cb1fcc 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusDetailsTabPanel.java @@ -19,6 +19,7 @@ import java.util.Arrays; import java.util.List; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import org.apache.wicket.model.IModel; import org.apache.wicket.request.resource.PackageResourceReference; @@ -60,10 +61,9 @@ public class FocusDetailsTabPanel extends AbstractFocusTabP public FocusDetailsTabPanel(String id, Form mainForm, LoadableModel> focusWrapperModel, - LoadableModel> assignmentsModel, LoadableModel>> projectionModel, PageBase pageBase) { - super(id, mainForm, focusWrapperModel, assignmentsModel, projectionModel, pageBase); + super(id, mainForm, focusWrapperModel, projectionModel, pageBase); initLayout(); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusMainPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusMainPanel.java index 1de250c1a44..2fd5b13ec8a 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusMainPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusMainPanel.java @@ -30,6 +30,7 @@ import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.web.component.assignment.AssignmentDto; import com.evolveum.midpoint.web.component.assignment.AssignmentEditorDto; +import com.evolveum.midpoint.web.component.assignment.AssignmentsUtil; import com.evolveum.midpoint.web.component.form.Form; import com.evolveum.midpoint.web.component.prism.ObjectWrapper; import com.evolveum.midpoint.web.page.admin.PageAdminFocus; @@ -65,20 +66,14 @@ public class FocusMainPanel extends AbstractObjectMainPanel private static final Trace LOGGER = TraceManager.getTrace(FocusMainPanel.class); private LoadableModel>> projectionModel; - private CountableLoadableModel assignmentsModel; - private CountableLoadableModel policyRulesModel; private TaskDtoProvider taskDtoProvider; private FocusAssignmentsTabPanel assignmentsTabPanel = null; public FocusMainPanel(String id, LoadableModel> objectModel, - CountableLoadableModel assignmentsModel, - CountableLoadableModel policyRulesModel, LoadableModel>> projectionModel, PageAdminFocus parentPage) { super(id, objectModel, parentPage); Validate.notNull(projectionModel, "Null projection model"); - this.assignmentsModel = assignmentsModel; - this.policyRulesModel = policyRulesModel; this.projectionModel = projectionModel; initLayout(parentPage); } @@ -173,7 +168,7 @@ protected WebMarkupContainer createTabPanel(String panelId, FormSpecificationTyp AbstractFocusTabPanel tabPanel; try { tabPanel = (AbstractFocusTabPanel) constructor.newInstance(panelId, getMainForm(), getObjectModel(), - assignmentsModel, projectionModel ,parentPage); + projectionModel ,parentPage); } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { throw new SystemException("Error instantiating "+panelClass+": "+e.getMessage(), e); } @@ -199,7 +194,7 @@ protected WebMarkupContainer createTabPanel(String panelId, FormSpecificationTyp } protected WebMarkupContainer createFocusDetailsTabPanel(String panelId, PageAdminObjectDetails parentPage) { - return new FocusDetailsTabPanel(panelId, getMainForm(), getObjectModel(), assignmentsModel, projectionModel, parentPage); + return new FocusDetailsTabPanel(panelId, getMainForm(), getObjectModel(), projectionModel, parentPage); } protected WebMarkupContainer createFocusProjectionsTabPanel(String panelId, PageAdminObjectDetails parentPage) { @@ -207,12 +202,12 @@ protected WebMarkupContainer createFocusProjectionsTabPanel(String panelId, Page } protected WebMarkupContainer createFocusAssignmentsTabPanel(String panelId, PageAdminObjectDetails parentPage) { - assignmentsTabPanel = new FocusAssignmentsTabPanel(panelId, getMainForm(), getObjectModel(), assignmentsModel, parentPage); + assignmentsTabPanel = new FocusAssignmentsTabPanel(panelId, getMainForm(), getObjectModel(), parentPage); return assignmentsTabPanel; } protected WebMarkupContainer createFocusPolicyRulesTabPanel(String panelId, PageAdminObjectDetails parentPage) { - return new FocusPolicyRulesTabPanel(panelId, getMainForm(), getObjectModel(), policyRulesModel, parentPage); + return new FocusPolicyRulesTabPanel(panelId, getMainForm(), getObjectModel(), parentPage); } protected WebMarkupContainer createObjectHistoryTabPanel(String panelId, PageAdminObjectDetails parentPage) { @@ -290,7 +285,7 @@ public WebMarkupContainer createPanel(String panelId) { @Override public String getCount() { - return Integer.toString(assignmentsModel.count()); + return Integer.toString(countAssignments()); } }); @@ -307,7 +302,7 @@ public WebMarkupContainer createPanel(String panelId) { @Override public String getCount() { - return Integer.toString(policyRulesModel.count()); + return Integer.toString(countPolicyRules()); } }); @@ -336,17 +331,44 @@ protected boolean areSavePreviewButtonsEnabled(){ } private boolean isAssignmentsModelChanged(){ - if (assignmentsModel == null && assignmentsModel.getObject() == null){ - return false; - } - if (assignmentsModel.getObject().isEmpty()){ - return false; +// if (assignmentsModel == null && assignmentsModel.getObject() == null){ +// return false; +// } +// if (assignmentsModel.getObject().isEmpty()){ +// return false; +// } +// for (AssignmentType assignment : assignmentsModel.getObject()){ +// //TODO check status +//// if (UserDtoStatus.DELETE.equals(dto.getStatus()) || UserDtoStatus.ADD.equals(dto.getStatus())){ +// return true; +//// } +// } + return false; + } + + protected int countPolicyRules() { + int policyRuleCounter = 0; + PrismObject focus = getObjectModel().getObject().getObject(); + List assignments = focus.asObjectable().getAssignment(); + for (AssignmentType assignment : assignments) { + if (AssignmentsUtil.isPolicyRuleAssignment(assignment)) { + policyRuleCounter++; + } } - for (AssignmentDto dto : assignmentsModel.getObject()){ - if (UserDtoStatus.DELETE.equals(dto.getStatus()) || UserDtoStatus.ADD.equals(dto.getStatus())){ - return true; + return policyRuleCounter; + } + + protected int countAssignments() { + + int rv = 0; + PrismObject focus = getObjectModel().getObject().getObject(); + List assignments = focus.asObjectable().getAssignment(); + for (AssignmentType assignment : assignments) { + if (!AssignmentsUtil.isPolicyRuleAssignment(assignment) && !AssignmentsUtil.isConsentAssignment(assignment) + && AssignmentsUtil.isAssignmentRelevant(assignment)) { + rv++; } } - return false; + return rv; } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusPolicyRulesTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusPolicyRulesTabPanel.java index 72077de6d2f..d0d697990ff 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusPolicyRulesTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/FocusPolicyRulesTabPanel.java @@ -20,12 +20,14 @@ import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismContainerValue; -import com.evolveum.midpoint.web.component.assignment.AssignmentDataTablePanel; -import com.evolveum.midpoint.web.component.assignment.AssignmentDto; -import com.evolveum.midpoint.web.component.assignment.AssignmentEditorDto; -import com.evolveum.midpoint.web.component.assignment.PolicyRuleDetailsPanel; -import com.evolveum.midpoint.web.component.assignment.PolicyRulesPanel; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.web.component.assignment.*; import com.evolveum.midpoint.web.component.form.Form; +import com.evolveum.midpoint.web.component.prism.ContainerValueWrapper; +import com.evolveum.midpoint.web.component.prism.ContainerWrapper; import com.evolveum.midpoint.web.component.prism.ObjectWrapper; import com.evolveum.midpoint.web.page.admin.PageAdminFocus; import com.evolveum.midpoint.web.page.admin.users.component.AssignmentPreviewDialog; @@ -36,6 +38,8 @@ import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.PropertyModel; import java.util.ArrayList; import java.util.List; @@ -48,8 +52,6 @@ public class FocusPolicyRulesTabPanel extends AbstractObjectTabPanel{ private static final long serialVersionUID = 1L; - private LoadableModel> policyRulesModel; - private static final String ID_POLICY_RULES_CONTAINER = "policyRulesContainer"; private static final String ID_POLICY_RULES_PANEL = "policyRulesPanel"; private static final String DOT_CLASS = FocusAssignmentsTabPanel.class.getName() + "."; @@ -57,21 +59,30 @@ public class FocusPolicyRulesTabPanel extends AbstractObje private PolicyRulesPanel policyRulesPanel = null; public FocusPolicyRulesTabPanel(String id, Form mainForm, LoadableModel> focusWrapperModel, - LoadableModel> policyRulesModel, PageBase page) { + PageBase page) { super(id, mainForm, focusWrapperModel, page); - this.policyRulesModel = policyRulesModel; initLayout(); } private void initLayout() { + ContainerWrapper assignmentsContainerWrapper = getObjectWrapper().findContainerWrapper(new ItemPath(FocusType.F_ASSIGNMENT)); + WebMarkupContainer policyRules = new WebMarkupContainer(ID_POLICY_RULES_CONTAINER); policyRules.setOutputMarkupId(true); add(policyRules); - PolicyRulesPanel policyRulesPanel = new PolicyRulesPanel(ID_POLICY_RULES_PANEL, policyRulesModel); + PolicyRulesPanel policyRulesPanel = new PolicyRulesPanel(ID_POLICY_RULES_PANEL, getPolicyRulesModel(assignmentsContainerWrapper), assignmentsContainerWrapper); policyRules.add(policyRulesPanel); } - - + private IModel>> getPolicyRulesModel(ContainerWrapper assignmentsContainerWrapper){ + List> policyRuleList = new ArrayList<>(); + assignmentsContainerWrapper.getValues().forEach(a -> { + if (AssignmentsUtil.isPolicyRuleAssignment(a.getContainerValue().getValue())){ + policyRuleList.add(a); + } + }); +// Collections.sort(consentsList); + return Model.ofList(policyRuleList); + } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/RoleMainPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/RoleMainPanel.java index ade709e5df6..8320b8bd590 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/RoleMainPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/RoleMainPanel.java @@ -32,6 +32,7 @@ import com.evolveum.midpoint.web.page.admin.roles.RolePolicyPanel; import com.evolveum.midpoint.web.page.admin.users.component.AbstractRoleMemberPanel; import com.evolveum.midpoint.web.page.admin.users.dto.FocusSubwrapperDto; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import org.apache.wicket.extensions.markup.html.tabs.ITab; @@ -49,11 +50,9 @@ public class RoleMainPanel extends AbstractRoleMainPanel { private static final long serialVersionUID = 1L; public RoleMainPanel(String id, LoadableModel> objectModel, - CountableLoadableModel assignmentsModel, - CountableLoadableModel policyRulesModel, LoadableModel>> projectionModel, LoadableModel> inducementsModel, PageAdminFocus parentPage) { - super(id, objectModel, assignmentsModel, policyRulesModel, projectionModel, inducementsModel, parentPage); + super(id, objectModel, projectionModel, inducementsModel, parentPage); } @Override diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerStatus.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerStatus.java index 143b444c741..469d9cb9e6e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerStatus.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerStatus.java @@ -21,5 +21,5 @@ */ public enum ContainerStatus { - ADDING, MODIFYING; + ADDING, MODIFYING, DELETING; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java index 1c70de9ca07..095c551fe91 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerValueWrapper.java @@ -80,6 +80,7 @@ public class ContainerValueWrapper extends PrismWrapper private ItemPath path; private List properties; private boolean readonly; + private boolean selected; ContainerValueWrapper(ContainerWrapper containerWrapper, PrismContainerValue containerValue, ValueStatus status, ItemPath path) { @@ -125,6 +126,10 @@ public ValueStatus getStatus() { return status; } + public void setStatus(ValueStatus status){ + this.status = status; + } + public ItemPath getPath() { return path; } @@ -259,6 +264,14 @@ public void setReadonly(boolean readonly) { this.readonly = readonly; } + public boolean isSelected() { + return selected; + } + + public void setSelected(boolean selected) { + this.selected = selected; + } + public void sort(final PageBase pageBase) { if (isSorted()) { Collections.sort(properties, new Comparator() { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java index 4bcc8cac1ea..3c52b6946a7 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java @@ -22,6 +22,8 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.delta.ContainerDelta; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; @@ -41,12 +43,6 @@ import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; /** * @author lazyman @@ -396,6 +392,49 @@ public void collectModifications(ObjectDelta delta) th } } + public void collectDeleteDelta(ObjectDelta delta, PrismContext prismContext) throws SchemaException { + + for (ContainerValueWrapper itemWrapper : getValues()) { + if (ValueStatus.DELETED.equals(itemWrapper.getStatus())){ + ContainerDelta containerDelta = new ContainerDelta(ItemPath.EMPTY_PATH, itemWrapper.getDefinition().getName(), + itemWrapper.getDefinition(), prismContext); + containerDelta.addValuesToDelete(itemWrapper.getContainerValue().clone()); + delta.addModification(containerDelta); + } + } + } + + public void collectAddDelta(ObjectDelta delta, ItemPath propertyPath, + PrismContainerDefinition def, PrismContext prismContext) throws SchemaException { + + ContainerDelta containerDelta = new ContainerDelta(propertyPath, def.getName(), def, prismContext); + + for (ContainerValueWrapper itemWrapper : getValues()) { + if (ValueStatus.ADDED.equals(itemWrapper.getStatus())) { + itemWrapper.getContainerValue().applyDefinition(def, false); + containerDelta.addValueToAdd(itemWrapper.getContainerValue().clone()); + + } + } +// ContainerDelta containerDelta = delta.createContainerModification(propertyPath); +// +// List containerValuesToAdd = new ArrayList<>(); +// +// for (ContainerValueWrapper itemWrapper : getValues()) { +// if (ValueStatus.ADDED.equals(itemWrapper.getStatus())){ +// containerValuesToAdd.add(itemWrapper.getContainerValue().clone()); + +// ContainerDelta containerDelta = new ContainerDelta(new ItemPath(FocusType.F_ASSIGNMENT), itemWrapper.getDefinition().getName(), +// itemWrapper.getDefinition(), prismContext); +// containerDelta.addValuesToAdd(itemWrapper.getContainerValue().clone()); +// } +// } +// containerDelta.addValuesToAdd(containerValuesToAdd.toArray(new PrismContainerValue[containerValuesToAdd.size()])); + if (!containerDelta.isEmpty()){ + delta.addModification(containerDelta); + } + } + @Override public boolean checkRequired(PageBase pageBase) { boolean rv = true; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java index 65473318f01..4afe877283b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ObjectWrapper.java @@ -24,6 +24,7 @@ import java.util.Iterator; import java.util.List; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; @@ -58,10 +59,6 @@ import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CapabilityType; import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType; @@ -74,6 +71,7 @@ public class ObjectWrapper extends PrismWrapper implements public static final String F_DISPLAY_NAME = "displayName"; public static final String F_SELECTED = "selected"; + public static final String F_OBJECT = "object"; private static final Trace LOGGER = TraceManager.getTrace(ObjectWrapper.class); @@ -345,6 +343,9 @@ public ObjectDelta getObjectDelta() throws SchemaException { for (ContainerWrapper containerWrapper : getContainers()) { containerWrapper.collectModifications(delta); + containerWrapper.collectDeleteDelta(delta, object.getPrismContext()); +// containerWrapper.collectAddDelta(delta, new ItemPath(FocusType.F_ASSIGNMENT), object.getDefinition().findContainerDefinition(UserType.F_ASSIGNMENT), +// object.getPrismContext()); } // returning container to previous order Collections.sort(containers, new ItemWrapperComparator()); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/sample/SampleFormFocusTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/sample/SampleFormFocusTabPanel.java index f41e6c22304..570faf87a9f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/sample/SampleFormFocusTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/sample/SampleFormFocusTabPanel.java @@ -18,6 +18,9 @@ import java.util.ArrayList; import java.util.List; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.web.component.prism.ContainerWrapper; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; @@ -41,10 +44,7 @@ import com.evolveum.midpoint.web.component.objectdetails.AbstractFocusTabPanel; import com.evolveum.midpoint.web.component.prism.ObjectWrapper; import com.evolveum.midpoint.web.page.admin.users.dto.FocusSubwrapperDto; -import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import org.apache.wicket.model.Model; /** * Sample showing a custom focus form that displays semi-static form. @@ -68,14 +68,13 @@ public class SampleFormFocusTabPanel extends AbstractFocusT public SampleFormFocusTabPanel(String id, Form mainForm, LoadableModel> focusWrapperModel, - LoadableModel> assignmentsModel, LoadableModel>> projectionModel, PageBase pageBase) { - super(id, mainForm, focusWrapperModel, assignmentsModel, projectionModel, pageBase); - initLayout(focusWrapperModel, assignmentsModel, pageBase); + super(id, mainForm, focusWrapperModel, projectionModel, pageBase); + initLayout(focusWrapperModel, pageBase); } - private void initLayout(final LoadableModel> focusModel, LoadableModel> assignmentsModel, PageBase pageBase) { + private void initLayout(final LoadableModel> focusModel, PageBase pageBase) { add(new Label(ID_HEADER, "Object details")); WebMarkupContainer body = new WebMarkupContainer("body"); add(body); @@ -96,7 +95,9 @@ private void initLayout(final LoadableModel> focusModel, Loadab // TODO: better errror reporting } - add(new SimpleRoleSelector(ID_ROLES, assignmentsModel, availableRoles)); + ContainerWrapper assignmentsContainerWrapper = getObjectWrapper().findContainerWrapper(new ItemPath(FocusType.F_ASSIGNMENT)); + + add(new SimpleRoleSelector(ID_ROLES, Model.ofList(assignmentsContainerWrapper.getValues()), availableRoles)); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/util/AssignmentListDataProvider.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/util/AssignmentListDataProvider.java index c97747d32f9..c0e59ae9c83 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/util/AssignmentListDataProvider.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/util/AssignmentListDataProvider.java @@ -24,6 +24,8 @@ import com.evolveum.midpoint.util.exception.TunnelException; import com.evolveum.midpoint.web.component.assignment.AssignmentDto; import com.evolveum.midpoint.web.component.data.BaseSortableDataProvider; +import com.evolveum.midpoint.web.component.prism.ContainerValueWrapper; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.Validate; @@ -42,17 +44,17 @@ /** * @author katkav */ -public class AssignmentListDataProvider extends BaseSortableDataProvider { +public class AssignmentListDataProvider extends BaseSortableDataProvider> { - private IModel> model; + private IModel>> model; private boolean sortable; // just to ensure backward compatibility with existing usages - public AssignmentListDataProvider(Component component, IModel> model) { + public AssignmentListDataProvider(Component component, IModel>> model) { this(component, model, false); } - public AssignmentListDataProvider(Component component, IModel> model, boolean sortable) { + public AssignmentListDataProvider(Component component, IModel>> model, boolean sortable) { super(component); Validate.notNull(model); @@ -62,10 +64,10 @@ public AssignmentListDataProvider(Component component, IModel internalIterator(long first, long count) { + public Iterator> internalIterator(long first, long count) { getAvailableData().clear(); - List list = searchThroughList(); + List> list = searchThroughList(); if (sortable && getSort() != null) { sort(list); @@ -84,16 +86,16 @@ public Iterator internalIterator(long first, long count } @SuppressWarnings("unchecked") - protected > void sort(List list) { - Collections.sort(list, new Comparator() { + protected > void sort(List> list) { + Collections.sort(list, new Comparator>() { @Override - public int compare(AssignmentDto o1, AssignmentDto o2) { + public int compare(ContainerValueWrapper o1, ContainerValueWrapper o2) { SortParam sortParam = getSort(); String propertyName = sortParam.getProperty(); V prop1, prop2; try { - prop1 = (V) PropertyUtils.getProperty(o1, propertyName); - prop2 = (V) PropertyUtils.getProperty(o2, propertyName); + prop1 = (V) PropertyUtils.getProperty(o1.getContainerValue().asContainerable(), propertyName); + prop2 = (V) PropertyUtils.getProperty(o2.getContainerValue().asContainerable(), propertyName); } catch (RuntimeException|IllegalAccessException|InvocationTargetException|NoSuchMethodException e) { throw new SystemException("Couldn't sort the object list: " + e.getMessage(), e); } @@ -105,7 +107,7 @@ public int compare(AssignmentDto o1, AssignmentDto o2) { @Override protected int internalSize() { - List list = searchThroughList(); + List> list = searchThroughList(); if (list == null) { return 0; } @@ -113,12 +115,12 @@ protected int internalSize() { return list.size(); } - public List getSelectedData() { + public List> getSelectedData() { return getAvailableData().stream().filter(a -> a.isSelected()).collect(Collectors.toList()); } - private List searchThroughList() { - List list = model.getObject(); + private List> searchThroughList() { + List> list = model.getObject(); if (list == null || list.isEmpty()) { return null; @@ -128,9 +130,9 @@ private List searchThroughList() { return list; } - List filtered = list.stream().filter(a -> { + List> filtered = list.stream().filter(a -> { try { - return ObjectQuery.match(a.getAssignment(), getQuery().getFilter(), null); + return ObjectQuery.match(a.getContainerValue().asContainerable(), getQuery().getFilter(), null); } catch (SchemaException e) { throw new TunnelException(e.getMessage()); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminAbstractRole.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminAbstractRole.java index dfcc3562d2f..758e4fdc383 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminAbstractRole.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminAbstractRole.java @@ -43,20 +43,6 @@ public LoadableModel> getInducementsModel() { return inducementsModel; } - @Override - public CountableLoadableModel getPolicyRulesModel() { - CountableLoadableModel policyModel = super.getPolicyRulesModel(); - policyModel.getObject().addAll(loadInducementsPolicyRules()); - Collections.sort(policyModel.getObject()); - return policyModel; - } - - @Override - protected int countPolicyRules() { - return super.countPolicyRules() + loadInducementsPolicyRules().size(); - } - - @Override protected void prepareObjectDeltaForModify(ObjectDelta focusDelta) throws SchemaException { super.prepareObjectDeltaForModify(focusDelta); @@ -99,14 +85,6 @@ private List loadInducements() { return list; } - private List loadInducementsPolicyRules(){ - List inducements = getInducementsList(); - List list = getPolicyRulesList(inducements, StringUtils.isEmpty(getObjectWrapper().getOid()) ? - UserDtoStatus.ADD : UserDtoStatus.MODIFY); - Collections.sort(list); - return list; - } - private List getInducementsList(){ ObjectWrapper focusWrapper = getObjectWrapper(); PrismObject focus = focusWrapper.getObject(); 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 5cbf5e0394e..f75f5495283 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 @@ -45,6 +45,8 @@ import com.evolveum.midpoint.web.component.assignment.AssignmentEditorDtoType; import com.evolveum.midpoint.web.component.assignment.AssignmentsUtil; import com.evolveum.midpoint.web.component.prism.ContainerStatus; +import com.evolveum.midpoint.web.component.prism.ContainerValueWrapper; +import com.evolveum.midpoint.web.component.prism.ContainerWrapper; import com.evolveum.midpoint.web.component.prism.ObjectWrapper; import com.evolveum.midpoint.web.component.prism.show.PagePreviewChanges; import com.evolveum.midpoint.web.component.progress.ProgressReportingAwarePage; @@ -77,8 +79,6 @@ public abstract class PageAdminFocus extends PageAdminObjec public static final String AUTH_ORG_ALL_DESCRIPTION = "PageAdminUsers.auth.orgAll.description"; private LoadableModel>> projectionModel; - private CountableLoadableModel assignmentsModel; - private CountableLoadableModel policyRulesModel; private LoadableModel> delegatedToMeModel; private static final String DOT_CLASS = PageAdminFocus.class.getName() + "."; @@ -102,36 +102,6 @@ protected List> load() { } }; - assignmentsModel = new CountableLoadableModel(false) { - private static final long serialVersionUID = 1L; - - @Override - protected List load() { - return loadAssignments(); - } - - @Override - public int countInternal() { - return countAssignments(); - } - }; - - policyRulesModel = new CountableLoadableModel(false) { - private static final long serialVersionUID = 1L; - - @Override - protected List load() { - return loadPolicyRules(); - } - - @Override - public int countInternal() { - return countPolicyRules(); - } - }; - - - delegatedToMeModel= new LoadableModel>(false) { private static final long serialVersionUID = 1L; @@ -147,14 +117,6 @@ public LoadableModel>> getProjectionModel() return projectionModel; } - public CountableLoadableModel getAssignmentsModel() { - return assignmentsModel; - } - - public CountableLoadableModel getPolicyRulesModel() { - return policyRulesModel; - } - public LoadableModel> getDelegatedToMeModel() { return delegatedToMeModel; } @@ -163,19 +125,9 @@ public List> getFocusShadows() { return projectionModel.getObject(); } - public boolean isAssignmentsLoaded() { - return assignmentsModel.isLoaded() || policyRulesModel.isLoaded(); - } - - public List getFocusAssignments() { - return assignmentsModel.getObject(); - } - protected void reviveModels() throws SchemaException { super.reviveModels(); WebComponentUtil.revive(projectionModel, getPrismContext()); - WebComponentUtil.revive(assignmentsModel, getPrismContext()); - WebComponentUtil.revive(policyRulesModel, getPrismContext()); } protected ObjectWrapper loadFocusWrapper(PrismObject userToEdit) { @@ -400,22 +352,10 @@ private List loadDelegatedToMe() { return list; } - private int countAssignments() { - int rv = 0; - PrismObject focus = getObjectModel().getObject().getObject(); - List assignments = focus.asObjectable().getAssignment(); - for (AssignmentType assignment : assignments) { - if (!AssignmentsUtil.isPolicyRuleAssignment(assignment) && !AssignmentsUtil.isConsentAssignment(assignment) - && AssignmentsUtil.isAssignmentRelevant(assignment)) { - rv++; - } - } - return rv; - } - private List loadAssignments() { - List list = new ArrayList(); + private List loadAssignments() { + List list = new ArrayList(); ObjectWrapper focusWrapper = getObjectModel().getObject(); PrismObject focus = focusWrapper.getObject(); @@ -423,41 +363,33 @@ private List loadAssignments() { for (AssignmentType assignment : assignments) { if (!AssignmentsUtil.isPolicyRuleAssignment(assignment) && !AssignmentsUtil.isConsentAssignment(assignment) && AssignmentsUtil.isAssignmentRelevant(assignment)) { - list.add(new AssignmentDto(assignment, StringUtils.isEmpty(focusWrapper.getOid()) ? UserDtoStatus.ADD : UserDtoStatus.MODIFY)); + //TODO set status + list.add(assignment); +// list.add(new AssignmentDto(assignment, StringUtils.isEmpty(focusWrapper.getOid()) ? UserDtoStatus.ADD : UserDtoStatus.MODIFY)); } } - - Collections.sort(list); +//TODO uncomment +// Collections.sort(list); return list; } - protected int countPolicyRules() { - int policyRuleCounter = 0; - PrismObject focus = getObjectModel().getObject().getObject(); - List assignments = focus.asObjectable().getAssignment(); - for (AssignmentType assignment : assignments) { - if (AssignmentsUtil.isPolicyRuleAssignment(assignment)) { - policyRuleCounter++; - } - } - return policyRuleCounter; - } - - private List loadPolicyRules() { + private List loadPolicyRules() { ObjectWrapper focusWrapper = getObjectModel().getObject(); PrismObject focus = focusWrapper.getObject(); - List list = getPolicyRulesList(focus.asObjectable().getAssignment(), StringUtils.isEmpty(focusWrapper.getOid()) ? + List list = getPolicyRulesList(focus.asObjectable().getAssignment(), StringUtils.isEmpty(focusWrapper.getOid()) ? UserDtoStatus.ADD : UserDtoStatus.MODIFY); - Collections.sort(list); + //TODO uncomment +// Collections.sort(list); return list; } - protected List getPolicyRulesList(List assignments, UserDtoStatus status){ - List list = new ArrayList(); + protected List getPolicyRulesList(List assignments, UserDtoStatus status){ + List list = new ArrayList(); for (AssignmentType assignment : assignments) { if (AssignmentsUtil.isPolicyRuleAssignment(assignment)) { - list.add(new AssignmentDto(assignment, status)); + //TODO set status + list.add(assignment); } } return list; @@ -480,7 +412,7 @@ protected void prepareObjectForAdd(PrismObject focus) throws SchemaException focusType.getParentOrg().addAll(orgsToAdd); } - handleAssignmentForAdd(focus, UserType.F_ASSIGNMENT, assignmentsModel.getObject()); +// handleAssignmentForAdd(focus, UserType.F_ASSIGNMENT, assignmentsModel.getObject()); } @@ -536,15 +468,20 @@ protected void prepareObjectDeltaForModify(ObjectDelta focusDelta) throws Sch // There may be assignments delta only if they are loaded. Otherwise the user didn't open // the assignments tab at all. So, we are not loaded do not force load here. The load will // only slow down the operation - especially if we have many assignments - if (isAssignmentsLoaded()) { +// if (isAssignmentsLoaded()) { // handle assignments - PrismContainerDefinition def = objectDefinition.findContainerDefinition(UserType.F_ASSIGNMENT); +// PrismContainerDefinition def = objectDefinition.findContainerDefinition(UserType.F_ASSIGNMENT); // handleAssignmentDeltas(focusDelta, getFocusAssignments(), def); - List assignmentsList = new ArrayList<>(); - assignmentsList.addAll(getFocusAssignments()); - assignmentsList.addAll(getPolicyRulesModel().getObject()); - handleAssignmentExperimentalDeltas(focusDelta, assignmentsList, def, false); - } +// List assignmentsList = new ArrayList<>(); +// assignmentsList.addAll(getFocusAssignments()); +// assignmentsList.addAll(getPolicyRulesModel().getObject()); + //TODO perhaps not needed any more +// ContainerWrapper assignmentContainerWrapper = getObjectWrapper().findContainerWrapper(new ItemPath(FocusType.F_ASSIGNMENT)); +// +// handleAssignmentExperimentalDeltas(focusDelta, +// assignmentContainerWrapper.getValues(), +// def, false); +// } } protected PrismObjectDefinition getObjectDefinition() { @@ -611,38 +548,53 @@ protected ContainerDelta handleAssignmentDeltas(ObjectDelta focusDelta, } protected ContainerDelta handleAssignmentExperimentalDeltas(ObjectDelta focusDelta, - List assignments, PrismContainerDefinition def, - boolean isDelegation) throws SchemaException { + List> assignments, PrismContainerDefinition def, + boolean isDelegation) throws SchemaException { ContainerDelta assDelta = new ContainerDelta(ItemPath.EMPTY_PATH, def.getName(), def, getPrismContext()); - for (AssignmentDto assDto : assignments) { - PrismContainerValue newValue = assDto.getAssignment().asPrismContainerValue(); - - switch (assDto.getStatus()) { - case ADD: - newValue.applyDefinition(def, false); - assDelta.addValueToAdd(newValue.clone()); - break; - case DELETE: - PrismContainerValue oldValue = assDto.getAssignment().asPrismContainerValue(); - if (isDelegation){ - oldValue.applyDefinition(def, false); - } else { - oldValue.applyDefinition(def); - } - assDelta.addValueToDelete(oldValue.clone()); - break; - case MODIFY: - Collection deltas = assDto.computeAssignmentDelta(); - if (deltas != null || !deltas.isEmpty()) { - focusDelta.addModifications(deltas); - } +// for (ContainerValueWrapper assignmentContainerWrapper : assignments) { +// switch (assignmentContainerWrapper.getStatus()) { +// case ADDED: +// assDelta.addValueToAdd(assignmentContainerWrapper.getContainerValue().clone()); +// break; +// case NOT_CHANGED: +// assignmentContainerWrapper.collectModifications(focusDelta); +// break; +// case DELETED: +// assDelta.addValuesToDelete(assignmentContainerWrapper.getContainerValue().clone()); +// break; +// } +// + + +// PrismContainerValue newValue = assignmentContainerWrapper.getAssignment().asPrismContainerValue(); +// +// switch (assignmentContainerWrapper.getStatus()) { +// case ADD: +// newValue.applyDefinition(def, false); +// assDelta.addValueToAdd(newValue.clone()); +// break; +// case DELETE: +// PrismContainerValue oldValue = assignmentContainerWrapper.getAssignment().asPrismContainerValue(); +// if (isDelegation){ +// oldValue.applyDefinition(def, false); +// } else { +// oldValue.applyDefinition(def); +// } +// assDelta.addValueToDelete(oldValue.clone()); +// break; +// case MODIFY: +// Collection deltas = assignmentContainerWrapper.computeAssignmentDelta(); +// if (deltas != null || !deltas.isEmpty()) { +// focusDelta.addModifications(deltas); +// } +// +// break; +// default: +// warn(getString("pageAdminUser.message.illegalAssignmentState", assignmentContainerWrapper.getStatus())); +// } +// } - break; - default: - warn(getString("pageAdminUser.message.illegalAssignmentState", assDto.getStatus())); - } - } if (!assDelta.isEmpty()) { assDelta = focusDelta.addModification(assDelta); @@ -739,8 +691,9 @@ private ObjectDelta getForceDeleteDelta(ObjectWrapper focusWrapper) throws Schem forceDeleteDelta = ObjectDelta.createEmptyModifyDelta(getCompileTimeClass(), focusWrapper.getObject().getOid(), getPrismContext()); } - - handleAssignmentExperimentalDeltas(forceDeleteDelta, getFocusAssignments(), def, false); +//perhaps not needed anymore + ContainerWrapper assignmentContainerWrapper = getObjectWrapper().findContainerWrapper(new ItemPath(FocusType.F_ASSIGNMENT)); + handleAssignmentExperimentalDeltas(forceDeleteDelta, assignmentContainerWrapper.getValues(), def, false); return forceDeleteDelta; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/PageRole.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/PageRole.java index a2b7003b186..329360f7d91 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/PageRole.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/PageRole.java @@ -165,6 +165,6 @@ protected FocusSummaryPanel createSummaryPanel() { @Override protected AbstractObjectMainPanel createMainPanel(String id) { - return new RoleMainPanel(id, getObjectModel(), getAssignmentsModel(), getPolicyRulesModel(), getProjectionModel(), getInducementsModel(), this); + return new RoleMainPanel(id, getObjectModel(), getProjectionModel(), getInducementsModel(), this); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/services/PageService.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/services/PageService.java index d701016fc56..61b0bea5155 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/services/PageService.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/services/PageService.java @@ -77,7 +77,7 @@ protected FocusSummaryPanel createSummaryPanel() { @Override protected AbstractObjectMainPanel createMainPanel(String id) { - return new AbstractRoleMainPanel(id, getObjectModel(), getAssignmentsModel(), getPolicyRulesModel(), + return new AbstractRoleMainPanel(id, getObjectModel(), getProjectionModel(), getInducementsModel(), this) { private static final long serialVersionUID = 1L; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageMergeObjects.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageMergeObjects.java index fad1bc2f8af..bb3328a998d 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageMergeObjects.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageMergeObjects.java @@ -38,6 +38,7 @@ import com.evolveum.midpoint.web.page.admin.users.component.UserSummaryPanel; import com.evolveum.midpoint.web.page.admin.users.dto.FocusSubwrapperDto; import com.evolveum.midpoint.web.util.OnePageParameterEncoder; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; @@ -132,21 +133,21 @@ public void detach() { protected AbstractObjectMainPanel createMainPanel(String id){ //empty assignments model - CountableLoadableModel assignemtns = new CountableLoadableModel() { + CountableLoadableModel assignemtns = new CountableLoadableModel() { private static final long serialVersionUID = 1L; @Override - protected List load() { + protected List load() { return new ArrayList<>(); } }; - //empty projections model - CountableLoadableModel policyRules = new CountableLoadableModel() { + //empty policy rules model + CountableLoadableModel policyRules = new CountableLoadableModel() { private static final long serialVersionUID = 1L; @Override - protected List load() { + protected List load() { return new ArrayList<>(); } }; @@ -160,7 +161,7 @@ protected List> load() { } }; - return new FocusMainPanel(id, getObjectModel(), assignemtns, policyRules, shadows, this) { + return new FocusMainPanel(id, getObjectModel(), shadows, this) { private static final long serialVersionUID = 1L; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageOrgUnit.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageOrgUnit.java index 9cd8237da4b..df2e670be57 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageOrgUnit.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageOrgUnit.java @@ -80,7 +80,7 @@ protected FocusSummaryPanel createSummaryPanel() { @Override protected AbstractObjectMainPanel createMainPanel(String id) { - return new AbstractRoleMainPanel(id, getObjectModel(), getAssignmentsModel(), getPolicyRulesModel(), + return new AbstractRoleMainPanel(id, getObjectModel(), getProjectionModel(), getInducementsModel(), this) { @Override diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUser.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUser.java index 3bf81cd7bc9..b9046c7afee 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUser.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUser.java @@ -92,7 +92,6 @@ public class PageUser extends PageAdminFocus { private static final String ID_TASKS = "tasks"; private LoadableModel> delegationsModel; private LoadableModel> privilegesListModel; - private CountableLoadableModel consentsModel; private UserDelegationsTabPanel userDelegationsTabPanel = null; private static final Trace LOGGER = TraceManager.getTrace(PageUser.class); @@ -129,21 +128,6 @@ protected List load() { return getUserPrivilegesList(); } }; - - consentsModel = new CountableLoadableModel(false) { - private static final long serialVersionUID = 1L; - - @Override - protected List load() { - return loadConsents(); - } - - @Override - public int count() { - return countConsents(); - } - - }; } @Override @@ -188,7 +172,7 @@ public Class getCompileTimeClass() { @Override protected AbstractObjectMainPanel createMainPanel(String id) { - return new FocusMainPanel(id, getObjectModel(), getAssignmentsModel(), getPolicyRulesModel(), getProjectionModel(), this) { + return new FocusMainPanel(id, getObjectModel(), getProjectionModel(), this) { @Override protected void addSpecificTabs(final PageAdminObjectDetails parentPage, List tabs) { FocusTabVisibleBehavior authorization; @@ -276,12 +260,12 @@ public String getCount() { @Override public WebMarkupContainer createPanel(String panelId) { - return new FocusConsentTabPanel(panelId, getMainForm(), getObjectModel(), consentsModel, parentPage); + return new FocusConsentTabPanel(panelId, getMainForm(), getObjectModel(), parentPage); } @Override public String getCount() { - return Integer.toString(consentsModel.count()); + return Integer.toString(countConsents()); } }); } @@ -368,17 +352,6 @@ private List getUserPrivilegesList(){ return list; } - @Override - protected void prepareObjectDeltaForModify(ObjectDelta focusDelta) throws SchemaException { - - super.prepareObjectDeltaForModify(focusDelta); - - PrismContainerDefinition def = getObjectDefinition().findContainerDefinition(UserType.F_ASSIGNMENT); - if (consentsModel.isLoaded()) { - handleAssignmentExperimentalDeltas(focusDelta, consentsModel.getObject(), def, false); - } -} - @Override protected boolean processDeputyAssignments(boolean previewOnly) { boolean isAnythingChanged = false; @@ -438,24 +411,16 @@ protected int countConsents() { return consentCounter; } - private List loadConsents() { - ObjectWrapper focusWrapper = getObjectModel().getObject(); - PrismObject focus = focusWrapper.getObject(); - List list = getConsentsList(focus.asObjectable().getAssignment(), StringUtils.isEmpty(focusWrapper.getOid()) ? - UserDtoStatus.ADD : UserDtoStatus.MODIFY); - Collections.sort(list); - return list; - } - private boolean isConsentAssignment(AssignmentType assignment) { return assignment.getTargetRef() != null && QNameUtil.match(assignment.getTargetRef().getRelation(), SchemaConstants.ORG_CONSENT); } - protected List getConsentsList(List assignments, UserDtoStatus status){ - List list = new ArrayList(); + protected List getConsentsList(List assignments, UserDtoStatus status){ + List list = new ArrayList(); for (AssignmentType assignment : assignments) { if (isConsentAssignment(assignment)) { - list.add(new AssignmentDto(assignment, status)); + //TODO set status + list.add(assignment); } } return list; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUserHistory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUserHistory.java index 1cd25ff242b..36731ddf265 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUserHistory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUserHistory.java @@ -163,7 +163,7 @@ public Class getCompileTimeClass() { @Override protected AbstractObjectMainPanel createMainPanel(String id) { - return new FocusMainPanel(id, getObjectModel(), getAssignmentsModel(), getPolicyRulesModel(), getProjectionModel(), this) { + return new FocusMainPanel(id, getObjectModel(), getProjectionModel(), this) { @Override protected List createTabs(final PageAdminObjectDetails parentPage) { List tabs = new ArrayList<>(); @@ -213,8 +213,7 @@ public WebMarkupContainer createPanel(String panelId) { @Override public String getCount() { - return Integer.toString(getAssignmentsModel().getObject() == null ? - 0 : getAssignmentsModel().getObject().size()); + return Integer.toString(countAssignments()); } }); authorization = new FocusTabVisibleBehavior(unwrapModel(), diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageSelfConsents.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageSelfConsents.java index 50dfccbc774..887da38a0c7 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageSelfConsents.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageSelfConsents.java @@ -69,7 +69,7 @@ public class PageSelfConsents extends PageBase{ private static final long serialVersionUID = 1L; - private LoadableModel> consentModel; + private LoadableModel> consentModel; private static final String DOT_CLASS = PageSelfConsents.class.getSimpleName() + "."; private static final String OPERATION_LOAD_USER = DOT_CLASS + "loadUserSelf"; @@ -77,12 +77,12 @@ public class PageSelfConsents extends PageBase{ public PageSelfConsents() { - consentModel = new LoadableModel>() { + consentModel = new LoadableModel>() { private static final long serialVersionUID = 1L; @Override - protected List load() { + protected List load() { MidPointPrincipal principal = SecurityUtils.getPrincipalUser(); if (principal == null) { @@ -100,7 +100,8 @@ protected List load() { Collection assignments = assignmentContainer.getRealValues(); return assignments.stream() .filter(a -> a.getTargetRef()!= null && QNameUtil.match(a.getTargetRef().getRelation(), SchemaConstants.ORG_CONSENT)) - .map(a -> new AssignmentDto(a, UserDtoStatus.MODIFY)) +//TODO set status +// .map(a -> new AssignmentDto(a, UserDtoStatus.MODIFY)) .collect(Collectors.toList()); } }; @@ -112,8 +113,8 @@ private void initLayout() { RepeatingView consents = new RepeatingView(ID_CONSENTS); consents.setOutputMarkupId(true); - for (AssignmentDto assignmentDto : consentModel.getObject()) { - SelfConsentPanel consentPanel = new SelfConsentPanel(consents.newChildId(), Model.of(assignmentDto), this); + for (AssignmentType assignmentType : consentModel.getObject()) { + SelfConsentPanel consentPanel = new SelfConsentPanel(consents.newChildId(), Model.of(assignmentType), this); consentPanel.setOutputMarkupId(true); consents.add(consentPanel); } From d403251c064c5e0bd16b30fbd219209a7a71ff81 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 2 Oct 2017 08:51:27 +0200 Subject: [PATCH 82/97] Serializing wf execution tasks on object OID (not on request id). (cherry picked from commit 83ffdaf) --- .../BaseModelInvocationProcessingHelper.java | 3 +- .../primary/PrimaryChangeProcessor.java | 3 +- .../wf/impl/policy/AbstractWfTestPolicy.java | 6 + .../policy/other/TestParallelApprovals.java | 246 ++++++++++++++++-- .../resources/policy/role-role50a-slow.xml | 43 +++ .../src/test/resources/policy/user-bob.xml | 28 ++ .../src/test/resources/policy/user-chuck.xml | 28 ++ 7 files changed, 337 insertions(+), 20 deletions(-) create mode 100644 model/workflow-impl/src/test/resources/policy/role-role50a-slow.xml create mode 100644 model/workflow-impl/src/test/resources/policy/user-bob.xml create mode 100644 model/workflow-impl/src/test/resources/policy/user-chuck.xml diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseModelInvocationProcessingHelper.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseModelInvocationProcessingHelper.java index 18f1123fdb5..48a7814a38e 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseModelInvocationProcessingHelper.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseModelInvocationProcessingHelper.java @@ -80,7 +80,7 @@ public class BaseModelInvocationProcessingHelper { */ public WfTaskCreationInstruction createInstructionForRoot(ChangeProcessor changeProcessor, ModelContext modelContext, Task taskFromModel, ModelContext contextForRoot, OperationResult result) throws SchemaException { - WfTaskCreationInstruction instruction; + WfTaskCreationInstruction instruction; if (contextForRoot != null) { instruction = WfTaskCreationInstruction.createModelOnly(changeProcessor, contextForRoot); } else { @@ -92,6 +92,7 @@ public WfTaskCreationInstruction createInstructionForRoot(ChangeProcessor change instruction.setTaskOwner(taskFromModel.getOwner()); instruction.setCreateTaskAsWaiting(); + instruction.setObjectRef(modelContext, result); instruction.setRequesterRef(getRequester(taskFromModel, result)); return instruction; } diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PrimaryChangeProcessor.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PrimaryChangeProcessor.java index 49a6c81d575..efb6bc4903a 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PrimaryChangeProcessor.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PrimaryChangeProcessor.java @@ -271,8 +271,9 @@ private WfTask submitTask0(ModelContext context, ObjectTreeDeltas changesWithout WfConfigurationType wfConfigurationType, OperationResult result) throws SchemaException, ObjectNotFoundException { if (changesWithoutApproval != null && !changesWithoutApproval.isEmpty() && executionMode != ALL_AFTERWARDS) { ModelContext task0context = contextCopyWithDeltasReplaced(context, changesWithoutApproval); - WfTaskCreationInstruction instruction0 = WfTaskCreationInstruction.createModelOnly(rootWfTask.getChangeProcessor(), task0context); + WfTaskCreationInstruction instruction0 = WfTaskCreationInstruction.createModelOnly(rootWfTask.getChangeProcessor(), task0context); instruction0.setTaskName("Executing changes that do not require approval"); + instruction0.setObjectRef(context, result); return wfTaskController.submitWfTask(instruction0, rootWfTask, wfConfigurationType, result); } else { return null; diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/AbstractWfTestPolicy.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/AbstractWfTestPolicy.java index fc8e1c0bbba..e63d4f52b46 100644 --- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/AbstractWfTestPolicy.java +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/AbstractWfTestPolicy.java @@ -93,6 +93,8 @@ public class AbstractWfTestPolicy extends AbstractModelImplementationIntegration public static final File USER_ADMINISTRATOR_FILE = new File(TEST_RESOURCE_DIR, "user-administrator.xml"); protected static final File USER_JACK_FILE = new File(TEST_RESOURCE_DIR, "user-jack.xml"); + protected static final File USER_BOB_FILE = new File(TEST_RESOURCE_DIR, "user-bob.xml"); + protected static final File USER_CHUCK_FILE = new File(TEST_RESOURCE_DIR, "user-chuck.xml"); protected static final File USER_LEAD1_FILE = new File(TEST_RESOURCE_DIR, "user-lead1.xml"); protected static final File USER_LEAD1_DEPUTY_1_FILE = new File(TEST_RESOURCE_DIR, "user-lead1-deputy1.xml"); protected static final File USER_LEAD1_DEPUTY_2_FILE = new File(TEST_RESOURCE_DIR, "user-lead1-deputy2.xml"); @@ -134,6 +136,8 @@ public class AbstractWfTestPolicy extends AbstractModelImplementationIntegration protected static final String USER_ADMINISTRATOR_OID = SystemObjectsType.USER_ADMINISTRATOR.value(); protected String userJackOid; + protected String userBobOid; + protected String userChuckOid; protected String userLead1Oid; protected String userLead1Deputy1Oid; protected String userLead1Deputy2Oid; @@ -202,6 +206,8 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti metaroleApproveUnassign = repoAddObjectFromFile(METAROLE_APPROVE_UNASSIGN_FILE, initResult).getOid(); userJackOid = repoAddObjectFromFile(USER_JACK_FILE, initResult).getOid(); + userBobOid = repoAddObjectFromFile(USER_BOB_FILE, initResult).getOid(); + userChuckOid = repoAddObjectFromFile(USER_CHUCK_FILE, initResult).getOid(); roleRole1Oid = repoAddObjectFromFile(ROLE_ROLE1_FILE, initResult).getOid(); roleRole1aOid = repoAddObjectFromFile(ROLE_ROLE1A_FILE, initResult).getOid(); roleRole1bOid = repoAddObjectFromFile(ROLE_ROLE1B_FILE, initResult).getOid(); diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestParallelApprovals.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestParallelApprovals.java index 536f4b46869..73f9e52232e 100644 --- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestParallelApprovals.java +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestParallelApprovals.java @@ -41,11 +41,16 @@ import org.testng.annotations.Test; import java.io.File; -import java.util.Collections; +import java.util.Arrays; +import java.util.Collection; import java.util.List; import static com.evolveum.midpoint.model.api.ModelExecuteOptions.createExecuteImmediatelyAfterApproval; import static com.evolveum.midpoint.xml.ns._public.common.common_3.TaskExecutionStatusType.CLOSED; +import static java.util.Collections.emptySet; +import static java.util.Collections.singleton; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNull; /** * @author mederly @@ -54,11 +59,12 @@ @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) public class TestParallelApprovals extends AbstractWfTestPolicy { + private static final File ROLE_ROLE50A_FILE = new File(TEST_RESOURCE_DIR, "role-role50a-slow.xml"); private static final File ROLE_ROLE51A_FILE = new File(TEST_RESOURCE_DIR, "role-role51a-slow.xml"); private static final File ROLE_ROLE52A_FILE = new File(TEST_RESOURCE_DIR, "role-role52a-slow.xml"); private static final File ROLE_ROLE53A_FILE = new File(TEST_RESOURCE_DIR, "role-role53a-slow.xml"); - private String roleRole51aOid, roleRole52aOid, roleRole53aOid; + private String roleRole50aOid, roleRole51aOid, roleRole52aOid, roleRole53aOid; @Override protected PrismObject getDefaultActor() { @@ -69,6 +75,7 @@ protected PrismObject getDefaultActor() { public void initSystem(Task initTask, OperationResult initResult) throws Exception { super.initSystem(initTask, initResult); + roleRole50aOid = repoAddObjectFromFile(ROLE_ROLE50A_FILE, initResult).getOid(); roleRole51aOid = repoAddObjectFromFile(ROLE_ROLE51A_FILE, initResult).getOid(); roleRole52aOid = repoAddObjectFromFile(ROLE_ROLE52A_FILE, initResult).getOid(); roleRole53aOid = repoAddObjectFromFile(ROLE_ROLE53A_FILE, initResult).getOid(); @@ -85,6 +92,8 @@ protected void updateSystemConfiguration(SystemConfigurationType systemConfigura .retryAfter(XmlTypeConverter.createDuration(1000)); // makes tests run faster } + private CheckingTaskListener listener; + @Test public void test100ParallelApprovals() throws Exception { final String TEST_NAME = "test100ParallelApprovals"; @@ -98,6 +107,7 @@ public void test100ParallelApprovals() throws Exception { displayWhen(TEST_NAME); ObjectDelta assignDelta = DeltaBuilder.deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).add( + ObjectTypeUtil.createAssignmentTo(roleRole50aOid, ObjectTypes.ROLE, prismContext), ObjectTypeUtil.createAssignmentTo(roleRole51aOid, ObjectTypes.ROLE, prismContext), ObjectTypeUtil.createAssignmentTo(roleRole52aOid, ObjectTypes.ROLE, prismContext), ObjectTypeUtil.createAssignmentTo(roleRole53aOid, ObjectTypes.ROLE, prismContext)) @@ -111,66 +121,266 @@ public void test100ParallelApprovals() throws Exception { String rootTaskOid = wfTaskUtil.getRootTaskOid(task); display("root task", getTask(rootTaskOid)); - CheckingTaskListener listener = new CheckingTaskListener(rootTaskOid); + if (listener != null) { + taskManager.unregisterTaskListener(listener); + } + listener = new CheckingTaskListener(singleton(rootTaskOid)); + taskManager.registerTaskListener(listener); + + approveAllWorkItems(task, result); + + waitForTaskCloseOrSuspend(rootTaskOid, 120000, 1000); + + // THEN + + PrismObject rootTask = getTask(rootTaskOid); + assertNull("Exception has occurred " + listener.getException(), listener.getException()); + assertEquals("Wrong root task1 status", CLOSED, rootTask.asObjectable().getExecutionStatus()); + + PrismObject jack = getUser(userJackOid); + assertAssignedRole(jack, roleRole50aOid); + assertAssignedRole(jack, roleRole51aOid); + assertAssignedRole(jack, roleRole52aOid); + assertAssignedRole(jack, roleRole53aOid); + } + + @Test + public void test110ParallelApprovalsAdd() throws Exception { + final String TEST_NAME = "test110ParallelApprovalsAdd"; + TestUtil.displayTestTitle(this, TEST_NAME); + login(userAdministrator); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + if (listener != null) { + taskManager.unregisterTaskListener(listener); + } + listener = new CheckingTaskListener(); taskManager.registerTaskListener(listener); + // WHEN + displayWhen(TEST_NAME); + UserType alice = prismContext.createObjectable(UserType.class) + .name("alice") + .assignment(ObjectTypeUtil.createAssignmentTo(roleRole50aOid, ObjectTypes.ROLE, prismContext)) + .assignment(ObjectTypeUtil.createAssignmentTo(roleRole51aOid, ObjectTypes.ROLE, prismContext)) + .assignment(ObjectTypeUtil.createAssignmentTo(roleRole52aOid, ObjectTypes.ROLE, prismContext)) + .assignment(ObjectTypeUtil.createAssignmentTo(roleRole53aOid, ObjectTypes.ROLE, prismContext)); + executeChanges(ObjectDelta.createAddDelta(alice.asPrismObject()), createExecuteImmediatelyAfterApproval(), task, result); // should start approval processes + + display("Task after operation", task); + String rootTaskOid = wfTaskUtil.getRootTaskOid(task); + display("root task", getTask(rootTaskOid)); + + listener.setTasksToSuspendOnError(singleton(rootTaskOid)); + + approveAllWorkItems(task, result); + waitForTaskCloseOrSuspend(rootTaskOid, 120000, 1000); + + // THEN + + PrismObject rootTask = getTask(rootTaskOid); + assertNull("Exception has occurred " + listener.getException(), listener.getException()); + assertEquals("Wrong root task1 status", CLOSED, rootTask.asObjectable().getExecutionStatus()); + + PrismObject aliceAfter = findUserByUsername("alice"); + assertAssignedRole(aliceAfter, roleRole50aOid); + assertAssignedRole(aliceAfter, roleRole51aOid); + assertAssignedRole(aliceAfter, roleRole52aOid); + assertAssignedRole(aliceAfter, roleRole53aOid); + } + + public void approveAllWorkItems(Task task, OperationResult result) throws Exception { List workItems = getWorkItems(task, result); display("work items", workItems); display("approving work items"); for (WorkItemType workItem : workItems) { workflowManager.completeWorkItem(workItem.getExternalId(), true, null, null, null, result); } + } - waitForTaskCloseOrSuspend(rootTaskOid, 120000, 1000); + @Test + public void test120ParallelApprovalsInTwoOperations() throws Exception { + final String TEST_NAME = "test120ParallelApprovalsInTwoOperations"; + TestUtil.displayTestTitle(this, TEST_NAME); + login(userAdministrator); + + Task task = createTask(TEST_NAME); + Task task1 = createTask(TEST_NAME); + Task task2 = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + if (listener != null) { + taskManager.unregisterTaskListener(listener); + } + listener = new CheckingTaskListener(); + taskManager.registerTaskListener(listener); + + // WHEN + displayWhen(TEST_NAME); + ObjectDelta assignDelta1 = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT).add( + ObjectTypeUtil.createAssignmentTo(roleRole50aOid, ObjectTypes.ROLE, prismContext), + ObjectTypeUtil.createAssignmentTo(roleRole51aOid, ObjectTypes.ROLE, prismContext)) + .asObjectDeltaCast(userBobOid); + executeChanges(assignDelta1, createExecuteImmediatelyAfterApproval(), task1, result); // should start approval processes + ObjectDelta assignDelta2 = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT).add( + ObjectTypeUtil.createAssignmentTo(roleRole50aOid, ObjectTypes.ROLE, prismContext), + ObjectTypeUtil.createAssignmentTo(roleRole52aOid, ObjectTypes.ROLE, prismContext), + ObjectTypeUtil.createAssignmentTo(roleRole53aOid, ObjectTypes.ROLE, prismContext)) + .asObjectDeltaCast(userBobOid); + executeChanges(assignDelta2, createExecuteImmediatelyAfterApproval(), task2, result); // should start approval processes + assertNotAssignedRole(userBobOid, roleRole51aOid, task, result); + assertNotAssignedRole(userBobOid, roleRole52aOid, task, result); + assertNotAssignedRole(userBobOid, roleRole53aOid, task, result); + + display("Task1 after operation", task1); + display("Task2 after operation", task2); + String rootTask1Oid = wfTaskUtil.getRootTaskOid(task1); + String rootTask2Oid = wfTaskUtil.getRootTaskOid(task2); + display("root task 1", getTask(rootTask1Oid)); + display("root task 2", getTask(rootTask2Oid)); + + assertNull("Exception has occurred " + listener.getException(), listener.getException()); + listener.setTasksToSuspendOnError(Arrays.asList(rootTask1Oid, rootTask2Oid)); + + approveAllWorkItems(task, result); + + waitForTaskCloseOrSuspend(rootTask1Oid, 120000, 1000); + waitForTaskCloseOrSuspend(rootTask2Oid, 120000, 1000); // THEN - PrismObject rootTask = getTask(rootTaskOid); - if (listener.getException() != null || rootTask.asObjectable().getExecutionStatus() != CLOSED) { - fail("root task has not completed; recorded exception = " + listener.getException()); + PrismObject rootTask1 = getTask(rootTask1Oid); + PrismObject rootTask2 = getTask(rootTask2Oid); + assertNull("Exception has occurred " + listener.getException(), listener.getException()); + assertEquals("Wrong root task1 status", CLOSED, rootTask1.asObjectable().getExecutionStatus()); + assertEquals("Wrong root task2 status", CLOSED, rootTask2.asObjectable().getExecutionStatus()); + + PrismObject bob = getUser(userBobOid); + assertAssignedRole(bob, roleRole50aOid); + assertAssignedRole(bob, roleRole51aOid); + assertAssignedRole(bob, roleRole52aOid); + assertAssignedRole(bob, roleRole53aOid); + } + + @Test + public void test130ParallelApprovalsInThreeSummarizingOperations() throws Exception { + final String TEST_NAME = "test130ParallelApprovalsInThreeSummarizingOperations"; + TestUtil.displayTestTitle(this, TEST_NAME); + login(userAdministrator); + + Task task = createTask(TEST_NAME); + Task task1 = createTask(TEST_NAME); + Task task2 = createTask(TEST_NAME); + Task task3 = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + if (listener != null) { + taskManager.unregisterTaskListener(listener); } + listener = new CheckingTaskListener(); + taskManager.registerTaskListener(listener); - PrismObject jack = getUser(userJackOid); - assertAssignedRole(jack, roleRole51aOid); - assertAssignedRole(jack, roleRole52aOid); - assertAssignedRole(jack, roleRole53aOid); + // WHEN + displayWhen(TEST_NAME); + // three separate approval contexts, "summarizing" as the deltas are executed after all approvals + assignRole(userChuckOid, roleRole51aOid, task1, result); + assignRole(userChuckOid, roleRole52aOid, task2, result); + assignRole(userChuckOid, roleRole53aOid, task3, result); + assertNotAssignedRole(userChuckOid, roleRole51aOid, task, result); + assertNotAssignedRole(userChuckOid, roleRole52aOid, task, result); + assertNotAssignedRole(userChuckOid, roleRole53aOid, task, result); + + display("Task1 after operation", task1); + display("Task2 after operation", task2); + display("Task3 after operation", task3); + String rootTask1Oid = wfTaskUtil.getRootTaskOid(task1); + String rootTask2Oid = wfTaskUtil.getRootTaskOid(task2); + String rootTask3Oid = wfTaskUtil.getRootTaskOid(task3); + display("root task 1", getTask(rootTask1Oid)); + display("root task 2", getTask(rootTask2Oid)); + display("root task 3", getTask(rootTask3Oid)); + + assertNull("Exception has occurred " + listener.getException(), listener.getException()); + listener.setTasksToSuspendOnError(Arrays.asList(rootTask1Oid, rootTask2Oid, rootTask3Oid)); + + approveAllWorkItems(task, result); + + waitForTaskCloseOrSuspend(rootTask1Oid, 120000, 1000); + waitForTaskCloseOrSuspend(rootTask2Oid, 120000, 1000); + waitForTaskCloseOrSuspend(rootTask3Oid, 120000, 1000); + + // THEN + + PrismObject rootTask1 = getTask(rootTask1Oid); + PrismObject rootTask2 = getTask(rootTask2Oid); + PrismObject rootTask3 = getTask(rootTask3Oid); + assertNull("Exception has occurred " + listener.getException(), listener.getException()); + assertEquals("Wrong root task1 status", CLOSED, rootTask1.asObjectable().getExecutionStatus()); + assertEquals("Wrong root task2 status", CLOSED, rootTask2.asObjectable().getExecutionStatus()); + assertEquals("Wrong root task3 status", CLOSED, rootTask3.asObjectable().getExecutionStatus()); + + PrismObject chuck = getUser(userChuckOid); + assertAssignedRole(chuck, roleRole51aOid); + assertAssignedRole(chuck, roleRole52aOid); + assertAssignedRole(chuck, roleRole53aOid); } private class CheckingTaskListener implements TaskListener { - private String rootTaskOid; + private Collection tasksToSuspendOnError; private Task executing; private RuntimeException exception; - public CheckingTaskListener(String rootTaskOid) { - this.rootTaskOid = rootTaskOid; + public CheckingTaskListener() { + this.tasksToSuspendOnError = emptySet(); + } + + public CheckingTaskListener(Collection tasksToSuspendOnError) { + this.tasksToSuspendOnError = tasksToSuspendOnError; } public RuntimeException getException() { return exception; } + public void setTasksToSuspendOnError(Collection tasksToSuspendOnError) { + this.tasksToSuspendOnError = tasksToSuspendOnError; + if (exception != null) { + suspendTasks(); + } + } + @Override public synchronized void onTaskStart(Task task) { if (!ModelOperationTaskHandler.MODEL_OPERATION_TASK_URI.equals(task.getHandlerUri())) { return; } - System.out.println("Starting " + task + ", handler uri " + task.getHandlerUri()); + System.out.println(Thread.currentThread().getName() + ": Starting " + task + ", handler uri " + task.getHandlerUri() + ", group " + task.getGroup()); if (executing != null) { exception = new IllegalStateException("Started task " + task + " but another one is already executing: " + executing); System.out.println(exception.getMessage()); - // suspend root task in order to fail faster - taskManager.suspendTasks(Collections.singleton(rootTaskOid), TaskManager.DO_NOT_WAIT, new OperationResult("dummy")); + display("newly started task", task); + display("already executing task", executing); + suspendTasks(); } executing = task; } + public void suspendTasks() { + // suspend root task in order to fail faster + taskManager.suspendTasks(tasksToSuspendOnError, TaskManager.DO_NOT_WAIT, new OperationResult("dummy")); + } + @Override public synchronized void onTaskFinish(Task task, TaskRunResult runResult) { if (!ModelOperationTaskHandler.MODEL_OPERATION_TASK_URI.equals(task.getHandlerUri())) { return; } - System.out.println("Finishing " + task + ", handler uri " + task.getHandlerUri()); + System.out.println(Thread.currentThread().getName() + ": Finishing " + task + ", handler uri " + task.getHandlerUri()); assert executing.getOid().equals(task.getOid()); executing = null; } diff --git a/model/workflow-impl/src/test/resources/policy/role-role50a-slow.xml b/model/workflow-impl/src/test/resources/policy/role-role50a-slow.xml new file mode 100644 index 00000000000..b506adcb10f --- /dev/null +++ b/model/workflow-impl/src/test/resources/policy/role-role50a-slow.xml @@ -0,0 +1,43 @@ + + + + Role50a-slow + + + + + description + + + + + + description + + + + + + diff --git a/model/workflow-impl/src/test/resources/policy/user-bob.xml b/model/workflow-impl/src/test/resources/policy/user-bob.xml new file mode 100644 index 00000000000..814b7c96950 --- /dev/null +++ b/model/workflow-impl/src/test/resources/policy/user-bob.xml @@ -0,0 +1,28 @@ + + + + bob + Bob White + Bob + White + diff --git a/model/workflow-impl/src/test/resources/policy/user-chuck.xml b/model/workflow-impl/src/test/resources/policy/user-chuck.xml new file mode 100644 index 00000000000..cce1f0c551d --- /dev/null +++ b/model/workflow-impl/src/test/resources/policy/user-chuck.xml @@ -0,0 +1,28 @@ + + + + chuck + Chuck Black + Chuck + Black + From 0b7fe521e491a07184f9c8ebfba4cf0f7918bd98 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 2 Oct 2017 10:49:33 +0200 Subject: [PATCH 83/97] Configurable wf execution tasks serialization scope. --- .../ns/public/common/common-workflows-3.xsd | 62 ++++++++++++++ .../impl/tasks/WfTaskCreationInstruction.java | 84 +++++++++++++------ .../policy/other/TestParallelApprovals.java | 7 +- 3 files changed, 124 insertions(+), 29 deletions(-) diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd index 9a5c77e35f5..a4ee3263847 100644 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-workflows-3.xsd @@ -703,6 +703,13 @@ + + + + Scope of serialization. The default is "object". If multiple scopes are defined, serialization occurs on each one. + + + @@ -720,6 +727,61 @@ + + + + Scope of execution task serialization. + + + + + + + + + + No two workflow execution tasks from a single operation are allowed to execute at once. + + + + + + + + + + No two workflow execution tasks on a given object are allowed to execute at once. + + + + + + + + + + No two workflow execution tasks related to give target are allowed to execute at once. + Note that the information on target is not always available (e.g. when executing changes + that do not require approval), so this may not be absolutely reliable. + + + + + + + + + + No two workflow execution tasks are allowed to execute at once. + + + + + + + + + diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java index 3edb8cb0e57..fd424af94d1 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java @@ -410,38 +410,74 @@ public Task createTask(WfTaskController taskController, Task parentTask, WfConfi } // serialization WfExecutionTasksSerializationType serialization = tasksConfig.getSerialization(); - if (serialization != null && !Boolean.FALSE.equals(serialization.isEnabled()) && parentTask != null) { - String groupPrefix = serialization.getGroupPrefix() != null ? - serialization.getGroupPrefix() : DEFAULT_EXECUTION_GROUP_PREFIX_FOR_SERIALIZATION; - String groupName = groupPrefix + parentTask.getTaskIdentifier(); - Duration retryAfter; - if (serialization.getRetryAfter() != null) { - if (constraints != null && constraints.getRetryAfter() != null && !constraints.getRetryAfter().equals(serialization.getRetryAfter())) { - LOGGER.warn( - "Workflow configuration: task constraints retryAfter ({}) is different from serialization retryAfter ({}) -- using the latter", - constraints.getRetryAfter(), serialization.getRetryAfter()); + if (serialization != null && !Boolean.FALSE.equals(serialization.isEnabled())) { + List scopes = new ArrayList<>(serialization.getScope()); + if (scopes.isEmpty()) { + scopes.add(WfExecutionTasksSerializationScopeType.OBJECT); + } + List groups = new ArrayList<>(scopes.size()); + for (WfExecutionTasksSerializationScopeType scope : scopes) { + String groupPrefix = serialization.getGroupPrefix() != null + ? serialization.getGroupPrefix() : DEFAULT_EXECUTION_GROUP_PREFIX_FOR_SERIALIZATION; + String groupSuffix = getGroupSuffix(scope, wfContext, parentTask, task); + if (groupSuffix == null) { + continue; } - retryAfter = serialization.getRetryAfter(); - } else if (constraints != null && constraints.getRetryAfter() != null) { - retryAfter = constraints.getRetryAfter(); - } else { - retryAfter = XmlTypeConverter.createDuration(DEFAULT_SERIALIZATION_RETRY_TIME); + groups.add(groupPrefix + scope.value() + ":" + groupSuffix); } - if (taskBean.getExecutionConstraints() == null) { - taskBean.setExecutionConstraints(new TaskExecutionConstraintsType()); + if (!groups.isEmpty()) { + Duration retryAfter; + if (serialization.getRetryAfter() != null) { + if (constraints != null && constraints.getRetryAfter() != null && !constraints.getRetryAfter() + .equals(serialization.getRetryAfter())) { + LOGGER.warn( + "Workflow configuration: task constraints retryAfter ({}) is different from serialization retryAfter ({}) -- using the latter", + constraints.getRetryAfter(), serialization.getRetryAfter()); + } + retryAfter = serialization.getRetryAfter(); + } else if (constraints != null && constraints.getRetryAfter() != null) { + retryAfter = constraints.getRetryAfter(); + } else { + retryAfter = XmlTypeConverter.createDuration(DEFAULT_SERIALIZATION_RETRY_TIME); + } + TaskExecutionConstraintsType executionConstraints = taskBean.getExecutionConstraints(); + if (executionConstraints == null) { + executionConstraints = new TaskExecutionConstraintsType(); + taskBean.setExecutionConstraints(executionConstraints); + } + for (String group : groups) { + executionConstraints + .beginSecondaryGroup() + .group(group) + .groupTaskLimit(1); + } + executionConstraints.setRetryAfter(retryAfter); + LOGGER.trace("Setting groups {} with a limit of 1 for task {}", groups, task); } - taskBean.getExecutionConstraints() - .beginSecondaryGroup() - .group(groupName) - .groupTaskLimit(1) - .end() - .retryAfter(retryAfter); - LOGGER.trace("Setting group '{}' with a limit of 1 for task {}", groupName, task); } } return task; } + private String getGroupSuffix(WfExecutionTasksSerializationScopeType scope, WfContextType wfContext, Task parentTask, Task task) { + switch (scope) { + case GLOBAL: return ""; + case OBJECT: + String oid = wfContext.getObjectRef() != null ? wfContext.getObjectRef().getOid() : null; + if (oid == null) { + LOGGER.warn("No object OID present, synchronization with the scope of {} couldn't be set up for task {}", scope, task); + return null; + } + return oid; + case TARGET: + return wfContext.getTargetRef() != null ? wfContext.getTargetRef().getOid() : null; // null can occur so let's be silent then + case OPERATION: + return parentTask != null ? parentTask.getTaskIdentifier() : null; // null can occur so let's be silent then + default: + throw new AssertionError("Unknown scope: " + scope); + } + } + // FIXME brutal hack because of objectDelta should be in wfContext when evaluating auto completion expression public void createProcessorContent() { if (processorContent != null) { diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestParallelApprovals.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestParallelApprovals.java index 73f9e52232e..0bd276162be 100644 --- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestParallelApprovals.java +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestParallelApprovals.java @@ -32,10 +32,7 @@ import com.evolveum.midpoint.test.util.TestUtil; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.wf.impl.policy.AbstractWfTestPolicy; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.WorkItemType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.Test; @@ -359,7 +356,7 @@ public synchronized void onTaskStart(Task task) { if (!ModelOperationTaskHandler.MODEL_OPERATION_TASK_URI.equals(task.getHandlerUri())) { return; } - System.out.println(Thread.currentThread().getName() + ": Starting " + task + ", handler uri " + task.getHandlerUri() + ", group " + task.getGroup()); + System.out.println(Thread.currentThread().getName() + ": Starting " + task + ", handler uri " + task.getHandlerUri() + ", groups " + task.getGroups()); if (executing != null) { exception = new IllegalStateException("Started task " + task + " but another one is already executing: " + executing); System.out.println(exception.getMessage()); From f38820f6f7292ed5576a0c8aa297d9ee2638efcc Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 2 Oct 2017 12:02:29 +0200 Subject: [PATCH 84/97] Fixing performance of associationFromLink evaluation. (cherry picked from commit 229afa2) --- ...ssociationFromLinkExpressionEvaluator.java | 86 +++++++++++-------- 1 file changed, 51 insertions(+), 35 deletions(-) diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationFromLinkExpressionEvaluator.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationFromLinkExpressionEvaluator.java index be3b7eefd8e..bf0e0d97464 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationFromLinkExpressionEvaluator.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationFromLinkExpressionEvaluator.java @@ -15,7 +15,9 @@ */ package com.evolveum.midpoint.model.common.expression.evaluator; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; import javax.xml.namespace.QName; @@ -25,17 +27,18 @@ import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; +import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterExit; import com.evolveum.midpoint.repo.common.expression.ExpressionEvaluationContext; import com.evolveum.midpoint.repo.common.expression.ExpressionEvaluator; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.ResultHandler; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.ExpressionConstants; import com.evolveum.midpoint.schema.util.ObjectResolver; -import com.evolveum.midpoint.schema.util.ShadowUtil; -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.*; 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; @@ -46,6 +49,9 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowDiscriminatorType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; +import org.apache.commons.collections4.CollectionUtils; + +import static com.evolveum.midpoint.schema.GetOperationOptions.createNoFetchCollection; /** * @author Radovan Semancik @@ -110,54 +116,64 @@ public PrismValueDeltaSetTriple> eval QName assocName = context.getMappingQName(); String resourceOid = rAssocTargetDef.getResourceOid(); Collection> options = null; - + List candidateShadowOidList = new ArrayList<>(); // Always process the first role (myself) regardless of recursion setting - gatherAssociationsFromAbstractRole(thisRole, output, resourceOid, kind, intent, assocName, options, desc, context); - + gatherCandidateShadowsFromAbstractRole(thisRole, candidateShadowOidList); if (thisRole instanceof OrgType && matchesForRecursion((OrgType)thisRole)) { - gatherAssociationsFromAbstractRoleRecurse((OrgType)thisRole, output, resourceOid, kind, intent, assocName, options, desc, - context); + gatherCandidateShadowsFromAbstractRoleRecurse((OrgType)thisRole, candidateShadowOidList, options, desc, context); } + LOGGER.trace("Candidate shadow OIDs: {}", candidateShadowOidList); + selectMatchingShadows(candidateShadowOidList, output, resourceOid, kind, intent, assocName, context); return ItemDelta.toDeltaSetTriple(output, null); } - private void gatherAssociationsFromAbstractRole(AbstractRoleType thisRole, + private void selectMatchingShadows(List candidateShadowsOidList, PrismContainer output, String resourceOid, ShadowKindType kind, - String intent, QName assocName, Collection> options, - String desc, ExpressionEvaluationContext params) throws SchemaException { - for (ObjectReferenceType linkRef: thisRole.getLinkRef()) { - ShadowType shadowType; - try { - shadowType = objectResolver.resolve(linkRef, ShadowType.class, options, desc, params.getTask(), params.getResult()); - } catch (ObjectNotFoundException e) { - // Linked shadow not found. This may happen e.g. if the account is deleted and model haven't got - // the chance to react yet. Just ignore such shadow. - LOGGER.trace("Ignoring shadow "+linkRef.getOid()+" linked in "+thisRole+" because it no longer exists"); - continue; - } - if (ShadowUtil.matches(shadowType, resourceOid, kind, intent)) { - PrismContainerValue newValue = output.createNewValue(); - ShadowAssociationType shadowAssociationType = newValue.asContainerable(); - shadowAssociationType.setName(assocName); - ObjectReferenceType shadowRef = new ObjectReferenceType(); - shadowRef.setOid(linkRef.getOid()); - shadowAssociationType.setShadowRef(shadowRef); - } + String intent, QName assocName, ExpressionEvaluationContext params) + throws SchemaException { + + S_AtomicFilterExit filter = QueryBuilder.queryFor(ShadowType.class, prismContext) + .id(candidateShadowsOidList.toArray(new String[0])) + .and().item(ShadowType.F_RESOURCE_REF).ref(resourceOid) + .and().item(ShadowType.F_KIND).eq(kind); + if (intent != null) { + filter = filter.and().item(ShadowType.F_INTENT).eq(intent); + } + ObjectQuery query = filter.build(); + + ResultHandler handler = (object, parentResult) -> { + PrismContainerValue newValue = output.createNewValue(); + ShadowAssociationType shadowAssociationType = newValue.asContainerable(); + shadowAssociationType.setName(assocName); + shadowAssociationType.setShadowRef(new ObjectReferenceType().oid(object.getOid()).type(ShadowType.COMPLEX_TYPE)); + return true; + }; + try { + objectResolver.searchIterative(ShadowType.class, query, createNoFetchCollection(), handler, params.getTask(), params.getResult()); + } catch (CommonException e) { + throw new SystemException("Couldn't search for relevant shadows: " + e.getMessage(), e); } } - private void gatherAssociationsFromAbstractRoleRecurse(OrgType thisOrg, - PrismContainer output, String resourceOid, ShadowKindType kind, - String intent, QName assocName, Collection> options, + private void gatherCandidateShadowsFromAbstractRole(AbstractRoleType thisRole, List candidateShadowsOidList) { + for (ObjectReferenceType linkRef: thisRole.getLinkRef()) { + CollectionUtils.addIgnoreNull(candidateShadowsOidList, linkRef.getOid()); + } + } + + private void gatherCandidateShadowsFromAbstractRoleRecurse(OrgType thisOrg, + List< String > candidateShadowsOidList, + Collection> options, String desc, ExpressionEvaluationContext params) throws SchemaException, ObjectNotFoundException { - gatherAssociationsFromAbstractRole(thisOrg, output, resourceOid, kind, intent, assocName, options, desc, params); + for (ObjectReferenceType parentOrgRef: thisOrg.getParentOrgRef()) { OrgType parent = objectResolver.resolve(parentOrgRef, OrgType.class, options, desc, params.getTask(), params.getResult()); if (matchesForRecursion(parent)) { - gatherAssociationsFromAbstractRoleRecurse(parent, output, resourceOid, kind, intent, assocName, options, desc, params); + gatherCandidateShadowsFromAbstractRole(parent, candidateShadowsOidList); + gatherCandidateShadowsFromAbstractRoleRecurse(parent, candidateShadowsOidList, options, desc, params); } } } From c3fc1876d9f7e5ecf00ffb118788cb37d20e5cdb Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 2 Oct 2017 12:53:40 +0200 Subject: [PATCH 85/97] A couple of trivial fixes for story tests. (cherry picked from commit db27e84) --- .../java/com/evolveum/midpoint/testing/story/TestTrafo.java | 4 ++-- .../java/com/evolveum/midpoint/testing/story/TestUnix.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestTrafo.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestTrafo.java index 75a36f08e88..bf6c1de65bd 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestTrafo.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestTrafo.java @@ -680,7 +680,7 @@ public void test150JackAssignRoleEmployee() throws Exception { dummyAuditService.assertExecutionDeltas(0,3); dummyAuditService.assertHasDelta(0,ChangeType.MODIFY, UserType.class); // primary, link (2 deltas) dummyAuditService.assertHasDelta(0,ChangeType.ADD, ShadowType.class); // AD account - dummyAuditService.assertExecutionDeltas(1,2); + dummyAuditService.assertExecutionDeltas(1,3); dummyAuditService.assertHasDelta(1,ChangeType.MODIFY, UserType.class); // link dummyAuditService.assertHasDelta(1,ChangeType.ADD, ShadowType.class); // Mail account dummyAuditService.assertExecutionDeltas(2,2); @@ -797,7 +797,7 @@ public void test160AngelicaAdd() throws Exception { dummyAuditService.assertHasDelta(0, ChangeType.ADD, UserType.class); // primary dummyAuditService.assertHasDelta(0,ChangeType.MODIFY, UserType.class); // link dummyAuditService.assertHasDelta(0,ChangeType.ADD, ShadowType.class); // AD account - dummyAuditService.assertExecutionDeltas(1, 2); + dummyAuditService.assertExecutionDeltas(1, 3); dummyAuditService.assertHasDelta(1, ChangeType.MODIFY, UserType.class); // link dummyAuditService.assertHasDelta(1,ChangeType.ADD, ShadowType.class); // Mail account dummyAuditService.assertExecutionDeltas(2, 2); diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java index 8bbff25d710..f6c9276d6b2 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java @@ -804,7 +804,7 @@ protected void assertTest132Audit() { display("Audit", dummyAuditService); dummyAuditService.assertSimpleRecordSanity(); dummyAuditService.assertRecords(2); - dummyAuditService.assertExecutionDeltas(1); + dummyAuditService.assertExecutionDeltas(2); dummyAuditService.assertHasDelta(ChangeType.MODIFY, ShadowType.class); } From 70c7fa8be18df904c1221b7933b04ad8f56738f4 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 2 Oct 2017 12:54:22 +0200 Subject: [PATCH 86/97] Added missing dependency. (cherry picked from commit 86019d9) --- model/model-common/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/model/model-common/pom.xml b/model/model-common/pom.xml index e95757dd3d5..496a34b9065 100644 --- a/model/model-common/pom.xml +++ b/model/model-common/pom.xml @@ -105,6 +105,10 @@ commons-lang commons-lang + + org.apache.commons + commons-collections4 + commons-io commons-io From 77bc73fef67f30887c7382808404cf996dfc333c Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Mon, 2 Oct 2017 11:14:33 +0200 Subject: [PATCH 87/97] Better provisioning schema error message --- .../ucf/impl/connid/ConnIdConvertor.java | 55 ++++++++++--------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnIdConvertor.java b/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnIdConvertor.java index acd418dafe4..76ab6131b3d 100644 --- a/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnIdConvertor.java +++ b/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnIdConvertor.java @@ -146,25 +146,25 @@ PrismObject convertToResourceObject(ConnectorObject co break; } } - - for (Attribute icfAttr : co.getAttributes()) { + + for (Attribute connIdAttr : co.getAttributes()) { if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Reading ICF attribute {}: {}", icfAttr.getName(), icfAttr.getValue()); + LOGGER.trace("Reading ICF attribute {}: {}", connIdAttr.getName(), connIdAttr.getValue()); } - if (icfAttr.getName().equals(Uid.NAME)) { + if (connIdAttr.getName().equals(Uid.NAME)) { // UID is handled specially (see above) continue; } - if (icfAttr.is(PredefinedAttributes.AUXILIARY_OBJECT_CLASS_NAME)) { + if (connIdAttr.is(PredefinedAttributes.AUXILIARY_OBJECT_CLASS_NAME)) { // Already processed continue; } - if (icfAttr.getName().equals(OperationalAttributes.PASSWORD_NAME)) { + if (connIdAttr.getName().equals(OperationalAttributes.PASSWORD_NAME)) { // password has to go to the credentials section - ProtectedStringType password = getSingleValue(icfAttr, ProtectedStringType.class); + ProtectedStringType password = getSingleValue(connIdAttr, ProtectedStringType.class); if (password == null) { // equals() instead of == is needed. The AttributeValueCompleteness enum may be loaded by different classloader - if (!AttributeValueCompleteness.INCOMPLETE.equals(icfAttr.getAttributeValueCompleteness())) { + if (!AttributeValueCompleteness.INCOMPLETE.equals(connIdAttr.getAttributeValueCompleteness())) { continue; } // There is no password value in the ConnId attribute. But it was indicated that @@ -178,8 +178,8 @@ PrismObject convertToResourceObject(ConnectorObject co } continue; } - if (icfAttr.getName().equals(OperationalAttributes.ENABLE_NAME)) { - Boolean enabled = getSingleValue(icfAttr, Boolean.class); + if (connIdAttr.getName().equals(OperationalAttributes.ENABLE_NAME)) { + Boolean enabled = getSingleValue(connIdAttr, Boolean.class); if (enabled == null) { continue; } @@ -195,9 +195,9 @@ PrismObject convertToResourceObject(ConnectorObject co LOGGER.trace("Converted activation administrativeStatus: {}", activationStatusType); continue; } - - if (icfAttr.getName().equals(OperationalAttributes.ENABLE_DATE_NAME)) { - Long millis = getSingleValue(icfAttr, Long.class); + + if (connIdAttr.getName().equals(OperationalAttributes.ENABLE_DATE_NAME)) { + Long millis = getSingleValue(connIdAttr, Long.class); if (millis == null) { continue; } @@ -206,8 +206,8 @@ PrismObject convertToResourceObject(ConnectorObject co continue; } - if (icfAttr.getName().equals(OperationalAttributes.DISABLE_DATE_NAME)) { - Long millis = getSingleValue(icfAttr, Long.class); + if (connIdAttr.getName().equals(OperationalAttributes.DISABLE_DATE_NAME)) { + Long millis = getSingleValue(connIdAttr, Long.class); if (millis == null) { continue; } @@ -215,9 +215,9 @@ PrismObject convertToResourceObject(ConnectorObject co activationType.setValidTo(XmlTypeConverter.createXMLGregorianCalendar(millis)); continue; } - - if (icfAttr.getName().equals(OperationalAttributes.LOCK_OUT_NAME)) { - Boolean lockOut = getSingleValue(icfAttr, Boolean.class); + + if (connIdAttr.getName().equals(OperationalAttributes.LOCK_OUT_NAME)) { + Boolean lockOut = getSingleValue(connIdAttr, Boolean.class); if (lockOut == null) { continue; } @@ -233,7 +233,7 @@ PrismObject convertToResourceObject(ConnectorObject co continue; } - QName qname = icfNameMapper.convertAttributeNameToQName(icfAttr.getName(), attributesContainerDefinition); + QName qname = icfNameMapper.convertAttributeNameToQName(connIdAttr.getName(), attributesContainerDefinition); ResourceAttributeDefinition attributeDefinition = attributesContainerDefinition.findAttributeDefinition(qname, caseIgnoreAttributeNames); if (attributeDefinition == null) { @@ -245,7 +245,8 @@ PrismObject convertToResourceObject(ConnectorObject co } } if (attributeDefinition == null) { - throw new SchemaException("Unknown attribute "+qname+" in definition of object class "+attributesContainerDefinition.getTypeName()+". Original ICF name: "+icfAttr.getName(), qname); + throw new SchemaException("Unknown attribute " + qname + " in definition of object class " + attributesContainerDefinition.getTypeName() + + ". Original ConnId name: " + connIdAttr.getName() + " in resource object identified by " + co.getName(), qname); } } @@ -258,12 +259,12 @@ PrismObject convertToResourceObject(ConnectorObject co // if true, we need to convert whole connector object to the // resource object also with the null-values attributes if (full) { - if (icfAttr.getValue() != null) { + if (connIdAttr.getValue() != null) { // Convert the values. While most values do not need // conversions, some // of them may need it (e.g. GuardedString) - for (Object icfValue : icfAttr.getValue()) { - Object value = convertValueFromIcf(icfValue, qname); + for (Object connIdValue : connIdAttr.getValue()) { + Object value = convertValueFromIcf(connIdValue, qname); resourceAttribute.add(new PrismPropertyValue<>(value)); } } @@ -274,13 +275,13 @@ PrismObject convertToResourceObject(ConnectorObject co // in this case when false, we need only the attributes with the // non-null values. } else { - if (icfAttr.getValue() != null && !icfAttr.getValue().isEmpty()) { + if (connIdAttr.getValue() != null && !connIdAttr.getValue().isEmpty()) { // Convert the values. While most values do not need // conversions, some of them may need it (e.g. GuardedString) boolean empty = true; - for (Object icfValue : icfAttr.getValue()) { - if (icfValue != null) { - Object value = convertValueFromIcf(icfValue, qname); + for (Object connIdValue : connIdAttr.getValue()) { + if (connIdValue != null) { + Object value = convertValueFromIcf(connIdValue, qname); empty = false; resourceAttribute.add(new PrismPropertyValue<>(value)); } From fc6c1e4dcd62c60a0596131bf22d6c8a416fb22a Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Mon, 2 Oct 2017 13:11:52 +0200 Subject: [PATCH 88/97] Forgotten TestNotifications --- model/model-intest/testng-integration.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/model/model-intest/testng-integration.xml b/model/model-intest/testng-integration.xml index 8b31c226ace..649851ac5b7 100644 --- a/model/model-intest/testng-integration.xml +++ b/model/model-intest/testng-integration.xml @@ -63,6 +63,7 @@ + From c6c509fb13fab69836a83652075fecaacfb899b7 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Mon, 2 Oct 2017 13:12:07 +0200 Subject: [PATCH 89/97] Tests for resource read (resource caching) --- .../schema/internals/InternalCounters.java | 2 + .../midpoint/model/intest/TestCaseIgnore.java | 75 ++++---- .../midpoint/model/intest/TestIntent.java | 32 ++-- .../intest/TestModelServiceContract.java | 5 + .../midpoint/model/intest/TestResources.java | 181 ++++++++++++------ .../provisioning/impl/ResourceManager.java | 10 +- .../TestDummyResourceAndSchemaCaching.java | 149 ++++++++++---- .../test/AbstractIntegrationTest.java | 2 + 8 files changed, 295 insertions(+), 161 deletions(-) diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/internals/InternalCounters.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/internals/InternalCounters.java index e244fff5fa2..bc76a5c25fa 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/internals/InternalCounters.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/internals/InternalCounters.java @@ -23,6 +23,8 @@ public enum InternalCounters { RESOURCE_SCHEMA_PARSE_COUNT("resourceSchemaParseCount", "resource schema parse count", InternalOperationClasses.RESOURCE_SCHEMA_OPERATIONS), RESOURCE_SCHEMA_FETCH_COUNT("resourceSchemaFetchCount", "resource schema fetch count", InternalOperationClasses.REPOSITORY_OPERATIONS), + + RESOURCE_REPOSITORY_READ_COUNT("resourceRepositoryReadCount", "resource repository read count", null), CONNECTOR_INSTANCE_INITIALIZATION_COUNT("connectorInstanceInitializationCount", "connector instance initialization count", InternalOperationClasses.CONNECTOR_OPERATIONS), diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestCaseIgnore.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestCaseIgnore.java index 3dc3c7124d3..9770a349081 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestCaseIgnore.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestCaseIgnore.java @@ -111,7 +111,7 @@ public void initSystem(Task initTask, OperationResult initResult) @Test public void test000Sanity() throws Exception { final String TEST_NAME="test000Sanity"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); assertShadows(5); } @@ -119,7 +119,7 @@ public void test000Sanity() throws Exception { @Test public void test131ModifyUserJackAssignAccount() throws Exception { final String TEST_NAME="test131ModifyUserJackAssignAccount"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestCaseIgnore.class.getName() + "." + TEST_NAME); @@ -132,7 +132,7 @@ public void test131ModifyUserJackAssignAccount() throws Exception { XMLGregorianCalendar startTime = clock.currentTimeXMLGregorianCalendar(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(deltas, null, task, result); // THEN @@ -174,7 +174,7 @@ public void test131ModifyUserJackAssignAccount() throws Exception { @Test public void test133SeachAccountShadows() throws Exception { final String TEST_NAME="test133SeachAccountShadows"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestCaseIgnore.class.getName() + "." + TEST_NAME); @@ -186,7 +186,7 @@ public void test133SeachAccountShadows() throws Exception { rememberCounter(InternalCounters.SHADOW_FETCH_OPERATION_COUNT); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); SearchResultList> foundShadows = modelService.searchObjects(ShadowType.class, query, null, task, result); // THEN @@ -228,7 +228,7 @@ public void test133SeachAccountShadows() throws Exception { @Test public void test139ModifyUserJackUnassignAccount() throws Exception { final String TEST_NAME = "test139ModifyUserJackUnassignAccount"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestCaseIgnore.class.getName() + "." + TEST_NAME); @@ -268,7 +268,7 @@ public void test139ModifyUserJackUnassignAccount() throws Exception { @Test public void test150JackAssignRoleX() throws Exception { final String TEST_NAME = "test150JackAssignRoleX"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); @@ -280,7 +280,7 @@ public void test150JackAssignRoleX() throws Exception { assignRole(USER_JACK_OID, ROLE_X_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -315,7 +315,7 @@ public void test150JackAssignRoleX() throws Exception { @Test public void test152GetJack() throws Exception { final String TEST_NAME = "test152GetJack"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); @@ -324,7 +324,7 @@ public void test152GetJack() throws Exception { PrismObject userJack = modelService.getObject(UserType.class, USER_JACK_OID, null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -357,7 +357,7 @@ public void test152GetJack() throws Exception { @Test public void test159JackUnAssignRoleX() throws Exception { final String TEST_NAME = "test159JackUnAssignRoleX"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); @@ -369,7 +369,7 @@ public void test159JackUnAssignRoleX() throws Exception { unassignRole(USER_JACK_OID, ROLE_X_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -389,7 +389,7 @@ public void test159JackUnAssignRoleX() throws Exception { @Test public void test160JackAssignRoleBasic() throws Exception { final String TEST_NAME = "test160JackAssignRoleBasic"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); @@ -398,11 +398,11 @@ public void test160JackAssignRoleBasic() throws Exception { display("User jack before", userBefore); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignRole(USER_JACK_OID, ROLE_UPCASE_BASIC_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -438,7 +438,7 @@ public void test160JackAssignRoleBasic() throws Exception { @Test public void test161JackAssignRoleJoker() throws Exception { final String TEST_NAME = "test161JackAssignRoleJoker"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); @@ -447,11 +447,11 @@ public void test161JackAssignRoleJoker() throws Exception { display("User jack before", userBefore); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignRole(USER_JACK_OID, ROLE_JOKER_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -491,7 +491,7 @@ public void test161JackAssignRoleJoker() throws Exception { @Test public void test165JackUnAssignRoleJoker() throws Exception { final String TEST_NAME = "test165JackUnAssignRoleJoker"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); @@ -500,11 +500,11 @@ public void test165JackUnAssignRoleJoker() throws Exception { display("User jack before", userBefore); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); unassignRole(USER_JACK_OID, ROLE_JOKER_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -540,7 +540,7 @@ public void test165JackUnAssignRoleJoker() throws Exception { @Test public void test169JackUnAssignRoleBasic() throws Exception { final String TEST_NAME = "test169JackUnAssignRoleBasic"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); @@ -549,11 +549,11 @@ public void test169JackUnAssignRoleBasic() throws Exception { display("User jack before", userBefore); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); unassignRole(USER_JACK_OID, ROLE_UPCASE_BASIC_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); result.computeStatus(); TestUtil.assertSuccess(result); @@ -575,7 +575,7 @@ public void test169JackUnAssignRoleBasic() throws Exception { @Test public void test170JackAssignRoleJoker() throws Exception { final String TEST_NAME = "test170JackAssignRoleJoker"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); @@ -584,13 +584,12 @@ public void test170JackAssignRoleJoker() throws Exception { display("User jack before", userBefore); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignRole(USER_JACK_OID, ROLE_JOKER_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); // Make sure this is repository so we do not destroy the "evidence" yet. PrismObject userJack = repositoryService.getObject(UserType.class, USER_JACK_OID, null, result); @@ -624,7 +623,7 @@ public void test170JackAssignRoleJoker() throws Exception { @Test public void test179JackUnAssignRoleJoker() throws Exception { final String TEST_NAME = "test179JackUnAssignRoleJoker"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); @@ -633,13 +632,12 @@ public void test179JackUnAssignRoleJoker() throws Exception { display("User jack before", userBefore); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); unassignRole(USER_JACK_OID, ROLE_JOKER_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); // Make sure this is repository so we do not destroy the "evidence" yet. PrismObject userJack = repositoryService.getObject(UserType.class, USER_JACK_OID, null, result); @@ -668,7 +666,7 @@ public void test179JackUnAssignRoleJoker() throws Exception { @Test public void test200GuybrushAssignRoleFools() throws Exception { final String TEST_NAME = "test200GuybrushAssignRoleFools"; - TestUtil.displayTestTitle(this, TEST_NAME); + displayTestTitle(TEST_NAME); Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); @@ -689,13 +687,12 @@ public void test200GuybrushAssignRoleFools() throws Exception { assertShadows(4); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); assignRole(USER_GUYBRUSH_OID, ROLE_FOOL_OID, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); assertShadows(6); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIntent.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIntent.java index 64cf9f33acd..f4bb40f8842 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIntent.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIntent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum + * Copyright (c) 2010-2017 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,8 +15,6 @@ */ package com.evolveum.midpoint.model.intest; -import static com.evolveum.midpoint.test.IntegrationTestTools.display; - import java.io.File; import java.util.ArrayList; import java.util.Collection; @@ -82,13 +80,12 @@ public void test131ModifyUserJackAssignAccountDefault() throws Exception { XMLGregorianCalendar startTime = clock.currentTimeXMLGregorianCalendar(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(deltas, null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess("executeChanges result", result); + displayThen(TEST_NAME); + assertSuccess(result); XMLGregorianCalendar endTime = clock.currentTimeXMLGregorianCalendar(); assertCounterIncrement(InternalCounters.SHADOW_FETCH_OPERATION_COUNT, 0); @@ -143,13 +140,12 @@ public void test132ModifyUserJackAssignAccountTest() throws Exception { XMLGregorianCalendar startTime = clock.currentTimeXMLGregorianCalendar(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(deltas, null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess("executeChanges result", result); + displayThen(TEST_NAME); + assertSuccess(result); XMLGregorianCalendar endTime = clock.currentTimeXMLGregorianCalendar(); assertCounterIncrement(InternalCounters.SHADOW_FETCH_OPERATION_COUNT, 1); @@ -210,13 +206,12 @@ public void test135ModifyUserJackFullName() throws Exception { preTestCleanup(AssignmentPolicyEnforcementType.RELATIVE); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modifyUserReplace(USER_JACK_OID, UserType.F_FULL_NAME, task, result, PrismTestUtil.createPolyString("cpt. Jack Sparrow")); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess("executeChanges result", result); + displayThen(TEST_NAME); + assertSuccess(result); assertCounterIncrement(InternalCounters.SHADOW_FETCH_OPERATION_COUNT, 2); PrismObject userJack = getUser(USER_JACK_OID); @@ -280,13 +275,12 @@ public void test147ModifyUserJackUnAssignAccountDefault() throws Exception { XMLGregorianCalendar startTime = clock.currentTimeXMLGregorianCalendar(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.executeChanges(deltas, null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess("executeChanges result", result); + displayThen(TEST_NAME); + assertSuccess(result); XMLGregorianCalendar endTime = clock.currentTimeXMLGregorianCalendar(); assertCounterIncrement(InternalCounters.SHADOW_FETCH_OPERATION_COUNT, 1); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContract.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContract.java index 798190b5eae..a23f4c2b840 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContract.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContract.java @@ -1574,7 +1574,10 @@ public void test148ModifyUserJackUnassignAccountPositiveEnforcement() throws Exc // the previous command changes resource, therefore let's explicitly re-read it before test // to refresh the cache and not affect the performance results (monitor). modelService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, null, task, result); + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 1); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 1); + + assertSteadyResources(); // WHEN displayWhen(TEST_NAME); @@ -1634,7 +1637,9 @@ public void test148ModifyUserJackUnassignAccountPositiveEnforcement() throws Exc // the previous command changes resource, therefore let's explicitly re-read it before test // to refresh the cache and not affect the performance results (monitor). modelService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, null, task, result); + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 1); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 1); + assertSteadyResources(); } /** diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestResources.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestResources.java index d502dd69d25..74429514022 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestResources.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestResources.java @@ -16,7 +16,6 @@ package com.evolveum.midpoint.model.intest; import static org.testng.AssertJUnit.assertNull; -import static com.evolveum.midpoint.test.IntegrationTestTools.display; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertNotNull; @@ -163,6 +162,7 @@ public void test050GetResourceRaw() throws Exception { preTestCleanup(AssignmentPolicyEnforcementType.POSITIVE); // precondition + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); @@ -173,13 +173,12 @@ public void test050GetResourceRaw() throws Exception { Collection> options = SelectorOptions.createCollection(GetOperationOptions.createRaw()); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); PrismObject resource = modelService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, options , task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess("getObject result", result); + displayThen(TEST_NAME); + assertSuccess(result); display("Resource", resource); @@ -189,6 +188,7 @@ public void test050GetResourceRaw() throws Exception { assertNull("Schema sneaked in", ResourceTypeUtil.getResourceXsdSchema(resource)); + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); @@ -210,6 +210,7 @@ public void test052GetResourceNoFetch() throws Exception { preTestCleanup(AssignmentPolicyEnforcementType.POSITIVE); // precondition + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); @@ -221,14 +222,13 @@ public void test052GetResourceNoFetch() throws Exception { GetOperationOptions.createNoFetch()); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); PrismObject resource = modelService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, options, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess("getObject result", result); + displayThen(TEST_NAME); + assertSuccess(result); display("Resource", resource); @@ -238,6 +238,59 @@ public void test052GetResourceNoFetch() throws Exception { assertNull("Schema sneaked in", ResourceTypeUtil.getResourceXsdSchema(resource)); + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 1); // First "real" read + assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); + assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 0); + assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); + assertCounterIncrement(InternalCounters.CONNECTOR_INSTANCE_INITIALIZATION_COUNT, 0); + assertCounterIncrement(InternalCounters.CONNECTOR_SCHEMA_PARSE_COUNT, 0); + } + + /** + * Make sure that resource caching works well even if noFetch is used. + */ + @Test + public void test053GetResourceNoFetchAgain() throws Exception { + final String TEST_NAME = "test053GetResourceNoFetchAgain"; + displayTestTitle(TEST_NAME); + + // GIVEN + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + preTestCleanup(AssignmentPolicyEnforcementType.POSITIVE); + + // precondition + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 0); + assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); + assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 0); + assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); + assertCounterIncrement(InternalCounters.CONNECTOR_INSTANCE_INITIALIZATION_COUNT, 0); + assertCounterIncrement(InternalCounters.CONNECTOR_SCHEMA_PARSE_COUNT, 0); + rememberCounter(InternalCounters.PRISM_OBJECT_CLONE_COUNT); + + Collection> options = SelectorOptions.createCollection( + GetOperationOptions.createNoFetch()); + + // WHEN + displayWhen(TEST_NAME); + PrismObject resource = modelService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, options, + task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + display("Resource", resource); + + assertCounterIncrement(InternalCounters.PRISM_OBJECT_CLONE_COUNT, 1); + + assertResourceDummy(resource, false); + + assertNull("Schema sneaked in", ResourceTypeUtil.getResourceXsdSchema(resource)); + + // Previous noFetch read did NOT place resource in the cache. Because the resource + // may not be complete. + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 1); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); @@ -249,8 +302,8 @@ public void test052GetResourceNoFetch() throws Exception { * MID-3424 */ @Test - public void test053GetResourceNoFetchReadOnly() throws Exception { - final String TEST_NAME = "test053GetResourceNoFetchReadOnly"; + public void test055GetResourceNoFetchReadOnly() throws Exception { + final String TEST_NAME = "test055GetResourceNoFetchReadOnly"; displayTestTitle(TEST_NAME); // GIVEN @@ -259,6 +312,7 @@ public void test053GetResourceNoFetchReadOnly() throws Exception { preTestCleanup(AssignmentPolicyEnforcementType.POSITIVE); // precondition + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); @@ -271,14 +325,13 @@ public void test053GetResourceNoFetchReadOnly() throws Exception { Collection> options = SelectorOptions.createCollection(option); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); PrismObject resource = modelService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, options, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess("getObject result", result); + displayThen(TEST_NAME); + assertSuccess(result); display("Resource", resource); @@ -288,6 +341,9 @@ public void test053GetResourceNoFetchReadOnly() throws Exception { assertNull("Schema sneaked in", ResourceTypeUtil.getResourceXsdSchema(resource)); + // Previous noFetch read did NOT place resource in the cache. Because the resource + // may not be complete. + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 1); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); @@ -315,17 +371,16 @@ public void test100SearchResourcesNoFetch() throws Exception { Collection> options = SelectorOptions.createCollection(GetOperationOptions.createNoFetch()); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); List> resources = modelService.searchObjects(ResourceType.class, null, options, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); assertNotNull("null search return", resources); assertFalse("Empty search return", resources.isEmpty()); assertEquals("Unexpected number of resources found", 2, resources.size()); - result.computeStatus(); - TestUtil.assertSuccess("searchObjects result", result); + assertSuccess(result); assertCounterIncrement(InternalCounters.PRISM_OBJECT_CLONE_COUNT, 2); @@ -333,6 +388,8 @@ public void test100SearchResourcesNoFetch() throws Exception { assertResource(resource, false); } + // No explicit get. Search is doing all the work. + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); @@ -364,17 +421,16 @@ public void test102SearchResourcesNoFetchReadOnly() throws Exception { Collection> options = SelectorOptions.createCollection(option); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); List> resources = modelService.searchObjects(ResourceType.class, null, options, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); assertNotNull("null search return", resources); assertFalse("Empty search return", resources.isEmpty()); assertEquals("Unexpected number of resources found", 2, resources.size()); - result.computeStatus(); - TestUtil.assertSuccess("searchObjects result", result); + assertSuccess(result); assertCounterIncrement(InternalCounters.PRISM_OBJECT_CLONE_COUNT, 0); @@ -382,6 +438,8 @@ public void test102SearchResourcesNoFetchReadOnly() throws Exception { assertResource(resource, false); } + // No explicit get. Search is doing all the work. + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); @@ -419,19 +477,20 @@ public void test105SearchResourcesIterativeNoFetch() throws Exception { Collection> options = SelectorOptions.createCollection(GetOperationOptions.createNoFetch()); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.searchObjectsIterative(ResourceType.class, null, handler, options, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess("searchObjects result", result); + displayThen(TEST_NAME); + assertSuccess(result); assertFalse("Empty search return", resources.isEmpty()); assertEquals("Unexpected number of resources found", 2, resources.size()); assertCounterIncrement(InternalCounters.PRISM_OBJECT_CLONE_COUNT, 2); + // No explicit get. Search is doing all the work. + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); @@ -471,19 +530,20 @@ public void test107SearchResourcesIterativeNoFetchReadOnly() throws Exception { Collection> options = SelectorOptions.createCollection(option); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelService.searchObjectsIterative(ResourceType.class, null, handler, options, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess("searchObjects result", result); + displayThen(TEST_NAME); + assertSuccess(result); assertFalse("Empty search return", resources.isEmpty()); assertEquals("Unexpected number of resources found", 2, resources.size()); assertCounterIncrement(InternalCounters.PRISM_OBJECT_CLONE_COUNT, 2); + // No explicit get. Search is doing all the work. + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); @@ -506,18 +566,21 @@ public void test110GetResourceDummy() throws Exception { rememberCounter(InternalCounters.PRISM_OBJECT_CLONE_COUNT); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); PrismObject resource = modelService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, null , task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess("getObject result", result); + displayThen(TEST_NAME); + assertSuccess(result); assertCounterIncrement(InternalCounters.PRISM_OBJECT_CLONE_COUNT, 4); assertResourceDummy(resource, true); + // TODO not sure why are there 2 read counts. Should be 1. But this is not that important right now. + // Some overhead on initial resource read is OK. What is important is that it does not increase during + // normal account operations. + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 2); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 1); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 1); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 1); @@ -545,19 +608,19 @@ public void test112GetResourceDummyReadOnly() throws Exception { GetOperationOptions.createReadOnly()); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); PrismObject resource = modelService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, options , task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess("getObject result", result); + displayThen(TEST_NAME); + assertSuccess(result); assertCounterIncrement(InternalCounters.PRISM_OBJECT_CLONE_COUNT, 1); assertResourceDummy(resource, true); + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); @@ -582,22 +645,23 @@ public void test120SearchResources() throws Exception { assertSteadyResources(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); List> resources = modelService.searchObjects(ResourceType.class, null, null, task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); assertNotNull("null search return", resources); assertFalse("Empty search return", resources.isEmpty()); assertEquals("Unexpected number of resources found", 2, resources.size()); - result.computeStatus(); - TestUtil.assertSuccess("searchObjects result", result); + assertSuccess(result); for (PrismObject resource: resources) { assertResource(resource, true); } + // Obviously, there is some uninitialized resource in the system + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 1); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 1); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 1); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 1); @@ -630,8 +694,7 @@ public void test125SearchResourcesIterative() throws Exception { modelService.searchObjectsIterative(ResourceType.class, null, handler, null, task, result); // THEN - result.computeStatus(); - TestUtil.assertSuccess("searchObjects result", result); + assertSuccess(result); assertFalse("Empty search return", resources.isEmpty()); assertEquals("Unexpected number of resources found", 2, resources.size()); @@ -747,8 +810,7 @@ public void test200GetResourceRawAfterSchema() throws Exception { lastVersion = resource.getVersion(); display("Initial version", lastVersion); - result.computeStatus(); - TestUtil.assertSuccess("getObject result", result); + assertSuccess(result); IntegrationTestTools.displayXml("Initialized dummy resource", resource); } @@ -769,11 +831,11 @@ public void test210GetResourceDummyRed() throws Exception { rememberCounter(InternalCounters.PRISM_OBJECT_CLONE_COUNT); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); PrismObject resource = modelService.getObject(ResourceType.class, RESOURCE_DUMMY_RED_OID, null , task, result); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); assertSuccess(result); assertCounterIncrement(InternalCounters.PRISM_OBJECT_CLONE_COUNT, 1); @@ -812,13 +874,12 @@ public void test750GetResourceRaw() throws Exception { Collection> options = SelectorOptions.createCollection(GetOperationOptions.createRaw()); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); PrismObject resource = modelService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, options , task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess("getObject result", result); + displayThen(TEST_NAME); + assertSuccess(result); display("Resource", resource); IntegrationTestTools.displayXml("Initialized dummy resource", resource); @@ -847,13 +908,12 @@ public void test752GetResourceDummy() throws Exception { rememberCounter(InternalCounters.PRISM_OBJECT_CLONE_COUNT); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); PrismObject resource = modelService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, null , task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); assertCounterIncrement(InternalCounters.PRISM_OBJECT_CLONE_COUNT, 1); @@ -1044,13 +1104,12 @@ public void test800GetResourceDummy() throws Exception { rememberCounter(InternalCounters.PRISM_OBJECT_CLONE_COUNT); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); PrismObject resource = modelService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, null , task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); + displayThen(TEST_NAME); + assertSuccess(result); assertCounterIncrement(InternalCounters.PRISM_OBJECT_CLONE_COUNT, 1); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceManager.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceManager.java index c9e4dbea9b9..1186e2494b8 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceManager.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceManager.java @@ -164,11 +164,15 @@ public PrismObject getResource(String oid, GetOperationOptions opt if (GetOperationOptions.isReadOnly(options)) { repoOptions = SelectorOptions.createCollection(GetOperationOptions.createReadOnly()); } - PrismObject repositoryObject = repositoryService.getObject(ResourceType.class, oid, repoOptions, parentResult); + PrismObject repositoryObject = readResourceFromRepository(oid, repoOptions, parentResult); return loadAndCacheResource(repositoryObject, options, task, parentResult); } - + + private PrismObject readResourceFromRepository(String oid, Collection> repoOptions, OperationResult parentResult) throws ObjectNotFoundException, SchemaException { + InternalMonitor.recordCount(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT); + return repositoryService.getObject(ResourceType.class, oid, repoOptions, parentResult); + } private PrismObject loadAndCacheResource(PrismObject repositoryObject, GetOperationOptions options, Task task, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, ExpressionEvaluationException { @@ -292,7 +296,7 @@ private PrismObject completeResource(PrismObject rep // Now we need to re-read the resource from the repository and re-aply the schemas. This ensures that we will // cache the correct version and that we avoid race conditions, etc. - newResource = repositoryService.getObject(ResourceType.class, repoResource.getOid(), null, result); + newResource = readResourceFromRepository(repoResource.getOid(), null, result); applyConnectorSchemaToResource(newResource, task, result); } catch (SchemaException e) { diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyResourceAndSchemaCaching.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyResourceAndSchemaCaching.java index 7946b5f1997..7fe051f3bc0 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyResourceAndSchemaCaching.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyResourceAndSchemaCaching.java @@ -19,8 +19,6 @@ */ package com.evolveum.midpoint.provisioning.impl.dummy; -import static com.evolveum.midpoint.test.IntegrationTestTools.display; - import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -40,6 +38,8 @@ import com.evolveum.midpoint.prism.delta.PropertyDelta; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.util.PrismTestUtil; +import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.internals.InternalCounters; import com.evolveum.midpoint.schema.internals.InternalMonitor; @@ -79,39 +79,45 @@ public class TestDummyResourceAndSchemaCaching extends AbstractDummyTest { @Test public void test010GetResource() throws Exception { final String TEST_NAME = "test010GetResource"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN OperationResult result = new OperationResult(TestDummyResourceAndSchemaCaching.class.getName() + "." + TEST_NAME); + // Check that there is no schema before test (pre-condition) + PrismObject resourceBefore = repositoryService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, null, result); + ResourceType resourceTypeBefore = resourceBefore.asObjectable(); + Element resourceXsdSchemaElementBefore = ResourceTypeUtil.getResourceXsdSchema(resourceTypeBefore); + AssertJUnit.assertNull("Found schema before test connection. Bad test setup?", resourceXsdSchemaElementBefore); + + assertVersion(resourceBefore, "0"); + // Some connector initialization and other things might happen in previous tests. // The monitor is static, not part of spring context, it will not be cleared rememberCounter(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT); + rememberCounter(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT); rememberCounter(InternalCounters.CONNECTOR_SCHEMA_PARSE_COUNT); rememberCounter(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT); rememberCounter(InternalCounters.CONNECTOR_INSTANCE_INITIALIZATION_COUNT); rememberCounter(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT); rememberResourceCacheStats(); - // Check that there is no schema before test (pre-condition) - PrismObject resourceBefore = repositoryService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, null, result); - ResourceType resourceTypeBefore = resourceBefore.asObjectable(); - Element resourceXsdSchemaElementBefore = ResourceTypeUtil.getResourceXsdSchema(resourceTypeBefore); - AssertJUnit.assertNull("Found schema before test connection. Bad test setup?", resourceXsdSchemaElementBefore); - - assertVersion(resourceBefore, "0"); - // WHEN + displayWhen(TEST_NAME); PrismObject resourceProvisioning = provisioningService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, null, null, result); // THEN + displayThen(TEST_NAME); display("Resource", resource); - result.computeStatus(); - TestUtil.assertSuccess(result); + assertSuccess(result); assertHasSchema(resourceProvisioning, "provisioning resource"); rememberSchemaMetadata(resourceProvisioning); + // TODO not sure why are there 2 read counts. Should be 1. But this is not that important right now. + // Some overhead on initial resource read is OK. What is important is that it does not increase during + // normal account operations. + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 2); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 1); assertCounterIncrement(InternalCounters.CONNECTOR_SCHEMA_PARSE_COUNT, 1); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 1); @@ -142,7 +148,7 @@ public void test010GetResource() throws Exception { @Test public void test011GetResourceAgain() throws Exception { final String TEST_NAME = "test011GetResourceAgain"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN OperationResult result = new OperationResult(TestDummyResourceAndSchemaCaching.class.getName() + "." + TEST_NAME); @@ -152,12 +158,12 @@ public void test011GetResourceAgain() throws Exception { // THEN display("Resource(1)", resource); - result.computeStatus(); - TestUtil.assertSuccess(result); + assertSuccess(result); assertHasSchema(resourceProvisioning, "provisioning resource(1)"); assertSchemaMetadataUnchanged(resourceProvisioning); + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); @@ -181,8 +187,7 @@ public void test011GetResourceAgain() throws Exception { // THEN display("Resource(2)", resource); - result.computeStatus(); - TestUtil.assertSuccess(result); + assertSuccess(result); assertHasSchema(resourceProvisioning, "provisioning resource(2)"); assertSchemaMetadataUnchanged(resourceProvisioning); @@ -212,7 +217,7 @@ public void test011GetResourceAgain() throws Exception { @Test public void test012AddAccountGetResource() throws Exception { final String TEST_NAME = "test012AddAccountGetResource"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN OperationResult result = new OperationResult(TestDummyResourceAndSchemaCaching.class.getName() + "." + TEST_NAME); @@ -227,12 +232,12 @@ public void test012AddAccountGetResource() throws Exception { PrismObject resourceProvisioning = provisioningService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, null, null, result); display("Resource(2)", resource); - result.computeStatus(); - TestUtil.assertSuccess(result); + assertSuccess(result); assertHasSchema(resourceProvisioning, "provisioning resource(2)"); assertSchemaMetadataUnchanged(resourceProvisioning); + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); @@ -251,6 +256,73 @@ public void test012AddAccountGetResource() throws Exception { assertConnectorInstanceUnchanged(resourceProvisioning); } + + @Test + public void test013GetResourceNoFetch() throws Exception { + final String TEST_NAME = "test013GetResourceNoFetch"; + displayTestTitle(TEST_NAME); + // GIVEN + OperationResult result = new OperationResult(TestDummyResourceAndSchemaCaching.class.getName() + + "." + TEST_NAME); + + Collection> options = GetOperationOptions.createNoFetchCollection(); + + // WHEN + PrismObject resourceProvisioning = provisioningService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, options, null, result); + + // THEN + display("Resource(1)", resource); + assertSuccess(result); + + assertHasSchema(resourceProvisioning, "provisioning resource(1)"); + assertSchemaMetadataUnchanged(resourceProvisioning); + + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 0); + assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); + assertCounterIncrement(InternalCounters.CONNECTOR_SCHEMA_PARSE_COUNT, 0); + assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); + assertCounterIncrement(InternalCounters.CONNECTOR_INSTANCE_INITIALIZATION_COUNT, 0); + assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 0); + + assertResourceVersionIncrement(resourceProvisioning, 0); + + display("Resource cache (1)", InternalMonitor.getResourceCacheStats()); + assertResourceCacheHitsIncrement(1); + assertResourceCacheMissesIncrement(0); + + assertResourceSchemaUnchanged(RefinedResourceSchemaImpl.getResourceSchema(resourceProvisioning, prismContext)); + assertRefinedResourceSchemaUnchanged(RefinedResourceSchemaImpl.getRefinedSchema(resourceProvisioning)); + assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 0); + + assertConnectorInstanceUnchanged(resourceProvisioning); + + // WHEN + resourceProvisioning = provisioningService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, options, null, result); + + // THEN + display("Resource(2)", resource); + assertSuccess(result); + + assertHasSchema(resourceProvisioning, "provisioning resource(2)"); + assertSchemaMetadataUnchanged(resourceProvisioning); + + assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); + assertCounterIncrement(InternalCounters.CONNECTOR_SCHEMA_PARSE_COUNT, 0); + assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); + assertCounterIncrement(InternalCounters.CONNECTOR_INSTANCE_INITIALIZATION_COUNT, 0); + + assertResourceVersionIncrement(resourceProvisioning, 0); + + display("Resource cache (1)", InternalMonitor.getResourceCacheStats()); + assertResourceCacheHitsIncrement(1); + assertResourceCacheMissesIncrement(0); + + assertResourceSchemaUnchanged(RefinedResourceSchemaImpl.getResourceSchema(resourceProvisioning, prismContext)); + assertRefinedResourceSchemaUnchanged(RefinedResourceSchemaImpl.getRefinedSchema(resourceProvisioning)); + assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 0); + + assertConnectorInstanceUnchanged(resourceProvisioning); + } /** @@ -260,7 +332,7 @@ public void test012AddAccountGetResource() throws Exception { @Test public void test020ModifyAndGetResource() throws Exception { final String TEST_NAME = "test020ModifyAndGetResource"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestDummyResourceAndSchemaCaching.class.getName() + "." + TEST_NAME); @@ -277,8 +349,7 @@ public void test020ModifyAndGetResource() throws Exception { provisioningService.modifyObject(ResourceType.class, RESOURCE_DUMMY_OID, objectDelta.getModifications(), null, null, task, result); // THEN - result.computeStatus(); - TestUtil.assertSuccess(result); + assertSuccess(result); String versionAfter = repositoryService.getVersion(ResourceType.class, RESOURCE_DUMMY_OID, result); assertResourceVersionIncrement(versionAfter, 1); @@ -288,12 +359,12 @@ public void test020ModifyAndGetResource() throws Exception { // THEN display("Resource", resource); - result.computeStatus(); - TestUtil.assertSuccess(result); + assertSuccess(result); assertHasSchema(resourceProvisioning, "provisioning resource"); assertSchemaMetadataUnchanged(resourceProvisioning); + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 1); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); @@ -321,7 +392,7 @@ public void test020ModifyAndGetResource() throws Exception { @Test public void test022GetAccountGetResource() throws Exception { final String TEST_NAME = "test012AddAccountGetResource"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN OperationResult result = new OperationResult(TestDummyResourceAndSchemaCaching.class.getName() + "." + TEST_NAME); @@ -342,6 +413,7 @@ public void test022GetAccountGetResource() throws Exception { assertHasSchema(resourceProvisioning, "provisioning resource(2)"); assertSchemaMetadataUnchanged(resourceProvisioning); + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); @@ -371,7 +443,7 @@ public void test022GetAccountGetResource() throws Exception { @Test public void test023ModifyRepoAndGetResource() throws Exception { final String TEST_NAME = "test023ModifyRepoAndGetResource"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestDummyResourceAndSchemaCaching.class.getName() + "." + TEST_NAME); @@ -388,8 +460,7 @@ public void test023ModifyRepoAndGetResource() throws Exception { repositoryService.modifyObject(ResourceType.class, RESOURCE_DUMMY_OID, objectDelta.getModifications(), result); // THEN - result.computeStatus(); - TestUtil.assertSuccess(result); + assertSuccess(result); String versionAfter = repositoryService.getVersion(ResourceType.class, RESOURCE_DUMMY_OID, result); assertResourceVersionIncrement(versionAfter, 1); @@ -399,12 +470,12 @@ public void test023ModifyRepoAndGetResource() throws Exception { // THEN display("Resource", resource); - result.computeStatus(); - TestUtil.assertSuccess(result); + assertSuccess(result); assertHasSchema(resourceProvisioning, "provisioning resource"); assertSchemaMetadataUnchanged(resourceProvisioning); + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 1); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); @@ -432,7 +503,7 @@ public void test023ModifyRepoAndGetResource() throws Exception { @Test public void test030ModifyConnectorConfigAndGetResource() throws Exception { final String TEST_NAME = "test030ModifyConnectorConfigAndGetResource"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestDummyResourceAndSchemaCaching.class.getName() + "." + TEST_NAME); @@ -448,8 +519,7 @@ public void test030ModifyConnectorConfigAndGetResource() throws Exception { provisioningService.modifyObject(ResourceType.class, RESOURCE_DUMMY_OID, modifications, null, null, task, result); // THEN - result.computeStatus(); - TestUtil.assertSuccess(result); + assertSuccess(result); assertConnectorConfigChanged(); } @@ -464,7 +534,7 @@ public void test030ModifyConnectorConfigAndGetResource() throws Exception { @Test public void test031ModifyConnectorConfigRepoAndGetResource() throws Exception { final String TEST_NAME = "test031ModifyConnectorConfigRepoAndGetResource"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestDummyResourceAndSchemaCaching.class.getName() + "." + TEST_NAME); @@ -489,7 +559,7 @@ public void test031ModifyConnectorConfigRepoAndGetResource() throws Exception { @Test public void test900DeleteResource() throws Exception { final String TEST_NAME = "test900DeleteResource"; - TestUtil.displayTestTitle(TEST_NAME); + displayTestTitle(TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestDummyResourceAndSchemaCaching.class.getName() + "." + TEST_NAME); @@ -541,12 +611,12 @@ private void assertConnectorConfigChanged() throws ObjectNotFoundException, Sche // THEN display("Resource", resource); - result.computeStatus(); - TestUtil.assertSuccess(result); + assertSuccess(result); assertHasSchema(resourceProvisioning, "provisioning resource"); assertSchemaMetadataUnchanged(resourceProvisioning); + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 1); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); @@ -572,6 +642,7 @@ private void assertConnectorConfigChanged() throws ObjectNotFoundException, Sche assertResourceCacheHitsIncrement(1); assertResourceCacheMissesIncrement(0); + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java index 7625b1dff50..a905b2fa6b7 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java @@ -971,6 +971,7 @@ protected void assertCacheMisses(CachingStatistics lastStats, CachingStatistics } protected void assertSteadyResources() { + assertCounterIncrement(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT, 0); assertCounterIncrement(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT, 0); assertCounterIncrement(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT, 0); @@ -979,6 +980,7 @@ protected void assertSteadyResources() { } protected void rememberSteadyResources() { + rememberCounter(InternalCounters.RESOURCE_REPOSITORY_READ_COUNT); rememberCounter(InternalCounters.RESOURCE_SCHEMA_FETCH_COUNT); rememberCounter(InternalCounters.RESOURCE_SCHEMA_PARSE_COUNT); rememberCounter(InternalCounters.CONNECTOR_CAPABILITIES_FETCH_COUNT); From a45d25e905762654810aa45bf5fff963ae166c53 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Mon, 2 Oct 2017 13:28:37 +0200 Subject: [PATCH 90/97] Steady resource asserts --- .../midpoint/model/intest/TestEntitlements.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestEntitlements.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestEntitlements.java index 76e97315d4c..42a49c9f536 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestEntitlements.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestEntitlements.java @@ -124,6 +124,8 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti importObjectFromFile(ROLE_CREW_OF_GUYBRUSH_FILE); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); + + rememberSteadyResources(); } /** @@ -136,6 +138,8 @@ public void test100AddGroupShadowSwashbucklers() throws Exception { Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); + + assertSteadyResources(); PrismObject group = prismContext.parseObject(SHADOW_GROUP_DUMMY_SWASHBUCKLERS_FILE); @@ -150,6 +154,8 @@ public void test100AddGroupShadowSwashbucklers() throws Exception { display("Group", dummyGroup); assertEquals("Wrong group description", GROUP_DUMMY_SWASHBUCKLERS_DESCRIPTION, dummyGroup.getAttributeValue(DummyResourceContoller.DUMMY_GROUP_ATTRIBUTE_DESCRIPTION)); + + assertSteadyResources(); } @Test @@ -374,6 +380,8 @@ public void test300AddRoleWimp() throws Exception { assertNotNull("No group on orange dummy resource", dummyGroupAtOrange); display("Group @orange", dummyGroupAtOrange); assertNoGroupMembers(dummyGroupAtOrange); + + assertSteadyResources(); } @Test @@ -1006,6 +1014,8 @@ public void test359UnassignOrangeAccountFromGuybrushAndRapp() throws Exception { assertNoDummyAccount(RESOURCE_DUMMY_ORANGE_NAME, ACCOUNT_GUYBRUSH_DUMMY_USERNAME); assertNoDummyAccount(RESOURCE_DUMMY_ORANGE_NAME, USER_RAPP_USERNAME); + + assertSteadyResources(); } @Test @@ -1354,6 +1364,8 @@ public void test700ReconcileGuybrush() throws Exception { // THEN dumpUserAndAccounts(getUser(USER_GUYBRUSH_OID), task, result); assertNoGroupMember(getDummyGroup(null, GROUP_DUMMY_SWASHBUCKLERS_NAME), USER_GUYBRUSH_USERNAME); + + assertSteadyResources(); } /** @@ -1485,6 +1497,8 @@ public void test800AssignRoleSwashbucklerToJackNone() throws Exception { assertAssignments(userAfter, 1); assertNoDummyAccount(ACCOUNT_JACK_DUMMY_USERNAME); + + assertSteadyResources(); } /** @@ -2082,6 +2096,8 @@ public void test899UnAssignAccountJackDummy() throws Exception { assertAssignments(userAfter, 0); assertJackNoAccountNoSwashbuckler(); + + assertSteadyResources(); } private void assertJackClean() throws SchemaViolationException, ConflictException, ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException { From b1b759b562377c6075c0912c7c1496e88a5a80b5 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 2 Oct 2017 14:17:29 +0200 Subject: [PATCH 91/97] Fixed notifications for (seemingly) empty containers. --- model/model-intest/testng-integration.xml | 1 + .../impl/formatters/TextFormatter.java | 96 +++++++++---------- 2 files changed, 45 insertions(+), 52 deletions(-) diff --git a/model/model-intest/testng-integration.xml b/model/model-intest/testng-integration.xml index 8b31c226ace..649851ac5b7 100644 --- a/model/model-intest/testng-integration.xml +++ b/model/model-intest/testng-integration.xml @@ -63,6 +63,7 @@ + diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/formatters/TextFormatter.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/formatters/TextFormatter.java index 09a6f8b2826..1648fc35056 100644 --- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/formatters/TextFormatter.java +++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/formatters/TextFormatter.java @@ -68,6 +68,7 @@ public class TextFormatter { private static final Trace LOGGER = TraceManager.getTrace(TextFormatter.class); + @SuppressWarnings("unused") public String formatObjectModificationDelta(ObjectDelta objectDelta, List hiddenPaths, boolean showOperationalAttributes) { return formatObjectModificationDelta(objectDelta, hiddenPaths, showOperationalAttributes, null, null); } @@ -166,7 +167,7 @@ private void formatItemDeltaContent(StringBuilder sb, ItemDelta itemDelta, List< private void formatItemDeltaValues(StringBuilder sb, String type, Collection values, boolean mightBeRemoved, List hiddenPaths, boolean showOperationalAttributes) { if (values != null) { for (PrismValue prismValue : values) { - sb.append(" - " + type + ": "); + sb.append(" - ").append(type).append(": "); String prefix = " "; formatPrismValue(sb, prefix, prismValue, mightBeRemoved, hiddenPaths, showOperationalAttributes); if (!(prismValue instanceof PrismContainerValue)) { // container values already end with newline @@ -254,15 +255,19 @@ private void formatContainerValue(StringBuilder sb, String prefix, PrismContaine private void formatPrismContainer(StringBuilder sb, String prefix, Item item, boolean mightBeRemoved, List hiddenPaths, boolean showOperationalAttributes) { for (PrismContainerValue subContainerValue : ((PrismContainer) item).getValues()) { - sb.append(prefix); - sb.append(" - "); - sb.append(getItemLabel(item)); - if (subContainerValue.getId() != null) { - sb.append(" #").append(subContainerValue.getId()); - } - sb.append(":\n"); String prefixSubContainer = prefix + " "; - formatContainerValue(sb, prefixSubContainer, subContainerValue, mightBeRemoved, hiddenPaths, showOperationalAttributes); + StringBuilder valueSb = new StringBuilder(); + formatContainerValue(valueSb, prefixSubContainer, subContainerValue, mightBeRemoved, hiddenPaths, showOperationalAttributes); + if (valueSb.length() > 0) { + sb.append(prefix); + sb.append(" - "); + sb.append(getItemLabel(item)); + if (subContainerValue.getId() != null) { + sb.append(" #").append(subContainerValue.getId()); + } + sb.append(":\n"); + sb.append(valueSb.toString()); + } } } @@ -274,7 +279,7 @@ private void formatPrismReference(StringBuilder sb, String prefix, Item item, bo if (item.size() > 1) { for (PrismReferenceValue referenceValue : ((PrismReference) item).getValues()) { sb.append("\n"); - sb.append(prefix + " - "); + sb.append(prefix).append(" - "); sb.append(formatReferenceValue(referenceValue, mightBeRemoved)); } } else if (item.size() == 1) { @@ -289,13 +294,13 @@ private void formatPrismProperty(StringBuilder sb, String prefix, Item item) { sb.append(getItemLabel(item)); sb.append(": "); if (item.size() > 1) { - for (PrismPropertyValue propertyValue : ((PrismProperty) item).getValues()) { + for (PrismPropertyValue propertyValue : ((PrismProperty) item).getValues()) { sb.append("\n"); - sb.append(prefix + " - "); + sb.append(prefix).append(" - "); sb.append(ValueDisplayUtil.toStringValue(propertyValue)); } } else if (item.size() == 1) { - sb.append(ValueDisplayUtil.toStringValue(((PrismProperty) item).getValue(0))); + sb.append(ValueDisplayUtil.toStringValue(((PrismProperty) item).getValue(0))); } sb.append("\n"); } @@ -354,6 +359,7 @@ private PrismObject getPrismObject(String oid, boolean mig if (!mightBeRemoved) { LoggingUtils.logException(LOGGER, "Couldn't resolve reference when displaying object name within a notification (it might be already removed)", e); } else { + // ok, accepted } } catch (SchemaException e) { LoggingUtils.logException(LOGGER, "Couldn't resolve reference when displaying object name within a notification", e); @@ -361,14 +367,6 @@ private PrismObject getPrismObject(String oid, boolean mig return null; } - private String localPartOfType(Item item) { - if (item.getDefinition() != null) { - return localPart(item.getDefinition().getTypeName()); - } else { - return null; - } - } - private String localPart(QName qname) { return qname == null ? null : qname.getLocalPart(); } @@ -441,7 +439,7 @@ private ItemPath getPathToExplain(ItemDelta itemDelta) { } private List filterAndOrderItemDeltas(ObjectDelta objectDelta, List hiddenPaths, boolean showOperationalAttributes) { - List toBeDisplayed = new ArrayList(objectDelta.getModifications().size()); + List toBeDisplayed = new ArrayList<>(objectDelta.getModifications().size()); List noDefinition = new ArrayList<>(); for (ItemDelta itemDelta: objectDelta.getModifications()) { if (itemDelta.getDefinition() != null) { @@ -457,20 +455,17 @@ private List filterAndOrderItemDeltas(ObjectDelta() { - @Override - public int compare(ItemDelta delta1, ItemDelta delta2) { - Integer order1 = delta1.getDefinition().getDisplayOrder(); - Integer order2 = delta2.getDefinition().getDisplayOrder(); - if (order1 != null && order2 != null) { - return order1 - order2; - } else if (order1 == null && order2 == null) { - return 0; - } else if (order1 == null) { - return 1; - } else { - return -1; - } + toBeDisplayed.sort((delta1, delta2) -> { + Integer order1 = delta1.getDefinition().getDisplayOrder(); + Integer order2 = delta2.getDefinition().getDisplayOrder(); + if (order1 != null && order2 != null) { + return order1 - order2; + } else if (order1 == null && order2 == null) { + return 0; + } else if (order1 == null) { + return 1; + } else { + return -1; } }); return toBeDisplayed; @@ -486,12 +481,12 @@ private List filterAndOrderItems(List items, List hiddenPa if (items == null) { return new ArrayList<>(); } - List toBeDisplayed = new ArrayList(items.size()); + List toBeDisplayed = new ArrayList<>(items.size()); List noDefinition = new ArrayList<>(); for (Item item : items) { if (item.getDefinition() != null) { boolean isHidden = NotificationFunctionsImpl.isAmongHiddenPaths(item.getPath(), hiddenPaths); - if (!isHidden && (showOperationalAttributes || !item.getDefinition().isOperational())) { + if (!isHidden && (showOperationalAttributes || !item.getDefinition().isOperational()) && !item.isEmpty()) { toBeDisplayed.add(item); } } else { @@ -502,20 +497,17 @@ private List filterAndOrderItems(List items, List hiddenPa LOGGER.error("Items {} without definition - THEY WILL NOT BE INCLUDED IN NOTIFICATION.\nAll items:\n{}", noDefinition, DebugUtil.debugDump(items)); } - Collections.sort(toBeDisplayed, new Comparator() { - @Override - public int compare(Item item1, Item item2) { - Integer order1 = item1.getDefinition().getDisplayOrder(); - Integer order2 = item2.getDefinition().getDisplayOrder(); - if (order1 != null && order2 != null) { - return order1 - order2; - } else if (order1 == null && order2 == null) { - return 0; - } else if (order1 == null) { - return 1; - } else { - return -1; - } + toBeDisplayed.sort((item1, item2) -> { + Integer order1 = item1.getDefinition().getDisplayOrder(); + Integer order2 = item2.getDefinition().getDisplayOrder(); + if (order1 != null && order2 != null) { + return order1 - order2; + } else if (order1 == null && order2 == null) { + return 0; + } else if (order1 == null) { + return 1; + } else { + return -1; } }); return toBeDisplayed; From 399b64f0d264e92b9aeeb3979b7a8e1e2c74281d Mon Sep 17 00:00:00 2001 From: Andrew Cope Date: Fri, 29 Sep 2017 16:50:57 -0400 Subject: [PATCH 92/97] Temporarily disable failing test --- .../midpoint/provisioning/impl/dummy/TestDummyParallelism.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyParallelism.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyParallelism.java index 034b4856297..ae76d027e3a 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyParallelism.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyParallelism.java @@ -371,7 +371,7 @@ public void test212ParallelModifyElizabethSlow() throws Exception { * is finished. But the threads are fast and the operations are slow. So this is * a very slim chance. */ - @Test + @Test(enabled = false) public void test214ParallelModifyDisableSlow() throws Exception { final String TEST_NAME = "test214ParallelModifyDisableSlow"; From b32f299d60dfdd3c36e3b922bc1405862528b8ef Mon Sep 17 00:00:00 2001 From: Andrew Cope Date: Fri, 29 Sep 2017 16:50:40 -0400 Subject: [PATCH 93/97] Fixes build issues --- dist/pom.xml | 2 +- model/model-test/pom.xml | 4 ++++ model/report-impl/pom.xml | 5 +++++ provisioning/provisioning-impl/pom.xml | 5 ++++- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/dist/pom.xml b/dist/pom.xml index 6fae1713377..aca59e787a1 100644 --- a/dist/pom.xml +++ b/dist/pom.xml @@ -117,7 +117,7 @@ src/main/assembly/dist.xml - midpoint-${version} + midpoint-${project.version} diff --git a/model/model-test/pom.xml b/model/model-test/pom.xml index 3e8a3cb97e7..b6c368a3867 100644 --- a/model/model-test/pom.xml +++ b/model/model-test/pom.xml @@ -185,6 +185,10 @@ org.jetbrains annotations-java5 + + com.h2database + h2 + com.evolveum.midpoint.provisioning diff --git a/model/report-impl/pom.xml b/model/report-impl/pom.xml index 8e8454dd744..d1e0a7a2407 100644 --- a/model/report-impl/pom.xml +++ b/model/report-impl/pom.xml @@ -103,6 +103,11 @@ model-impl 3.7-SNAPSHOT + + com.evolveum.midpoint.model + workflow-api + 3.6.1-SNAPSHOT + org.jetbrains diff --git a/provisioning/provisioning-impl/pom.xml b/provisioning/provisioning-impl/pom.xml index 57501f10f12..8199e1fe53d 100644 --- a/provisioning/provisioning-impl/pom.xml +++ b/provisioning/provisioning-impl/pom.xml @@ -99,7 +99,10 @@ repo-common 3.7-SNAPSHOT - + + net.tirasa.connid + connector-framework + commons-lang commons-lang From 1f77cf5020e3b8aeb8b910352baf8cc83540ecd1 Mon Sep 17 00:00:00 2001 From: Andrew Cope Date: Thu, 28 Sep 2017 12:13:30 -0400 Subject: [PATCH 94/97] Fixes a few maven issues --- build-system/pom.xml | 2 +- infra/ws-util/pom.xml | 4 ++++ repo/task-quartz-impl/pom.xml | 4 ++++ tools/repo-ninja/pom.xml | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/build-system/pom.xml b/build-system/pom.xml index 7f927f4ab37..577f77e18f8 100644 --- a/build-system/pom.xml +++ b/build-system/pom.xml @@ -1491,7 +1491,7 @@ org.apache.maven.plugins maven-dependency-plugin - 2.10 + 3.0.2 analyze diff --git a/infra/ws-util/pom.xml b/infra/ws-util/pom.xml index 2788e3623bc..e14330634e6 100644 --- a/infra/ws-util/pom.xml +++ b/infra/ws-util/pom.xml @@ -61,6 +61,10 @@ org.apache.wss4j wss4j-ws-security-common + + org.apache.wss4j + wss4j-ws-security-dom + diff --git a/repo/task-quartz-impl/pom.xml b/repo/task-quartz-impl/pom.xml index 886d8b72360..82364003aa7 100644 --- a/repo/task-quartz-impl/pom.xml +++ b/repo/task-quartz-impl/pom.xml @@ -105,6 +105,10 @@ org.jetbrains annotations-java5 + + org.hibernate + hibernate-core + com.evolveum.midpoint.repo diff --git a/tools/repo-ninja/pom.xml b/tools/repo-ninja/pom.xml index 9403ada1b96..8ceb8a6e07a 100644 --- a/tools/repo-ninja/pom.xml +++ b/tools/repo-ninja/pom.xml @@ -157,7 +157,7 @@ copy-dependencies - package + prepare-package copy-dependencies From e52b4b6a179cd8fd479e999e9cc6905c45127f98 Mon Sep 17 00:00:00 2001 From: Andrew Cope Date: Wed, 27 Sep 2017 22:04:51 -0400 Subject: [PATCH 95/97] Adds support for in queries --- .../midpoint/prism/query/ObjectGrouping.java | 73 +++++++++ .../midpoint/prism/query/ObjectPaging.java | 141 +++++++++++++++++- .../midpoint/prism/query/PagingConvertor.java | 15 +- .../prism/query/builder/R_AtomicFilter.java | 10 ++ .../prism/query/builder/R_Filter.java | 50 +++++-- .../prism/query/builder/S_FilterExit.java | 2 + .../xml/ns/_public/query_3/PagingType.java | 62 +++++++- .../main/resources/xml/ns/public/query-3.xsd | 11 ++ .../repo/sql/query2/QueryInterpreter2.java | 53 ++++++- .../repo/sql/query2/hqm/HibernateQuery.java | 42 ++++++ 10 files changed, 438 insertions(+), 21 deletions(-) create mode 100644 infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectGrouping.java diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectGrouping.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectGrouping.java new file mode 100644 index 00000000000..6db729e2d58 --- /dev/null +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectGrouping.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2010-2017 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.prism.query; + +import com.evolveum.midpoint.prism.path.ItemPath; + +import java.io.Serializable; + +/** + * @author acope + */ +public class ObjectGrouping implements Serializable { + + final private ItemPath groupBy; + + ObjectGrouping(ItemPath groupBy) { + if (ItemPath.isNullOrEmpty(groupBy)) { + throw new IllegalArgumentException("Null or empty groupBy path is not supported."); + } + this.groupBy = groupBy; + } + + public static ObjectGrouping createGrouping(ItemPath groupBy) { + return new ObjectGrouping(groupBy); + } + + public ItemPath getGroupBy() { + return groupBy; + } + + + @Override + public String toString() { + return groupBy.toString(); + } + + @Override + public boolean equals(Object o) { + return equals(o, true); + } + + public boolean equals(Object o, boolean exact) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + ObjectGrouping that = (ObjectGrouping) o; + + if (groupBy != null ? !groupBy.equals(that.groupBy, exact) : that.groupBy != null) + return false; + return true; + } + + @Override + public int hashCode() { + return groupBy.hashCode(); + } +} diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectPaging.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectPaging.java index d189bdffa87..abd14154b16 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectPaging.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/ObjectPaging.java @@ -33,6 +33,8 @@ public class ObjectPaging implements DebugDumpable, Serializable { private Integer offset; private Integer maxSize; @NotNull private final List ordering = new ArrayList<>(); + private List grouping = new ArrayList<>(); + private String cookie; protected ObjectPaging() { @@ -43,15 +45,38 @@ protected ObjectPaging() { this.maxSize = maxSize; } + ObjectPaging(Integer offset, Integer maxSize, ItemPath groupBy) { + this.offset = offset; + this.maxSize = maxSize; + setGrouping(groupBy); + } + ObjectPaging(ItemPath orderBy, OrderDirection direction) { setOrdering(orderBy, direction); } - ObjectPaging(Integer offset, Integer maxSize, ItemPath orderBy, OrderDirection direction) { + ObjectPaging(ItemPath orderBy, OrderDirection direction, ItemPath groupBy) { + setOrdering(orderBy, direction); + setGrouping(groupBy); + } + + ObjectPaging(Integer offset, Integer maxSize, ItemPath orderBy, OrderDirection direction) { this.offset = offset; this.maxSize = maxSize; setOrdering(orderBy, direction); } + + ObjectPaging(Integer offset, Integer maxSize, ItemPath orderBy, OrderDirection direction, ItemPath groupBy) { + this.offset = offset; + this.maxSize = maxSize; + setOrdering(orderBy, direction); + + setGrouping(groupBy); + } + + ObjectPaging(ItemPath groupBy) { + setGrouping(groupBy); + } public static ObjectPaging createPaging(Integer offset, Integer maxSize){ return new ObjectPaging(offset, maxSize); @@ -64,13 +89,28 @@ public static ObjectPaging createPaging(Integer offset, Integer maxSize, QName o public static ObjectPaging createPaging(Integer offset, Integer maxSize, ItemPath orderBy, OrderDirection direction) { return new ObjectPaging(offset, maxSize, orderBy, direction); } - - public static ObjectPaging createPaging(Integer offset, Integer maxSize, List orderings) { + + public static ObjectPaging createPaging(Integer offset, Integer maxSize, ItemPath groupBy) { + return new ObjectPaging(offset, maxSize, groupBy); + } + + public static ObjectPaging createPaging(Integer offset, Integer maxSize, ItemPath orderBy, OrderDirection direction, ItemPath groupBy) { + return new ObjectPaging(offset, maxSize, orderBy, direction, groupBy); + } + + public static ObjectPaging createPaging(Integer offset, Integer maxSize, List orderings) { + ObjectPaging paging = new ObjectPaging(offset, maxSize); + paging.setOrdering(orderings); + return paging; + } + + public static ObjectPaging createPaging(Integer offset, Integer maxSize, List orderings, List groupings) { ObjectPaging paging = new ObjectPaging(offset, maxSize); paging.setOrdering(orderings); + paging.setGrouping(groupings); return paging; } - + public static ObjectPaging createPaging(ItemPath orderBy, OrderDirection direction) { return new ObjectPaging(orderBy, direction); } @@ -78,6 +118,22 @@ public static ObjectPaging createPaging(ItemPath orderBy, OrderDirection directi public static ObjectPaging createPaging(QName orderBy, OrderDirection direction) { return new ObjectPaging(new ItemPath(orderBy), direction); } + + public static ObjectPaging createPaging(ItemPath orderBy, OrderDirection direction, ItemPath groupBy) { + return new ObjectPaging(orderBy, direction, groupBy); + } + + public static ObjectPaging createPaging(QName orderBy, OrderDirection direction, QName groupBy) { + return new ObjectPaging(new ItemPath(orderBy), direction, new ItemPath(groupBy)); + } + + public static ObjectPaging createPaging(ItemPath groupBy) { + return new ObjectPaging(groupBy); + } + + public static ObjectPaging createPaging(QName groupBy) { + return new ObjectPaging(new ItemPath(groupBy)); + } public static ObjectPaging createEmptyPaging(){ return new ObjectPaging(); @@ -103,11 +159,28 @@ public ObjectOrdering getPrimaryOrdering() { } } + public ItemPath getGroupBy(){ + ObjectGrouping primary = getPrimaryGrouping(); + return primary != null ? primary.getGroupBy() : null; + } + + public ObjectGrouping getPrimaryGrouping() { + if (hasGrouping()) { + return grouping.get(0); + } else { + return null; + } + } + // TODO name? public List getOrderingInstructions() { return ordering; } + public List getGroupingInstructions() { + return grouping; + } + public boolean hasOrdering() { return !ordering.isEmpty(); } @@ -117,6 +190,15 @@ public void setOrdering(ItemPath orderBy, OrderDirection direction) { addOrderingInstruction(orderBy, direction); } + public boolean hasGrouping() { + return !grouping.isEmpty(); + } + + public void setGrouping(ItemPath groupBy) { + this.grouping.clear(); + addGroupingInstruction(groupBy); + } + public void addOrderingInstruction(ItemPath orderBy, OrderDirection direction) { this.ordering.add(new ObjectOrdering(orderBy, direction)); } @@ -140,6 +222,29 @@ public void setOrdering(Collection orderings) { } } + + public void addGroupingInstruction(ItemPath groupBy) { + this.grouping.add(new ObjectGrouping(groupBy)); + } + + public void addGroupingInstruction(QName groupBy) { + addGroupingInstruction(new ItemPath(groupBy)); + } + + public void setGrouping(ObjectGrouping... groupings) { + this.grouping.clear(); + if (groupings != null) { + this.grouping.addAll(Arrays.asList(groupings)); + } + } + + public void setGrouping(Collection groupings) { + this.grouping.clear(); + if (groupings != null) { + this.grouping.addAll(groupings); + } + } + public Integer getOffset() { return offset; } @@ -197,6 +302,13 @@ protected void copyTo(ObjectPaging clone) { clone.maxSize = this.maxSize; clone.ordering.clear(); clone.ordering.addAll(this.ordering); + + if (this.grouping != null) { + clone.grouping = new ArrayList<>(this.grouping); + } else { + clone.grouping = null; + } + clone.cookie = this.cookie; } @@ -224,6 +336,11 @@ public String debugDump(int indent) { DebugUtil.indentDebugDump(sb, indent + 1); sb.append("Ordering: ").append(ordering); } + if (hasGrouping()) { + sb.append("\n"); + DebugUtil.indentDebugDump(sb, indent + 1); + sb.append("Grouping: ").append(grouping); + } if (getCookie() != null) { sb.append("\n"); DebugUtil.indentDebugDump(sb, indent + 1); @@ -251,6 +368,11 @@ public String toString() { sb.append(ordering); sb.append(", "); } + if (hasGrouping()) { + sb.append("GRP: "); + sb.append(grouping); + sb.append(", "); + } if (getCookie() != null) { sb.append("C:"); sb.append(getCookie()); @@ -287,6 +409,16 @@ public boolean equals(Object o, boolean exact) { return false; } } + if (grouping.size() != that.grouping.size()) { + return false; + } + for (int i = 0; i < grouping.size(); i++) { + ObjectGrouping og1 = this.grouping.get(i); + ObjectGrouping og2 = that.grouping.get(i); + if (!og1.equals(og2, exact)) { + return false; + } + } return cookie != null ? cookie.equals(that.cookie) : that.cookie == null; } @@ -295,6 +427,7 @@ public int hashCode() { int result = offset != null ? offset.hashCode() : 0; result = 31 * result + (maxSize != null ? maxSize.hashCode() : 0); result = 31 * result + ordering.hashCode(); + result = 31 * result + (grouping != null ? grouping.hashCode() : 0); result = 31 * result + (cookie != null ? cookie.hashCode() : 0); return result; } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/PagingConvertor.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/PagingConvertor.java index f7f9bdaaff7..e5d647c90d4 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/PagingConvertor.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/PagingConvertor.java @@ -28,10 +28,19 @@ public static ObjectPaging createObjectPaging(PagingType pagingType){ if (pagingType == null) { return null; } + if (pagingType.getOrderBy() != null && pagingType.getGroupBy() != null) { + return ObjectPaging.createPaging(pagingType.getOffset(), pagingType.getMaxSize(), + pagingType.getOrderBy().getItemPath(), toOrderDirection(pagingType.getOrderDirection()), pagingType.getGroupBy().getItemPath()); + } + if (pagingType.getOrderBy() != null) { return ObjectPaging.createPaging(pagingType.getOffset(), pagingType.getMaxSize(), pagingType.getOrderBy().getItemPath(), toOrderDirection(pagingType.getOrderDirection())); - } else { + + } if (pagingType.getGroupBy() != null) { + return ObjectPaging.createPaging(pagingType.getGroupBy().getItemPath()); + + } else { return ObjectPaging.createPaging(pagingType.getOffset(), pagingType.getMaxSize()); } } @@ -62,7 +71,9 @@ public static PagingType createPagingType(ObjectPaging paging){ if (paging.getOrderBy() != null) { pagingType.setOrderBy(new ItemPathType(paging.getOrderBy())); } - + if (paging.getGroupBy() != null) { + pagingType.setGroupBy(new ItemPathType(paging.getGroupBy())); + } return pagingType; } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/R_AtomicFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/R_AtomicFilter.java index 97bb7de31ce..af188a920bf 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/R_AtomicFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/R_AtomicFilter.java @@ -345,6 +345,16 @@ public S_FilterExit desc(ItemPath path) { return finish().desc(path); } + @Override + public S_FilterExit group(QName... names) { + return finish().group(names); + } + + @Override + public S_FilterExit group(ItemPath path) { + return finish().group(path); + } + @Override public S_FilterExit offset(Integer n) { return finish().offset(n); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/R_Filter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/R_Filter.java index a6ed8635331..2f9e15107de 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/R_Filter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/R_Filter.java @@ -41,6 +41,7 @@ public class R_Filter implements S_FilterEntryOrEmpty, S_AtomicFilterExit { final private QName typeRestriction; final private ItemPath existsRestriction; final private List orderingList; + final private List groupingList; final private Integer offset; final private Integer maxSize; @@ -54,12 +55,13 @@ public R_Filter(QueryBuilder queryBuilder) { this.typeRestriction = null; this.existsRestriction = null; this.orderingList = new ArrayList<>(); + this.groupingList = new ArrayList<>(); this.offset = null; this.maxSize = null; } private R_Filter(QueryBuilder queryBuilder, Class currentClass, OrFilter currentFilter, LogicalSymbol lastLogicalSymbol, - boolean isNegated, R_Filter parentFilter, QName typeRestriction, ItemPath existsRestriction, List orderingList, Integer offset, Integer maxSize) { + boolean isNegated, R_Filter parentFilter, QName typeRestriction, ItemPath existsRestriction, List orderingList, List groupingList, Integer offset, Integer maxSize) { this.queryBuilder = queryBuilder; this.currentClass = currentClass; this.currentFilter = currentFilter; @@ -73,6 +75,11 @@ private R_Filter(QueryBuilder queryBuilder, Class curre } else { this.orderingList = new ArrayList<>(); } + if (groupingList != null) { + this.groupingList = groupingList; + } else { + this.groupingList = new ArrayList<>(); + } this.offset = offset; this.maxSize = maxSize; } @@ -112,7 +119,7 @@ R_Filter addSubfilter(ObjectFilter subfilter) { subfilter)); } else { OrFilter newFilter = appendAtomicFilter(subfilter, isNegated, lastLogicalSymbol); - return new R_Filter(queryBuilder, currentClass, newFilter, null, false, parentFilter, typeRestriction, existsRestriction, orderingList, offset, maxSize); + return new R_Filter(queryBuilder, currentClass, newFilter, null, false, parentFilter, typeRestriction, existsRestriction, orderingList, groupingList, offset, maxSize); } } @@ -135,29 +142,36 @@ private R_Filter setLastLogicalSymbol(LogicalSymbol newLogicalSymbol) { if (this.lastLogicalSymbol != null) { throw new IllegalStateException("Two logical symbols in a sequence"); } - return new R_Filter(queryBuilder, currentClass, currentFilter, newLogicalSymbol, isNegated, parentFilter, typeRestriction, existsRestriction, orderingList, offset, maxSize); + return new R_Filter(queryBuilder, currentClass, currentFilter, newLogicalSymbol, isNegated, parentFilter, typeRestriction, existsRestriction, orderingList, groupingList, offset, maxSize); } private R_Filter setNegated() { if (isNegated) { throw new IllegalStateException("Double negation"); } - return new R_Filter(queryBuilder, currentClass, currentFilter, lastLogicalSymbol, true, parentFilter, typeRestriction, existsRestriction, orderingList, offset, maxSize); + return new R_Filter(queryBuilder, currentClass, currentFilter, lastLogicalSymbol, true, parentFilter, typeRestriction, existsRestriction, orderingList, groupingList, offset, maxSize); } private R_Filter addOrdering(ObjectOrdering ordering) { Validate.notNull(ordering); List newList = new ArrayList<>(orderingList); newList.add(ordering); - return new R_Filter(queryBuilder, currentClass, currentFilter, lastLogicalSymbol, isNegated, parentFilter, typeRestriction, existsRestriction, newList, offset, maxSize); + return new R_Filter(queryBuilder, currentClass, currentFilter, lastLogicalSymbol, isNegated, parentFilter, typeRestriction, existsRestriction, newList, groupingList, offset, maxSize); + } + + private R_Filter addGrouping(ObjectGrouping grouping) { + Validate.notNull(grouping); + List newList = new ArrayList<>(groupingList); + newList.add(grouping); + return new R_Filter(queryBuilder, currentClass, currentFilter, lastLogicalSymbol, isNegated, parentFilter, typeRestriction, existsRestriction, orderingList, newList, offset, maxSize); } private R_Filter setOffset(Integer n) { - return new R_Filter(queryBuilder, currentClass, currentFilter, lastLogicalSymbol, isNegated, parentFilter, typeRestriction, existsRestriction, orderingList, n, maxSize); + return new R_Filter(queryBuilder, currentClass, currentFilter, lastLogicalSymbol, isNegated, parentFilter, typeRestriction, existsRestriction, orderingList, groupingList, n, maxSize); } private R_Filter setMaxSize(Integer n) { - return new R_Filter(queryBuilder, currentClass, currentFilter, lastLogicalSymbol, isNegated, parentFilter, typeRestriction, existsRestriction, orderingList, offset, n); + return new R_Filter(queryBuilder, currentClass, currentFilter, lastLogicalSymbol, isNegated, parentFilter, typeRestriction, existsRestriction, orderingList, groupingList, offset, n); } @Override @@ -265,7 +279,7 @@ public S_AtomicFilterExit fullText(String... words) { @Override public S_FilterEntryOrEmpty block() { - return new R_Filter(queryBuilder, currentClass, OrFilter.createOr(), null, false, this, null, null, null, null, null); + return new R_Filter(queryBuilder, currentClass, OrFilter.createOr(), null, false, this, null, null, null, null, null, null); } @Override @@ -278,7 +292,7 @@ public S_FilterEntryOrEmpty type(Class type) { if (typeName == null) { throw new IllegalStateException("No type name for " + ctd); } - return new R_Filter(queryBuilder, type, OrFilter.createOr(), null, false, this, typeName, null, null, null, null); + return new R_Filter(queryBuilder, type, OrFilter.createOr(), null, false, this, typeName, null, null, null, null, null); } @Override @@ -295,7 +309,7 @@ public S_FilterEntryOrEmpty exists(QName... names) { if (clazz == null) { throw new IllegalArgumentException("Item path of '" + existsPath + "' in " + currentClass + " does not point to a valid prism container."); } - return new R_Filter(queryBuilder, clazz, OrFilter.createOr(), null, false, this, null, existsPath, null, null, null); + return new R_Filter(queryBuilder, clazz, OrFilter.createOr(), null, false, this, null, existsPath, null, null,null, null); } ID resolveItemPath(ItemPath itemPath, Class type) { @@ -419,6 +433,22 @@ public S_FilterExit desc(ItemPath path) { return addOrdering(ObjectOrdering.createOrdering(path, OrderDirection.DESCENDING)); } + @Override + public S_FilterExit group(QName... names) { + if (names.length == 0) { + throw new IllegalArgumentException("There must be at least one name for uniq(...) grouping"); + } + return addGrouping(ObjectGrouping.createGrouping(new ItemPath(names))); + } + + @Override + public S_FilterExit group(ItemPath path) { + if (ItemPath.isNullOrEmpty(path)) { + throw new IllegalArgumentException("There must be non-empty path for uniq(...) grouping"); + } + return addGrouping(ObjectGrouping.createGrouping(path)); + } + @Override public S_FilterExit offset(Integer n) { return setOffset(n); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/S_FilterExit.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/S_FilterExit.java index 00edf4b9690..0bb2e077c8b 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/S_FilterExit.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/S_FilterExit.java @@ -30,6 +30,8 @@ public interface S_FilterExit extends S_QueryExit { S_FilterExit asc(ItemPath path); S_FilterExit desc(QName... names); S_FilterExit desc(ItemPath path); + S_FilterExit group(QName... names); + S_FilterExit group(ItemPath path); S_FilterExit offset(Integer n); S_FilterExit maxSize(Integer n); } diff --git a/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/query_3/PagingType.java b/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/query_3/PagingType.java index 08cc9d665c2..621c9d97c0a 100644 --- a/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/query_3/PagingType.java +++ b/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/query_3/PagingType.java @@ -37,6 +37,7 @@ *

The following schema fragment specifies the expected content contained within this class. * *

+<<<<<<< HEAD
  * <complexType name="PagingType">
  *   <complexContent>
  *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
@@ -49,6 +50,21 @@
  *     </restriction>
  *   </complexContent>
  * </complexType>
+=======
+ * <complexType name="PagingType">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="orderBy" type="{http://prism.evolveum.com/xml/ns/public/types-3}XPathType" minOccurs="0"/>
+ *         <element name="orderDirection" type="{http://prism.evolveum.com/xml/ns/public/query-2}OrderDirectionType" minOccurs="0"/>
+ *         <element name="offset" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
+ *         <element name="maxSize" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
+ *         <element name="groupBy" type="{http://prism.evolveum.com/xml/ns/public/types-3}XPathType" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+>>>>>>> 0f7b0ca... Adds support for  in queries
  * 
*/ @XmlAccessorType(XmlAccessType.FIELD) @@ -56,7 +72,8 @@ "orderBy", "orderDirection", "offset", - "maxSize" + "maxSize", + "groupBy" }) public class PagingType implements Serializable, Cloneable, Equals, HashCode { @@ -69,6 +86,8 @@ public class PagingType implements Serializable, Cloneable, Equals, HashCode protected Integer offset; @XmlElement(defaultValue = "2147483647") protected Integer maxSize; + protected ItemPathType groupBy; + public final static QName COMPLEX_TYPE = new QName(PrismConstants.NS_QUERY, "PagingType"); public final static QName F_ORDER_DIRECTION = new QName(PrismConstants.NS_QUERY, "orderDirection"); public final static QName F_OFFSET = new QName(PrismConstants.NS_QUERY, "offset"); @@ -105,6 +124,7 @@ public PagingType(final PagingType o) { this.offset = ((o.offset == null)?null:o.getOffset()); // CBuiltinLeafInfo: java.lang.Integer this.maxSize = ((o.maxSize == null)?null:o.getMaxSize()); + this.groupBy = (o.groupBy == null)?null:o.groupBy.clone(); } /** @@ -203,6 +223,30 @@ public void setMaxSize(Integer value) { this.maxSize = value; } + /** + * Gets the value of the groupBy property. + * + * @return + * possible object is + * {@link Element } + * + */ + public ItemPathType getGroupBy() { + return groupBy; + } + + /** + * Sets the value of the orderBy property. + * + * @param value + * allowed object is + * {@link Element } + * + */ + public void setGroupBy(ItemPathType value) { + this.groupBy = value; + } + /** * Generates a String representation of the contents of this type. * This is an extension method, produced by the 'ts' xjc plugin @@ -235,6 +279,11 @@ public int hashCode(ObjectLocator locator, HashCodeStrategy strategy) { theMaxSize = this.getMaxSize(); currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "maxSize", theMaxSize), currentHashCode, theMaxSize); } + { + ItemPathType theGroupBy; + theGroupBy = this.getGroupBy(); + currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "groupBy", theGroupBy), currentHashCode, theGroupBy); + } return currentHashCode; } @@ -287,6 +336,15 @@ public boolean equals(ObjectLocator thisLocator, ObjectLocator thatLocator, Obje return false; } } + { + ItemPathType lhsGroupBy; + lhsGroupBy = this.getGroupBy(); + ItemPathType rhsGroupBy; + rhsGroupBy = that.getOrderBy(); + if (!strategy.equals(LocatorUtils.property(thisLocator, "groupBy", lhsGroupBy), LocatorUtils.property(thatLocator, "groupBy", rhsGroupBy), lhsGroupBy, rhsGroupBy)) { + return false; + } + } return true; } @@ -316,6 +374,8 @@ public PagingType clone() { clone.offset = ((this.offset == null)?null:this.getOffset()); // CBuiltinLeafInfo: java.lang.Integer clone.maxSize = ((this.maxSize == null)?null:this.getMaxSize()); + // CWildcardTypeInfo: org.w3c.dom.Element + clone.groupBy = ((this.groupBy == null)?null:((this.getGroupBy() == null)?null:(this.getGroupBy().clone()))); return clone; } } catch (CloneNotSupportedException e) { diff --git a/infra/prism/src/main/resources/xml/ns/public/query-3.xsd b/infra/prism/src/main/resources/xml/ns/public/query-3.xsd index b7a09e89542..b80cf11e104 100644 --- a/infra/prism/src/main/resources/xml/ns/public/query-3.xsd +++ b/infra/prism/src/main/resources/xml/ns/public/query-3.xsd @@ -120,6 +120,17 @@
+ + + + Property by which the results should be grouped. + Reference to a property (XPath). + Just one property for now. + Maybe we will change this to a list later. + If not specified, no grouping is assumed. + + + diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/QueryInterpreter2.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/QueryInterpreter2.java index c9fe432ffaa..dd9912a6444 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/QueryInterpreter2.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/QueryInterpreter2.java @@ -49,6 +49,7 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationWorkItemType; import org.apache.commons.lang3.StringUtils; import org.hibernate.Session; +import org.hibernate.criterion.Projections; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -338,15 +339,20 @@ private void updatePagingAndSorting(InterpretationContext context, ObjectPaging hibernateQuery.setMaxResults(paging.getMaxSize()); } - if (!paging.hasOrdering()) { - return; + if (paging.hasOrdering()) { + for (ObjectOrdering ordering : paging.getOrderingInstructions()) { + addOrdering(context, ordering); + } } - for (ObjectOrdering ordering : paging.getOrderingInstructions()) { - addOrdering(context, ordering); + if (paging.hasGrouping()) { + for (ObjectGrouping grouping : paging.getGroupingInstructions()) { + addGrouping(context, grouping); + } } } + private void addOrdering(InterpretationContext context, ObjectOrdering ordering) throws QueryException { ItemPath orderByPath = ordering.getOrderBy(); @@ -397,6 +403,45 @@ private void addOrdering(InterpretationContext context, ObjectOrdering ordering) } + private void addGrouping(InterpretationContext context, ObjectGrouping grouping) throws QueryException { + + ItemPath groupByPath = grouping.getGroupBy(); + + // TODO if we'd like to have group-by extension properties, we'd need to provide itemDefinition for them + ProperDataSearchResult result = context.getItemPathResolver().findProperDataDefinition( + context.getRootEntityDefinition(), groupByPath, null, JpaDataNodeDefinition.class, context.getPrismContext()); + if (result == null) { + LOGGER.error("Unknown path '" + groupByPath + "', couldn't find definition for it, " + + "list will not be grouped by it."); + return; + } + JpaDataNodeDefinition targetDefinition = result.getLinkDefinition().getTargetDefinition(); + if (targetDefinition instanceof JpaAnyContainerDefinition) { + throw new QueryException("Grouping based on extension item or attribute is not supported yet: " + groupByPath); + } else if (targetDefinition instanceof JpaReferenceDefinition) { + throw new QueryException("Grouping based on reference is not supported: " + groupByPath); + } else if (result.getLinkDefinition().isMultivalued()) { + throw new QueryException("Grouping based on multi-valued item is not supported: " + groupByPath); + } else if (targetDefinition instanceof JpaEntityDefinition) { + throw new QueryException("Grouping based on entity is not supported: " + groupByPath); + } else if (!(targetDefinition instanceof JpaPropertyDefinition)) { + throw new IllegalStateException("Unknown item definition type: " + result.getClass()); + } + + JpaEntityDefinition baseEntityDefinition = result.getEntityDefinition(); + JpaPropertyDefinition groupByDefinition = (JpaPropertyDefinition) targetDefinition; + String hqlPropertyPath = context.getItemPathResolver() + .resolveItemPath(groupByPath, null, context.getPrimaryEntityAlias(), baseEntityDefinition, true) + .getHqlPath(); + if (RPolyString.class.equals(groupByDefinition.getJpaClass())) { + hqlPropertyPath += ".orig"; + } + + RootHibernateQuery hibernateQuery = context.getHibernateQuery(); + + hibernateQuery.addGrouping(hqlPropertyPath); + } + public Matcher findMatcher(T value) { return findMatcher(value != null ? (Class) value.getClass() : null); } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/hqm/HibernateQuery.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/hqm/HibernateQuery.java index cadc70e3428..5f99c8b961f 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/hqm/HibernateQuery.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/hqm/HibernateQuery.java @@ -80,6 +80,23 @@ public OrderDirection getDirection() { private List orderingList = new ArrayList<>(); + + public class Grouping { + @NotNull private final String byProperty; + + Grouping(@NotNull String byProperty) { + this.byProperty = byProperty; + } + + @NotNull + public String getByProperty() { + return byProperty; + } + } + + private List groupingList = new ArrayList<>(); + + public HibernateQuery(@NotNull JpaEntityDefinition primaryEntityDef) { primaryEntity = createItemSpecification(primaryEntityDef); } @@ -161,6 +178,22 @@ public String getAsHqlText(int indent, boolean distinct) { } } } + + if (!groupingList.isEmpty()) { + sb.append("\n"); + indent(sb, indent); + sb.append("group by "); + boolean first = true; + for (Grouping grouping : groupingList) { + if (first) { + first = false; + } else { + sb.append(", "); + } + sb.append(grouping.byProperty); + } + } + return sb.toString(); } @@ -232,6 +265,15 @@ public List getOrderingList() { return orderingList; } + public void addGrouping(String propertyPath) { + groupingList.add(new Grouping(propertyPath)); + } + + public List getGroupingList() { + return groupingList; + } + + public abstract RootHibernateQuery getRootQuery(); // used to narrow the primary entity e.g. from RObject to RUser (e.g. during ItemValueRestriction processing) From 9f86f4b426fc0dc7f2b78e3bb705bbb56d28e803 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Mon, 2 Oct 2017 15:26:02 +0200 Subject: [PATCH 96/97] Post-merge fixes. --- model/report-impl/pom.xml | 2 +- provisioning/provisioning-impl/pom.xml | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/model/report-impl/pom.xml b/model/report-impl/pom.xml index d1e0a7a2407..dd5d0fd15be 100644 --- a/model/report-impl/pom.xml +++ b/model/report-impl/pom.xml @@ -106,7 +106,7 @@ com.evolveum.midpoint.model workflow-api - 3.6.1-SNAPSHOT + 3.7-SNAPSHOT diff --git a/provisioning/provisioning-impl/pom.xml b/provisioning/provisioning-impl/pom.xml index 8199e1fe53d..008aa2367d6 100644 --- a/provisioning/provisioning-impl/pom.xml +++ b/provisioning/provisioning-impl/pom.xml @@ -99,10 +99,6 @@ repo-common 3.7-SNAPSHOT - - net.tirasa.connid - connector-framework - commons-lang commons-lang @@ -270,5 +266,13 @@ spring-aop test + + + + net.tirasa.connid + connector-framework + test + + From d373d07744f6c20ea3765cad9f7e4e108a510741 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Mon, 2 Oct 2017 15:39:23 +0200 Subject: [PATCH 97/97] More post-merge fixes --- .../xml/ns/_public/query_3/PagingType.java | 17 +---------------- .../impl/dummy/TestDummyParallelism.java | 2 +- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/query_3/PagingType.java b/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/query_3/PagingType.java index 621c9d97c0a..0a6de358b4b 100644 --- a/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/query_3/PagingType.java +++ b/infra/prism/src/main/java/com/evolveum/prism/xml/ns/_public/query_3/PagingType.java @@ -37,7 +37,6 @@ *

The following schema fragment specifies the expected content contained within this class. * *

-<<<<<<< HEAD
  * <complexType name="PagingType">
  *   <complexContent>
  *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
@@ -46,25 +45,11 @@
  *         <element name="orderDirection" type="{http://prism.evolveum.com/xml/ns/public/query-2}OrderDirectionType" minOccurs="0"/>
  *         <element name="offset" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
  *         <element name="maxSize" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
+ *         <element name="groupBy" type="{http://prism.evolveum.com/xml/ns/public/types-3}XPathType" minOccurs="0"/>
  *       </sequence>
  *     </restriction>
  *   </complexContent>
  * </complexType>
-=======
- * <complexType name="PagingType">
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element name="orderBy" type="{http://prism.evolveum.com/xml/ns/public/types-3}XPathType" minOccurs="0"/>
- *         <element name="orderDirection" type="{http://prism.evolveum.com/xml/ns/public/query-2}OrderDirectionType" minOccurs="0"/>
- *         <element name="offset" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
- *         <element name="maxSize" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
- *         <element name="groupBy" type="{http://prism.evolveum.com/xml/ns/public/types-3}XPathType" minOccurs="0"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
->>>>>>> 0f7b0ca... Adds support for  in queries
  * 
*/ @XmlAccessorType(XmlAccessType.FIELD) diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyParallelism.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyParallelism.java index ae76d027e3a..034b4856297 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyParallelism.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyParallelism.java @@ -371,7 +371,7 @@ public void test212ParallelModifyElizabethSlow() throws Exception { * is finished. But the threads are fast and the operations are slow. So this is * a very slim chance. */ - @Test(enabled = false) + @Test public void test214ParallelModifyDisableSlow() throws Exception { final String TEST_NAME = "test214ParallelModifyDisableSlow";