From 382edd6287ffddc05fc336ebbcd4fcef0e4bc5cf Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Mon, 6 Apr 2020 16:31:19 +0200 Subject: [PATCH 1/9] changing assignmentRelationApproach into assignmentHolderRelationApproach. and later assignmentTargetRelationApproach can come. --- .../src/main/resources/xml/ns/public/common/common-core-3.xsd | 2 +- .../model/impl/controller/ModelInteractionServiceImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 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 2282242d72e..4ceaf55d4e1 100755 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd @@ -15025,7 +15025,7 @@ - +

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 9347be64bce..ab98af98097 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 @@ -1790,7 +1790,7 @@ private AssignmentCandidatesSpecification determineArchetypeAssignmentCandidateS } spec.setAssignmentObjectRelations(assignmentHolderRelations); spec.setSupportGenericAssignment(archetypePolicy == null - || AssignmentRelationApproachType.CLOSED != archetypePolicy.getAssignmentRelationApproach()); + || AssignmentRelationApproachType.CLOSED != archetypePolicy.getAssignmentHolderRelationApproach()); return spec; } From 1931ca0bb819c3193865c56eb970025af84a3713 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Mon, 6 Apr 2020 17:26:32 +0200 Subject: [PATCH 2/9] Improving assignmentHolderRelationApproach schemadoc --- .../xml/ns/public/common/common-core-3.xsd | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 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 4ceaf55d4e1..b066782c249 100755 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd @@ -15029,8 +15029,8 @@

- Configures overall assignmentRelation approach for archetypes objects. This essentially means - that is allows or disables the use of "generic" assignments for archetyped objects. + Configures overall assignmentRelation approach for archetyped objects (assignment holders). + This essentially means that is allows or disables the use of "generic" assignments for archetyped objects. If the generic assignments are allowed (open approach), the archetyped object can be a holder of any assignment that targets any assignable type with any relation (Note: this is still subject to authorizations). @@ -15039,10 +15039,18 @@ If this property is set to "closed" then GUI will not render that button. In that case only those assignments that are explicitly allowed by assignmentRelation statements are possible.

+

+ This setting controls behavior of midPoint user interface. + E.g. setting the approach to "closed" will hide the button that controls generic assignment in user's the "Assignments" tab. + But it will not disable similar button in the "Members" tab of the role. + This setting is only about controlling uni-directional behavior of GUI. + It does not constraint the entire assignment model. + That will be too complex to implement (at least for now). +

4.1 - ArchetypePolicyType.assignmentRelationApproach + ArchetypePolicyType.assignmentHolderRelationApproach
From 13826a1926f32de461910e0cd55bd3ebf028cf1f Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Mon, 6 Apr 2020 17:58:58 +0200 Subject: [PATCH 3/9] show/hide improvement for task basic tab, making executeScript panel smaller, adding objectDelta panel --- .../factory/ExecuteScriptWrapperFactory.java | 2 +- .../gui/impl/factory/ObjectDeltaModel.java | 67 +++++++++++++++++++ .../impl/factory/ObjectDeltaPanelFactory.java | 44 ++++++++++++ .../page/admin/server/TaskBasicTabPanel.java | 23 +++++++ .../schema/constants/SchemaConstants.java | 1 + 5 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/ObjectDeltaModel.java create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/ObjectDeltaPanelFactory.java diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/ExecuteScriptWrapperFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/ExecuteScriptWrapperFactory.java index f6c6419ad2a..f525a556bd2 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/ExecuteScriptWrapperFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/ExecuteScriptWrapperFactory.java @@ -39,6 +39,6 @@ public Integer getOrder() { @Override protected Panel getPanel(PrismPropertyPanelContext panelCtx) { - return new TextAreaPanel<>(panelCtx.getComponentId(), new ExecuteScriptModel(panelCtx.getRealValueModel(), panelCtx.getPageBase()), 100); + return new TextAreaPanel<>(panelCtx.getComponentId(), new ExecuteScriptModel(panelCtx.getRealValueModel(), panelCtx.getPageBase()), 20); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/ObjectDeltaModel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/ObjectDeltaModel.java new file mode 100644 index 00000000000..85bc5f59646 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/ObjectDeltaModel.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2020 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.gui.impl.factory; + +import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType; + +import org.apache.commons.lang3.StringUtils; +import org.apache.wicket.ThreadContext; +import org.apache.wicket.model.IModel; + +import com.evolveum.midpoint.gui.api.util.ModelServiceLocator; +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.model.scripting_3.ExecuteScriptType; + +public class ObjectDeltaModel implements IModel { + + private static final transient Trace LOGGER = TraceManager.getTrace(ObjectDeltaModel.class); + + private IModel baseModel; + private ModelServiceLocator locator; + + public ObjectDeltaModel(IModel model, ModelServiceLocator locator) { + this.baseModel = model; + this.locator = locator; + } + + + @Override + public String getObject() { + try { + ObjectDeltaType value = baseModel.getObject(); + if (value == null) { + return null; + } + + return locator.getPrismContext().xmlSerializer().serializeRealValue(value); + } catch (Exception e) { + // TODO handle!!!! + LoggingUtils.logUnexpectedException(LOGGER, "Cannot serialize delta", e); + ThreadContext.getSession().error("Cannot serialize delta: " + e.getMessage()); + } + return null; + } + + @Override + public void setObject(String object) { + if (StringUtils.isBlank(object)) { + return; + } + + try { + ObjectDeltaType script = locator.getPrismContext().parserFor(object).parseRealValue(ObjectDeltaType.class); + baseModel.setObject(script); + } catch (Exception e) { + // TODO handle!!!! + LoggingUtils.logUnexpectedException(LOGGER, "Cannot parse delta", e); + ThreadContext.getSession().error("Cannot parse delta: " + e.getMessage()); + } + } +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/ObjectDeltaPanelFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/ObjectDeltaPanelFactory.java new file mode 100644 index 00000000000..8139d3e779c --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/factory/ObjectDeltaPanelFactory.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ + +package com.evolveum.midpoint.gui.impl.factory; + +import javax.annotation.PostConstruct; + +import com.evolveum.midpoint.web.component.input.TextAreaPanel; + +import org.apache.wicket.markup.html.panel.Panel; +import org.springframework.stereotype.Component; + +import com.evolveum.midpoint.gui.api.factory.AbstractGuiComponentFactory; +import com.evolveum.midpoint.gui.api.prism.ItemWrapper; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType; + +@Component +public class ObjectDeltaPanelFactory extends AbstractGuiComponentFactory { + + @PostConstruct + public void register() { + getRegistry().addToRegistry(this); + } + + @Override + public Integer getOrder() { + return super.getOrder() - 100; + } + + @Override + protected Panel getPanel(PrismPropertyPanelContext panelCtx) { + return new TextAreaPanel<>(panelCtx.getComponentId(), new ObjectDeltaModel(panelCtx.getRealValueModel(), panelCtx.getPageBase()), 20); + } + + @Override + public boolean match(IW wrapper) { + return QNameUtil.match(ObjectDeltaType.COMPLEX_TYPE, wrapper.getTypeName()); + } +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskBasicTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskBasicTabPanel.java index 0dff1748ffb..7dd3c604d63 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskBasicTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskBasicTabPanel.java @@ -173,6 +173,29 @@ private ItemVisibility getBasicTabVisibility(ItemPath path) { return ItemVisibility.HIDDEN; } + // region no panel for type + if (ItemPath.create(TaskType.F_EXTENSION, SchemaConstants.MODEL_EXTENSION_SEARCH_OPTIONS).equivalent(path)) { + return ItemVisibility.HIDDEN; + } + + if (ItemPath.create(TaskType.F_EXTENSION, SchemaConstants.MODEL_EXTENSION_EXECUTE_OPTIONS).equivalent(path)) { + return ItemVisibility.HIDDEN; + } + + if (ItemPath.create(TaskType.F_EXTENSION, SchemaConstants.MODEL_EXTENSION_MODEL_EXECUTE_OPTIONS).equivalent(path)) { + return ItemVisibility.HIDDEN; + } + + if (TaskType.F_RESULT.equivalent(path)) { + return ItemVisibility.HIDDEN; + } + + if (TaskType.F_OTHER_HANDLERS_URI_STACK.equivalent(path)) { + return ItemVisibility.HIDDEN; + } + + //end region unsupported panel for type + String taskHandler = getTask().getHandlerUri(); if (taskHandler == null) { diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java index 5f32b88a2d9..e08ab9b46c0 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java @@ -357,6 +357,7 @@ public abstract class SchemaConstants { public static final ItemName MODEL_EXTENSION_WORKER_THREADS = new ItemName(NS_MODEL_EXTENSION, "workerThreads"); public static final ItemName MODEL_EXTENSION_OPTION_RAW = new ItemName(NS_MODEL_EXTENSION, "optionRaw"); public static final ItemName MODEL_EXTENSION_EXECUTE_OPTIONS = new ItemName(NS_MODEL_EXTENSION, "executeOptions"); + public static final ItemName MODEL_EXTENSION_MODEL_EXECUTE_OPTIONS = new ItemName(NS_MODEL_EXTENSION, "modelExecuteOptions"); public static final ItemName MODEL_EXTENSION_DIAGNOSE = new ItemName(NS_MODEL_EXTENSION, "diagnose"); public static final ItemName MODEL_EXTENSION_FIX = new ItemName(NS_MODEL_EXTENSION, "fix"); From fcde18a4cb60f9ca151e52ec4ac17f69fddf423d Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Mon, 6 Apr 2020 18:35:54 +0200 Subject: [PATCH 4/9] fixing MID-6170, sorting works again + cleanup --- .../midpoint/gui/impl/prism/PrismContainerValuePanel.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismContainerValuePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismContainerValuePanel.java index 1f63eee3afc..cf4aca78edb 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismContainerValuePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismContainerValuePanel.java @@ -186,7 +186,6 @@ protected void populateItem(final ListItem item) { populateNonContainer(item); } }; - properties.setReuseItems(true); properties.setOutputMarkupId(true); add(propertiesLabel); propertiesLabel.add(properties); @@ -355,13 +354,8 @@ public boolean isVisible() { private void populateContainer(ListItem> container) { PrismContainerWrapper itemWrapper = container.getModelObject(); try { -// ItemPanelSettingsBuilder builder = new ItemPanelSettingsBuilder().visibilityHandler(getVisibilityHandler()); Panel panel = getPageBase().initItemPanel("container", itemWrapper.getTypeName(), container.getModel(), settings); panel.setOutputMarkupId(true); -// panel.add(new VisibleBehaviour(() -> { -// CVW parent = PrismContainerValuePanel.this.getModelObject(); -// return container.getModelObject().isVisible(parent, visibilityHandler); -// })); container.add(panel); } catch (SchemaException e) { throw new SystemException("Cannot instantiate panel for: " + itemWrapper.getDisplayName()); From 08f177f641b1101a1c5a057d2586a06ff09a5a5e Mon Sep 17 00:00:00 2001 From: kate Date: Mon, 6 Apr 2020 20:26:21 +0200 Subject: [PATCH 5/9] MID-6177 Cleaning task operational stats --- .../evolveum/midpoint/web/page/admin/server/PageTask.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTask.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTask.java index fe16fcd16a2..20316e3e765 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTask.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTask.java @@ -3,6 +3,7 @@ import java.io.InputStream; import java.util.Collection; import java.util.Collections; +import com.evolveum.midpoint.web.component.prism.ValueStatus; import org.apache.wicket.Page; import org.apache.wicket.ajax.AjaxRequestTarget; @@ -350,12 +351,12 @@ private void createCleanupPerformanceButton(RepeatingView repeatingView) { @Override public void onClick(AjaxRequestTarget target) { try { - getObjectWrapper().findProperty(ItemPath.create(TaskType.F_OPERATION_STATS, - OperationStatsType.F_ENVIRONMENTAL_PERFORMANCE_INFORMATION)).getValue().setRealValue(null); + getObjectWrapper().findContainer(TaskType.F_OPERATION_STATS).getValue().setStatus(ValueStatus.DELETED); } catch (SchemaException e){ LOGGER.error("Cannot clear task results: {}", e.getMessage()); } saveTaskChanges(target); + refresh(target); } }; cleanupPerformance.add(AttributeAppender.append("class", "btn btn-default btn-margin-left btn-sm")); From 0864f3762c3f2c66bfab40370ecf008e1a8c8f8e Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Mon, 6 Apr 2020 21:10:40 +0200 Subject: [PATCH 6/9] fix for MID-6178 - delete task result repeatedly, fixed by fixing delta computation for deleted values, small improvements for refreshing after operation. --- .../gui/impl/prism/PrismValueWrapperImpl.java | 4 +- .../web/page/admin/server/PageTask.java | 26 +- .../page/admin/server/TaskResultTabPanel.java | 323 +++++++++--------- 3 files changed, 186 insertions(+), 167 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismValueWrapperImpl.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismValueWrapperImpl.java index ec613fc757a..2fcca437e77 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismValueWrapperImpl.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismValueWrapperImpl.java @@ -78,7 +78,9 @@ public , ID extends ItemDefinition> void addToDelta(D } break; case DELETED: - delta.addValueToDelete((V) oldValue.clone()); + if (oldValue != null && !oldValue.isEmpty()) { + delta.addValueToDelete((V) oldValue.clone()); + } break; default: break; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTask.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTask.java index fe16fcd16a2..db4d963e033 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTask.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTask.java @@ -4,6 +4,9 @@ import java.util.Collection; import java.util.Collections; +import com.evolveum.midpoint.prism.path.ItemName; +import com.evolveum.midpoint.web.component.prism.ValueStatus; + import org.apache.wicket.Page; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.behavior.AttributeAppender; @@ -370,13 +373,12 @@ private void createCleanupResultsButton(RepeatingView repeatingView) { @Override public void onClick(AjaxRequestTarget target) { try { - getObjectWrapper().findProperty(TaskType.F_RESULT).getValue().setRealValue(null); - getObjectWrapper().findProperty(TaskType.F_RESULT_STATUS).getValue().setRealValue(null); + deleteProperty(TaskType.F_RESULT); + deleteProperty(TaskType.F_RESULT_STATUS); } catch (SchemaException e){ LOGGER.error("Cannot clear task results: {}", e.getMessage()); } saveTaskChanges(target); - refresh(target); } }; cleanupResults.add(new VisibleBehaviour(this::isNotRunning)); @@ -384,6 +386,21 @@ public void onClick(AjaxRequestTarget target) { repeatingView.add(cleanupResults); } + private void deleteProperty(ItemName propertyName) throws SchemaException { + PrismPropertyWrapper property = getObjectWrapper().findProperty(propertyName); + if (property == null) { + return; + } + + PrismPropertyValueWrapper propertyValue = property.getValue(); + if (propertyValue == null) { + return; + } + + propertyValue.setStatus(ValueStatus.DELETED); + + } + private void saveTaskChanges(AjaxRequestTarget target) { try { ObjectDelta taskDelta = getObjectWrapper().getObjectDelta(); @@ -398,6 +415,7 @@ private void saveTaskChanges(AjaxRequestTarget target) { private void saveTaskChanges(AjaxRequestTarget target, ObjectDelta taskDelta){ if (taskDelta.isEmpty()) { getSession().warn("Nothing to save, no changes were made."); + target.add(getFeedbackPanel()); return; } @@ -408,7 +426,6 @@ private void saveTaskChanges(AjaxRequestTarget target, ObjectDelta tas taskDelta.revive(getPrismContext()); //do we need revive here? getModelService().executeChanges(MiscUtil.createCollection(taskDelta), null, task, result); result.computeStatus(); - getObjectModel().reset(); } catch (Exception e) { LoggingUtils.logUnexpectedException(LOGGER, "Cannot save tasks changes", e); result.recordFatalError("Cannot save tasks changes, " + e.getMessage(), e); @@ -425,6 +442,7 @@ private CompositedIcon getTaskCleanupCompositedIcon(String basicIconClass){ } private void afterOperation(AjaxRequestTarget target, OperationResult result) { + taskTabsVisibility = new TaskTabsVisibility(); showResult(result); getObjectModel().reset(); refresh(target); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskResultTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskResultTabPanel.java index 86c56b0bf6b..2400531f627 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskResultTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskResultTabPanel.java @@ -1,162 +1,161 @@ -/* - * Copyright (c) 2010-2017 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.web.page.admin.server; - -import com.evolveum.midpoint.gui.api.component.BasePanel; -import com.evolveum.midpoint.gui.api.component.result.OpResult; -import com.evolveum.midpoint.gui.api.component.result.OperationResultPanel; -import com.evolveum.midpoint.gui.api.model.LoadableModel; -import com.evolveum.midpoint.gui.api.prism.PrismObjectWrapper; -import com.evolveum.midpoint.gui.api.util.WebComponentUtil; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.web.component.data.BoxedTablePanel; -import com.evolveum.midpoint.web.component.util.SelectableListDataProvider; -import com.evolveum.midpoint.web.component.util.SelectableBean; -import com.evolveum.midpoint.web.component.util.SelectableBeanImpl; -import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; -import org.apache.wicket.Component; -import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.ajax.markup.html.AjaxFallbackLink; -import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; -import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn; -import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; -import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn; -import org.apache.wicket.markup.html.basic.Label; -import org.apache.wicket.markup.repeater.Item; -import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; - -import java.util.*; - -/** - * @author semancik - */ -public class TaskResultTabPanel extends BasePanel> implements RefreshableTabPanel { - private static final long serialVersionUID = 1L; - - private static final String ID_OPERATION_RESULT = "operationResult"; - private static final String ID_SHOW_RESULT = "showResult"; - - private static final Trace LOGGER = TraceManager.getTrace(TaskResultTabPanel.class); - - public TaskResultTabPanel(String id, LoadableModel> taskWrapperModel) { - super(id, taskWrapperModel); - - } - - @Override - protected void onInitialize() { - super.onInitialize(); - initLayout(); - setOutputMarkupId(true); - } - - private void initLayout() { - - LoadableModel> resultModel= new LoadableModel>() { - @Override - protected List load() { - PrismObject taskPrism = getModelObject().getObject(); - if (taskPrism == null) { - return null; - } - - OperationResultType result = taskPrism.asObjectable().getResult(); - if (result == null) { - return null; - } - - List results = new ArrayList<>(); - OperationResult opResult = OperationResult.createOperationResult(result); - results.add(opResult); - results.addAll(opResult.getSubresults()); - return results; - } - }; - - SelectableListDataProvider, OperationResult> provider = new SelectableListDataProvider<>(this, resultModel); - BoxedTablePanel> resultTablePanel = new BoxedTablePanel<>(ID_OPERATION_RESULT, provider, initResultColumns()); - resultTablePanel.setOutputMarkupId(true); - add(resultTablePanel); - - AjaxFallbackLink showResult = new AjaxFallbackLink(ID_SHOW_RESULT) { - private static final long serialVersionUID = 1L; - - @Override - public void onClick(Optional optionalTarget) { - AjaxRequestTarget target = optionalTarget.get(); - PrismObjectWrapper taskWrapper = TaskResultTabPanel.this.getModelObject(); - TaskType taskType = taskWrapper.getObject().asObjectable(); - OperationResult opResult = OperationResult.createOperationResult(taskType.getResult()); - OperationResultPanel body = new OperationResultPanel( - getPageBase().getMainPopupBodyId(), - new Model<>(OpResult.getOpResult(getPageBase(), opResult)), - getPageBase()); - body.setOutputMarkupId(true); - getPageBase().showMainPopup(body, target); - } - - - }; - showResult.setOutputMarkupId(true); - add(showResult); - - } - - private List, String>> initResultColumns() { - List, String>> columns = new ArrayList<>(); - columns.add(new PropertyColumn<>(createStringResource("pageTaskEdit.opResult.token"), createPropertyExpression("token"))); - columns.add(new PropertyColumn<>(createStringResource("pageTaskEdit.opResult.operation"), createPropertyExpression("operation"))); - columns.add(new PropertyColumn<>(createStringResource("pageTaskEdit.opResult.status"), createPropertyExpression("status"))); - columns.add(new AbstractColumn, String>(createStringResource("pageTaskEdit.opResult.timestamp")){ - private static final long serialVersionUID = 1L; - - @Override - public void populateItem(Item>> cellItem, String componentId, - IModel> rowModel) { - Label label = new Label(componentId, (IModel) () -> { - Long resultEndTime = rowModel.getObject().getValue().getEnd(); - return resultEndTime != null && resultEndTime > 0 ? - WebComponentUtil.getShortDateTimeFormattedValue(new Date(), getPageBase()) : ""; - }); - cellItem.add(label); - } - }); - columns.add(new AbstractColumn, String>(createStringResource("pageTaskEdit.opResult.message"), createPropertyExpression("message")) { - private static final long serialVersionUID = 1L; - - @Override - public void populateItem(Item>> cellItem, String componentId, - IModel> rowModel) { - Label label = new Label(componentId, (IModel) () -> WebComponentUtil.nl2br(rowModel.getObject().getValue().getMessage())); - label.setEscapeModelStrings(false); - cellItem.add(label); - } - }); - //columns.add(new PropertyColumn(createStringResource("pageTaskEdit.opResult.message"), "message")); - return columns; - } - - private String createPropertyExpression(String propertyName) { - return SelectableBeanImpl.F_VALUE + "." + propertyName; - } - - @Override - public Collection getComponentsToUpdate() { - return Collections.singleton(get(ID_OPERATION_RESULT)); - } - - @Override - protected void detachModel() { - super.detachModel(); - ((LoadableModel) getModel()).reset(); - } -} +/* + * Copyright (c) 2010-2017 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ +package com.evolveum.midpoint.web.page.admin.server; + +import com.evolveum.midpoint.gui.api.component.BasePanel; +import com.evolveum.midpoint.gui.api.component.result.OpResult; +import com.evolveum.midpoint.gui.api.component.result.OperationResultPanel; +import com.evolveum.midpoint.gui.api.model.LoadableModel; +import com.evolveum.midpoint.gui.api.model.ReadOnlyModel; +import com.evolveum.midpoint.gui.api.prism.PrismObjectWrapper; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.web.component.data.BoxedTablePanel; +import com.evolveum.midpoint.web.component.util.SelectableListDataProvider; +import com.evolveum.midpoint.web.component.util.SelectableBean; +import com.evolveum.midpoint.web.component.util.SelectableBeanImpl; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; +import org.apache.wicket.Component; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.AjaxFallbackLink; +import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; +import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn; +import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; +import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.repeater.Item; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; + +import java.util.*; + +/** + * @author semancik + */ +public class TaskResultTabPanel extends BasePanel> implements RefreshableTabPanel { + private static final long serialVersionUID = 1L; + + private static final String ID_OPERATION_RESULT = "operationResult"; + private static final String ID_SHOW_RESULT = "showResult"; + + private static final Trace LOGGER = TraceManager.getTrace(TaskResultTabPanel.class); + + public TaskResultTabPanel(String id, LoadableModel> taskWrapperModel) { + super(id, taskWrapperModel); + + } + + @Override + protected void onInitialize() { + super.onInitialize(); + initLayout(); + setOutputMarkupId(true); + } + + private void initLayout() { + + IModel> resultModel= new ReadOnlyModel<>(() -> createOperationResultList()); + + SelectableListDataProvider, OperationResult> provider = new SelectableListDataProvider<>(this, resultModel); + BoxedTablePanel> resultTablePanel = new BoxedTablePanel<>(ID_OPERATION_RESULT, provider, initResultColumns()); + resultTablePanel.setOutputMarkupId(true); + add(resultTablePanel); + + AjaxFallbackLink showResult = new AjaxFallbackLink(ID_SHOW_RESULT) { + private static final long serialVersionUID = 1L; + + @Override + public void onClick(Optional optionalTarget) { + if (optionalTarget.isPresent()) { + LOGGER.warn("Cannot show result in interactive way, request target not present."); + return; + } + AjaxRequestTarget target = optionalTarget.get(); + PrismObjectWrapper taskWrapper = TaskResultTabPanel.this.getModelObject(); + TaskType taskType = taskWrapper.getObject().asObjectable(); + OperationResult opResult = OperationResult.createOperationResult(taskType.getResult()); + OperationResultPanel body = new OperationResultPanel( + getPageBase().getMainPopupBodyId(), + new Model<>(OpResult.getOpResult(getPageBase(), opResult)), + getPageBase()); + body.setOutputMarkupId(true); + getPageBase().showMainPopup(body, target); + } + + + }; + showResult.setOutputMarkupId(true); + add(showResult); + + } + + private List createOperationResultList() { + PrismObject taskPrism = getModelObject().getObject(); + if (taskPrism == null) { + return null; + } + + OperationResultType result = taskPrism.asObjectable().getResult(); + if (result == null) { + return null; + } + + List results = new ArrayList<>(); + OperationResult opResult = OperationResult.createOperationResult(result); + results.add(opResult); + results.addAll(opResult.getSubresults()); + return results; + } + + private List, String>> initResultColumns() { + List, String>> columns = new ArrayList<>(); + columns.add(new PropertyColumn<>(createStringResource("pageTaskEdit.opResult.token"), createPropertyExpression("token"))); + columns.add(new PropertyColumn<>(createStringResource("pageTaskEdit.opResult.operation"), createPropertyExpression("operation"))); + columns.add(new PropertyColumn<>(createStringResource("pageTaskEdit.opResult.status"), createPropertyExpression("status"))); + columns.add(new AbstractColumn, String>(createStringResource("pageTaskEdit.opResult.timestamp")){ + private static final long serialVersionUID = 1L; + + @Override + public void populateItem(Item>> cellItem, String componentId, + IModel> rowModel) { + Label label = new Label(componentId, (IModel) () -> { + Long resultEndTime = rowModel.getObject().getValue().getEnd(); + return resultEndTime != null && resultEndTime > 0 ? + WebComponentUtil.getShortDateTimeFormattedValue(new Date(), getPageBase()) : ""; + }); + cellItem.add(label); + } + }); + columns.add(new AbstractColumn, String>(createStringResource("pageTaskEdit.opResult.message"), createPropertyExpression("message")) { + private static final long serialVersionUID = 1L; + + @Override + public void populateItem(Item>> cellItem, String componentId, + IModel> rowModel) { + Label label = new Label(componentId, (IModel) () -> WebComponentUtil.nl2br(rowModel.getObject().getValue().getMessage())); + label.setEscapeModelStrings(false); + cellItem.add(label); + } + }); + //columns.add(new PropertyColumn(createStringResource("pageTaskEdit.opResult.message"), "message")); + return columns; + } + + private String createPropertyExpression(String propertyName) { + return SelectableBeanImpl.F_VALUE + "." + propertyName; + } + + @Override + public Collection getComponentsToUpdate() { + return Collections.singleton(get(ID_OPERATION_RESULT)); + } + +} From 0a325f919946915437e64533637830ead0af416d Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Mon, 6 Apr 2020 21:19:16 +0200 Subject: [PATCH 7/9] union delete operations stats with delete result and resultStatus --- .../web/page/admin/server/PageTask.java | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTask.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTask.java index 2c1ae541d33..5d8bbc891d1 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTask.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTask.java @@ -3,10 +3,6 @@ import java.io.InputStream; import java.util.Collection; import java.util.Collections; -import com.evolveum.midpoint.web.component.prism.ValueStatus; - -import com.evolveum.midpoint.prism.path.ItemName; -import com.evolveum.midpoint.web.component.prism.ValueStatus; import org.apache.wicket.Page; import org.apache.wicket.ajax.AjaxRequestTarget; @@ -18,6 +14,7 @@ import org.apache.wicket.request.mapper.parameter.PageParameters; import com.evolveum.midpoint.gui.api.GuiStyleConstants; +import com.evolveum.midpoint.gui.api.prism.ItemWrapper; import com.evolveum.midpoint.gui.api.prism.PrismObjectWrapper; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; @@ -25,15 +22,13 @@ import com.evolveum.midpoint.gui.impl.component.icon.CompositedIcon; import com.evolveum.midpoint.gui.impl.component.icon.CompositedIconBuilder; import com.evolveum.midpoint.gui.impl.component.icon.IconCssStyle; -import com.evolveum.midpoint.gui.impl.prism.PrismPropertyValueWrapper; -import com.evolveum.midpoint.gui.impl.prism.PrismPropertyWrapper; -import com.evolveum.midpoint.gui.impl.prism.PrismReferenceValueWrapperImpl; -import com.evolveum.midpoint.gui.impl.prism.PrismReferenceWrapper; +import com.evolveum.midpoint.gui.impl.prism.*; import com.evolveum.midpoint.model.api.authentication.GuiProfiledPrincipal; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismProperty; import com.evolveum.midpoint.prism.Referencable; import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.prism.path.ItemName; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.report.api.ReportConstants; import com.evolveum.midpoint.schema.GetOperationOptions; @@ -57,6 +52,7 @@ import com.evolveum.midpoint.web.component.AjaxIconButton; import com.evolveum.midpoint.web.component.ObjectSummaryPanel; import com.evolveum.midpoint.web.component.objectdetails.AbstractObjectMainPanel; +import com.evolveum.midpoint.web.component.prism.ValueStatus; import com.evolveum.midpoint.web.component.refresh.Refreshable; import com.evolveum.midpoint.web.component.util.VisibleBehaviour; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; @@ -354,12 +350,11 @@ private void createCleanupPerformanceButton(RepeatingView repeatingView) { @Override public void onClick(AjaxRequestTarget target) { try { - getObjectWrapper().findContainer(TaskType.F_OPERATION_STATS).getValue().setStatus(ValueStatus.DELETED); + deleteItem(TaskType.F_OPERATION_STATS); } catch (SchemaException e){ LOGGER.error("Cannot clear task results: {}", e.getMessage()); } saveTaskChanges(target); - refresh(target); } }; cleanupPerformance.add(AttributeAppender.append("class", "btn btn-default btn-margin-left btn-sm")); @@ -374,8 +369,8 @@ private void createCleanupResultsButton(RepeatingView repeatingView) { @Override public void onClick(AjaxRequestTarget target) { try { - deleteProperty(TaskType.F_RESULT); - deleteProperty(TaskType.F_RESULT_STATUS); + deleteItem(TaskType.F_RESULT); + deleteItem(TaskType.F_RESULT_STATUS); } catch (SchemaException e){ LOGGER.error("Cannot clear task results: {}", e.getMessage()); } @@ -387,18 +382,18 @@ public void onClick(AjaxRequestTarget target) { repeatingView.add(cleanupResults); } - private void deleteProperty(ItemName propertyName) throws SchemaException { - PrismPropertyWrapper property = getObjectWrapper().findProperty(propertyName); - if (property == null) { + private void deleteItem(ItemName itemName) throws SchemaException { + ItemWrapper item = getObjectWrapper().findItem(itemName, ItemWrapper.class); + if (item == null) { return; } - PrismPropertyValueWrapper propertyValue = property.getValue(); - if (propertyValue == null) { + PrismValueWrapper itemValue = item.getValue(); + if (itemValue == null) { return; } - propertyValue.setStatus(ValueStatus.DELETED); + itemValue.setStatus(ValueStatus.DELETED); } From 43a7fc93b9c1b60c739b9eb3c84af0ef2422c0d9 Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Mon, 6 Apr 2020 23:13:46 +0200 Subject: [PATCH 8/9] fix for MID-6187 - ignore blank string if it already exists. --- .../com/evolveum/midpoint/gui/impl/prism/ItemPanel.java | 9 ++++++--- .../gui/impl/prism/PrismContainerValuePanel.java | 8 ++++++-- .../gui/impl/prism/PrismPropertyValueWrapper.java | 5 +++++ .../gui/impl/prism/component/PolyStringEditorPanel.java | 2 +- .../midpoint/web/component/input/TextAreaPanel.java | 2 ++ .../evolveum/midpoint/web/component/input/TextPanel.java | 1 + 6 files changed, 21 insertions(+), 6 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/ItemPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/ItemPanel.java index 8cd87d9344e..2b2d18a71b8 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/ItemPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/ItemPanel.java @@ -108,6 +108,7 @@ protected void populateItem(ListItem item) { GuiComponentFactory componentFactory = getPageBase().getRegistry() .findValuePanelFactory(ItemPanel.this.getModelObject()); + Component panel = createValuePanel(item, componentFactory, getVisibilityHandler(), getEditabilityHandler()); // panel.add(getEnableBehaviourOfValuePanel(ItemPanel.this.getModelObject())); createButtons(item); @@ -230,8 +231,10 @@ protected void removeValue(VW valueToRemove, AjaxRequestTarget target) throws Sc break; case DELETED: valueToRemove.setStatus(ValueStatus.NOT_CHANGED); + getModelObject().getItem().add(valueToRemove.getNewValue()); break; case NOT_CHANGED: + getModelObject().getItem().remove(valueToRemove.getNewValue()); valueToRemove.setStatus(ValueStatus.DELETED); break; } @@ -248,9 +251,9 @@ protected void removeValue(VW valueToRemove, AjaxRequestTarget target) throws Sc private int countUsableValues(List values) { int count = 0; for (VW value : values) { -// if (ValueStatus.DELETED.equals(value.getStatus())) { -// continue; -// } + if (ValueStatus.DELETED.equals(value.getStatus())) { + continue; + } if (ValueStatus.ADDED.equals(value.getStatus())) { continue; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismContainerValuePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismContainerValuePanel.java index cf4aca78edb..a7b0f6b8dd4 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismContainerValuePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismContainerValuePanel.java @@ -93,6 +93,10 @@ public boolean isVisible() { return false; } + if (ValueStatus.DELETED == modelObject.getStatus()) { + return false; + } + ItemWrapper parent = modelObject.getParent(); if (!PrismContainerWrapper.class.isAssignableFrom(parent.getClass())) { return false; @@ -103,10 +107,10 @@ public boolean isVisible() { } - if (!isShowOnTopLevel() && !((PrismContainerWrapper) parent).isExpanded() && parent.isMultiValue()) { + if (!isShowOnTopLevel() && !((PrismContainerWrapper) parent).isExpanded()) { // && parent.isMultiValue()) { return false; } - return true; + return ((PrismContainerWrapper) parent).isExpanded(); } @Override diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismPropertyValueWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismPropertyValueWrapper.java index 553c11b7824..b8042cebcc2 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismPropertyValueWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/PrismPropertyValueWrapper.java @@ -40,6 +40,11 @@ public void setRealValue(T newRealValue) { newRealValue = trimValueIfNeeded(newRealValue); if (newRealValue == null) { + if (getRealValue() == null) { + //nothing to do, value vas not changed + return; + } + getNewValue().setValue(null); setStatus(ValueStatus.DELETED); return; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/component/PolyStringEditorPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/component/PolyStringEditorPanel.java index fbf5ddc5d8c..35d048db13c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/component/PolyStringEditorPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/component/PolyStringEditorPanel.java @@ -155,7 +155,7 @@ public void setObject(String object) { PolyString oldModelObject = getModelObject(); if (oldModelObject != null && (oldModelObject.getTranslation() != null || MapUtils.isNotEmpty(oldModelObject.getLang()))) { getModel().setObject(new PolyString(object, oldModelObject.getNorm(), oldModelObject.getTranslation(), oldModelObject.getLang())); - } else if (StringUtils.isNotBlank(object)) { + } else if (StringUtils.isNotEmpty(object)) { getModel().setObject(new PolyString(object)); } else { getModel().setObject(null); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/TextAreaPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/TextAreaPanel.java index 0be807991d3..30245cbfa6c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/TextAreaPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/TextAreaPanel.java @@ -26,7 +26,9 @@ public TextAreaPanel(String id, IModel model, Integer rowsOverride) { protected boolean shouldTrimInput() { return false; } + }; + text.setConvertEmptyInputStringToNull(false); text.add(AttributeModifier.append("style", "max-width: 100%")); if (rowsOverride != null) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/TextPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/TextPanel.java index 6aff711d658..d0954b5175a 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/TextPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/TextPanel.java @@ -51,6 +51,7 @@ public void convertInput() { }; + text.setConvertEmptyInputStringToNull(false); text.setType(clazz); add(text); } From b7303d32101481475b707bbb4fbc5f143fdbec5c Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Mon, 6 Apr 2020 23:26:50 +0200 Subject: [PATCH 9/9] fixing MID-6188 - do not hide non-empty fields when adding object --- .../gui/impl/prism/ItemWrapperImpl.java | 1460 ++++++++--------- 1 file changed, 730 insertions(+), 730 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/ItemWrapperImpl.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/ItemWrapperImpl.java index 548f4c8fc76..8c32bad0bca 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/ItemWrapperImpl.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/prism/ItemWrapperImpl.java @@ -1,730 +1,730 @@ -/* - * Copyright (c) 2010-2018 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.gui.impl.prism; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; - -import javax.xml.namespace.QName; - -import com.evolveum.midpoint.prism.*; -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; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import com.evolveum.midpoint.gui.api.page.PageBase; -import com.evolveum.midpoint.gui.api.prism.ItemStatus; -import com.evolveum.midpoint.gui.api.prism.ItemWrapper; -import com.evolveum.midpoint.gui.api.prism.PrismObjectWrapper; -import com.evolveum.midpoint.gui.api.util.WebPrismUtil; -import com.evolveum.midpoint.prism.delta.ItemDelta; -import com.evolveum.midpoint.prism.path.ItemName; -import com.evolveum.midpoint.prism.path.ItemPath; -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 com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.web.component.data.column.ColumnUtils; -import com.evolveum.midpoint.web.component.prism.ItemVisibility; -import com.evolveum.midpoint.web.component.prism.ValueStatus; - -/** - * @author katka - * - */ -public abstract class ItemWrapperImpl, ID extends ItemDefinition, VW extends PrismValueWrapper> implements ItemWrapper, Serializable { - - private static final long serialVersionUID = 1L; - - private static final Trace LOGGER = TraceManager.getTrace(ItemWrapperImpl.class); - - private PrismContainerValueWrapper parent; - - private ItemStatus status = null; - - private String displayName; - - private List values = new ArrayList<>(); - - private I oldItem; - private I newItem; - - private boolean column; - - private boolean stripe; - - private boolean showEmpty; - - private boolean showInVirtualContainer; - - - //consider - private boolean readOnly; - private UserInterfaceElementVisibilityType visibleOverwrite; - - public ItemWrapperImpl(@Nullable PrismContainerValueWrapper parent, I item, ItemStatus status) { - Validate.notNull(item, "Item must not be null."); - Validate.notNull(status, "Item status must not be null."); - - this.parent = parent; - this.newItem = item; - this.oldItem = (I) item.clone(); - this.status = status; - - } - - protected , O extends ObjectType> D getItemDelta(Class objectClass, Class deltaClass) throws SchemaException { - D delta = (D) createEmptyDelta(null); - for (VW value : values) { - value.addToDelta(delta); - } - - if (delta.isEmpty()) { - return null; - } - return delta; - } - - @Override - public > Collection getDelta() throws SchemaException { - LOGGER.trace("Start computing delta for {}", newItem); - - if (isOperational()) { - return null; - } - - D delta = null; - if (parent != null && ValueStatus.ADDED == parent.getStatus()) { - delta = (D) createEmptyDelta(getItemName()); - } else { - delta = (D) createEmptyDelta(getPath()); - } - - for (VW value : values) { - value.addToDelta(delta); - } - - if (delta.isEmpty()) { - LOGGER.trace("There is no delta for {}", newItem); - return null; - } - - LOGGER.trace("Returning delta {}", delta); - return MiscUtil.createCollection(delta); - } - - - @Override - public > void applyDelta(D delta) throws SchemaException { - if (delta == null) { - return; - } - - LOGGER.trace("Applying {} to {}", delta, newItem); - delta.applyTo(newItem); - } - - @Override - public String getDisplayName() { - if (displayName == null) { - displayName = getLocalizedDisplayName(); - } - - return displayName; - } - - - - @Override - public String getHelp() { - return WebPrismUtil.getHelpText(getItemDefinition()); - } - - @Override - public boolean isExperimental() { - return getItemDefinition().isExperimental(); - } - - @Override - public String getDeprecatedSince() { - return getItemDefinition().getDeprecatedSince(); - } - - @Override - public boolean isDeprecated() { - return getItemDefinition().isDeprecated(); - } - - @Override - public boolean isMandatory() { - return getItemDefinition().isMandatory(); - } - - public ItemStatus getStatus() { - return status; - } - - @Override - public I getItem() { - return newItem; - } - - @Override - public void setColumn(boolean column) { - this.column = column; - } - - @Override - public boolean isColumn() { - return column; - } - - public PrismContainerValueWrapper getParent() { - return parent; - } - - @Override - public boolean isMultiValue() { - return getItemDefinition().isMultiValue(); - } - - @Override - public boolean isReadOnly() { - return readOnly; - } - - @Override - public ItemPath getPath() { - return newItem.getPath(); - } - - @Override - public ExpressionType getFormComponentValidator() { - FormItemValidationType formItemValidation = getItemDefinition().getAnnotation(ItemRefinedDefinitionType.F_VALIDATION); - if (formItemValidation == null) { - return null; - } - - List serverValidators = formItemValidation.getServer(); - if (CollectionUtils.isNotEmpty(serverValidators)) { - return serverValidators.iterator().next().getExpression(); - } - - return null; - } - - ID getItemDefinition() { - return newItem.getDefinition(); - } - - @Override - public String debugDump(int indent) { - StringBuilder sb = DebugUtil.createIndentedStringBuilder(indent); - sb.append(toString()); - sb.append("Original definition: ").append(newItem.getDefinition()).append("\n"); - sb.append("Display nam: ").append(displayName).append("\n"); - sb.append("Item status: ").append(status).append("\n"); - sb.append("Read only: ").append(isReadOnly()).append("\n"); - sb.append("New item: \n").append(newItem).append("\n"); - sb.append("Old item: \n").append(oldItem).append("\n"); - sb.append("Values: \n"); - for (VW value : values) { - DebugUtil.indentDebugDump(sb, indent + 1); - sb.append(value.debugDump()); - } - return sb.toString(); - - } - - private String getLocalizedDisplayName() { - Validate.notNull(newItem, "Item must not be null."); - - String displayName = newItem.getDisplayName(); - if (!StringUtils.isEmpty(displayName)) { - return localizeName(displayName, displayName); - } - - QName name = newItem.getElementName(); - if (name != null) { - displayName = name.getLocalPart(); - - PrismContainerValue val = newItem.getParent(); - if (val != null && val.getDefinition() != null - && val.getDefinition().isRuntimeSchema()) { - return localizeName(displayName, displayName); - } - - if (val != null && val.getTypeName() != null) { - if (val.getRealClass() != null) { - displayName = val.getRealClass().getSimpleName() + "." + displayName; - } else { - displayName = val.getTypeName().getLocalPart() + "." + displayName; - } - } - } else { - displayName = newItem.getDefinition().getTypeName().getLocalPart(); - } - - return localizeName(displayName, name.getLocalPart()); - } - - private String localizeName(String nameKey, String defaultString) { - Validate.notNull(nameKey, "Null localization key"); - return ColumnUtils.createStringResource(nameKey, defaultString).getString(); - } - - - @Override - public ItemStatus findObjectStatus() { - if (parent == null) { - return status; - } - - ItemWrapper parentWrapper = parent.getParent(); - - PrismObjectWrapper objectWrapper = findObjectWrapper(parentWrapper); - if (objectWrapper == null) { - return status; - } - - return objectWrapper.getStatus(); - } - - @Override - public , O extends ObjectType> OW findObjectWrapper() { - if (parent == null) { - return null; - } - - ItemWrapper parentWrapper = parent.getParent(); - - return findObjectWrapper(parentWrapper); - - } - - private , O extends ObjectType> OW findObjectWrapper(ItemWrapper parent) { - if (parent != null) { - if (parent instanceof PrismObjectWrapper) { - return (OW) parent; - } - if (parent.getParent() != null) { - return findObjectWrapper(parent.getParent().getParent()); - } - } - return null; - - } - - - @Override - public List getValues() { - return values; - } - - @Override - public VW getValue() throws SchemaException { - if (CollectionUtils.isEmpty(getValues())) { - return null; - } - - if (isMultiValue()) { - throw new SchemaException("Attempt to get sngle value from multi-value property."); - } - - return getValues().iterator().next(); - } - - @Override - public boolean checkRequired(PageBase pageBase) { - return newItem.getDefinition().isMandatory(); - } - - @Override - public boolean isShowEmpty() { - return showEmpty; - } - - @Override - public void setShowEmpty(boolean isShowEmpty, boolean recursive) { - this.showEmpty = isShowEmpty; - } - - @Override - public boolean isShowInVirtualContainer() { - return showInVirtualContainer; - } - - @Override - public void setShowInVirtualContainer(boolean showInVirtualContainer) { - this.showInVirtualContainer = showInVirtualContainer; - } - - @Override - public void setVisibleOverwrite(UserInterfaceElementVisibilityType visibleOverwrite) { - this.visibleOverwrite = visibleOverwrite; - } - - @Override - public boolean isVisible(PrismContainerValueWrapper parentContainer, ItemVisibilityHandler visibilityHandler) { - - if (!isVisibleByVisibilityHandler(parentContainer.isExpanded(), visibilityHandler)) { - return false; - } - - if (!parentContainer.isVirtual() && showInVirtualContainer) { - return false; - } - - ID def = getItemDefinition(); - switch (findObjectStatus()) { - case NOT_CHANGED: - return isVisibleForModify(parentContainer.isShowEmpty(), def); - case ADDED: - return isVisibleForAdd(parentContainer.isShowEmpty(), def); - case DELETED: - return false; - } - - return false; - } - - protected boolean isVisibleByVisibilityHandler(boolean parentExpanded, ItemVisibilityHandler visibilityHandler) { - if (!parentExpanded) { - return false; - } - - - if (visibilityHandler != null) { - ItemVisibility visible = visibilityHandler.isVisible(this); - if (visible != null) { - switch (visible) { - case VISIBLE: - return true; - case HIDDEN: - return false; - default: - // automatic, go on ... - } - } - } - - return true; - - } - - private boolean isVisibleForModify(boolean parentShowEmpty, ID def) { - if (parentShowEmpty) { - return def.canRead(); - } - - return def.canRead() && (def.isEmphasized() || !isEmpty()); - } - - private boolean isVisibleForAdd(boolean parentShowEmpty, ID def) { - if (parentShowEmpty) { - return def.canAdd(); - } - - return def.isEmphasized() && def.canAdd(); - } - - protected boolean isEmpty() { - if (newItem.isEmpty()) { - return true; - } - - return false; - } - - ItemStatus getItemStatus() { - return status; - } - - @NotNull - @Override - public ItemName getItemName() { - return getItemDefinition().getItemName(); - } - - @Override - public String getNamespace() { - return getItemDefinition().getNamespace(); - } - - @Override - public int getMinOccurs() { - return getItemDefinition().getMinOccurs(); - } - - @Override - public int getMaxOccurs() { - return getItemDefinition().getMaxOccurs(); - } - - @Override - public boolean isSingleValue() { - return getItemDefinition().isSingleValue(); - } - - @Override - public boolean isOptional() { - return getItemDefinition().isOptional(); - } - - @Override - public boolean isOperational() { - return getItemDefinition().isOperational(); - } - - @Override - public boolean isInherited() { - return getItemDefinition().isInherited(); - } - - @Override - public boolean isDynamic() { - return getItemDefinition().isDynamic(); - } - - @Override - public boolean canRead() { - return getItemDefinition().canRead(); - } - - @Override - public boolean canModify() { - return getItemDefinition().canModify(); - } - - @Override - public boolean canAdd() { - return getItemDefinition().canAdd(); - } - - @Override - public QName getSubstitutionHead() { - return getItemDefinition().getSubstitutionHead(); - } - - @Override - public boolean isHeterogeneousListItem() { - return getItemDefinition().isHeterogeneousListItem(); - } - - @Override - public PrismReferenceValue getValueEnumerationRef() { - return getItemDefinition().getValueEnumerationRef(); - } - - @Override - public boolean isValidFor(QName elementQName, Class clazz) { - return getItemDefinition().isValidFor(elementQName, clazz); - } - - @Override - public boolean isValidFor(QName elementQName, Class clazz, boolean caseInsensitive) { - return getItemDefinition().isValidFor(elementQName, clazz, caseInsensitive); - } - - @Override - public void adoptElementDefinitionFrom(ItemDefinition otherDef) { - getItemDefinition().adoptElementDefinitionFrom(otherDef); - } - - @NotNull - @Override - public I instantiate() throws SchemaException { - return getItemDefinition().instantiate(); - } - - @NotNull - @Override - public I instantiate(QName name) throws SchemaException { - return getItemDefinition().instantiate(); - } - - @Override - public T findItemDefinition(ItemPath path, Class clazz) { - return getItemDefinition().findItemDefinition(path, clazz); - } - - @Override - public ItemDelta createEmptyDelta(ItemPath path) { - return getItemDefinition().createEmptyDelta(path); - } - - @Override - public ItemDefinition clone() { - return getItemDefinition().clone(); - } - - @Override - public ItemDefinition deepClone(boolean ultraDeep, Consumer postCloneAction) { - return getItemDefinition().deepClone(ultraDeep, postCloneAction); - } - - @Override - public ItemDefinition deepClone(Map ctdMap, Map onThisPath, - Consumer postCloneAction) { - return getItemDefinition().deepClone(ctdMap, onThisPath, postCloneAction); - } - - @Override - public void revive(PrismContext prismContext) { - getItemDefinition().revive(prismContext); - } - - @Override - public void debugDumpShortToString(StringBuilder sb) { - //TODO implement for wrappers - getItemDefinition().debugDumpShortToString(sb); - } - - @Override - public boolean canBeDefinitionOf(I item) { - return getItemDefinition().canBeDefinitionOf(item); - } - - @Override - public boolean canBeDefinitionOf(PrismValue pvalue) { - return getItemDefinition().canBeDefinitionOf(pvalue); - } - - @Override - public MutableItemDefinition toMutable() { - return getItemDefinition().toMutable(); - } - - @Override - public QName getTypeName() { - return getItemDefinition().getTypeName(); - } - - @Override - public boolean isRuntimeSchema() { - return getItemDefinition().isRuntimeSchema(); - } - - @Override - @Deprecated - public boolean isIgnored() { - return getItemDefinition().isIgnored(); - } - - @Override - public ItemProcessing getProcessing() { - return getItemDefinition().getProcessing(); - } - - @Override - public boolean isAbstract() { - return getItemDefinition().isAbstract(); - } - - @Override - public String getPlannedRemoval() { - return getItemDefinition().getPlannedRemoval(); - } - - @Override - public boolean isElaborate() { - return getItemDefinition().isElaborate(); - } - - @Override - public boolean isEmphasized() { - return getItemDefinition().isEmphasized(); - } - - @Override - public Integer getDisplayOrder() { - return getItemDefinition().getDisplayOrder(); - } - - @Override - public String getDocumentation() { - return getItemDefinition().getDocumentation(); - } - - @Override - public String getDocumentationPreview() { - return getItemDefinition().getDocumentationPreview(); - } - - @Override - public PrismContext getPrismContext() { - return getItemDefinition().getPrismContext(); - } - - @Override - public Class getTypeClassIfKnown() { - return getItemDefinition().getTypeClassIfKnown(); - } - - @Override - public Class getTypeClass() { - return getItemDefinition().getTypeClass(); - } - - @Override - public A getAnnotation(QName qname) { - return getItemDefinition().getAnnotation(qname); - } - - @Override - public void setAnnotation(QName qname, A value) { - getItemDefinition().setAnnotation(qname, value); - } - - @Override - public List getSchemaMigrations() { - return getItemDefinition().getSchemaMigrations(); - } - -// @Override -// public void accept(Visitor visitor) { -// getItemDefinition().accept(visitor); -// } -// - - @Override - public void setReadOnly(boolean readOnly) { - this.readOnly = readOnly; - } - - @Override - public boolean isStripe() { - return stripe; - } - - @Override - public void setStripe(boolean stripe) { - this.stripe = stripe; - } - - protected I getOldItem() { - return oldItem; - } - - @Override - public boolean isIndexOnly() { - return false; // todo - } - - protected UserInterfaceElementVisibilityType getVisibleOverwrite() { - return visibleOverwrite; - } -} +/* + * Copyright (c) 2010-2018 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ +package com.evolveum.midpoint.gui.impl.prism; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.prism.*; +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; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import com.evolveum.midpoint.gui.api.page.PageBase; +import com.evolveum.midpoint.gui.api.prism.ItemStatus; +import com.evolveum.midpoint.gui.api.prism.ItemWrapper; +import com.evolveum.midpoint.gui.api.prism.PrismObjectWrapper; +import com.evolveum.midpoint.gui.api.util.WebPrismUtil; +import com.evolveum.midpoint.prism.delta.ItemDelta; +import com.evolveum.midpoint.prism.path.ItemName; +import com.evolveum.midpoint.prism.path.ItemPath; +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 com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.web.component.data.column.ColumnUtils; +import com.evolveum.midpoint.web.component.prism.ItemVisibility; +import com.evolveum.midpoint.web.component.prism.ValueStatus; + +/** + * @author katka + * + */ +public abstract class ItemWrapperImpl, ID extends ItemDefinition, VW extends PrismValueWrapper> implements ItemWrapper, Serializable { + + private static final long serialVersionUID = 1L; + + private static final Trace LOGGER = TraceManager.getTrace(ItemWrapperImpl.class); + + private PrismContainerValueWrapper parent; + + private ItemStatus status = null; + + private String displayName; + + private List values = new ArrayList<>(); + + private I oldItem; + private I newItem; + + private boolean column; + + private boolean stripe; + + private boolean showEmpty; + + private boolean showInVirtualContainer; + + + //consider + private boolean readOnly; + private UserInterfaceElementVisibilityType visibleOverwrite; + + public ItemWrapperImpl(@Nullable PrismContainerValueWrapper parent, I item, ItemStatus status) { + Validate.notNull(item, "Item must not be null."); + Validate.notNull(status, "Item status must not be null."); + + this.parent = parent; + this.newItem = item; + this.oldItem = (I) item.clone(); + this.status = status; + + } + + protected , O extends ObjectType> D getItemDelta(Class objectClass, Class deltaClass) throws SchemaException { + D delta = (D) createEmptyDelta(null); + for (VW value : values) { + value.addToDelta(delta); + } + + if (delta.isEmpty()) { + return null; + } + return delta; + } + + @Override + public > Collection getDelta() throws SchemaException { + LOGGER.trace("Start computing delta for {}", newItem); + + if (isOperational()) { + return null; + } + + D delta = null; + if (parent != null && ValueStatus.ADDED == parent.getStatus()) { + delta = (D) createEmptyDelta(getItemName()); + } else { + delta = (D) createEmptyDelta(getPath()); + } + + for (VW value : values) { + value.addToDelta(delta); + } + + if (delta.isEmpty()) { + LOGGER.trace("There is no delta for {}", newItem); + return null; + } + + LOGGER.trace("Returning delta {}", delta); + return MiscUtil.createCollection(delta); + } + + + @Override + public > void applyDelta(D delta) throws SchemaException { + if (delta == null) { + return; + } + + LOGGER.trace("Applying {} to {}", delta, newItem); + delta.applyTo(newItem); + } + + @Override + public String getDisplayName() { + if (displayName == null) { + displayName = getLocalizedDisplayName(); + } + + return displayName; + } + + + + @Override + public String getHelp() { + return WebPrismUtil.getHelpText(getItemDefinition()); + } + + @Override + public boolean isExperimental() { + return getItemDefinition().isExperimental(); + } + + @Override + public String getDeprecatedSince() { + return getItemDefinition().getDeprecatedSince(); + } + + @Override + public boolean isDeprecated() { + return getItemDefinition().isDeprecated(); + } + + @Override + public boolean isMandatory() { + return getItemDefinition().isMandatory(); + } + + public ItemStatus getStatus() { + return status; + } + + @Override + public I getItem() { + return newItem; + } + + @Override + public void setColumn(boolean column) { + this.column = column; + } + + @Override + public boolean isColumn() { + return column; + } + + public PrismContainerValueWrapper getParent() { + return parent; + } + + @Override + public boolean isMultiValue() { + return getItemDefinition().isMultiValue(); + } + + @Override + public boolean isReadOnly() { + return readOnly; + } + + @Override + public ItemPath getPath() { + return newItem.getPath(); + } + + @Override + public ExpressionType getFormComponentValidator() { + FormItemValidationType formItemValidation = getItemDefinition().getAnnotation(ItemRefinedDefinitionType.F_VALIDATION); + if (formItemValidation == null) { + return null; + } + + List serverValidators = formItemValidation.getServer(); + if (CollectionUtils.isNotEmpty(serverValidators)) { + return serverValidators.iterator().next().getExpression(); + } + + return null; + } + + ID getItemDefinition() { + return newItem.getDefinition(); + } + + @Override + public String debugDump(int indent) { + StringBuilder sb = DebugUtil.createIndentedStringBuilder(indent); + sb.append(toString()); + sb.append("Original definition: ").append(newItem.getDefinition()).append("\n"); + sb.append("Display nam: ").append(displayName).append("\n"); + sb.append("Item status: ").append(status).append("\n"); + sb.append("Read only: ").append(isReadOnly()).append("\n"); + sb.append("New item: \n").append(newItem).append("\n"); + sb.append("Old item: \n").append(oldItem).append("\n"); + sb.append("Values: \n"); + for (VW value : values) { + DebugUtil.indentDebugDump(sb, indent + 1); + sb.append(value.debugDump()); + } + return sb.toString(); + + } + + private String getLocalizedDisplayName() { + Validate.notNull(newItem, "Item must not be null."); + + String displayName = newItem.getDisplayName(); + if (!StringUtils.isEmpty(displayName)) { + return localizeName(displayName, displayName); + } + + QName name = newItem.getElementName(); + if (name != null) { + displayName = name.getLocalPart(); + + PrismContainerValue val = newItem.getParent(); + if (val != null && val.getDefinition() != null + && val.getDefinition().isRuntimeSchema()) { + return localizeName(displayName, displayName); + } + + if (val != null && val.getTypeName() != null) { + if (val.getRealClass() != null) { + displayName = val.getRealClass().getSimpleName() + "." + displayName; + } else { + displayName = val.getTypeName().getLocalPart() + "." + displayName; + } + } + } else { + displayName = newItem.getDefinition().getTypeName().getLocalPart(); + } + + return localizeName(displayName, name.getLocalPart()); + } + + private String localizeName(String nameKey, String defaultString) { + Validate.notNull(nameKey, "Null localization key"); + return ColumnUtils.createStringResource(nameKey, defaultString).getString(); + } + + + @Override + public ItemStatus findObjectStatus() { + if (parent == null) { + return status; + } + + ItemWrapper parentWrapper = parent.getParent(); + + PrismObjectWrapper objectWrapper = findObjectWrapper(parentWrapper); + if (objectWrapper == null) { + return status; + } + + return objectWrapper.getStatus(); + } + + @Override + public , O extends ObjectType> OW findObjectWrapper() { + if (parent == null) { + return null; + } + + ItemWrapper parentWrapper = parent.getParent(); + + return findObjectWrapper(parentWrapper); + + } + + private , O extends ObjectType> OW findObjectWrapper(ItemWrapper parent) { + if (parent != null) { + if (parent instanceof PrismObjectWrapper) { + return (OW) parent; + } + if (parent.getParent() != null) { + return findObjectWrapper(parent.getParent().getParent()); + } + } + return null; + + } + + + @Override + public List getValues() { + return values; + } + + @Override + public VW getValue() throws SchemaException { + if (CollectionUtils.isEmpty(getValues())) { + return null; + } + + if (isMultiValue()) { + throw new SchemaException("Attempt to get sngle value from multi-value property."); + } + + return getValues().iterator().next(); + } + + @Override + public boolean checkRequired(PageBase pageBase) { + return newItem.getDefinition().isMandatory(); + } + + @Override + public boolean isShowEmpty() { + return showEmpty; + } + + @Override + public void setShowEmpty(boolean isShowEmpty, boolean recursive) { + this.showEmpty = isShowEmpty; + } + + @Override + public boolean isShowInVirtualContainer() { + return showInVirtualContainer; + } + + @Override + public void setShowInVirtualContainer(boolean showInVirtualContainer) { + this.showInVirtualContainer = showInVirtualContainer; + } + + @Override + public void setVisibleOverwrite(UserInterfaceElementVisibilityType visibleOverwrite) { + this.visibleOverwrite = visibleOverwrite; + } + + @Override + public boolean isVisible(PrismContainerValueWrapper parentContainer, ItemVisibilityHandler visibilityHandler) { + + if (!isVisibleByVisibilityHandler(parentContainer.isExpanded(), visibilityHandler)) { + return false; + } + + if (!parentContainer.isVirtual() && showInVirtualContainer) { + return false; + } + + ID def = getItemDefinition(); + switch (findObjectStatus()) { + case NOT_CHANGED: + return isVisibleForModify(parentContainer.isShowEmpty(), def); + case ADDED: + return isVisibleForAdd(parentContainer.isShowEmpty(), def); + case DELETED: + return false; + } + + return false; + } + + protected boolean isVisibleByVisibilityHandler(boolean parentExpanded, ItemVisibilityHandler visibilityHandler) { + if (!parentExpanded) { + return false; + } + + + if (visibilityHandler != null) { + ItemVisibility visible = visibilityHandler.isVisible(this); + if (visible != null) { + switch (visible) { + case VISIBLE: + return true; + case HIDDEN: + return false; + default: + // automatic, go on ... + } + } + } + + return true; + + } + + private boolean isVisibleForModify(boolean parentShowEmpty, ID def) { + if (parentShowEmpty) { + return def.canRead(); + } + + return def.canRead() && (def.isEmphasized() || !isEmpty()); + } + + private boolean isVisibleForAdd(boolean parentShowEmpty, ID def) { + if (parentShowEmpty) { + return def.canAdd(); + } + + return (def.isEmphasized() || !isEmpty()) && def.canAdd(); + } + + protected boolean isEmpty() { + if (newItem.isEmpty()) { + return true; + } + + return false; + } + + ItemStatus getItemStatus() { + return status; + } + + @NotNull + @Override + public ItemName getItemName() { + return getItemDefinition().getItemName(); + } + + @Override + public String getNamespace() { + return getItemDefinition().getNamespace(); + } + + @Override + public int getMinOccurs() { + return getItemDefinition().getMinOccurs(); + } + + @Override + public int getMaxOccurs() { + return getItemDefinition().getMaxOccurs(); + } + + @Override + public boolean isSingleValue() { + return getItemDefinition().isSingleValue(); + } + + @Override + public boolean isOptional() { + return getItemDefinition().isOptional(); + } + + @Override + public boolean isOperational() { + return getItemDefinition().isOperational(); + } + + @Override + public boolean isInherited() { + return getItemDefinition().isInherited(); + } + + @Override + public boolean isDynamic() { + return getItemDefinition().isDynamic(); + } + + @Override + public boolean canRead() { + return getItemDefinition().canRead(); + } + + @Override + public boolean canModify() { + return getItemDefinition().canModify(); + } + + @Override + public boolean canAdd() { + return getItemDefinition().canAdd(); + } + + @Override + public QName getSubstitutionHead() { + return getItemDefinition().getSubstitutionHead(); + } + + @Override + public boolean isHeterogeneousListItem() { + return getItemDefinition().isHeterogeneousListItem(); + } + + @Override + public PrismReferenceValue getValueEnumerationRef() { + return getItemDefinition().getValueEnumerationRef(); + } + + @Override + public boolean isValidFor(QName elementQName, Class clazz) { + return getItemDefinition().isValidFor(elementQName, clazz); + } + + @Override + public boolean isValidFor(QName elementQName, Class clazz, boolean caseInsensitive) { + return getItemDefinition().isValidFor(elementQName, clazz, caseInsensitive); + } + + @Override + public void adoptElementDefinitionFrom(ItemDefinition otherDef) { + getItemDefinition().adoptElementDefinitionFrom(otherDef); + } + + @NotNull + @Override + public I instantiate() throws SchemaException { + return getItemDefinition().instantiate(); + } + + @NotNull + @Override + public I instantiate(QName name) throws SchemaException { + return getItemDefinition().instantiate(); + } + + @Override + public T findItemDefinition(ItemPath path, Class clazz) { + return getItemDefinition().findItemDefinition(path, clazz); + } + + @Override + public ItemDelta createEmptyDelta(ItemPath path) { + return getItemDefinition().createEmptyDelta(path); + } + + @Override + public ItemDefinition clone() { + return getItemDefinition().clone(); + } + + @Override + public ItemDefinition deepClone(boolean ultraDeep, Consumer postCloneAction) { + return getItemDefinition().deepClone(ultraDeep, postCloneAction); + } + + @Override + public ItemDefinition deepClone(Map ctdMap, Map onThisPath, + Consumer postCloneAction) { + return getItemDefinition().deepClone(ctdMap, onThisPath, postCloneAction); + } + + @Override + public void revive(PrismContext prismContext) { + getItemDefinition().revive(prismContext); + } + + @Override + public void debugDumpShortToString(StringBuilder sb) { + //TODO implement for wrappers + getItemDefinition().debugDumpShortToString(sb); + } + + @Override + public boolean canBeDefinitionOf(I item) { + return getItemDefinition().canBeDefinitionOf(item); + } + + @Override + public boolean canBeDefinitionOf(PrismValue pvalue) { + return getItemDefinition().canBeDefinitionOf(pvalue); + } + + @Override + public MutableItemDefinition toMutable() { + return getItemDefinition().toMutable(); + } + + @Override + public QName getTypeName() { + return getItemDefinition().getTypeName(); + } + + @Override + public boolean isRuntimeSchema() { + return getItemDefinition().isRuntimeSchema(); + } + + @Override + @Deprecated + public boolean isIgnored() { + return getItemDefinition().isIgnored(); + } + + @Override + public ItemProcessing getProcessing() { + return getItemDefinition().getProcessing(); + } + + @Override + public boolean isAbstract() { + return getItemDefinition().isAbstract(); + } + + @Override + public String getPlannedRemoval() { + return getItemDefinition().getPlannedRemoval(); + } + + @Override + public boolean isElaborate() { + return getItemDefinition().isElaborate(); + } + + @Override + public boolean isEmphasized() { + return getItemDefinition().isEmphasized(); + } + + @Override + public Integer getDisplayOrder() { + return getItemDefinition().getDisplayOrder(); + } + + @Override + public String getDocumentation() { + return getItemDefinition().getDocumentation(); + } + + @Override + public String getDocumentationPreview() { + return getItemDefinition().getDocumentationPreview(); + } + + @Override + public PrismContext getPrismContext() { + return getItemDefinition().getPrismContext(); + } + + @Override + public Class getTypeClassIfKnown() { + return getItemDefinition().getTypeClassIfKnown(); + } + + @Override + public Class getTypeClass() { + return getItemDefinition().getTypeClass(); + } + + @Override + public A getAnnotation(QName qname) { + return getItemDefinition().getAnnotation(qname); + } + + @Override + public void setAnnotation(QName qname, A value) { + getItemDefinition().setAnnotation(qname, value); + } + + @Override + public List getSchemaMigrations() { + return getItemDefinition().getSchemaMigrations(); + } + +// @Override +// public void accept(Visitor visitor) { +// getItemDefinition().accept(visitor); +// } +// + + @Override + public void setReadOnly(boolean readOnly) { + this.readOnly = readOnly; + } + + @Override + public boolean isStripe() { + return stripe; + } + + @Override + public void setStripe(boolean stripe) { + this.stripe = stripe; + } + + protected I getOldItem() { + return oldItem; + } + + @Override + public boolean isIndexOnly() { + return false; // todo + } + + protected UserInterfaceElementVisibilityType getVisibleOverwrite() { + return visibleOverwrite; + } +}