From e2ca89d6ec4ead3c0137e30e65e3aa8318084b9f Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Mon, 23 Mar 2020 10:34:10 +0100 Subject: [PATCH] background taskOid to operationRest for newly created tasks --- .../web/component/progress/ProgressPanel.java | 22 +- .../component/progress/ProgressReporter.java | 9 + .../progress/ProgressReportingAwarePage.java | 7 +- .../page/admin/PageAdminObjectDetails.java | 2255 +++++++++-------- .../web/page/admin/cases/PageCase.java | 549 ++-- .../PageSystemConfiguration.java | 855 +++---- .../web/page/admin/server/PageTask.java | 1029 ++++---- 7 files changed, 2380 insertions(+), 2346 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressPanel.java index 28b328038da..923c18b7e3e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressPanel.java @@ -18,14 +18,12 @@ import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismProperty; import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.delta.DeltaFactory; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.schema.DeltaConvertor; import com.evolveum.midpoint.schema.ObjectDeltaOperation; import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.security.api.HttpConnectionInformation; import com.evolveum.midpoint.security.api.MidPointPrincipal; import com.evolveum.midpoint.security.api.SecurityContextManager; @@ -34,7 +32,6 @@ import com.evolveum.midpoint.task.api.TaskExecutionStatus; import com.evolveum.midpoint.task.api.TaskManager; import com.evolveum.midpoint.util.exception.CommonException; -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; @@ -43,7 +40,6 @@ import com.evolveum.midpoint.web.component.AjaxSubmitButton; import com.evolveum.midpoint.web.component.SecurityContextAwareCallable; import com.evolveum.midpoint.web.component.form.Form; -import com.evolveum.midpoint.web.page.admin.PageAdminObjectDetails; import com.evolveum.midpoint.web.page.admin.server.dto.OperationResultStatusPresentationProperties; import com.evolveum.midpoint.web.page.login.PageLogin; import com.evolveum.midpoint.web.security.MidPointApplication; @@ -52,8 +48,6 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType; -import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; - import org.apache.wicket.AttributeModifier; import org.apache.wicket.Component; import org.apache.wicket.RestartResponseException; @@ -78,9 +72,6 @@ import static com.evolveum.midpoint.model.api.ProgressInformation.ActivityType.RESOURCE_OBJECT_OPERATION; import static com.evolveum.midpoint.schema.util.ObjectTypeUtil.createObjectRef; import static com.evolveum.midpoint.web.component.progress.ProgressReportActivityDto.ResourceOperationResult; -import static com.evolveum.midpoint.xml.ns._public.common.common_3.TaskExecutionStatusType.RUNNABLE; - -import static java.util.Collections.singleton; /** * @author mederly @@ -429,7 +420,7 @@ public void executeChanges(Collection> deltas, if (!reporter.isAsynchronousExecution() && page instanceof ProgressReportingAwarePage) { ProgressReportingAwarePage aware = (ProgressReportingAwarePage) page; - aware.finishProcessing(target, result, reporter.isAsynchronousExecution()); + aware.finishProcessing(target, reporter.getObjectDeltaOperation(), reporter.isAsynchronousExecution(), result); } } @@ -484,7 +475,7 @@ public void executeChangesInBackground(Collection> deltas, boolean previewOnly, ModelExecuteOptions options, Task task, OperationResult result) { + try { MidPointApplication application = MidPointApplication.get(); @@ -632,7 +624,8 @@ private void executeChangesSync(ProgressReporter reporter, Collection>executedDeltas = service.executeChanges(deltas, options, task, result); + reporter.setObjectDeltaOperation(executedDeltas); } result.computeStatusIfUnknown(); } catch (CommonException | RuntimeException e) { @@ -670,7 +663,8 @@ public Void callWithContextPrepared() throws Exception { .previewChanges(deltas, options, task, Collections.singleton(reporter), result); reporter.setPreviewResult(previewResult); } else if (deltas != null && deltas.size() > 0){ - model.executeChanges(deltas, options, task, Collections.singleton(reporter), result); + Collection> executedDeltas = model.executeChanges(deltas, options, task, Collections.singleton(reporter), result); + reporter.setObjectDeltaOperation(executedDeltas); } } catch (CommonException | RuntimeException e) { LoggingUtils.logUnexpectedException(LOGGER, "Error executing changes", e); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressReporter.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressReporter.java index 01c4f0c61fd..f2d276f3dec 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressReporter.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressReporter.java @@ -58,6 +58,7 @@ public class ProgressReporter implements ProgressListener { // Operation result got from the asynchronous operation (null if async op not yet finished) private OperationResult asyncOperationResult; private ModelContext previewResult; + private Collection> objectDeltaOperation; private long operationStartTime; // if 0, operation hasn't start yet private long operationDurationTime; // if >0, operation has finished @@ -95,6 +96,14 @@ public void setAsyncOperationResult(OperationResult asyncOperationResult) { this.asyncOperationResult = asyncOperationResult; } + public Collection> getObjectDeltaOperation() { + return objectDeltaOperation; + } + + public void setObjectDeltaOperation(Collection> objectDeltaOperation) { + this.objectDeltaOperation = objectDeltaOperation; + } + public void setPreviewResult(ModelContext previewResult) { this.previewResult = previewResult; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressReportingAwarePage.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressReportingAwarePage.java index c8130669841..0a5da2ae625 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressReportingAwarePage.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressReportingAwarePage.java @@ -7,9 +7,14 @@ package com.evolveum.midpoint.web.component.progress; +import com.evolveum.midpoint.schema.ObjectDeltaOperation; import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; + import org.apache.wicket.ajax.AjaxRequestTarget; +import java.util.Collection; + /** * A page that supports progress reporting, e.g. page for editing users, orgs, roles. *

@@ -22,7 +27,7 @@ public interface ProgressReportingAwarePage { void startProcessing(AjaxRequestTarget target, OperationResult result); - void finishProcessing(AjaxRequestTarget target, OperationResult result, boolean returningFromAsync); + void finishProcessing(AjaxRequestTarget target, Collection> executedDeltas, boolean returningFromAsync, OperationResult result); void continueEditing(AjaxRequestTarget target); } 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 7f48e36fc3f..16bdd93a6d0 100755 --- 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 @@ -1,1126 +1,1129 @@ -/* - * 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.web.page.admin; - -import java.util.*; - -import javax.xml.namespace.QName; - -import com.evolveum.midpoint.gui.api.component.*; -import com.evolveum.midpoint.gui.api.component.tabs.PanelTab; -import com.evolveum.midpoint.gui.api.prism.PrismContainerWrapper; -import com.evolveum.midpoint.gui.api.util.WebPrismUtil; -import com.evolveum.midpoint.model.api.context.ModelContext; -import com.evolveum.midpoint.prism.PrismContainerValue; -import com.evolveum.midpoint.prism.PrismReference; -import com.evolveum.midpoint.prism.PrismReferenceValue; -import com.evolveum.midpoint.prism.query.ObjectFilter; -import com.evolveum.midpoint.prism.query.ObjectQuery; -import com.evolveum.midpoint.schema.constants.SchemaConstants; -import com.evolveum.midpoint.schema.util.ObjectTypeUtil; -import com.evolveum.midpoint.util.exception.*; -import com.evolveum.midpoint.web.component.AjaxButton; -import com.evolveum.midpoint.web.component.prism.ValueStatus; -import com.evolveum.midpoint.web.component.prism.show.PagePreviewChanges; -import com.evolveum.midpoint.web.component.refresh.Refreshable; -import com.evolveum.midpoint.web.component.util.SelectableBean; -import com.evolveum.midpoint.web.component.util.VisibleBehaviour; -import com.evolveum.midpoint.web.page.admin.configuration.PageSystemConfiguration; -import com.evolveum.midpoint.web.page.admin.server.OperationalButtonsPanel; -import com.evolveum.midpoint.web.page.admin.server.RefreshableTabPanel; -import com.evolveum.midpoint.web.security.util.SecurityUtils; -import com.evolveum.midpoint.xml.ns._public.common.common_3.*; - -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.wicket.Component; -import org.apache.wicket.Page; -import org.apache.wicket.RestartResponseException; -import org.apache.wicket.Session; -import org.apache.wicket.ajax.AbstractAjaxTimerBehavior; -import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.ajax.AjaxSelfUpdatingTimerBehavior; -import org.apache.wicket.behavior.AttributeAppender; -import org.apache.wicket.extensions.markup.html.tabs.ITab; -import org.apache.wicket.markup.html.WebMarkupContainer; -import org.apache.wicket.markup.repeater.RepeatingView; -import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; -import org.apache.wicket.model.StringResourceModel; -import org.apache.wicket.protocol.http.WebSession; -import org.apache.wicket.request.mapper.parameter.PageParameters; -import org.apache.wicket.util.string.StringValue; -import org.apache.wicket.util.time.Duration; -import org.jetbrains.annotations.NotNull; - -import com.evolveum.midpoint.gui.api.model.LoadableModel; -import com.evolveum.midpoint.gui.api.prism.ItemStatus; -import com.evolveum.midpoint.gui.api.prism.PrismObjectWrapper; -import com.evolveum.midpoint.gui.api.util.WebComponentUtil; -import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; -import com.evolveum.midpoint.gui.impl.factory.PrismObjectWrapperFactory; -import com.evolveum.midpoint.gui.impl.factory.WrapperContext; -import com.evolveum.midpoint.model.api.ModelExecuteOptions; -import com.evolveum.midpoint.model.api.authentication.CompiledGuiProfile; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.delta.ObjectDelta; -import com.evolveum.midpoint.schema.GetOperationOptions; -import com.evolveum.midpoint.schema.SelectorOptions; -import com.evolveum.midpoint.schema.constants.ObjectTypes; -import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.task.api.Task; -import com.evolveum.midpoint.util.QNameUtil; -import com.evolveum.midpoint.util.logging.LoggingUtils; -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.web.component.ObjectSummaryPanel; -import com.evolveum.midpoint.web.component.objectdetails.AbstractObjectMainPanel; -import com.evolveum.midpoint.web.component.progress.ProgressPanel; -import com.evolveum.midpoint.web.component.progress.ProgressReportingAwarePage; -import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; -import com.evolveum.midpoint.web.page.admin.users.dto.FocusSubwrapperDto; -import com.evolveum.midpoint.web.util.OnePageParameterEncoder; -import com.evolveum.midpoint.web.util.validation.MidpointFormValidator; -import com.evolveum.midpoint.web.util.validation.SimpleValidationError; - -/** - * @author semancik - */ -public abstract class PageAdminObjectDetails extends PageAdmin - implements ProgressReportingAwarePage, Refreshable { - private static final long serialVersionUID = 1L; - - private static final String DOT_CLASS = PageAdminObjectDetails.class.getName() + "."; - - private static final String OPERATION_LOAD_OBJECT = DOT_CLASS + "loadObject"; - protected static final String OPERATION_SAVE = DOT_CLASS + "save"; - protected static final String OPERATION_PREVIEW_CHANGES = DOT_CLASS + "previewChanges"; - protected static final String OPERATION_SEND_TO_SUBMIT = DOT_CLASS + "sendToSubmit"; - protected static final String OPERATION_LOAD_ARCHETYPE_REF = DOT_CLASS + "loadArchetypeRef"; - protected static final String OPERATION_EXECUTE_ARCHETYPE_CHANGES = DOT_CLASS + "executeArchetypeChanges"; - protected static final String OPERATION_LOAD_FILTERED_ARCHETYPES = DOT_CLASS + "loadFilteredArchetypes"; - protected static final String OPERATION_LOAD_PARENT_ORG = DOT_CLASS + "loadParentOrgs"; - - protected static final String ID_SUMMARY_PANEL = "summaryPanel"; - protected static final String ID_MAIN_PANEL = "mainPanel"; - private static final String ID_PROGRESS_PANEL = "progressPanel"; - private static final String ID_BUTTONS = "buttons"; - - private static final Trace LOGGER = TraceManager.getTrace(PageAdminObjectDetails.class); - - private LoadableModel> objectModel; - private LoadableModel>> parentOrgModel; - - private ProgressPanel progressPanel; - - // used to determine whether to leave this page or stay on it (after - // operation finishing) - private ObjectDelta delta; - - private AbstractObjectMainPanel mainPanel; - private boolean saveOnConfigure; // ugly hack - whether to invoke 'Save' when returning to this page - - private boolean editingFocus = false; //before we got isOidParameterExists status depending only on oid parameter existence - //we should set editingFocus=true not only when oid parameter exists but also - //when object is given as a constructor parameter - - public boolean isEditingFocus() { - return editingFocus; - } - - @Override - protected void createBreadcrumb() { - createInstanceBreadcrumb(); - } - - @Override - protected void onConfigure() { - super.onConfigure(); - if (saveOnConfigure) { - saveOnConfigure = false; - add(new AbstractAjaxTimerBehavior(Duration.milliseconds(100)) { - @Override - protected void onTimer(AjaxRequestTarget target) { - stop(target); - savePerformed(target); - } - }); - } - } - - @Override - protected IModel createPageTitleModel() { - if (PageAdminObjectDetails.this instanceof PageSystemConfiguration){ - return super.createPageTitleModel(); - } - String simpleName = getObjectSimpleName(); - String lokalizedSimpleName = new StringResourceModel("ObjectType." + simpleName).setDefaultValue(simpleName).getString(); - if (isAdd()) { - return createStringResource("PageAdminObjectDetails.title.new", lokalizedSimpleName); - } - - String name = null; - if (getObjectWrapper() != null && getObjectWrapper().getObject() != null) { - name = WebComponentUtil.getName(getObjectWrapper().getObject()); - } - - return createStringResource("PageAdminObjectDetails.title.edit.readonly.${readOnly}", getObjectModel(), lokalizedSimpleName, name); - } - - private String getObjectSimpleName(){ - if (getObjectWrapper() != null && getObjectWrapper().getObject() != null - && getObjectWrapper().getObject().asObjectable() instanceof AssignmentHolderType){ - AssignmentHolderType assignmentHolderObj = (AssignmentHolderType) getObjectWrapper().getObject().asObjectable(); - DisplayType displayType = WebComponentUtil - .getArchetypePolicyDisplayType(assignmentHolderObj, PageAdminObjectDetails.this); - if (displayType == null){ - ObjectReferenceType archetypeReference = getObjectArchetypeRef(); - if (archetypeReference != null){ - OperationResult result = new OperationResult(OPERATION_LOAD_ARCHETYPE_REF); - Task task = createSimpleTask(OPERATION_LOAD_ARCHETYPE_REF); - PrismObject archetypeObj = WebModelServiceUtils.resolveReferenceNoFetch(archetypeReference, - this, task, result); - displayType = archetypeObj != null && archetypeObj.asObjectable().getArchetypePolicy() != null ? - archetypeObj.asObjectable().getArchetypePolicy().getDisplay() : null; - } - } - if (displayType != null && displayType.getLabel() != null) { - String archetypeLocalizedName = getLocalizationService() - .translate(displayType.getLabel().toPolyString(), WebComponentUtil.getCurrentLocale(), true); - if (StringUtils.isNotEmpty(archetypeLocalizedName)) { - return archetypeLocalizedName; - } - } - } - return getCompileTimeClass().getSimpleName(); - } - - public boolean isAdd() { - return !isOidParameterExists() && !editingFocus; - } - - public LoadableModel> getObjectModel() { - return objectModel; - } - - protected AbstractObjectMainPanel getMainPanel() { - return mainPanel; - } - - public PrismObjectWrapper getObjectWrapper() { - return objectModel.getObject(); - } - - public List> getParentOrgs() { - return parentOrgModel.getObject(); - } - - public ObjectDelta getDelta() { - return delta; - } - - public void setDelta(ObjectDelta delta) { - this.delta = delta; - } - - public ProgressPanel getProgressPanel() { - return progressPanel; - } - - protected void reviveModels() throws SchemaException { - WebComponentUtil.revive(objectModel, getPrismContext()); - WebComponentUtil.revive(parentOrgModel, getPrismContext()); - } - - public abstract Class getCompileTimeClass(); - - - public void initialize(final PrismObject objectToEdit) { - boolean isNewObject = objectToEdit == null && StringUtils.isEmpty(getObjectOidParameter()); - - initialize(objectToEdit, isNewObject, false); - } - - public void initialize(final PrismObject objectToEdit, boolean isNewObject) { - initialize(objectToEdit, isNewObject, false); - } - - public void initialize(final PrismObject objectToEdit, boolean isNewObject, boolean isReadonly) { - initializeModel(objectToEdit, isNewObject, isReadonly); - } - - protected void initializeModel(final PrismObject objectToEdit, boolean isNewObject, boolean isReadonly) { - editingFocus = !isNewObject; - - objectModel = new LoadableModel>(false) { - private static final long serialVersionUID = 1L; - - @Override - protected PrismObjectWrapper load() { - PrismObjectWrapper wrapper = loadObjectWrapper(objectToEdit, isReadonly); - return wrapper; - } - }; - - parentOrgModel = new LoadableModel>>(false) { - private static final long serialVersionUID = 1L; - - @Override - protected List> load() { - return loadOrgWrappers(); - } - }; - } - - private ObjectReferenceType getObjectArchetypeRef() { - ObjectReferenceType archetypeReference = null; - if (getObjectWrapper() != null && getObjectWrapper().getObject() != null - && getObjectWrapper().getObject().asObjectable() instanceof AssignmentHolderType) { - AssignmentHolderType assignmentHolderObj = (AssignmentHolderType) getObjectWrapper().getObject().asObjectable(); - if (assignmentHolderObj.getAssignment() != null) { - for (AssignmentType assignment : assignmentHolderObj.getAssignment()) { - if (assignment.getTargetRef() != null && assignment.getTargetRef().getType() != null - && QNameUtil.match(assignment.getTargetRef().getType(), ArchetypeType.COMPLEX_TYPE)) { - archetypeReference = assignment.getTargetRef(); - break; - } - } - } - } - return archetypeReference; - } - - protected List> loadOrgWrappers() { - // WRONG!! TODO: fix - return null; - } - - protected abstract O createNewObject(); - - @Override - protected void onInitialize() { - super.onInitialize(); - initLayout(); - } - - protected void initLayout() { - initLayoutSummaryPanel(); - initOperationalButtonsPanel(); - - mainPanel = createMainPanel(ID_MAIN_PANEL); - mainPanel.setOutputMarkupId(true); - add(mainPanel); - - progressPanel = new ProgressPanel(ID_PROGRESS_PANEL); - add(progressPanel); - } - - protected abstract ObjectSummaryPanel createSummaryPanel(IModel summaryModel); - - protected void initLayoutSummaryPanel() { - - ObjectSummaryPanel summaryPanel = createSummaryPanel(loadModelForSummaryPanel()); - summaryPanel.setOutputMarkupId(true); - - setSummaryPanelVisibility(summaryPanel); - add(summaryPanel); - } - - private IModel loadModelForSummaryPanel() { - return new LoadableModel(true) { - - @Override - protected O load() { - PrismObjectWrapper wrapper = getObjectWrapper(); - if (wrapper == null) { - return null; - } - - PrismObject object = wrapper.getObject(); - loadParentOrgs(object); - return object.asObjectable(); - } - }; - } - - protected void setSummaryPanelVisibility(ObjectSummaryPanel summaryPanel){ - summaryPanel.add(new VisibleEnableBehaviour() { - private static final long serialVersionUID = 1L; - - @Override - public boolean isVisible() { - return isOidParameterExists() || editingFocus; - } - }); - } - - private void initOperationalButtonsPanel(){ - OperationalButtonsPanel opButtonPanel = new OperationalButtonsPanel(ID_BUTTONS) { - private static final long serialVersionUID = 1L; - - @Override - protected void addButtons(RepeatingView repeatingView) { - initOperationalButtons(repeatingView); - } - }; - - opButtonPanel.setOutputMarkupId(true); - opButtonPanel.add(new VisibleBehaviour(() -> isEditingFocus() && opButtonPanel.buttonsExist())); - - AjaxSelfUpdatingTimerBehavior behavior = new AjaxSelfUpdatingTimerBehavior(Duration.milliseconds(getRefreshInterval())) { - private static final long serialVersionUID = 1L; - - @Override - protected void onPostProcessTarget(AjaxRequestTarget target) { - refresh(target); - } - - @Override - protected boolean shouldTrigger() { - return isRefreshEnabled(); - } - }; - - opButtonPanel.add(behavior); - - add(opButtonPanel); - } - - public boolean isRefreshEnabled() { - return false; - } - - public void refresh(AjaxRequestTarget target) { - getObjectModel().reset(); - target.add(getSummaryPanel()); - target.add(getOperationalButtonsPanel()); - target.add(getFeedbackPanel()); - - for (Component component : getMainPanel().getTabbedPanel()) { - if (component instanceof RefreshableTabPanel) { - for (Component c : ((RefreshableTabPanel) component).getComponentsToUpdate()) { - target.add(c); - } - } - } - } - - public int getRefreshInterval() { - return 30; - } - - protected void initOperationalButtons(RepeatingView repeatingView){ - if (getObjectArchetypeRef() != null && CollectionUtils.isNotEmpty(getArchetypeOidsListToAssign())) { - AjaxButton changeArchetype = new AjaxButton(repeatingView.newChildId(), createStringResource("PageAdminObjectDetails.button.changeArchetype")) { - @Override - public void onClick(AjaxRequestTarget target) { - changeArchetypeButtonClicked(target); - } - }; - changeArchetype.add(new VisibleBehaviour(() -> getObjectArchetypeRef() != null)); - changeArchetype.add(AttributeAppender.append("class", "btn-default")); - repeatingView.add(changeArchetype); - } - } - - protected OperationalButtonsPanel getOperationalButtonsPanel(){ - return (OperationalButtonsPanel) get(ID_BUTTONS); - } - - private void changeArchetypeButtonClicked(AjaxRequestTarget target){ - - AssignmentPopup changeArchetypePopup = new AssignmentPopup(getMainPopupBodyId()) { - - private static final long serialVersionUID = 1L; - - @Override - protected void addPerformed(AjaxRequestTarget target, List newAssignmentsList) { - super.addPerformed(target, newAssignmentsList); - try { - PrismContainerWrapper assignmentsWrapper = getObjectWrapper().findContainer(FocusType.F_ASSIGNMENT); - ((List) newAssignmentsList).forEach(assignment -> { - PrismContainerValue newAssignment = assignmentsWrapper.getItem().createNewValue(); - assignmentsWrapper.getValues().forEach(assignmentValue -> { - if (assignmentValue.getRealValue().getTargetRef() != null - && assignmentValue.getRealValue().getTargetRef().getType() != null - && QNameUtil.match(assignmentValue.getRealValue().getTargetRef().getType(), ArchetypeType.COMPLEX_TYPE)){ - assignmentValue.setStatus(ValueStatus.DELETED); - } - }); - AssignmentType assignmentType = newAssignment.asContainerable(); - assignmentType.setTargetRef(assignment.getTargetRef()); - WebPrismUtil.createNewValueWrapper(assignmentsWrapper, newAssignment, PageAdminObjectDetails.this, target); - OperationResult result = new OperationResult(OPERATION_EXECUTE_ARCHETYPE_CHANGES); - Task task = createSimpleTask(OPERATION_EXECUTE_ARCHETYPE_CHANGES); - try { - ObjectDelta archetypeDelta = getObjectWrapper().getObjectDelta(); - if (!archetypeDelta.isEmpty()) { - archetypeDelta.revive(getPrismContext()); - getModelService().executeChanges(WebComponentUtil.createDeltaCollection(archetypeDelta), null, task, result); - result.computeStatus(); - } - } catch (Exception e) { - LOGGER.error("Cannot save archetype assignment changes: {}", e.getMessage()); - } - showResult(result); - }); - } catch (SchemaException e) { - LOGGER.error("Cannot find assignment wrapper: {}", e.getMessage()); - } - target.add(PageAdminObjectDetails.this.getFeedbackPanel()); - refresh(target); - } - - @Override - protected List createAssignmentTabs() { - List tabs = new ArrayList<>(); - - tabs.add(new PanelTab(getPageBase().createStringResource("ObjectTypes.ARCHETYPE"), - new VisibleBehaviour(() -> true)) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer createPanel(String panelId) { - return new FocusTypeAssignmentPopupTabPanel(panelId, ObjectTypes.ARCHETYPE) { - private static final long serialVersionUID = 1L; - - @Override - protected PrismContainerWrapper getAssignmentWrapperModel() { - PrismContainerWrapper assignmentsWrapper = null; - try { - assignmentsWrapper = getObjectWrapper().findContainer(FocusType.F_ASSIGNMENT); - } catch (SchemaException e) { - LOGGER.error("Cannot find assignment wrapper: {}", e.getMessage()); - } - return assignmentsWrapper; - } - - @Override - protected List getSupportedRelations() { - return Collections.singletonList(SchemaConstants.ORG_DEFAULT); - } - - @Override - protected void onSelectionPerformed(AjaxRequestTarget target, IModel> rowModel) { - target.add(getObjectListPanel()); - tabLabelPanelUpdate(target); - } - - @Override - protected IModel getObjectSelectCheckBoxEnableModel(IModel> rowModel){ - if (rowModel == null){ - return Model.of(false); - } - List selectedObjects = getSelectedObjectsList(); - return Model.of(selectedObjects == null || selectedObjects.size() == 0 - || (rowModel.getObject() != null && rowModel.getObject().isSelected())); - } - - - @Override - protected ObjectTypes getObjectType() { - return ObjectTypes.ARCHETYPE; - } - - @Override - protected ObjectQuery addFilterToContentQuery(ObjectQuery query){ - super.addFilterToContentQuery(query); - if (query == null) { - query = getPrismContext().queryFactory().createQuery(); - } - List archetypeOidsList = getArchetypeOidsListToAssign(); - ObjectFilter filter = getPrismContext().queryFor(ArchetypeType.class) - .id(archetypeOidsList.toArray(new String[0])) - .buildFilter(); - query.addFilter(filter); - return query; - } - }; - } - }); - return tabs; - } - }; - - changeArchetypePopup.setOutputMarkupPlaceholderTag(true); - showMainPopup(changeArchetypePopup, target); - - } - - private List getArchetypeOidsListToAssign(){ - List archetypeOidsList = getFilteredArchetypeOidsList(); - - ObjectReferenceType archetypeRef = getObjectArchetypeRef(); - if (archetypeRef != null && StringUtils.isNotEmpty(archetypeRef.getOid())){ - if (archetypeOidsList.contains(archetypeRef.getOid())){ - archetypeOidsList.remove(archetypeRef.getOid()); - } - } - return archetypeOidsList; - } - - private List getFilteredArchetypeOidsList(){ - OperationResult result = new OperationResult(OPERATION_LOAD_FILTERED_ARCHETYPES); - PrismObject obj = getObjectWrapper().getObject(); - List oidsList = new ArrayList<>(); - try { - List filteredArchetypes = getModelInteractionService().getFilteredArchetypesByHolderType(obj, result); - if (filteredArchetypes != null){ - filteredArchetypes.forEach(archetype -> oidsList.add(archetype.getOid())); - } - } catch (SchemaException ex){ - result.recordPartialError(ex.getLocalizedMessage()); - LOGGER.error("Couldn't load assignment target specification for the object {} , {}", obj.getName(), ex.getLocalizedMessage()); - } - return oidsList; - } - - protected abstract AbstractObjectMainPanel createMainPanel(String id); - - protected String getObjectOidParameter() { - PageParameters parameters = getPageParameters(); - LOGGER.trace("Page parameters: {}", parameters); - StringValue oidValue = parameters.get(OnePageParameterEncoder.PARAMETER); - LOGGER.trace("OID parameter: {}", oidValue); - if (oidValue == null) { - return null; - } - String oid = oidValue.toString(); - if (StringUtils.isBlank(oid)) { - return null; - } - return oid; - } - - protected ObjectSummaryPanel getSummaryPanel() { - return (ObjectSummaryPanel) get(ID_SUMMARY_PANEL); - } - - public boolean isOidParameterExists() { - return getObjectOidParameter() != null; - } - - protected PrismObjectWrapper loadObjectWrapper(PrismObject objectToEdit, boolean isReadonly) { - Task task = createSimpleTask(OPERATION_LOAD_OBJECT); - OperationResult result = task.getResult(); - PrismObject object = null; - try { - if (!isOidParameterExists()) { - if (objectToEdit == null) { - LOGGER.trace("Loading object: New object (creating)"); - O focusType = createNewObject(); - - // Apply subtype using page parameters - List subtypes = getPageParameters().getValues(ObjectType.F_SUBTYPE.getLocalPart()); - subtypes.stream().filter(p -> !p.isEmpty()).forEach(c -> focusType.subtype(c.toString())); - - getMidpointApplication().getPrismContext().adopt(focusType); - object = (PrismObject) focusType.asPrismObject(); - } else { - LOGGER.trace("Loading object: New object (supplied): {}", objectToEdit); - object = objectToEdit.clone(); - } - } else { - - String focusOid = getObjectOidParameter(); - object = WebModelServiceUtils.loadObject(getCompileTimeClass(), focusOid, buildGetOptions(), this, task, result); - LOGGER.trace("Loading object: Existing object (loadled): {} -> {}", focusOid, object); - } - - result.recordSuccess(); - } catch (Exception ex) { - result.recordFatalError(getString("PageAdminObjectDetails.message.loadObjectWrapper.fatalError"), ex); - LoggingUtils.logUnexpectedException(LOGGER, "Couldn't load object", ex); - } - - showResult(result, false); - - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Loaded object:\n{}", object.debugDump()); - } - - if (object == null) { - if (isOidParameterExists()) { - getSession().error(getString("pageAdminFocus.message.cantEditFocus")); - } else { - getSession().error(getString("pageAdminFocus.message.cantNewFocus")); - } - throw new RestartResponseException(getRestartResponsePage()); - } - - ItemStatus itemStatus = isOidParameterExists() || editingFocus ? ItemStatus.NOT_CHANGED : ItemStatus.ADDED; - PrismObjectWrapper wrapper; - - PrismObjectWrapperFactory factory = getRegistry().getObjectWrapperFactory(object.getDefinition()); - WrapperContext context = new WrapperContext(task, result); - context.setCreateIfEmpty(ItemStatus.ADDED == itemStatus); - //we don't want to set to false.. refactor this method to take either enum (READONLY, AUTO, ...) or - // Boolean instead of boolean isReadonly - if (isReadonly) { - context.setReadOnly(isReadonly); - } - - - try { - wrapper = factory.createObjectWrapper(object, itemStatus, context); - } catch (Exception ex) { - result.recordFatalError(getString("PageAdminObjectDetails.message.loadObjectWrapper.fatalError"), ex); - LoggingUtils.logUnexpectedException(LOGGER, "Couldn't load object", ex); - showResult(result, false); - throw new RestartResponseException(getRestartResponsePage()); - } - - showResult(result, false); - - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Loaded focus wrapper:\n{}", wrapper.debugDump()); - } - - return wrapper; - } - - protected Collection> buildGetOptions() { - return getOperationOptionsBuilder() - .item(FocusType.F_JPEG_PHOTO).retrieve() - .build(); - } - - private void loadParentOrgs(PrismObject object) { - Task task = createSimpleTask(OPERATION_LOAD_PARENT_ORG); - OperationResult subResult = task.getResult(); - // Load parent organizations (full objects). There are used in the - // summary panel and also in the main form. - // Do it here explicitly instead of using resolve option to have ability - // to better handle (ignore) errors. - for (ObjectReferenceType parentOrgRef : object.asObjectable().getParentOrgRef()) { - - PrismObject parentOrg = null; - try { - - parentOrg = getModelService().getObject(OrgType.class, parentOrgRef.getOid(), null, task, - subResult); - LOGGER.trace("Loaded parent org with result {}", - new Object[] { subResult.getLastSubresult() }); - } catch (AuthorizationException e) { - // This can happen if the user has permission to read parentOrgRef but it does not have - // the permission to read target org - // It is OK to just ignore it. - subResult.muteLastSubresultError(); - LOGGER.debug("User {} does not have permission to read parent org unit {} (ignoring error)", task.getOwner().getName(), parentOrgRef.getOid()); - } catch (Exception ex) { - subResult.recordWarning(createStringResource("PageAdminObjectDetails.message.loadParentOrgs.warning", parentOrgRef.getOid()).getString(), ex); - LOGGER.warn("Cannot load parent org {}: {}", parentOrgRef.getOid(), ex.getMessage(), ex); - } - - if (parentOrg != null) { - ObjectReferenceType ref = ObjectTypeUtil.createObjectRef(parentOrg, getPrismContext()); - ref.asReferenceValue().setObject(parentOrg); - object.asObjectable().getParentOrgRef().add(ref); - } - } - subResult.computeStatus(); - } - - protected abstract Class getRestartResponsePage(); - - // TODO put this into correct place - protected boolean previewRequested; - - /** - * This will be called from the main form when save button is pressed. - */ - public void savePerformed(AjaxRequestTarget target) { - progressPanel.onBeforeSave(); - OperationResult result = new OperationResult(OPERATION_SAVE); - previewRequested = false; - saveOrPreviewPerformed(target, result, false); - } - - public void previewPerformed(AjaxRequestTarget target) { - progressPanel.onBeforeSave(); - OperationResult result = new OperationResult(OPERATION_PREVIEW_CHANGES); - previewRequested = true; - saveOrPreviewPerformed(target, result, true); - } - - public void saveOrPreviewPerformed(AjaxRequestTarget target, OperationResult result, boolean previewOnly) { - saveOrPreviewPerformed(target, result, previewOnly, null); - } - - public void saveOrPreviewPerformed(AjaxRequestTarget target, OperationResult result, boolean previewOnly, Task task) { - boolean delegationChangesExist = processDeputyAssignments(previewOnly); - - PrismObjectWrapper objectWrapper = getObjectWrapper(); - LOGGER.debug("Saving object {}", objectWrapper); - - // todo: improve, delta variable is quickfix for MID-1006 - // redirecting to user list page everytime user is created in repository - // during user add in gui, - // and we're not taking care about account/assignment create errors - // (error message is still displayed) - delta = null; - - if(task == null) { - task = createSimpleTask(OPERATION_SEND_TO_SUBMIT); - } - - ModelExecuteOptions options = getOptions(previewOnly); - - LOGGER.debug("Using execute options {}.", options); - - try { - reviveModels(); - - delta = objectWrapper.getObjectDelta(); - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("User delta computed from form:\n{}", new Object[] { delta.debugDump(3) }); - } - } catch (Exception ex) { - result.recordFatalError(getString("pageAdminObjectDetails.message.cantCreateObject"), ex); - LoggingUtils.logUnexpectedException(LOGGER, "Create Object failed", ex); - showResult(result); - target.add(getFeedbackPanel()); - return; - } - - switch (objectWrapper.getStatus()) { - case ADDED: - try { - PrismObject objectToAdd = delta.getObjectToAdd(); - WebComponentUtil.encryptCredentials(objectToAdd, true, getMidpointApplication()); - prepareObjectForAdd(objectToAdd); - getPrismContext().adopt(objectToAdd, getCompileTimeClass()); - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Delta before add user:\n{}", new Object[] { delta.debugDump(3) }); - } - - if (!delta.isEmpty()) { - delta.revive(getPrismContext()); - - final Collection> deltas = WebComponentUtil.createDeltaCollection(delta); - final Collection validationErrors = performCustomValidation(objectToAdd, deltas); - if (checkValidationErrors(target, validationErrors)) { - return; - } - if (isSaveInBackground()){ - progressPanel.executeChangesInBackground(deltas, previewOnly, options, task, result, target); - } else { - progressPanel.executeChanges(deltas, previewOnly, options, task, result, target); - } - } else { - result.recordSuccess(); - } - } catch (Exception ex) { - result.recordFatalError(getString("pageFocus.message.cantCreateFocus"), ex); - LoggingUtils.logUnexpectedException(LOGGER, "Create user failed", ex); - showResult(result); - } - break; - - case NOT_CHANGED: - try { - WebComponentUtil.encryptCredentials(delta, true, getMidpointApplication()); - prepareObjectDeltaForModify(delta); //preparing of deltas for projections (ADD, DELETE, UNLINK) - - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Delta before modify user:\n{}", new Object[] { delta.debugDump(3) }); - } - - Collection> deltas = new ArrayList<>(); - if (!delta.isEmpty()) { - delta.revive(getPrismContext()); - deltas.add(delta); - } - - List> additionalDeltas = getAdditionalModifyDeltas(result); - if (additionalDeltas != null) { - for (ObjectDelta additionalDelta : additionalDeltas) { - if (!additionalDelta.isEmpty()) { - additionalDelta.revive(getPrismContext()); - deltas.add(additionalDelta); - } - } - } - - if (delta.isEmpty() && ModelExecuteOptions.isReconcile(options)) { - ObjectDelta emptyDelta = getPrismContext().deltaFactory().object().createEmptyModifyDelta(getCompileTimeClass(), - objectWrapper.getObject().getOid()); - deltas.add(emptyDelta); - - Collection validationErrors = performCustomValidation(null, deltas); - if (checkValidationErrors(target, validationErrors)) { - return; - } - if (isSaveInBackground()){ - progressPanel.executeChangesInBackground(deltas, previewOnly, options, task, result, target); - } else { - progressPanel.executeChanges(deltas, previewOnly, options, task, result, target); - } - } else if (!deltas.isEmpty()) { - Collection validationErrors = performCustomValidation(null, deltas); - if (checkValidationErrors(target, validationErrors)) { - return; - } - if (isSaveInBackground()){ - progressPanel.executeChangesInBackground(deltas, previewOnly, options, task, result, target); - } else { - progressPanel.executeChanges(deltas, previewOnly, options, task, result, target); - } - } else if (previewOnly && delta.isEmpty() && delegationChangesExist){ - if (isSaveInBackground()){ - progressPanel.executeChangesInBackground(deltas, previewOnly, options, task, result, target); - } else { - progressPanel.executeChanges(deltas, previewOnly, options, task, result, target); - } - } else { - progressPanel.clearProgressPanel(); // from previous attempts (useful only if we would call finishProcessing at the end, but that's not the case now) - if (!previewOnly) { - if (!delegationChangesExist) { - result.recordWarning(getString("PageAdminObjectDetails.noChangesSave")); - showResult(result); - } - redirectBack(); - } else { - if (!delegationChangesExist) { - warn(getString("PageAdminObjectDetails.noChangesPreview")); - target.add(getFeedbackPanel()); - } - } - } - - } catch (Exception ex) { - if (!executeForceDelete(objectWrapper, task, options, result)) { - result.recordFatalError(getString("pageUser.message.cantUpdateUser"), ex); - LoggingUtils.logUnexpectedException(LOGGER, getString("pageUser.message.cantUpdateUser"), ex); - } else { - result.recomputeStatus(); - } - showResult(result); - } - break; - // support for add/delete containers (e.g. delete credentials) - default: - error(getString("pageAdminFocus.message.unsupportedState", objectWrapper.getStatus())); - } - -// result.recomputeStatus(); -// -// if (!result.isInProgress()) { -// LOGGER.trace("Result NOT in progress, calling finishProcessing"); -// finishProcessing(target, result, false); -// } - - LOGGER.trace("returning from saveOrPreviewPerformed"); - } - - protected boolean processDeputyAssignments(boolean previewOnly){ - return false; - } - - protected boolean checkValidationErrors(AjaxRequestTarget target, Collection validationErrors) { - if (validationErrors != null && !validationErrors.isEmpty()) { - for (SimpleValidationError error : validationErrors) { - LOGGER.error("Validation error, attribute: '" + error.printAttribute() - + "', message: '" + error.getMessage() + "'."); - error("Validation error, attribute: '" + error.printAttribute() - + "', message: '" + error.getMessage() + "'."); - } - - target.add(getFeedbackPanel()); - return true; - } - return false; - } - - @Override - public void startProcessing(AjaxRequestTarget target, OperationResult result) { - LOGGER.trace("startProcessing called, making main panel invisible"); - mainPanel.setVisible(false); - target.add(mainPanel); - } - - @NotNull - protected ModelExecuteOptions getOptions(boolean previewOnly) { - ModelExecuteOptions options = mainPanel.getExecuteChangeOptionsDto().createOptions(); - if (previewOnly) { - options.getOrCreatePartialProcessing().setApprovals(PartialProcessingTypeType.PROCESS); - } - return options; - } - - protected void prepareObjectForAdd(PrismObject object) throws SchemaException { - - } - - protected void prepareObjectDeltaForModify(ObjectDelta objectDelta) throws SchemaException { - - } - - protected List> getAdditionalModifyDeltas(OperationResult result) { - return null; - } - - protected boolean executeForceDelete(PrismObjectWrapper userWrapper, Task task, ModelExecuteOptions options, - OperationResult parentResult) { - return isForce(); - } - - protected boolean isForce() { - return getMainPanel().getExecuteChangeOptionsDto().isForce(); - } - - protected boolean isKeepDisplayingResults() { - return getMainPanel().getExecuteChangeOptionsDto().isKeepDisplayingResults(); - } - - protected boolean isSaveInBackground(){ - return getMainPanel().getExecuteChangeOptionsDto().isSaveInBackground(); - } - - protected Collection performCustomValidation(PrismObject object, - Collection> deltas) throws SchemaException { - Collection errors = null; - - if (object == null) { - if (getObjectWrapper() != null && getObjectWrapper().getObjectOld() != null) { - object = getObjectWrapper().getObjectOld().clone(); // otherwise original object could get corrupted e.g. by applying the delta below - - for (ObjectDelta delta : deltas) { - // because among deltas there can be also ShadowType deltas - if (UserType.class.isAssignableFrom(delta.getObjectTypeClass())) { - delta.applyTo(object); - } - } - } - } else { - object = object.clone(); - } - - performAdditionalValidation(object, deltas, errors); - - for (MidpointFormValidator validator : getFormValidatorRegistry().getValidators()) { - if (errors == null) { - errors = validator.validateObject(object, deltas); - } else { - errors.addAll(validator.validateObject(object, deltas)); - } - } - - return errors; - } - - protected void performAdditionalValidation(PrismObject object, - Collection> deltas, Collection errors) throws SchemaException { - - } - - public List getObjectFormTypes() { - CompiledGuiProfile adminGuiConfiguration = getCompiledGuiProfile(); - ObjectFormsType objectFormsType = adminGuiConfiguration.getObjectForms(); - if (objectFormsType == null) { - return null; - } - List objectForms = objectFormsType.getObjectForm(); - if (objectForms == null || objectForms.isEmpty()) { - return objectForms; - } - List validObjectForms = new ArrayList<>(); - for (ObjectFormType objectForm: objectForms) { - if (isSupportedObjectType(objectForm.getType())) { - validObjectForms.add(objectForm); - } - } - return validObjectForms; - } - - protected boolean isSupportedObjectType(QName type) { - ObjectTypes objectType = ObjectTypes.getObjectType(getCompileTimeClass()); - return QNameUtil.match(objectType.getTypeQName(),type); - } - - public void setSaveOnConfigure(boolean saveOnConfigure) { - this.saveOnConfigure = saveOnConfigure; - } - - public boolean isSaveOnConfigure() { - return saveOnConfigure; - } - - public boolean isForcedPreview() { - GuiObjectDetailsPageType objectDetails = getCompiledGuiProfile().findObjectDetailsConfiguration(getCompileTimeClass()); - return objectDetails != null && DetailsPageSaveMethodType.FORCED_PREVIEW.equals(objectDetails.getSaveMethod()); - } - - //TODO moved from PageAdminFocus.. maybe we need PageAssignmentHolderDetails? - @Override - public void finishProcessing(AjaxRequestTarget target, OperationResult result, boolean returningFromAsync) { - - if (previewRequested) { - finishPreviewProcessing(target, result); - return; - } - if (result.isSuccess() && getDelta() != null && SecurityUtils.getPrincipalUser().getOid().equals(getDelta().getOid())) { - Session.get().setLocale(WebModelServiceUtils.getLocale()); - LOGGER.debug("Using {} as locale", getLocale()); - WebSession.get().getClientInfo().getProperties(). - setTimeZone(WebModelServiceUtils.getTimezone()); - LOGGER.debug("Using {} as time zone", WebSession.get().getClientInfo().getProperties().getTimeZone()); - } - boolean focusAddAttempted = getDelta() != null && getDelta().isAdd(); - boolean focusAddSucceeded = focusAddAttempted && StringUtils.isNotEmpty(getDelta().getOid()); - - // we don't want to allow resuming editing if a new focal object was created (on second 'save' there would be a conflict with itself) - // and also in case of partial errors, like those related to projections (many deltas would be already executed, and this could cause problems on second 'save'). - boolean canContinueEditing = !focusAddSucceeded && result.isFatalError(); - - boolean canExitPage; - if (returningFromAsync) { - canExitPage = getProgressPanel().isAllSuccess() || result.isInProgress() || result.isHandledError(); // if there's at least a warning in the progress table, we would like to keep the table open - } else { - canExitPage = !canContinueEditing; // no point in staying on page if we cannot continue editing (in synchronous case i.e. no progress table present) - } - - if (!isKeepDisplayingResults() && canExitPage) { - showResult(result); - redirectBack(); - } else { - if (returningFromAsync) { - getProgressPanel().showBackButton(target); - getProgressPanel().hideAbortButton(target); - } - showResult(result); - target.add(getFeedbackPanel()); - - if (canContinueEditing) { - getProgressPanel().hideBackButton(target); - getProgressPanel().showContinueEditingButton(target); - } - } - } - - private void finishPreviewProcessing(AjaxRequestTarget target, OperationResult result) { - getMainPanel().setVisible(true); - getProgressPanel().hide(); - getProgressPanel().hideAbortButton(target); - getProgressPanel().hideBackButton(target); - getProgressPanel().hideContinueEditingButton(target); - - showResult(result); - target.add(getFeedbackPanel()); - - Map, ModelContext> modelContextMap = new LinkedHashMap<>(); - modelContextMap.put(getObjectWrapper().getObject(), getProgressPanel().getPreviewResult()); - - processAdditionalFocalObjectsForPreview(modelContextMap); - - navigateToNext(new PagePreviewChanges(modelContextMap, getModelInteractionService())); - } - - protected void processAdditionalFocalObjectsForPreview(Map, ModelContext> modelContextMap){ - } -} +/* + * 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.web.page.admin; + +import java.util.*; + +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.gui.api.component.*; +import com.evolveum.midpoint.gui.api.component.tabs.PanelTab; +import com.evolveum.midpoint.gui.api.prism.PrismContainerWrapper; +import com.evolveum.midpoint.gui.api.util.WebPrismUtil; +import com.evolveum.midpoint.model.api.context.ModelContext; +import com.evolveum.midpoint.prism.PrismContainerValue; +import com.evolveum.midpoint.prism.query.ObjectFilter; +import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.schema.ObjectDeltaOperation; +import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.schema.util.ObjectTypeUtil; +import com.evolveum.midpoint.util.exception.*; +import com.evolveum.midpoint.web.component.AjaxButton; +import com.evolveum.midpoint.web.component.prism.ValueStatus; +import com.evolveum.midpoint.web.component.prism.show.PagePreviewChanges; +import com.evolveum.midpoint.web.component.refresh.Refreshable; +import com.evolveum.midpoint.web.component.util.SelectableBean; +import com.evolveum.midpoint.web.component.util.VisibleBehaviour; +import com.evolveum.midpoint.web.page.admin.configuration.PageSystemConfiguration; +import com.evolveum.midpoint.web.page.admin.server.OperationalButtonsPanel; +import com.evolveum.midpoint.web.page.admin.server.RefreshableTabPanel; +import com.evolveum.midpoint.web.security.util.SecurityUtils; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.wicket.Component; +import org.apache.wicket.Page; +import org.apache.wicket.RestartResponseException; +import org.apache.wicket.Session; +import org.apache.wicket.ajax.AbstractAjaxTimerBehavior; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.AjaxSelfUpdatingTimerBehavior; +import org.apache.wicket.behavior.AttributeAppender; +import org.apache.wicket.extensions.markup.html.tabs.ITab; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.repeater.RepeatingView; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.StringResourceModel; +import org.apache.wicket.protocol.http.WebSession; +import org.apache.wicket.request.mapper.parameter.PageParameters; +import org.apache.wicket.util.string.StringValue; +import org.apache.wicket.util.time.Duration; +import org.jetbrains.annotations.NotNull; + +import com.evolveum.midpoint.gui.api.model.LoadableModel; +import com.evolveum.midpoint.gui.api.prism.ItemStatus; +import com.evolveum.midpoint.gui.api.prism.PrismObjectWrapper; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; +import com.evolveum.midpoint.gui.impl.factory.PrismObjectWrapperFactory; +import com.evolveum.midpoint.gui.impl.factory.WrapperContext; +import com.evolveum.midpoint.model.api.ModelExecuteOptions; +import com.evolveum.midpoint.model.api.authentication.CompiledGuiProfile; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.SelectorOptions; +import com.evolveum.midpoint.schema.constants.ObjectTypes; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.util.logging.LoggingUtils; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.web.component.ObjectSummaryPanel; +import com.evolveum.midpoint.web.component.objectdetails.AbstractObjectMainPanel; +import com.evolveum.midpoint.web.component.progress.ProgressPanel; +import com.evolveum.midpoint.web.component.progress.ProgressReportingAwarePage; +import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; +import com.evolveum.midpoint.web.page.admin.users.dto.FocusSubwrapperDto; +import com.evolveum.midpoint.web.util.OnePageParameterEncoder; +import com.evolveum.midpoint.web.util.validation.MidpointFormValidator; +import com.evolveum.midpoint.web.util.validation.SimpleValidationError; + +/** + * @author semancik + */ +public abstract class PageAdminObjectDetails extends PageAdmin + implements ProgressReportingAwarePage, Refreshable { + private static final long serialVersionUID = 1L; + + private static final String DOT_CLASS = PageAdminObjectDetails.class.getName() + "."; + + private static final String OPERATION_LOAD_OBJECT = DOT_CLASS + "loadObject"; + protected static final String OPERATION_SAVE = DOT_CLASS + "save"; + protected static final String OPERATION_PREVIEW_CHANGES = DOT_CLASS + "previewChanges"; + protected static final String OPERATION_SEND_TO_SUBMIT = DOT_CLASS + "sendToSubmit"; + protected static final String OPERATION_LOAD_ARCHETYPE_REF = DOT_CLASS + "loadArchetypeRef"; + protected static final String OPERATION_EXECUTE_ARCHETYPE_CHANGES = DOT_CLASS + "executeArchetypeChanges"; + protected static final String OPERATION_LOAD_FILTERED_ARCHETYPES = DOT_CLASS + "loadFilteredArchetypes"; + protected static final String OPERATION_LOAD_PARENT_ORG = DOT_CLASS + "loadParentOrgs"; + + protected static final String ID_SUMMARY_PANEL = "summaryPanel"; + protected static final String ID_MAIN_PANEL = "mainPanel"; + private static final String ID_PROGRESS_PANEL = "progressPanel"; + private static final String ID_BUTTONS = "buttons"; + + private static final Trace LOGGER = TraceManager.getTrace(PageAdminObjectDetails.class); + + private LoadableModel> objectModel; + private LoadableModel>> parentOrgModel; + + private ProgressPanel progressPanel; + + // used to determine whether to leave this page or stay on it (after + // operation finishing) + private ObjectDelta delta; + + private AbstractObjectMainPanel mainPanel; + private boolean saveOnConfigure; // ugly hack - whether to invoke 'Save' when returning to this page + + private boolean editingFocus = false; //before we got isOidParameterExists status depending only on oid parameter existence + //we should set editingFocus=true not only when oid parameter exists but also + //when object is given as a constructor parameter + + // TODO put this into correct place + protected boolean previewRequested; + + public boolean isPreviewRequested() { + return previewRequested; + } + + public boolean isEditingFocus() { + return editingFocus; + } + + @Override + protected void createBreadcrumb() { + createInstanceBreadcrumb(); + } + + @Override + protected void onConfigure() { + super.onConfigure(); + if (saveOnConfigure) { + saveOnConfigure = false; + add(new AbstractAjaxTimerBehavior(Duration.milliseconds(100)) { + @Override + protected void onTimer(AjaxRequestTarget target) { + stop(target); + savePerformed(target); + } + }); + } + } + + @Override + protected IModel createPageTitleModel() { + if (PageAdminObjectDetails.this instanceof PageSystemConfiguration){ + return super.createPageTitleModel(); + } + String simpleName = getObjectSimpleName(); + String lokalizedSimpleName = new StringResourceModel("ObjectType." + simpleName).setDefaultValue(simpleName).getString(); + if (isAdd()) { + return createStringResource("PageAdminObjectDetails.title.new", lokalizedSimpleName); + } + + String name = null; + if (getObjectWrapper() != null && getObjectWrapper().getObject() != null) { + name = WebComponentUtil.getName(getObjectWrapper().getObject()); + } + + return createStringResource("PageAdminObjectDetails.title.edit.readonly.${readOnly}", getObjectModel(), lokalizedSimpleName, name); + } + + private String getObjectSimpleName(){ + if (getObjectWrapper() != null && getObjectWrapper().getObject() != null + && getObjectWrapper().getObject().asObjectable() instanceof AssignmentHolderType){ + AssignmentHolderType assignmentHolderObj = (AssignmentHolderType) getObjectWrapper().getObject().asObjectable(); + DisplayType displayType = WebComponentUtil + .getArchetypePolicyDisplayType(assignmentHolderObj, PageAdminObjectDetails.this); + if (displayType == null){ + ObjectReferenceType archetypeReference = getObjectArchetypeRef(); + if (archetypeReference != null){ + OperationResult result = new OperationResult(OPERATION_LOAD_ARCHETYPE_REF); + Task task = createSimpleTask(OPERATION_LOAD_ARCHETYPE_REF); + PrismObject archetypeObj = WebModelServiceUtils.resolveReferenceNoFetch(archetypeReference, + this, task, result); + displayType = archetypeObj != null && archetypeObj.asObjectable().getArchetypePolicy() != null ? + archetypeObj.asObjectable().getArchetypePolicy().getDisplay() : null; + } + } + if (displayType != null && displayType.getLabel() != null) { + String archetypeLocalizedName = getLocalizationService() + .translate(displayType.getLabel().toPolyString(), WebComponentUtil.getCurrentLocale(), true); + if (StringUtils.isNotEmpty(archetypeLocalizedName)) { + return archetypeLocalizedName; + } + } + } + return getCompileTimeClass().getSimpleName(); + } + + public boolean isAdd() { + return !isOidParameterExists() && !editingFocus; + } + + public LoadableModel> getObjectModel() { + return objectModel; + } + + protected AbstractObjectMainPanel getMainPanel() { + return mainPanel; + } + + public PrismObjectWrapper getObjectWrapper() { + return objectModel.getObject(); + } + + public List> getParentOrgs() { + return parentOrgModel.getObject(); + } + + public ObjectDelta getDelta() { + return delta; + } + + public void setDelta(ObjectDelta delta) { + this.delta = delta; + } + + public ProgressPanel getProgressPanel() { + return progressPanel; + } + + protected void reviveModels() throws SchemaException { + WebComponentUtil.revive(objectModel, getPrismContext()); + WebComponentUtil.revive(parentOrgModel, getPrismContext()); + } + + public abstract Class getCompileTimeClass(); + + + public void initialize(final PrismObject objectToEdit) { + boolean isNewObject = objectToEdit == null && StringUtils.isEmpty(getObjectOidParameter()); + + initialize(objectToEdit, isNewObject, false); + } + + public void initialize(final PrismObject objectToEdit, boolean isNewObject) { + initialize(objectToEdit, isNewObject, false); + } + + public void initialize(final PrismObject objectToEdit, boolean isNewObject, boolean isReadonly) { + initializeModel(objectToEdit, isNewObject, isReadonly); + } + + protected void initializeModel(final PrismObject objectToEdit, boolean isNewObject, boolean isReadonly) { + editingFocus = !isNewObject; + + objectModel = new LoadableModel>(false) { + private static final long serialVersionUID = 1L; + + @Override + protected PrismObjectWrapper load() { + PrismObjectWrapper wrapper = loadObjectWrapper(objectToEdit, isReadonly); + return wrapper; + } + }; + + parentOrgModel = new LoadableModel>>(false) { + private static final long serialVersionUID = 1L; + + @Override + protected List> load() { + return loadOrgWrappers(); + } + }; + } + + private ObjectReferenceType getObjectArchetypeRef() { + ObjectReferenceType archetypeReference = null; + if (getObjectWrapper() != null && getObjectWrapper().getObject() != null + && getObjectWrapper().getObject().asObjectable() instanceof AssignmentHolderType) { + AssignmentHolderType assignmentHolderObj = (AssignmentHolderType) getObjectWrapper().getObject().asObjectable(); + if (assignmentHolderObj.getAssignment() != null) { + for (AssignmentType assignment : assignmentHolderObj.getAssignment()) { + if (assignment.getTargetRef() != null && assignment.getTargetRef().getType() != null + && QNameUtil.match(assignment.getTargetRef().getType(), ArchetypeType.COMPLEX_TYPE)) { + archetypeReference = assignment.getTargetRef(); + break; + } + } + } + } + return archetypeReference; + } + + protected List> loadOrgWrappers() { + // WRONG!! TODO: fix + return null; + } + + protected abstract O createNewObject(); + + @Override + protected void onInitialize() { + super.onInitialize(); + initLayout(); + } + + protected void initLayout() { + initLayoutSummaryPanel(); + initOperationalButtonsPanel(); + + mainPanel = createMainPanel(ID_MAIN_PANEL); + mainPanel.setOutputMarkupId(true); + add(mainPanel); + + progressPanel = new ProgressPanel(ID_PROGRESS_PANEL); + add(progressPanel); + } + + protected abstract ObjectSummaryPanel createSummaryPanel(IModel summaryModel); + + protected void initLayoutSummaryPanel() { + + ObjectSummaryPanel summaryPanel = createSummaryPanel(loadModelForSummaryPanel()); + summaryPanel.setOutputMarkupId(true); + + setSummaryPanelVisibility(summaryPanel); + add(summaryPanel); + } + + private IModel loadModelForSummaryPanel() { + return new LoadableModel(true) { + + @Override + protected O load() { + PrismObjectWrapper wrapper = getObjectWrapper(); + if (wrapper == null) { + return null; + } + + PrismObject object = wrapper.getObject(); + loadParentOrgs(object); + return object.asObjectable(); + } + }; + } + + protected void setSummaryPanelVisibility(ObjectSummaryPanel summaryPanel){ + summaryPanel.add(new VisibleEnableBehaviour() { + private static final long serialVersionUID = 1L; + + @Override + public boolean isVisible() { + return isOidParameterExists() || editingFocus; + } + }); + } + + private void initOperationalButtonsPanel(){ + OperationalButtonsPanel opButtonPanel = new OperationalButtonsPanel(ID_BUTTONS) { + private static final long serialVersionUID = 1L; + + @Override + protected void addButtons(RepeatingView repeatingView) { + initOperationalButtons(repeatingView); + } + }; + + opButtonPanel.setOutputMarkupId(true); + opButtonPanel.add(new VisibleBehaviour(() -> isEditingFocus() && opButtonPanel.buttonsExist())); + + AjaxSelfUpdatingTimerBehavior behavior = new AjaxSelfUpdatingTimerBehavior(Duration.milliseconds(getRefreshInterval())) { + private static final long serialVersionUID = 1L; + + @Override + protected void onPostProcessTarget(AjaxRequestTarget target) { + refresh(target); + } + + @Override + protected boolean shouldTrigger() { + return isRefreshEnabled(); + } + }; + + opButtonPanel.add(behavior); + + add(opButtonPanel); + } + + public boolean isRefreshEnabled() { + return false; + } + + public void refresh(AjaxRequestTarget target) { + getObjectModel().reset(); + target.add(getSummaryPanel()); + target.add(getOperationalButtonsPanel()); + target.add(getFeedbackPanel()); + + for (Component component : getMainPanel().getTabbedPanel()) { + if (component instanceof RefreshableTabPanel) { + for (Component c : ((RefreshableTabPanel) component).getComponentsToUpdate()) { + target.add(c); + } + } + } + } + + public int getRefreshInterval() { + return 30; + } + + protected void initOperationalButtons(RepeatingView repeatingView){ + if (getObjectArchetypeRef() != null && CollectionUtils.isNotEmpty(getArchetypeOidsListToAssign())) { + AjaxButton changeArchetype = new AjaxButton(repeatingView.newChildId(), createStringResource("PageAdminObjectDetails.button.changeArchetype")) { + @Override + public void onClick(AjaxRequestTarget target) { + changeArchetypeButtonClicked(target); + } + }; + changeArchetype.add(new VisibleBehaviour(() -> getObjectArchetypeRef() != null)); + changeArchetype.add(AttributeAppender.append("class", "btn-default")); + repeatingView.add(changeArchetype); + } + } + + protected OperationalButtonsPanel getOperationalButtonsPanel(){ + return (OperationalButtonsPanel) get(ID_BUTTONS); + } + + private void changeArchetypeButtonClicked(AjaxRequestTarget target){ + + AssignmentPopup changeArchetypePopup = new AssignmentPopup(getMainPopupBodyId()) { + + private static final long serialVersionUID = 1L; + + @Override + protected void addPerformed(AjaxRequestTarget target, List newAssignmentsList) { + super.addPerformed(target, newAssignmentsList); + try { + PrismContainerWrapper assignmentsWrapper = getObjectWrapper().findContainer(FocusType.F_ASSIGNMENT); + ((List) newAssignmentsList).forEach(assignment -> { + PrismContainerValue newAssignment = assignmentsWrapper.getItem().createNewValue(); + assignmentsWrapper.getValues().forEach(assignmentValue -> { + if (assignmentValue.getRealValue().getTargetRef() != null + && assignmentValue.getRealValue().getTargetRef().getType() != null + && QNameUtil.match(assignmentValue.getRealValue().getTargetRef().getType(), ArchetypeType.COMPLEX_TYPE)){ + assignmentValue.setStatus(ValueStatus.DELETED); + } + }); + AssignmentType assignmentType = newAssignment.asContainerable(); + assignmentType.setTargetRef(assignment.getTargetRef()); + WebPrismUtil.createNewValueWrapper(assignmentsWrapper, newAssignment, PageAdminObjectDetails.this, target); + OperationResult result = new OperationResult(OPERATION_EXECUTE_ARCHETYPE_CHANGES); + Task task = createSimpleTask(OPERATION_EXECUTE_ARCHETYPE_CHANGES); + try { + ObjectDelta archetypeDelta = getObjectWrapper().getObjectDelta(); + if (!archetypeDelta.isEmpty()) { + archetypeDelta.revive(getPrismContext()); + getModelService().executeChanges(WebComponentUtil.createDeltaCollection(archetypeDelta), null, task, result); + result.computeStatus(); + } + } catch (Exception e) { + LOGGER.error("Cannot save archetype assignment changes: {}", e.getMessage()); + } + showResult(result); + }); + } catch (SchemaException e) { + LOGGER.error("Cannot find assignment wrapper: {}", e.getMessage()); + } + target.add(PageAdminObjectDetails.this.getFeedbackPanel()); + refresh(target); + } + + @Override + protected List createAssignmentTabs() { + List tabs = new ArrayList<>(); + + tabs.add(new PanelTab(getPageBase().createStringResource("ObjectTypes.ARCHETYPE"), + new VisibleBehaviour(() -> true)) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer createPanel(String panelId) { + return new FocusTypeAssignmentPopupTabPanel(panelId, ObjectTypes.ARCHETYPE) { + private static final long serialVersionUID = 1L; + + @Override + protected PrismContainerWrapper getAssignmentWrapperModel() { + PrismContainerWrapper assignmentsWrapper = null; + try { + assignmentsWrapper = getObjectWrapper().findContainer(FocusType.F_ASSIGNMENT); + } catch (SchemaException e) { + LOGGER.error("Cannot find assignment wrapper: {}", e.getMessage()); + } + return assignmentsWrapper; + } + + @Override + protected List getSupportedRelations() { + return Collections.singletonList(SchemaConstants.ORG_DEFAULT); + } + + @Override + protected void onSelectionPerformed(AjaxRequestTarget target, IModel> rowModel) { + target.add(getObjectListPanel()); + tabLabelPanelUpdate(target); + } + + @Override + protected IModel getObjectSelectCheckBoxEnableModel(IModel> rowModel){ + if (rowModel == null){ + return Model.of(false); + } + List selectedObjects = getSelectedObjectsList(); + return Model.of(selectedObjects == null || selectedObjects.size() == 0 + || (rowModel.getObject() != null && rowModel.getObject().isSelected())); + } + + + @Override + protected ObjectTypes getObjectType() { + return ObjectTypes.ARCHETYPE; + } + + @Override + protected ObjectQuery addFilterToContentQuery(ObjectQuery query){ + super.addFilterToContentQuery(query); + if (query == null) { + query = getPrismContext().queryFactory().createQuery(); + } + List archetypeOidsList = getArchetypeOidsListToAssign(); + ObjectFilter filter = getPrismContext().queryFor(ArchetypeType.class) + .id(archetypeOidsList.toArray(new String[0])) + .buildFilter(); + query.addFilter(filter); + return query; + } + }; + } + }); + return tabs; + } + }; + + changeArchetypePopup.setOutputMarkupPlaceholderTag(true); + showMainPopup(changeArchetypePopup, target); + + } + + private List getArchetypeOidsListToAssign(){ + List archetypeOidsList = getFilteredArchetypeOidsList(); + + ObjectReferenceType archetypeRef = getObjectArchetypeRef(); + if (archetypeRef != null && StringUtils.isNotEmpty(archetypeRef.getOid())){ + if (archetypeOidsList.contains(archetypeRef.getOid())){ + archetypeOidsList.remove(archetypeRef.getOid()); + } + } + return archetypeOidsList; + } + + private List getFilteredArchetypeOidsList(){ + OperationResult result = new OperationResult(OPERATION_LOAD_FILTERED_ARCHETYPES); + PrismObject obj = getObjectWrapper().getObject(); + List oidsList = new ArrayList<>(); + try { + List filteredArchetypes = getModelInteractionService().getFilteredArchetypesByHolderType(obj, result); + if (filteredArchetypes != null){ + filteredArchetypes.forEach(archetype -> oidsList.add(archetype.getOid())); + } + } catch (SchemaException ex){ + result.recordPartialError(ex.getLocalizedMessage()); + LOGGER.error("Couldn't load assignment target specification for the object {} , {}", obj.getName(), ex.getLocalizedMessage()); + } + return oidsList; + } + + protected abstract AbstractObjectMainPanel createMainPanel(String id); + + protected String getObjectOidParameter() { + PageParameters parameters = getPageParameters(); + LOGGER.trace("Page parameters: {}", parameters); + StringValue oidValue = parameters.get(OnePageParameterEncoder.PARAMETER); + LOGGER.trace("OID parameter: {}", oidValue); + if (oidValue == null) { + return null; + } + String oid = oidValue.toString(); + if (StringUtils.isBlank(oid)) { + return null; + } + return oid; + } + + protected ObjectSummaryPanel getSummaryPanel() { + return (ObjectSummaryPanel) get(ID_SUMMARY_PANEL); + } + + public boolean isOidParameterExists() { + return getObjectOidParameter() != null; + } + + protected PrismObjectWrapper loadObjectWrapper(PrismObject objectToEdit, boolean isReadonly) { + Task task = createSimpleTask(OPERATION_LOAD_OBJECT); + OperationResult result = task.getResult(); + PrismObject object = null; + try { + if (!isOidParameterExists()) { + if (objectToEdit == null) { + LOGGER.trace("Loading object: New object (creating)"); + O focusType = createNewObject(); + + // Apply subtype using page parameters + List subtypes = getPageParameters().getValues(ObjectType.F_SUBTYPE.getLocalPart()); + subtypes.stream().filter(p -> !p.isEmpty()).forEach(c -> focusType.subtype(c.toString())); + + getMidpointApplication().getPrismContext().adopt(focusType); + object = (PrismObject) focusType.asPrismObject(); + } else { + LOGGER.trace("Loading object: New object (supplied): {}", objectToEdit); + object = objectToEdit.clone(); + } + } else { + + String focusOid = getObjectOidParameter(); + object = WebModelServiceUtils.loadObject(getCompileTimeClass(), focusOid, buildGetOptions(), this, task, result); + LOGGER.trace("Loading object: Existing object (loadled): {} -> {}", focusOid, object); + } + + result.recordSuccess(); + } catch (Exception ex) { + result.recordFatalError(getString("PageAdminObjectDetails.message.loadObjectWrapper.fatalError"), ex); + LoggingUtils.logUnexpectedException(LOGGER, "Couldn't load object", ex); + } + + showResult(result, false); + + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Loaded object:\n{}", object.debugDump()); + } + + if (object == null) { + if (isOidParameterExists()) { + getSession().error(getString("pageAdminFocus.message.cantEditFocus")); + } else { + getSession().error(getString("pageAdminFocus.message.cantNewFocus")); + } + throw new RestartResponseException(getRestartResponsePage()); + } + + ItemStatus itemStatus = isOidParameterExists() || editingFocus ? ItemStatus.NOT_CHANGED : ItemStatus.ADDED; + PrismObjectWrapper wrapper; + + PrismObjectWrapperFactory factory = getRegistry().getObjectWrapperFactory(object.getDefinition()); + WrapperContext context = new WrapperContext(task, result); + context.setCreateIfEmpty(ItemStatus.ADDED == itemStatus); + //we don't want to set to false.. refactor this method to take either enum (READONLY, AUTO, ...) or + // Boolean instead of boolean isReadonly + if (isReadonly) { + context.setReadOnly(isReadonly); + } + + + try { + wrapper = factory.createObjectWrapper(object, itemStatus, context); + } catch (Exception ex) { + result.recordFatalError(getString("PageAdminObjectDetails.message.loadObjectWrapper.fatalError"), ex); + LoggingUtils.logUnexpectedException(LOGGER, "Couldn't load object", ex); + showResult(result, false); + throw new RestartResponseException(getRestartResponsePage()); + } + + showResult(result, false); + + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Loaded focus wrapper:\n{}", wrapper.debugDump()); + } + + return wrapper; + } + + protected Collection> buildGetOptions() { + return getOperationOptionsBuilder() + .item(FocusType.F_JPEG_PHOTO).retrieve() + .build(); + } + + private void loadParentOrgs(PrismObject object) { + Task task = createSimpleTask(OPERATION_LOAD_PARENT_ORG); + OperationResult subResult = task.getResult(); + // Load parent organizations (full objects). There are used in the + // summary panel and also in the main form. + // Do it here explicitly instead of using resolve option to have ability + // to better handle (ignore) errors. + for (ObjectReferenceType parentOrgRef : object.asObjectable().getParentOrgRef()) { + + PrismObject parentOrg = null; + try { + + parentOrg = getModelService().getObject(OrgType.class, parentOrgRef.getOid(), null, task, + subResult); + LOGGER.trace("Loaded parent org with result {}", + new Object[] { subResult.getLastSubresult() }); + } catch (AuthorizationException e) { + // This can happen if the user has permission to read parentOrgRef but it does not have + // the permission to read target org + // It is OK to just ignore it. + subResult.muteLastSubresultError(); + LOGGER.debug("User {} does not have permission to read parent org unit {} (ignoring error)", task.getOwner().getName(), parentOrgRef.getOid()); + } catch (Exception ex) { + subResult.recordWarning(createStringResource("PageAdminObjectDetails.message.loadParentOrgs.warning", parentOrgRef.getOid()).getString(), ex); + LOGGER.warn("Cannot load parent org {}: {}", parentOrgRef.getOid(), ex.getMessage(), ex); + } + + if (parentOrg != null) { + ObjectReferenceType ref = ObjectTypeUtil.createObjectRef(parentOrg, getPrismContext()); + ref.asReferenceValue().setObject(parentOrg); + object.asObjectable().getParentOrgRef().add(ref); + } + } + subResult.computeStatus(); + } + + protected abstract Class getRestartResponsePage(); + + /** + * This will be called from the main form when save button is pressed. + */ + public void savePerformed(AjaxRequestTarget target) { + progressPanel.onBeforeSave(); + OperationResult result = new OperationResult(OPERATION_SAVE); + previewRequested = false; + saveOrPreviewPerformed(target, result, false); + } + + public void previewPerformed(AjaxRequestTarget target) { + progressPanel.onBeforeSave(); + OperationResult result = new OperationResult(OPERATION_PREVIEW_CHANGES); + previewRequested = true; + saveOrPreviewPerformed(target, result, true); + } + + public void saveOrPreviewPerformed(AjaxRequestTarget target, OperationResult result, boolean previewOnly) { + saveOrPreviewPerformed(target, result, previewOnly, null); + } + + public void saveOrPreviewPerformed(AjaxRequestTarget target, OperationResult result, boolean previewOnly, Task task) { + boolean delegationChangesExist = processDeputyAssignments(previewOnly); + + PrismObjectWrapper objectWrapper = getObjectWrapper(); + LOGGER.debug("Saving object {}", objectWrapper); + + // todo: improve, delta variable is quickfix for MID-1006 + // redirecting to user list page everytime user is created in repository + // during user add in gui, + // and we're not taking care about account/assignment create errors + // (error message is still displayed) + delta = null; + + if(task == null) { + task = createSimpleTask(OPERATION_SEND_TO_SUBMIT); + } + + ModelExecuteOptions options = getOptions(previewOnly); + + LOGGER.debug("Using execute options {}.", options); + + try { + reviveModels(); + + delta = objectWrapper.getObjectDelta(); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("User delta computed from form:\n{}", new Object[] { delta.debugDump(3) }); + } + } catch (Exception ex) { + result.recordFatalError(getString("pageAdminObjectDetails.message.cantCreateObject"), ex); + LoggingUtils.logUnexpectedException(LOGGER, "Create Object failed", ex); + showResult(result); + target.add(getFeedbackPanel()); + return; + } + + switch (objectWrapper.getStatus()) { + case ADDED: + try { + PrismObject objectToAdd = delta.getObjectToAdd(); + WebComponentUtil.encryptCredentials(objectToAdd, true, getMidpointApplication()); + prepareObjectForAdd(objectToAdd); + getPrismContext().adopt(objectToAdd, getCompileTimeClass()); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Delta before add user:\n{}", new Object[] { delta.debugDump(3) }); + } + + if (!delta.isEmpty()) { + delta.revive(getPrismContext()); + + final Collection> deltas = WebComponentUtil.createDeltaCollection(delta); + final Collection validationErrors = performCustomValidation(objectToAdd, deltas); + if (checkValidationErrors(target, validationErrors)) { + return; + } + if (isSaveInBackground()){ + progressPanel.executeChangesInBackground(deltas, previewOnly, options, task, result, target); + } else { + progressPanel.executeChanges(deltas, previewOnly, options, task, result, target); + } + } else { + result.recordSuccess(); + } + } catch (Exception ex) { + result.recordFatalError(getString("pageFocus.message.cantCreateFocus"), ex); + LoggingUtils.logUnexpectedException(LOGGER, "Create user failed", ex); + showResult(result); + } + break; + + case NOT_CHANGED: + try { + WebComponentUtil.encryptCredentials(delta, true, getMidpointApplication()); + prepareObjectDeltaForModify(delta); //preparing of deltas for projections (ADD, DELETE, UNLINK) + + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Delta before modify user:\n{}", new Object[] { delta.debugDump(3) }); + } + + Collection> deltas = new ArrayList<>(); + if (!delta.isEmpty()) { + delta.revive(getPrismContext()); + deltas.add(delta); + } + + List> additionalDeltas = getAdditionalModifyDeltas(result); + if (additionalDeltas != null) { + for (ObjectDelta additionalDelta : additionalDeltas) { + if (!additionalDelta.isEmpty()) { + additionalDelta.revive(getPrismContext()); + deltas.add(additionalDelta); + } + } + } + + if (delta.isEmpty() && ModelExecuteOptions.isReconcile(options)) { + ObjectDelta emptyDelta = getPrismContext().deltaFactory().object().createEmptyModifyDelta(getCompileTimeClass(), + objectWrapper.getObject().getOid()); + deltas.add(emptyDelta); + + Collection validationErrors = performCustomValidation(null, deltas); + if (checkValidationErrors(target, validationErrors)) { + return; + } + if (isSaveInBackground()){ + progressPanel.executeChangesInBackground(deltas, previewOnly, options, task, result, target); + } else { + progressPanel.executeChanges(deltas, previewOnly, options, task, result, target); + } + } else if (!deltas.isEmpty()) { + Collection validationErrors = performCustomValidation(null, deltas); + if (checkValidationErrors(target, validationErrors)) { + return; + } + if (isSaveInBackground()){ + progressPanel.executeChangesInBackground(deltas, previewOnly, options, task, result, target); + } else { + progressPanel.executeChanges(deltas, previewOnly, options, task, result, target); + } + } else if (previewOnly && delta.isEmpty() && delegationChangesExist){ + if (isSaveInBackground()){ + progressPanel.executeChangesInBackground(deltas, previewOnly, options, task, result, target); + } else { + progressPanel.executeChanges(deltas, previewOnly, options, task, result, target); + } + } else { + progressPanel.clearProgressPanel(); // from previous attempts (useful only if we would call finishProcessing at the end, but that's not the case now) + if (!previewOnly) { + if (!delegationChangesExist) { + result.recordWarning(getString("PageAdminObjectDetails.noChangesSave")); + showResult(result); + } + redirectBack(); + } else { + if (!delegationChangesExist) { + warn(getString("PageAdminObjectDetails.noChangesPreview")); + target.add(getFeedbackPanel()); + } + } + } + + } catch (Exception ex) { + if (!executeForceDelete(objectWrapper, task, options, result)) { + result.recordFatalError(getString("pageUser.message.cantUpdateUser"), ex); + LoggingUtils.logUnexpectedException(LOGGER, getString("pageUser.message.cantUpdateUser"), ex); + } else { + result.recomputeStatus(); + } + showResult(result); + } + break; + // support for add/delete containers (e.g. delete credentials) + default: + error(getString("pageAdminFocus.message.unsupportedState", objectWrapper.getStatus())); + } + +// result.recomputeStatus(); +// +// if (!result.isInProgress()) { +// LOGGER.trace("Result NOT in progress, calling finishProcessing"); +// finishProcessing(target, result, false); +// } + + LOGGER.trace("returning from saveOrPreviewPerformed"); + } + + protected boolean processDeputyAssignments(boolean previewOnly){ + return false; + } + + protected boolean checkValidationErrors(AjaxRequestTarget target, Collection validationErrors) { + if (validationErrors != null && !validationErrors.isEmpty()) { + for (SimpleValidationError error : validationErrors) { + LOGGER.error("Validation error, attribute: '" + error.printAttribute() + + "', message: '" + error.getMessage() + "'."); + error("Validation error, attribute: '" + error.printAttribute() + + "', message: '" + error.getMessage() + "'."); + } + + target.add(getFeedbackPanel()); + return true; + } + return false; + } + + @Override + public void startProcessing(AjaxRequestTarget target, OperationResult result) { + LOGGER.trace("startProcessing called, making main panel invisible"); + mainPanel.setVisible(false); + target.add(mainPanel); + } + + @NotNull + protected ModelExecuteOptions getOptions(boolean previewOnly) { + ModelExecuteOptions options = mainPanel.getExecuteChangeOptionsDto().createOptions(); + if (previewOnly) { + options.getOrCreatePartialProcessing().setApprovals(PartialProcessingTypeType.PROCESS); + } + return options; + } + + protected void prepareObjectForAdd(PrismObject object) throws SchemaException { + + } + + protected void prepareObjectDeltaForModify(ObjectDelta objectDelta) throws SchemaException { + + } + + protected List> getAdditionalModifyDeltas(OperationResult result) { + return null; + } + + protected boolean executeForceDelete(PrismObjectWrapper userWrapper, Task task, ModelExecuteOptions options, + OperationResult parentResult) { + return isForce(); + } + + protected boolean isForce() { + return getMainPanel().getExecuteChangeOptionsDto().isForce(); + } + + protected boolean isKeepDisplayingResults() { + return getMainPanel().getExecuteChangeOptionsDto().isKeepDisplayingResults(); + } + + protected boolean isSaveInBackground(){ + return getMainPanel().getExecuteChangeOptionsDto().isSaveInBackground(); + } + + protected Collection performCustomValidation(PrismObject object, + Collection> deltas) throws SchemaException { + Collection errors = null; + + if (object == null) { + if (getObjectWrapper() != null && getObjectWrapper().getObjectOld() != null) { + object = getObjectWrapper().getObjectOld().clone(); // otherwise original object could get corrupted e.g. by applying the delta below + + for (ObjectDelta delta : deltas) { + // because among deltas there can be also ShadowType deltas + if (UserType.class.isAssignableFrom(delta.getObjectTypeClass())) { + delta.applyTo(object); + } + } + } + } else { + object = object.clone(); + } + + performAdditionalValidation(object, deltas, errors); + + for (MidpointFormValidator validator : getFormValidatorRegistry().getValidators()) { + if (errors == null) { + errors = validator.validateObject(object, deltas); + } else { + errors.addAll(validator.validateObject(object, deltas)); + } + } + + return errors; + } + + protected void performAdditionalValidation(PrismObject object, + Collection> deltas, Collection errors) throws SchemaException { + + } + + public List getObjectFormTypes() { + CompiledGuiProfile adminGuiConfiguration = getCompiledGuiProfile(); + ObjectFormsType objectFormsType = adminGuiConfiguration.getObjectForms(); + if (objectFormsType == null) { + return null; + } + List objectForms = objectFormsType.getObjectForm(); + if (objectForms == null || objectForms.isEmpty()) { + return objectForms; + } + List validObjectForms = new ArrayList<>(); + for (ObjectFormType objectForm: objectForms) { + if (isSupportedObjectType(objectForm.getType())) { + validObjectForms.add(objectForm); + } + } + return validObjectForms; + } + + protected boolean isSupportedObjectType(QName type) { + ObjectTypes objectType = ObjectTypes.getObjectType(getCompileTimeClass()); + return QNameUtil.match(objectType.getTypeQName(),type); + } + + public void setSaveOnConfigure(boolean saveOnConfigure) { + this.saveOnConfigure = saveOnConfigure; + } + + public boolean isSaveOnConfigure() { + return saveOnConfigure; + } + + public boolean isForcedPreview() { + GuiObjectDetailsPageType objectDetails = getCompiledGuiProfile().findObjectDetailsConfiguration(getCompileTimeClass()); + return objectDetails != null && DetailsPageSaveMethodType.FORCED_PREVIEW.equals(objectDetails.getSaveMethod()); + } + + //TODO moved from PageAdminFocus.. maybe we need PageAssignmentHolderDetails? + @Override + public void finishProcessing(AjaxRequestTarget target, Collection> executedDeltas, boolean returningFromAsync, OperationResult result) { + + if (previewRequested) { + finishPreviewProcessing(target, result); + return; + } + if (result.isSuccess() && getDelta() != null && SecurityUtils.getPrincipalUser().getOid().equals(getDelta().getOid())) { + Session.get().setLocale(WebModelServiceUtils.getLocale()); + LOGGER.debug("Using {} as locale", getLocale()); + WebSession.get().getClientInfo().getProperties(). + setTimeZone(WebModelServiceUtils.getTimezone()); + LOGGER.debug("Using {} as time zone", WebSession.get().getClientInfo().getProperties().getTimeZone()); + } + boolean focusAddAttempted = getDelta() != null && getDelta().isAdd(); + boolean focusAddSucceeded = focusAddAttempted && StringUtils.isNotEmpty(getDelta().getOid()); + + // we don't want to allow resuming editing if a new focal object was created (on second 'save' there would be a conflict with itself) + // and also in case of partial errors, like those related to projections (many deltas would be already executed, and this could cause problems on second 'save'). + boolean canContinueEditing = !focusAddSucceeded && result.isFatalError(); + + boolean canExitPage; + if (returningFromAsync) { + canExitPage = getProgressPanel().isAllSuccess() || result.isInProgress() || result.isHandledError(); // if there's at least a warning in the progress table, we would like to keep the table open + } else { + canExitPage = !canContinueEditing; // no point in staying on page if we cannot continue editing (in synchronous case i.e. no progress table present) + } + + if (!isKeepDisplayingResults() && canExitPage) { + showResult(result); + redirectBack(); + } else { + if (returningFromAsync) { + getProgressPanel().showBackButton(target); + getProgressPanel().hideAbortButton(target); + } + showResult(result); + target.add(getFeedbackPanel()); + + if (canContinueEditing) { + getProgressPanel().hideBackButton(target); + getProgressPanel().showContinueEditingButton(target); + } + } + } + + private void finishPreviewProcessing(AjaxRequestTarget target, OperationResult result) { + getMainPanel().setVisible(true); + getProgressPanel().hide(); + getProgressPanel().hideAbortButton(target); + getProgressPanel().hideBackButton(target); + getProgressPanel().hideContinueEditingButton(target); + + showResult(result); + target.add(getFeedbackPanel()); + + Map, ModelContext> modelContextMap = new LinkedHashMap<>(); + modelContextMap.put(getObjectWrapper().getObject(), getProgressPanel().getPreviewResult()); + + processAdditionalFocalObjectsForPreview(modelContextMap); + + navigateToNext(new PagePreviewChanges(modelContextMap, getModelInteractionService())); + } + + protected void processAdditionalFocalObjectsForPreview(Map, ModelContext> modelContextMap){ + } +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/cases/PageCase.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/cases/PageCase.java index 4fe5c384c64..bf4a4d3748e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/cases/PageCase.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/cases/PageCase.java @@ -1,274 +1,275 @@ -/* - * Copyright (c) 2010-2019 Evolveum and contributors - * - * This work is dual-licensed under the Apache License 2.0 - * and European Union Public License. See LICENSE file for details. - */ -package com.evolveum.midpoint.web.page.admin.cases; - -import java.util.List; - -import com.evolveum.midpoint.gui.api.component.tabs.PanelTab; -import com.evolveum.midpoint.gui.api.util.WebComponentUtil; -import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; -import com.evolveum.midpoint.prism.query.ObjectQuery; -import com.evolveum.midpoint.schema.util.CaseTypeUtil; -import com.evolveum.midpoint.web.component.AjaxButton; -import com.evolveum.midpoint.xml.ns._public.common.common_3.*; - -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.behavior.AttributeAppender; -import org.apache.wicket.extensions.markup.html.tabs.ITab; -import org.apache.wicket.markup.html.WebMarkupContainer; -import org.apache.wicket.markup.repeater.RepeatingView; -import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; -import org.apache.wicket.request.mapper.parameter.PageParameters; - -import com.evolveum.midpoint.gui.api.ComponentConstants; -import com.evolveum.midpoint.gui.api.component.tabs.CountablePanelTab; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.security.api.AuthorizationConstants; -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.component.ObjectSummaryPanel; -import com.evolveum.midpoint.web.component.objectdetails.AbstractObjectMainPanel; -import com.evolveum.midpoint.web.component.objectdetails.AssignmentHolderTypeMainPanel; -import com.evolveum.midpoint.web.page.admin.PageAdminObjectDetails; -import com.evolveum.midpoint.web.util.OnePageParameterEncoder; - -@PageDescriptor(url = "/admin/case", encoder = OnePageParameterEncoder.class, action = { - @AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_CASES_ALL_URL, - label = "PageAdminCases.auth.casesAll.label", - description = "PageAdminCases.auth.casesAll.description"), - @AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_CASE_URL, - label = "PageCase.auth.case.label", - description = "PageCase.auth.case.description")}) -public class PageCase extends PageAdminObjectDetails { - private static final long serialVersionUID = 1L; - - private static final Trace LOGGER = TraceManager.getTrace(PageCase.class); - private static final String DOT_CLASS = PageCase.class.getName() + "."; - private static final String OPERATION_LOAD_CONNECTED_TASK = DOT_CLASS + "loadConnectedTask"; - - private static final String ID_SUMMARY_PANEL = "summaryPanel"; - - public PageCase() { - this(null, true); - } - - public PageCase(PrismObject unitToEdit, boolean isNewObject) { - initialize(unitToEdit, isNewObject, true); - } - - public PageCase(PageParameters parameters) { - getPageParameters().overwriteWith(parameters); - initialize(null, false, true); - } - - - @Override - protected AbstractObjectMainPanel createMainPanel(String id) { - return new AssignmentHolderTypeMainPanel(id, getObjectModel(), this) { - - private static final long serialVersionUID = 1L; - - @Override - protected List createTabs(final PageAdminObjectDetails parentPage) { - List tabs = super.createTabs(parentPage); - - if (matchCaseType(SystemObjectsType.ARCHETYPE_APPROVAL_CASE) - && CaseTypeUtil.approvalSchemaExists(getObject() != null ? getObject().asObjectable() : null)) { - tabs.add(0, - new PanelTab(parentPage.createStringResource("PageCase.approvalTab"), - getTabVisibility(ComponentConstants.UI_CASE_TAB_APPROVAL_URL, true, parentPage)) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer createPanel(String panelId) { - return new ApprovalCaseTabPanel(panelId, getMainForm(), getObjectModel(), parentPage); - } - }); - } else if (matchCaseType(SystemObjectsType.ARCHETYPE_OPERATION_REQUEST)) { - tabs.add(0, - new PanelTab(parentPage.createStringResource("PageCase.operationRequestTab"), - getTabVisibility(ComponentConstants.UI_CASE_TAB_APPROVAL_URL, true, parentPage)) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer createPanel(String panelId) { - return new OperationRequestCaseTabPanel(panelId, getMainForm(), getObjectModel(), parentPage); - } - - }); - } else if (matchCaseType(SystemObjectsType.ARCHETYPE_MANUAL_CASE)) { - //todo manual case tab - } - if (!matchCaseType(SystemObjectsType.ARCHETYPE_OPERATION_REQUEST)) { - - tabs.add( - new CountablePanelTab(parentPage.createStringResource("PageCase.workitemsTab"), - getTabVisibility(ComponentConstants.UI_CASE_TAB_WORKITEMS_URL, false, parentPage)) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer createPanel(String panelId) { - return new CaseWorkitemsTabPanel(panelId, getMainForm(), getObjectModel(), parentPage); - } - - @Override - public String getCount() { - return Integer.toString(countWorkItems()); - } - }); - } - if (matchCaseType(SystemObjectsType.ARCHETYPE_OPERATION_REQUEST)){ - tabs.add( - new CountablePanelTab(parentPage.createStringResource("PageCase.childCasesTab"), - getTabVisibility(ComponentConstants.UI_CASE_TAB_CHILD_CASES_URL, false, parentPage)) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer createPanel(String panelId) { - return new ChildCasesTabPanel(panelId, getMainForm(), getObjectModel()); - } - - @Override - public String getCount() { - return Integer.toString(countChildrenCases()); - } - }); - } - - // commented now as it doesn't display informative data -// tabs.add( -// new CountablePanelTab(parentPage.createStringResource("PageCase.events"), -// getTabVisibility(ComponentConstants.UI_CASE_TAB_EVENTS_URL, false, parentPage)) { -// -// private static final long serialVersionUID = 1L; -// -// @Override -// public WebMarkupContainer createPanel(String panelId) { -// return new CaseEventsTabPanel(panelId, getMainForm(), getObjectModel(), parentPage); -// } -// -// @Override -// public String getCount() { -// return Integer.toString(countEvents()); -// } -// }); - return tabs; - } - - @Override - protected boolean getOptionsPanelVisibility() { - return false; - } - - @Override - protected boolean isReadonly(){ - return true; - } - }; - } - - @Override - protected IModel createPageTitleModel() { - return createStringResource("PageCase.title"); - } - - @Override - protected ObjectSummaryPanel createSummaryPanel(IModel summaryModel) { - return new CaseSummaryPanel(ID_SUMMARY_PANEL, CaseType.class, summaryModel, this); - } - - protected void initOperationalButtons(RepeatingView repeatingView){ - OperationResult result = new OperationResult(OPERATION_LOAD_CONNECTED_TASK); - ObjectQuery query = getPrismContext().queryFor(TaskType.class) - .item(TaskType.F_OBJECT_REF) - .ref(getObjectWrapper().getOid()) - .build(); - List> connectedTasks = WebModelServiceUtils.searchObjects(TaskType.class, query, result, PageCase.this); - final ObjectReferenceType taskRef = new ObjectReferenceType(); - if (CollectionUtils.isNotEmpty(connectedTasks)) { - taskRef.setOid(connectedTasks.get(0).getOid()); - taskRef.setType(TaskType.COMPLEX_TYPE); - } - if (StringUtils.isNotEmpty(taskRef.getOid())) { - AjaxButton navigateToTask = new AjaxButton(repeatingView.newChildId(), createStringResource("PageCase.navigateToTask")) { - @Override - public void onClick(AjaxRequestTarget target) { - WebComponentUtil.dispatchToObjectDetailsPage(taskRef, PageCase.this, false); - } - }; - navigateToTask.add(AttributeAppender.append("class", "btn-default")); - repeatingView.add(navigateToTask); - } - } - - @Override - public void finishProcessing(AjaxRequestTarget target, OperationResult result, boolean returningFromAsync) { - - } - - @Override - public void continueEditing(AjaxRequestTarget target) { - - } - - @Override - public Class getCompileTimeClass() { - return CaseType.class; - } - - @Override - protected CaseType createNewObject(){ - return new CaseType(); - } - - @Override - protected Class getRestartResponsePage() { - return PageCases.class; - } - - private boolean matchCaseType(SystemObjectsType archetypeType){ - CaseType caseObject = getObjectWrapper().getObject().asObjectable(); - if (caseObject == null || caseObject.getAssignment() == null){ - return false; - } - for (AssignmentType assignment : caseObject.getAssignment()){ - ObjectReferenceType targetRef = assignment.getTargetRef(); - if (targetRef != null && archetypeType.value().equals(targetRef.getOid())){ - return true; - } - } - return false; - } - - private int countWorkItems(){ - List workItemsList = getObjectModel().getObject().getObject().asObjectable().getWorkItem(); - return workItemsList == null ? 0 : workItemsList.size(); - } - - private int countChildrenCases(){ - CaseType currentCase = getObjectModel().getObject().getObject().asObjectable(); - ObjectQuery childrenCasesQuery = getPrismContext().queryFor(CaseType.class) - .item(CaseType.F_PARENT_REF).ref(currentCase.getOid()) - .build(); - return WebModelServiceUtils.countObjects(CaseType.class, childrenCasesQuery, PageCase.this); - } - - private int countEvents(){ - List eventsList = getObjectModel().getObject().getObject().asObjectable().getEvent(); - return eventsList == null ? 0 : eventsList.size(); - } -} +/* + * Copyright (c) 2010-2019 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ +package com.evolveum.midpoint.web.page.admin.cases; + +import java.util.Collection; +import java.util.List; + +import com.evolveum.midpoint.gui.api.component.tabs.PanelTab; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; +import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.schema.ObjectDeltaOperation; +import com.evolveum.midpoint.schema.util.CaseTypeUtil; +import com.evolveum.midpoint.web.component.AjaxButton; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.behavior.AttributeAppender; +import org.apache.wicket.extensions.markup.html.tabs.ITab; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.repeater.RepeatingView; +import org.apache.wicket.model.IModel; +import org.apache.wicket.request.mapper.parameter.PageParameters; + +import com.evolveum.midpoint.gui.api.ComponentConstants; +import com.evolveum.midpoint.gui.api.component.tabs.CountablePanelTab; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.security.api.AuthorizationConstants; +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.component.ObjectSummaryPanel; +import com.evolveum.midpoint.web.component.objectdetails.AbstractObjectMainPanel; +import com.evolveum.midpoint.web.component.objectdetails.AssignmentHolderTypeMainPanel; +import com.evolveum.midpoint.web.page.admin.PageAdminObjectDetails; +import com.evolveum.midpoint.web.util.OnePageParameterEncoder; + +@PageDescriptor(url = "/admin/case", encoder = OnePageParameterEncoder.class, action = { + @AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_CASES_ALL_URL, + label = "PageAdminCases.auth.casesAll.label", + description = "PageAdminCases.auth.casesAll.description"), + @AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_CASE_URL, + label = "PageCase.auth.case.label", + description = "PageCase.auth.case.description")}) +public class PageCase extends PageAdminObjectDetails { + private static final long serialVersionUID = 1L; + + private static final Trace LOGGER = TraceManager.getTrace(PageCase.class); + private static final String DOT_CLASS = PageCase.class.getName() + "."; + private static final String OPERATION_LOAD_CONNECTED_TASK = DOT_CLASS + "loadConnectedTask"; + + private static final String ID_SUMMARY_PANEL = "summaryPanel"; + + public PageCase() { + this(null, true); + } + + public PageCase(PrismObject unitToEdit, boolean isNewObject) { + initialize(unitToEdit, isNewObject, true); + } + + public PageCase(PageParameters parameters) { + getPageParameters().overwriteWith(parameters); + initialize(null, false, true); + } + + + @Override + protected AbstractObjectMainPanel createMainPanel(String id) { + return new AssignmentHolderTypeMainPanel(id, getObjectModel(), this) { + + private static final long serialVersionUID = 1L; + + @Override + protected List createTabs(final PageAdminObjectDetails parentPage) { + List tabs = super.createTabs(parentPage); + + if (matchCaseType(SystemObjectsType.ARCHETYPE_APPROVAL_CASE) + && CaseTypeUtil.approvalSchemaExists(getObject() != null ? getObject().asObjectable() : null)) { + tabs.add(0, + new PanelTab(parentPage.createStringResource("PageCase.approvalTab"), + getTabVisibility(ComponentConstants.UI_CASE_TAB_APPROVAL_URL, true, parentPage)) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer createPanel(String panelId) { + return new ApprovalCaseTabPanel(panelId, getMainForm(), getObjectModel(), parentPage); + } + }); + } else if (matchCaseType(SystemObjectsType.ARCHETYPE_OPERATION_REQUEST)) { + tabs.add(0, + new PanelTab(parentPage.createStringResource("PageCase.operationRequestTab"), + getTabVisibility(ComponentConstants.UI_CASE_TAB_APPROVAL_URL, true, parentPage)) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer createPanel(String panelId) { + return new OperationRequestCaseTabPanel(panelId, getMainForm(), getObjectModel(), parentPage); + } + + }); + } else if (matchCaseType(SystemObjectsType.ARCHETYPE_MANUAL_CASE)) { + //todo manual case tab + } + if (!matchCaseType(SystemObjectsType.ARCHETYPE_OPERATION_REQUEST)) { + + tabs.add( + new CountablePanelTab(parentPage.createStringResource("PageCase.workitemsTab"), + getTabVisibility(ComponentConstants.UI_CASE_TAB_WORKITEMS_URL, false, parentPage)) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer createPanel(String panelId) { + return new CaseWorkitemsTabPanel(panelId, getMainForm(), getObjectModel(), parentPage); + } + + @Override + public String getCount() { + return Integer.toString(countWorkItems()); + } + }); + } + if (matchCaseType(SystemObjectsType.ARCHETYPE_OPERATION_REQUEST)){ + tabs.add( + new CountablePanelTab(parentPage.createStringResource("PageCase.childCasesTab"), + getTabVisibility(ComponentConstants.UI_CASE_TAB_CHILD_CASES_URL, false, parentPage)) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer createPanel(String panelId) { + return new ChildCasesTabPanel(panelId, getMainForm(), getObjectModel()); + } + + @Override + public String getCount() { + return Integer.toString(countChildrenCases()); + } + }); + } + + // commented now as it doesn't display informative data +// tabs.add( +// new CountablePanelTab(parentPage.createStringResource("PageCase.events"), +// getTabVisibility(ComponentConstants.UI_CASE_TAB_EVENTS_URL, false, parentPage)) { +// +// private static final long serialVersionUID = 1L; +// +// @Override +// public WebMarkupContainer createPanel(String panelId) { +// return new CaseEventsTabPanel(panelId, getMainForm(), getObjectModel(), parentPage); +// } +// +// @Override +// public String getCount() { +// return Integer.toString(countEvents()); +// } +// }); + return tabs; + } + + @Override + protected boolean getOptionsPanelVisibility() { + return false; + } + + @Override + protected boolean isReadonly(){ + return true; + } + }; + } + + @Override + protected IModel createPageTitleModel() { + return createStringResource("PageCase.title"); + } + + @Override + protected ObjectSummaryPanel createSummaryPanel(IModel summaryModel) { + return new CaseSummaryPanel(ID_SUMMARY_PANEL, CaseType.class, summaryModel, this); + } + + protected void initOperationalButtons(RepeatingView repeatingView){ + OperationResult result = new OperationResult(OPERATION_LOAD_CONNECTED_TASK); + ObjectQuery query = getPrismContext().queryFor(TaskType.class) + .item(TaskType.F_OBJECT_REF) + .ref(getObjectWrapper().getOid()) + .build(); + List> connectedTasks = WebModelServiceUtils.searchObjects(TaskType.class, query, result, PageCase.this); + final ObjectReferenceType taskRef = new ObjectReferenceType(); + if (CollectionUtils.isNotEmpty(connectedTasks)) { + taskRef.setOid(connectedTasks.get(0).getOid()); + taskRef.setType(TaskType.COMPLEX_TYPE); + } + if (StringUtils.isNotEmpty(taskRef.getOid())) { + AjaxButton navigateToTask = new AjaxButton(repeatingView.newChildId(), createStringResource("PageCase.navigateToTask")) { + @Override + public void onClick(AjaxRequestTarget target) { + WebComponentUtil.dispatchToObjectDetailsPage(taskRef, PageCase.this, false); + } + }; + navigateToTask.add(AttributeAppender.append("class", "btn-default")); + repeatingView.add(navigateToTask); + } + } + + @Override + public void finishProcessing(AjaxRequestTarget target, Collection> executedDeltas, boolean returningFromAsync, OperationResult result) { + + } + + @Override + public void continueEditing(AjaxRequestTarget target) { + + } + + @Override + public Class getCompileTimeClass() { + return CaseType.class; + } + + @Override + protected CaseType createNewObject(){ + return new CaseType(); + } + + @Override + protected Class getRestartResponsePage() { + return PageCases.class; + } + + private boolean matchCaseType(SystemObjectsType archetypeType){ + CaseType caseObject = getObjectWrapper().getObject().asObjectable(); + if (caseObject == null || caseObject.getAssignment() == null){ + return false; + } + for (AssignmentType assignment : caseObject.getAssignment()){ + ObjectReferenceType targetRef = assignment.getTargetRef(); + if (targetRef != null && archetypeType.value().equals(targetRef.getOid())){ + return true; + } + } + return false; + } + + private int countWorkItems(){ + List workItemsList = getObjectModel().getObject().getObject().asObjectable().getWorkItem(); + return workItemsList == null ? 0 : workItemsList.size(); + } + + private int countChildrenCases(){ + CaseType currentCase = getObjectModel().getObject().getObject().asObjectable(); + ObjectQuery childrenCasesQuery = getPrismContext().queryFor(CaseType.class) + .item(CaseType.F_PARENT_REF).ref(currentCase.getOid()) + .build(); + return WebModelServiceUtils.countObjects(CaseType.class, childrenCasesQuery, PageCase.this); + } + + private int countEvents(){ + List eventsList = getObjectModel().getObject().getObject().asObjectable().getEvent(); + return eventsList == null ? 0 : eventsList.size(); + } +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageSystemConfiguration.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageSystemConfiguration.java index fcdf9bc2a01..f9a91f30218 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageSystemConfiguration.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageSystemConfiguration.java @@ -1,427 +1,428 @@ -/* - * Copyright (c) 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.web.page.admin.configuration; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import javax.xml.namespace.QName; - -import com.evolveum.midpoint.web.application.Url; -import com.evolveum.midpoint.web.page.admin.PageAdminObjectDetails; -import com.evolveum.midpoint.xml.ns._public.common.common_3.*; - -import org.apache.wicket.Page; -import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.extensions.markup.html.tabs.AbstractTab; -import org.apache.wicket.extensions.markup.html.tabs.ITab; -import org.apache.wicket.markup.html.WebMarkupContainer; -import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; -import org.apache.wicket.request.mapper.parameter.PageParameters; - -import com.evolveum.midpoint.gui.api.prism.PrismObjectWrapper; -import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; -import com.evolveum.midpoint.gui.impl.page.admin.configuration.component.GlobalPolicyRuleTabPanel; -import com.evolveum.midpoint.gui.impl.page.admin.configuration.component.LoggingConfigurationTabPanel; -import com.evolveum.midpoint.gui.impl.page.admin.configuration.component.NotificationConfigTabPanel; -import com.evolveum.midpoint.gui.impl.page.admin.configuration.component.ObjectPolicyConfigurationTabPanel; -import com.evolveum.midpoint.gui.impl.page.admin.configuration.component.ProfilingConfigurationTabPanel; -import com.evolveum.midpoint.gui.impl.page.admin.configuration.component.ContainerOfSystemConfigurationPanel; -import com.evolveum.midpoint.gui.impl.page.admin.configuration.component.SystemConfigPanel; -import com.evolveum.midpoint.gui.impl.page.admin.configuration.component.SystemConfigurationSummaryPanel; -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.path.ItemName; -import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.schema.result.OperationResultStatus; -import com.evolveum.midpoint.security.api.AuthorizationConstants; -import com.evolveum.midpoint.task.api.Task; -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.component.ObjectSummaryPanel; -import com.evolveum.midpoint.web.component.TabbedPanel; -import com.evolveum.midpoint.web.component.objectdetails.AbstractObjectMainPanel; -import com.evolveum.midpoint.web.component.progress.ProgressPanel; -import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; -import com.evolveum.midpoint.web.model.PrismContainerWrapperModel; - -/** - * @author lazyman - * @author skublik - */ -@PageDescriptor( - urls = { - @Url(mountUrl = "/admin/config/system", matchUrlForSecurity = "/admin/config/system"), - }, - action = { - @AuthorizationAction(actionUri = PageAdminConfiguration.AUTH_CONFIGURATION_ALL, - label = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_LABEL, - description = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_DESCRIPTION), - @AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_CONFIGURATION_SYSTEM_CONFIG_URL, - label = "PageSystemConfiguration.auth.configSystemConfiguration.label", - description = "PageSystemConfiguration.auth.configSystemConfiguration.description") - }) -public class PageSystemConfiguration extends PageAdminObjectDetails { - - private static final long serialVersionUID = 1L; - - public static final String SELECTED_TAB_INDEX = "tab"; - public static final String SELECTED_SERVER_INDEX = "mailServerIndex"; - public static final String SERVER_LIST_SIZE = "mailServerListSize"; - - private static final String DOT_CLASS = PageSystemConfiguration.class.getName() + "."; - private static final String OPERATION_LOAD_SYSTEM_CONFIG = DOT_CLASS + "load"; - - public static final int CONFIGURATION_TAB_BASIC = 0; - public static final int CONFIGURATION_TAB_OBJECT_POLICY = 1; - public static final int CONFIGURATION_TAB_GLOBAL_POLICY_RULE = 2; - public static final int CONFIGURATION_TAB_GLOBAL_ACCOUNT_SYNCHRONIZATION = 3; - public static final int CONFIGURATION_TAB_CLEANUP_POLICY = 4; - public static final int CONFIGURATION_TAB_NOTIFICATION = 5; - public static final int CONFIGURATION_TAB_LOGGING = 6; - public static final int CONFIGURATION_TAB_PROFILING = 7; - public static final int CONFIGURATION_TAB_ADMIN_GUI = 8; - public static final int CONFIGURATION_TAB_WORKFLOW = 9; - public static final int CONFIGURATION_TAB_ROLE_MANAGEMENT = 10; - public static final int CONFIGURATION_TAB_INTERNALS = 11; - public static final int CONFIGURATION_TAB_DEPLOYMENT_INFORMATION = 12; - public static final int CONFIGURATION_TAB_ACCESS_CERTIFICATION = 13; - public static final int CONFIGURATION_TAB_INFRASTRUCTURE = 14; - public static final int CONFIGURATION_TAB_FULL_TEXT_SEARCH = 15; - - private static final Trace LOGGER = TraceManager.getTrace(PageSystemConfiguration.class); - - private static final String ID_SUMM_PANEL = "summaryPanel"; - - public static final String ROOT_APPENDER_INHERITANCE_CHOICE = "(Inherit root)"; - - public PageSystemConfiguration() { - initialize(null); - } - - public PageSystemConfiguration(PageParameters parameters) { - getPageParameters().overwriteWith(parameters); - initialize(null); - } - - public PageSystemConfiguration(final PrismObject configToEdit) { - initialize(configToEdit); - } - - public PageSystemConfiguration(final PrismObject configToEdit, boolean isNewObject) { - initialize(configToEdit, isNewObject); - } - - @Override - protected void initializeModel(final PrismObject configToEdit, boolean isNewObject, boolean isReadonly) { - Task task = createSimpleTask(OPERATION_LOAD_SYSTEM_CONFIG); - OperationResult result = new OperationResult(OPERATION_LOAD_SYSTEM_CONFIG); - super.initializeModel(WebModelServiceUtils.loadSystemConfigurationAsPrismObject(this, task, result), false, isReadonly); - } - - private List getTabs(){ - List tabs = new ArrayList<>(); - tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.system.title")) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer getPanel(String panelId) { - return new SystemConfigPanel(panelId, getObjectModel()); - } - }); - - tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.objectPolicy.title")) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer getPanel(String panelId) { - PrismContainerWrapperModel model = createModel(getObjectModel(), SystemConfigurationType.F_DEFAULT_OBJECT_POLICY_CONFIGURATION); - return new ObjectPolicyConfigurationTabPanel<>(panelId, model); - } - }); - - tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.globalPolicyRule.title")) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer getPanel(String panelId) { - PrismContainerWrapperModel model = createModel(getObjectModel(), - SystemConfigurationType.F_GLOBAL_POLICY_RULE); - return new GlobalPolicyRuleTabPanel<>(panelId, model); - } - }); - - tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.globalAccountSynchronization.title")) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer getPanel(String panelId) { - return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_GLOBAL_ACCOUNT_SYNCHRONIZATION_SETTINGS, ProjectionPolicyType.COMPLEX_TYPE); - } - }); - - tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.cleanupPolicy.title")) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer getPanel(String panelId) { - return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_CLEANUP_POLICY, CleanupPoliciesType.COMPLEX_TYPE); - } - }); - - tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.notifications.title")) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer getPanel(String panelId) { - PrismContainerWrapperModel model = createModel(getObjectModel(), - SystemConfigurationType.F_NOTIFICATION_CONFIGURATION); - return new NotificationConfigTabPanel(panelId, model); - } - }); - - tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.logging.title")) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer getPanel(String panelId) { - PrismContainerWrapperModel model = createModel(getObjectModel(), SystemConfigurationType.F_LOGGING); - return new LoggingConfigurationTabPanel<>(panelId, model); - } - }); - - tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.profiling.title")) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer getPanel(String panelId) { - PrismContainerWrapperModel profilingModel = createModel(getObjectModel(), SystemConfigurationType.F_PROFILING_CONFIGURATION); - PrismContainerWrapperModel loggingModel = createModel(getObjectModel(), - SystemConfigurationType.F_LOGGING); - return new ProfilingConfigurationTabPanel(panelId, profilingModel, loggingModel); - } - }); - - tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.adminGui.title")) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer getPanel(String panelId) { - return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_ADMIN_GUI_CONFIGURATION, AdminGuiConfigurationType.COMPLEX_TYPE); - } - }); - - tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.workflow.title")) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer getPanel(String panelId) { - return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_WORKFLOW_CONFIGURATION, WfConfigurationType.COMPLEX_TYPE); - } - }); - - tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.roleManagement.title")) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer getPanel(String panelId) { - return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_ROLE_MANAGEMENT, RoleManagementConfigurationType.COMPLEX_TYPE); - } - }); - - tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.internals.title")) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer getPanel(String panelId) { - return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_INTERNALS, InternalsConfigurationType.COMPLEX_TYPE); - } - }); - - tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.deploymentInformation.title")) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer getPanel(String panelId) { - return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_DEPLOYMENT_INFORMATION, DeploymentInformationType.COMPLEX_TYPE); - } - }); - - tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.accessCertification.title")) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer getPanel(String panelId) { - return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_ACCESS_CERTIFICATION, AccessCertificationConfigurationType.COMPLEX_TYPE); - } - }); - - tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.infrastructure.title")) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer getPanel(String panelId) { - return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_INFRASTRUCTURE, InfrastructureConfigurationType.COMPLEX_TYPE); - } - }); - - tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.fullTextSearch.title")) { - - private static final long serialVersionUID = 1L; - - @Override - public WebMarkupContainer getPanel(String panelId) { - return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_FULL_TEXT_SEARCH, FullTextSearchConfigurationType.COMPLEX_TYPE); - } - }); - - - return tabs; - } - - private ContainerOfSystemConfigurationPanel createContainerPanel(String panelId, IModel> objectModel, ItemName propertyName, QName propertyType) { - return new ContainerOfSystemConfigurationPanel(panelId, createModel(objectModel, propertyName), propertyType); - } - - private PrismContainerWrapperModel createModel(IModel> model, ItemName itemName) { - return PrismContainerWrapperModel.fromContainerWrapper(model, itemName); - } - - @Override - public void finishProcessing(AjaxRequestTarget target, OperationResult result, boolean returningFromAsync) { - if (!isKeepDisplayingResults()) { - showResult(result); - redirectBack(); - } - } - - @Override - public Class getCompileTimeClass() { - return SystemConfigurationType.class; - } - - @Override - protected SystemConfigurationType createNewObject() { - return null; - } - - @Override - protected ObjectSummaryPanel createSummaryPanel(IModel summaryModel) { - return new SystemConfigurationSummaryPanel(ID_SUMM_PANEL, SystemConfigurationType.class, summaryModel, this); - } - - @Override - protected AbstractObjectMainPanel createMainPanel(String id) { - return new AbstractObjectMainPanel(id, getObjectModel(), this) { - - private static final long serialVersionUID = 1L; - - @Override - protected List createTabs(PageAdminObjectDetails parentPage) { - return getTabs(); - } - - @Override - protected boolean getOptionsPanelVisibility() { - return false; - } - - @Override - protected boolean isPreviewButtonVisible() { - return false; - } - - @Override - protected void initLayoutTabs(PageAdminObjectDetails parentPage) { - List tabs = createTabs(parentPage); - TabbedPanel tabPanel = new TabbedPanel(ID_TAB_PANEL, tabs) { - - private static final long serialVersionUID = 1L; - - @Override - protected void onTabChange(int index) { - PageParameters params = getPageParameters(); - params.set(SELECTED_TAB_INDEX, index); - - parentPage.updateBreadcrumbParameters(SELECTED_TAB_INDEX, index); - } - }; - getMainForm().add(tabPanel); - } - }; - } - - @Override - protected Class getRestartResponsePage() { - return getMidpointApplication().getHomePage(); - } - - @Override - public void continueEditing(AjaxRequestTarget target) { - - } - - @Override - protected void setSummaryPanelVisibility(ObjectSummaryPanel summaryPanel) { - summaryPanel.add(new VisibleEnableBehaviour() { - private static final long serialVersionUID = 1L; - - @Override - public boolean isVisible() { - return true; - } - }); - } - - @Override - public void saveOrPreviewPerformed(AjaxRequestTarget target, OperationResult result, boolean previewOnly) { - - ProgressPanel progressPanel = getProgressPanel(); - progressPanel.hide(); - Task task = createSimpleTask(OPERATION_SEND_TO_SUBMIT); - super.saveOrPreviewPerformed(target, result, previewOnly, task); - - try { - TimeUnit.SECONDS.sleep(1); - while(task.isClosed()) {TimeUnit.SECONDS.sleep(1);} - } catch ( InterruptedException ex) { - result.recomputeStatus(); - result.recordFatalError(getString("PageSystemConfiguration.message.saveOrPreviewPerformed.fatalError"), ex); - - LoggingUtils.logUnexpectedException(LOGGER, "Couldn't use sleep", ex); - } - result.recomputeStatus(); - target.add(getFeedbackPanel()); - - if(result.getStatus().equals(OperationResultStatus.SUCCESS)) { - showResult(result); - redirectBack(); - } - } - -} +/* + * Copyright (c) 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.web.page.admin.configuration; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.schema.ObjectDeltaOperation; +import com.evolveum.midpoint.web.application.Url; +import com.evolveum.midpoint.web.page.admin.PageAdminObjectDetails; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; + +import org.apache.wicket.Page; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.extensions.markup.html.tabs.AbstractTab; +import org.apache.wicket.extensions.markup.html.tabs.ITab; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.model.IModel; +import org.apache.wicket.request.mapper.parameter.PageParameters; + +import com.evolveum.midpoint.gui.api.prism.PrismObjectWrapper; +import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; +import com.evolveum.midpoint.gui.impl.page.admin.configuration.component.GlobalPolicyRuleTabPanel; +import com.evolveum.midpoint.gui.impl.page.admin.configuration.component.LoggingConfigurationTabPanel; +import com.evolveum.midpoint.gui.impl.page.admin.configuration.component.NotificationConfigTabPanel; +import com.evolveum.midpoint.gui.impl.page.admin.configuration.component.ObjectPolicyConfigurationTabPanel; +import com.evolveum.midpoint.gui.impl.page.admin.configuration.component.ProfilingConfigurationTabPanel; +import com.evolveum.midpoint.gui.impl.page.admin.configuration.component.ContainerOfSystemConfigurationPanel; +import com.evolveum.midpoint.gui.impl.page.admin.configuration.component.SystemConfigPanel; +import com.evolveum.midpoint.gui.impl.page.admin.configuration.component.SystemConfigurationSummaryPanel; +import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.path.ItemName; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.schema.result.OperationResultStatus; +import com.evolveum.midpoint.security.api.AuthorizationConstants; +import com.evolveum.midpoint.task.api.Task; +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.component.ObjectSummaryPanel; +import com.evolveum.midpoint.web.component.TabbedPanel; +import com.evolveum.midpoint.web.component.objectdetails.AbstractObjectMainPanel; +import com.evolveum.midpoint.web.component.progress.ProgressPanel; +import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; +import com.evolveum.midpoint.web.model.PrismContainerWrapperModel; + +/** + * @author lazyman + * @author skublik + */ +@PageDescriptor( + urls = { + @Url(mountUrl = "/admin/config/system", matchUrlForSecurity = "/admin/config/system"), + }, + action = { + @AuthorizationAction(actionUri = PageAdminConfiguration.AUTH_CONFIGURATION_ALL, + label = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_LABEL, + description = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_DESCRIPTION), + @AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_CONFIGURATION_SYSTEM_CONFIG_URL, + label = "PageSystemConfiguration.auth.configSystemConfiguration.label", + description = "PageSystemConfiguration.auth.configSystemConfiguration.description") + }) +public class PageSystemConfiguration extends PageAdminObjectDetails { + + private static final long serialVersionUID = 1L; + + public static final String SELECTED_TAB_INDEX = "tab"; + public static final String SELECTED_SERVER_INDEX = "mailServerIndex"; + public static final String SERVER_LIST_SIZE = "mailServerListSize"; + + private static final String DOT_CLASS = PageSystemConfiguration.class.getName() + "."; + private static final String OPERATION_LOAD_SYSTEM_CONFIG = DOT_CLASS + "load"; + + public static final int CONFIGURATION_TAB_BASIC = 0; + public static final int CONFIGURATION_TAB_OBJECT_POLICY = 1; + public static final int CONFIGURATION_TAB_GLOBAL_POLICY_RULE = 2; + public static final int CONFIGURATION_TAB_GLOBAL_ACCOUNT_SYNCHRONIZATION = 3; + public static final int CONFIGURATION_TAB_CLEANUP_POLICY = 4; + public static final int CONFIGURATION_TAB_NOTIFICATION = 5; + public static final int CONFIGURATION_TAB_LOGGING = 6; + public static final int CONFIGURATION_TAB_PROFILING = 7; + public static final int CONFIGURATION_TAB_ADMIN_GUI = 8; + public static final int CONFIGURATION_TAB_WORKFLOW = 9; + public static final int CONFIGURATION_TAB_ROLE_MANAGEMENT = 10; + public static final int CONFIGURATION_TAB_INTERNALS = 11; + public static final int CONFIGURATION_TAB_DEPLOYMENT_INFORMATION = 12; + public static final int CONFIGURATION_TAB_ACCESS_CERTIFICATION = 13; + public static final int CONFIGURATION_TAB_INFRASTRUCTURE = 14; + public static final int CONFIGURATION_TAB_FULL_TEXT_SEARCH = 15; + + private static final Trace LOGGER = TraceManager.getTrace(PageSystemConfiguration.class); + + private static final String ID_SUMM_PANEL = "summaryPanel"; + + public static final String ROOT_APPENDER_INHERITANCE_CHOICE = "(Inherit root)"; + + public PageSystemConfiguration() { + initialize(null); + } + + public PageSystemConfiguration(PageParameters parameters) { + getPageParameters().overwriteWith(parameters); + initialize(null); + } + + public PageSystemConfiguration(final PrismObject configToEdit) { + initialize(configToEdit); + } + + public PageSystemConfiguration(final PrismObject configToEdit, boolean isNewObject) { + initialize(configToEdit, isNewObject); + } + + @Override + protected void initializeModel(final PrismObject configToEdit, boolean isNewObject, boolean isReadonly) { + Task task = createSimpleTask(OPERATION_LOAD_SYSTEM_CONFIG); + OperationResult result = new OperationResult(OPERATION_LOAD_SYSTEM_CONFIG); + super.initializeModel(WebModelServiceUtils.loadSystemConfigurationAsPrismObject(this, task, result), false, isReadonly); + } + + private List getTabs(){ + List tabs = new ArrayList<>(); + tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.system.title")) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer getPanel(String panelId) { + return new SystemConfigPanel(panelId, getObjectModel()); + } + }); + + tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.objectPolicy.title")) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer getPanel(String panelId) { + PrismContainerWrapperModel model = createModel(getObjectModel(), SystemConfigurationType.F_DEFAULT_OBJECT_POLICY_CONFIGURATION); + return new ObjectPolicyConfigurationTabPanel<>(panelId, model); + } + }); + + tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.globalPolicyRule.title")) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer getPanel(String panelId) { + PrismContainerWrapperModel model = createModel(getObjectModel(), + SystemConfigurationType.F_GLOBAL_POLICY_RULE); + return new GlobalPolicyRuleTabPanel<>(panelId, model); + } + }); + + tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.globalAccountSynchronization.title")) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer getPanel(String panelId) { + return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_GLOBAL_ACCOUNT_SYNCHRONIZATION_SETTINGS, ProjectionPolicyType.COMPLEX_TYPE); + } + }); + + tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.cleanupPolicy.title")) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer getPanel(String panelId) { + return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_CLEANUP_POLICY, CleanupPoliciesType.COMPLEX_TYPE); + } + }); + + tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.notifications.title")) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer getPanel(String panelId) { + PrismContainerWrapperModel model = createModel(getObjectModel(), + SystemConfigurationType.F_NOTIFICATION_CONFIGURATION); + return new NotificationConfigTabPanel(panelId, model); + } + }); + + tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.logging.title")) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer getPanel(String panelId) { + PrismContainerWrapperModel model = createModel(getObjectModel(), SystemConfigurationType.F_LOGGING); + return new LoggingConfigurationTabPanel<>(panelId, model); + } + }); + + tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.profiling.title")) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer getPanel(String panelId) { + PrismContainerWrapperModel profilingModel = createModel(getObjectModel(), SystemConfigurationType.F_PROFILING_CONFIGURATION); + PrismContainerWrapperModel loggingModel = createModel(getObjectModel(), + SystemConfigurationType.F_LOGGING); + return new ProfilingConfigurationTabPanel(panelId, profilingModel, loggingModel); + } + }); + + tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.adminGui.title")) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer getPanel(String panelId) { + return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_ADMIN_GUI_CONFIGURATION, AdminGuiConfigurationType.COMPLEX_TYPE); + } + }); + + tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.workflow.title")) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer getPanel(String panelId) { + return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_WORKFLOW_CONFIGURATION, WfConfigurationType.COMPLEX_TYPE); + } + }); + + tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.roleManagement.title")) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer getPanel(String panelId) { + return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_ROLE_MANAGEMENT, RoleManagementConfigurationType.COMPLEX_TYPE); + } + }); + + tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.internals.title")) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer getPanel(String panelId) { + return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_INTERNALS, InternalsConfigurationType.COMPLEX_TYPE); + } + }); + + tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.deploymentInformation.title")) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer getPanel(String panelId) { + return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_DEPLOYMENT_INFORMATION, DeploymentInformationType.COMPLEX_TYPE); + } + }); + + tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.accessCertification.title")) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer getPanel(String panelId) { + return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_ACCESS_CERTIFICATION, AccessCertificationConfigurationType.COMPLEX_TYPE); + } + }); + + tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.infrastructure.title")) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer getPanel(String panelId) { + return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_INFRASTRUCTURE, InfrastructureConfigurationType.COMPLEX_TYPE); + } + }); + + tabs.add(new AbstractTab(createStringResource("pageSystemConfiguration.fullTextSearch.title")) { + + private static final long serialVersionUID = 1L; + + @Override + public WebMarkupContainer getPanel(String panelId) { + return createContainerPanel(panelId, getObjectModel(), SystemConfigurationType.F_FULL_TEXT_SEARCH, FullTextSearchConfigurationType.COMPLEX_TYPE); + } + }); + + + return tabs; + } + + private ContainerOfSystemConfigurationPanel createContainerPanel(String panelId, IModel> objectModel, ItemName propertyName, QName propertyType) { + return new ContainerOfSystemConfigurationPanel(panelId, createModel(objectModel, propertyName), propertyType); + } + + private PrismContainerWrapperModel createModel(IModel> model, ItemName itemName) { + return PrismContainerWrapperModel.fromContainerWrapper(model, itemName); + } + + @Override + public void finishProcessing(AjaxRequestTarget target, Collection> executedDeltas, boolean returningFromAsync, OperationResult result) { + if (!isKeepDisplayingResults()) { + showResult(result); + redirectBack(); + } + } + + @Override + public Class getCompileTimeClass() { + return SystemConfigurationType.class; + } + + @Override + protected SystemConfigurationType createNewObject() { + return null; + } + + @Override + protected ObjectSummaryPanel createSummaryPanel(IModel summaryModel) { + return new SystemConfigurationSummaryPanel(ID_SUMM_PANEL, SystemConfigurationType.class, summaryModel, this); + } + + @Override + protected AbstractObjectMainPanel createMainPanel(String id) { + return new AbstractObjectMainPanel(id, getObjectModel(), this) { + + private static final long serialVersionUID = 1L; + + @Override + protected List createTabs(PageAdminObjectDetails parentPage) { + return getTabs(); + } + + @Override + protected boolean getOptionsPanelVisibility() { + return false; + } + + @Override + protected boolean isPreviewButtonVisible() { + return false; + } + + @Override + protected void initLayoutTabs(PageAdminObjectDetails parentPage) { + List tabs = createTabs(parentPage); + TabbedPanel tabPanel = new TabbedPanel(ID_TAB_PANEL, tabs) { + + private static final long serialVersionUID = 1L; + + @Override + protected void onTabChange(int index) { + PageParameters params = getPageParameters(); + params.set(SELECTED_TAB_INDEX, index); + + parentPage.updateBreadcrumbParameters(SELECTED_TAB_INDEX, index); + } + }; + getMainForm().add(tabPanel); + } + }; + } + + @Override + protected Class getRestartResponsePage() { + return getMidpointApplication().getHomePage(); + } + + @Override + public void continueEditing(AjaxRequestTarget target) { + + } + + @Override + protected void setSummaryPanelVisibility(ObjectSummaryPanel summaryPanel) { + summaryPanel.add(new VisibleEnableBehaviour() { + private static final long serialVersionUID = 1L; + + @Override + public boolean isVisible() { + return true; + } + }); + } + + @Override + public void saveOrPreviewPerformed(AjaxRequestTarget target, OperationResult result, boolean previewOnly) { + + ProgressPanel progressPanel = getProgressPanel(); + progressPanel.hide(); + Task task = createSimpleTask(OPERATION_SEND_TO_SUBMIT); + super.saveOrPreviewPerformed(target, result, previewOnly, task); + + try { + TimeUnit.SECONDS.sleep(1); + while(task.isClosed()) {TimeUnit.SECONDS.sleep(1);} + } catch ( InterruptedException ex) { + result.recomputeStatus(); + result.recordFatalError(getString("PageSystemConfiguration.message.saveOrPreviewPerformed.fatalError"), ex); + + LoggingUtils.logUnexpectedException(LOGGER, "Couldn't use sleep", ex); + } + result.recomputeStatus(); + target.add(getFeedbackPanel()); + + if(result.getStatus().equals(OperationResultStatus.SUCCESS)) { + showResult(result); + redirectBack(); + } + } + +} 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 0fb784eef3e..1d4ae1cc2f1 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 @@ -1,504 +1,525 @@ -package com.evolveum.midpoint.web.page.admin.server; - -import java.io.InputStream; -import java.util.Collection; -import java.util.Collections; - -import org.apache.wicket.Page; -import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.behavior.AttributeAppender; -import org.apache.wicket.markup.html.basic.Label; -import org.apache.wicket.markup.repeater.RepeatingView; -import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; -import org.apache.wicket.request.mapper.parameter.PageParameters; - -import com.evolveum.midpoint.gui.api.GuiStyleConstants; -import com.evolveum.midpoint.gui.api.prism.PrismObjectWrapper; -import com.evolveum.midpoint.gui.api.util.WebComponentUtil; -import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; -import com.evolveum.midpoint.gui.impl.prism.PrismPropertyWrapper; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.delta.ObjectDelta; -import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.report.api.ReportConstants; -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.MiscUtil; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.logging.LoggingUtils; -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.web.application.AuthorizationAction; -import com.evolveum.midpoint.web.application.PageDescriptor; -import com.evolveum.midpoint.web.application.Url; -import com.evolveum.midpoint.web.component.AjaxButton; -import com.evolveum.midpoint.web.component.AjaxDownloadBehaviorFromStream; -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.refresh.Refreshable; -import com.evolveum.midpoint.web.component.util.VisibleBehaviour; -import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; -import com.evolveum.midpoint.web.page.admin.PageAdminObjectDetails; -import com.evolveum.midpoint.web.page.admin.reports.PageCreatedReports; -import com.evolveum.midpoint.web.util.OnePageParameterEncoder; -import com.evolveum.midpoint.web.util.TaskOperationUtils; -import com.evolveum.midpoint.xml.ns._public.common.common_3.*; - -@PageDescriptor( - urls = { - @Url(mountUrl = "/admin/task", matchUrlForSecurity = "/admin/task") - }, - encoder = OnePageParameterEncoder.class, - action = { - @AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_USERS_ALL_URL, - label = "PageAdminUsers.auth.usersAll.label", - description = "PageAdminUsers.auth.usersAll.description"), - @AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_USER_URL, - label = "PageUser.auth.user.label", - description = "PageUser.auth.user.description") - }) -public class PageTask extends PageAdminObjectDetails implements Refreshable { - private static final long serialVersionUID = 1L; - - private static final transient Trace LOGGER = TraceManager.getTrace(PageTask.class); - private static final String DOT_CLASS = PageTask.class.getName() + "."; - protected static final String OPERATION_EXECUTE_TASK_CHANGES = DOT_CLASS + "executeTaskChanges"; - private static final String OPERATION_LOAD_REPORT_OUTPUT = DOT_CLASS + "loadReport"; - - private static final int REFRESH_INTERVAL = 2000; - - private Boolean refreshEnabled; - - public PageTask() { - initialize(null); - } - - public PageTask(PageParameters parameters) { - getPageParameters().overwriteWith(parameters); - initialize(null); - } - - public PageTask(final PrismObject taskToEdit) { - initialize(taskToEdit); - } - - public PageTask(final PrismObject taskToEdit, boolean isNewObject) { - initialize(taskToEdit, isNewObject); - } - - @Override - public Class getCompileTimeClass() { - return TaskType.class; - } - - @Override - protected TaskType createNewObject() { - return new TaskType(); - } - - @Override - protected ObjectSummaryPanel createSummaryPanel(IModel summaryModel) { - return new TaskSummaryPanel(ID_SUMMARY_PANEL, summaryModel, this, this); - } - - @Override - protected Collection> buildGetOptions() { - //TODO use full options as defined in TaskDtoProviderOptions.fullOptions() - - return getOperationOptionsBuilder() - // retrieve - .item(TaskType.F_SUBTASK_REF).retrieve() - .item(TaskType.F_NODE_AS_OBSERVED).retrieve() - .item(TaskType.F_NEXT_RUN_START_TIMESTAMP).retrieve() - .item(TaskType.F_NEXT_RETRY_TIMESTAMP).retrieve() - .item(TaskType.F_RESULT).retrieve() // todo maybe only when it is to be displayed - .build(); - } - - protected void initOperationalButtons(RepeatingView repeatingView) { - super.initOperationalButtons(repeatingView); - - createSuspendButton(repeatingView); - createResumeButton(repeatingView); - createRunNowButton(repeatingView); - - createManageLivesyncTokenButton(repeatingView); - createDownloadReportButton(repeatingView); - createCleanupPerformanceButton(repeatingView); - createCleanupResultsButton(repeatingView); - - createRefreshNowIconButton(repeatingView); - createResumePauseButton(repeatingView); - - - -// AjaxIconButton cleanupErrors = new AjaxIconButton(repeatingView.newChildId(), new Model<>(GuiStyleConstants.CLASS_ICON_TRASH), -// createStringResource("operationalButtonsPanel.cleanupErrors")) { -// -// @Override -// public void onClick(AjaxRequestTarget target) { -// refresh(target); -// } -// }; -// cleanupErrors.add(AttributeAppender.append("class", "btn btn-default btn-margin-left btn-sm")); -// cleanupErrors.add(new VisibleBehaviour(this::isNotRunning)); -// repeatingView.add(cleanupErrors); - - setOutputMarkupId(true); - - final Label status = new Label(repeatingView.newChildId(), this::createRefreshingLabel); - status.setOutputMarkupId(true); - repeatingView.add(status); - - } - - private void createSuspendButton(RepeatingView repeatingView) { - AjaxButton suspend = new AjaxButton(repeatingView.newChildId(), createStringResource("pageTaskEdit.button.suspend")) { - @Override - public void onClick(AjaxRequestTarget target) { - String taskOid = getObjectWrapper().getOid(); - OperationResult result = TaskOperationUtils.suspendPerformed(getTaskService(), Collections.singletonList(taskOid), PageTask.this); - afterOperation(target, result); - } - }; - suspend.add(new VisibleBehaviour(() -> WebComponentUtil.canSuspendTask(getTask(), PageTask.this))); - suspend.add(AttributeAppender.append("class", "btn-danger")); - repeatingView.add(suspend); - } - - private void createResumeButton(RepeatingView repeatingView) { - AjaxButton resume = new AjaxButton(repeatingView.newChildId(), createStringResource("pageTaskEdit.button.resume")) { - @Override - public void onClick(AjaxRequestTarget target) { - String oid = getObjectWrapper().getOid(); - OperationResult result = TaskOperationUtils.resumePerformed(getTaskService(), Collections.singletonList(oid), PageTask.this); - afterOperation(target, result); - } - }; - resume.add(AttributeAppender.append("class", "btn-primary")); - resume.add(new VisibleBehaviour(() -> WebComponentUtil.canResumeTask(getTask(), PageTask.this))); - repeatingView.add(resume); - } - - private void createRunNowButton(RepeatingView repeatingView) { - AjaxButton runNow = new AjaxButton(repeatingView.newChildId(), createStringResource("pageTaskEdit.button.runNow")) { - @Override - public void onClick(AjaxRequestTarget target) { - String oid = getObjectWrapper().getOid(); - refreshEnabled = Boolean.TRUE; - OperationResult result = TaskOperationUtils.runNowPerformed(getTaskService(), Collections.singletonList(oid), PageTask.this); - afterOperation(target, result); - } - }; - runNow.add(AttributeAppender.append("class", "btn-success")); - runNow.add(new VisibleBehaviour(() -> WebComponentUtil.canRunNowTask(getTask(), PageTask.this))); - repeatingView.add(runNow); - } - - private void createManageLivesyncTokenButton(RepeatingView repeatingView) { - AjaxButton manageLivesyncToken = new AjaxButton(repeatingView.newChildId(), createStringResource("PageTask.livesync.token")) { - - @Override - public void onClick(AjaxRequestTarget ajaxRequestTarget) { - LivesyncTokenEditorPanel tokenEditor = new LivesyncTokenEditorPanel(PageTask.this.getMainPopupBodyId(), getObjectModel()) { - - @Override - protected void saveTokenPerformed(ObjectDelta tokenDelta, AjaxRequestTarget target) { - saveTaskChanges(target, tokenDelta); - } - }; - tokenEditor.setOutputMarkupId(true); - PageTask.this.showMainPopup(tokenEditor, ajaxRequestTarget); - } - }; - manageLivesyncToken.add(new VisibleEnableBehaviour() { - @Override - public boolean isVisible() { - return WebComponentUtil.isLiveSync(getTask()) && isNotRunning() && getTask().asPrismObject().findProperty(LivesyncTokenEditorPanel.PATH_TOKEN) != null; - } - - @Override - public boolean isEnabled() { - return isNotRunning(); - } - }); - manageLivesyncToken.add(AttributeAppender.append("class", "btn-default")); - manageLivesyncToken.setOutputMarkupId(true); - repeatingView.add(manageLivesyncToken); - } - - private void createDownloadReportButton(RepeatingView repeatingView) { - final AjaxDownloadBehaviorFromStream ajaxDownloadBehavior = new AjaxDownloadBehaviorFromStream() { - private static final long serialVersionUID = 1L; - - @Override - protected InputStream initStream() { - ReportOutputType reportObject = getReportOutput(); - if (reportObject != null) { - return PageCreatedReports.createReport(reportObject, this, PageTask.this); - } else { - return null; - } - } - - - @Override - public String getFileName() { - ReportOutputType reportObject = getReportOutput(); - return PageCreatedReports.getReportFileName(reportObject); - } - }; - add(ajaxDownloadBehavior); - - AjaxButton download = new AjaxButton(repeatingView.newChildId(), createStringResource("PageTask.download.report")) { - - private static final long serialVersionUID = 1L; - - @Override - public void onClick(AjaxRequestTarget target) { - ajaxDownloadBehavior.initiate(target); - } - }; - download.add(new VisibleBehaviour(() -> isDownloadReportVisible())); - download.add(AttributeAppender.append("class", "btn-primary")); - repeatingView.add(download); - } - - private boolean isDownloadReportVisible() { - return WebComponentUtil.isReport(getTask()) - && getReportOutputProperty() != null; - } - - private ReportOutputType getReportOutput() { - PrismProperty reportOutput = getReportOutputProperty(); - if (reportOutput == null) { - return null; - } - - String reportOutputOid = reportOutput.getRealValue(); - if (reportOutputOid == null) { - return null; - } - - Task opTask = createSimpleTask(OPERATION_LOAD_REPORT_OUTPUT); - OperationResult result = opTask.getResult(); - - PrismObject report = WebModelServiceUtils.loadObject(ReportOutputType.class, reportOutputOid, this, opTask, result); - if (report == null) { - return null; - } - result.computeStatusIfUnknown(); - showResult(result, false); - - return report.asObjectable(); - - } - - private PrismProperty getReportOutputProperty() { - PrismObject task = getTask().asPrismObject(); - return task.findProperty(ItemPath.create(TaskType.F_EXTENSION, ReportConstants.REPORT_OUTPUT_OID_PROPERTY_NAME)); - } - - private void createRefreshNowIconButton(RepeatingView repeatingView) { - AjaxIconButton refreshNow = new AjaxIconButton(repeatingView.newChildId(), new Model<>("fa fa-refresh"), createStringResource("autoRefreshPanel.refreshNow")) { - - @Override - public void onClick(AjaxRequestTarget target) { - refresh(target); - } - }; - refreshNow.add(AttributeAppender.append("class", "btn btn-default btn-sm")); - repeatingView.add(refreshNow); - } - - private void createResumePauseButton(RepeatingView repeatingView) { - AjaxIconButton resumePauseRefreshing = new AjaxIconButton(repeatingView.newChildId(), (IModel) this::createResumePauseButtonLabel, createStringResource("autoRefreshPanel.resumeRefreshing")) { - - @Override - public void onClick(AjaxRequestTarget target) { - refreshEnabled = !isRefreshEnabled(); - refresh(target); - } - }; - resumePauseRefreshing.add(AttributeAppender.append("class", "btn btn-default btn-margin-left btn-sm")); - repeatingView.add(resumePauseRefreshing); - } - - private void createCleanupPerformanceButton(RepeatingView repeatingView) { - AjaxIconButton cleanupPerformance = new AjaxIconButton(repeatingView.newChildId(), new Model<>(GuiStyleConstants.CLASS_ICON_TRASH), - createStringResource("operationalButtonsPanel.cleanupEnvironmentalPerformance")) { - - @Override - public void onClick(AjaxRequestTarget target) { - try { - getObjectWrapper().findProperty(ItemPath.create(TaskType.F_OPERATION_STATS, - OperationStatsType.F_ENVIRONMENTAL_PERFORMANCE_INFORMATION)).getValue().setRealValue(null); - } catch (SchemaException e){ - LOGGER.error("Cannot clear task results: {}", e.getMessage()); - } - saveTaskChanges(target); - } - }; - cleanupPerformance.add(AttributeAppender.append("class", "btn btn-default btn-margin-left btn-sm")); - cleanupPerformance.add(new VisibleBehaviour(this::isNotRunning)); - repeatingView.add(cleanupPerformance); - } - - private void createCleanupResultsButton(RepeatingView repeatingView) { - AjaxIconButton cleanupResults = new AjaxIconButton(repeatingView.newChildId(), new Model<>(GuiStyleConstants.CLASS_ICON_TRASH), - createStringResource("operationalButtonsPanel.cleanupResults")) { - - @Override - public void onClick(AjaxRequestTarget target) { - try { - getObjectWrapper().findProperty(TaskType.F_RESULT).getValue().setRealValue(null); - getObjectWrapper().findProperty(TaskType.F_RESULT_STATUS).getValue().setRealValue(null); - } catch (SchemaException e){ - LOGGER.error("Cannot clear task results: {}", e.getMessage()); - } - saveTaskChanges(target); - refresh(target); - } - }; - cleanupResults.add(new VisibleBehaviour(this::isNotRunning)); - cleanupResults.add(AttributeAppender.append("class", "btn btn-default btn-margin-left btn-sm")); - repeatingView.add(cleanupResults); - } - - private void saveTaskChanges(AjaxRequestTarget target) { - try { - ObjectDelta taskDelta = getObjectWrapper().getObjectDelta(); - saveTaskChanges(target, taskDelta); - } catch (SchemaException e) { - LoggingUtils.logUnexpectedException(LOGGER, "Cannot get task delta.", e); - getSession().error("Cannot save changes, there were problems with computing changes: " + e.getMessage()); - target.add(getFeedbackPanel()); - } - } - - private void saveTaskChanges(AjaxRequestTarget target, ObjectDelta taskDelta){ - if (taskDelta.isEmpty()) { - getSession().warn("Nothing to save, no changes were made."); - return; - } - - OperationResult result = new OperationResult(OPERATION_EXECUTE_TASK_CHANGES); - Task task = createSimpleTask(OPERATION_EXECUTE_TASK_CHANGES); - - try { - 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); - } - afterOperation(target, result); - } - - private void afterOperation(AjaxRequestTarget target, OperationResult result) { - showResult(result); - getObjectModel().reset(); - refresh(target); - } - - public void saveAndRunPerformed(AjaxRequestTarget target) { - PrismObjectWrapper taskWrapper = getObjectWrapper(); - try { - PrismPropertyWrapper executionStatus = taskWrapper.findProperty(ItemPath.create(TaskType.F_EXECUTION_STATUS)); - executionStatus.getValue().setRealValue(TaskExecutionStatusType.RUNNABLE); - } catch (SchemaException e) { - LoggingUtils.logUnexpectedException(LOGGER, "Error while setting task execution status", e); - target.add(getFeedbackPanel()); - return; - } - - if (!checkScheduleFilledForReccurentTask(taskWrapper)) { - getSession().error("Cannot run recurring task without setting scheduling for it."); - target.add(getFeedbackPanel()); - return; - } - - super.savePerformed(target); - } - - private boolean checkScheduleFilledForReccurentTask(PrismObjectWrapper taskWrapper) { - PrismObject task = taskWrapper.getObject(); - - PrismProperty recurrenceType = task.findProperty(ItemPath.create(TaskType.F_RECURRENCE)); - if (recurrenceType == null) { - return true; - } - - TaskRecurrenceType recurenceValue = recurrenceType.getRealValue(); - if (recurenceValue == null || TaskRecurrenceType.SINGLE == recurenceValue) { - return true; - } - - ScheduleType schedule = task.asObjectable().getSchedule(); - //if schedule is not set and task is recurring, show warning. - return schedule.getCronLikePattern() != null || schedule.getEarliestStartTime() != null - || schedule.getInterval() != null || schedule.getLatestFinishTime() != null - || schedule.getLatestStartTime() != null || schedule.getMisfireAction() != null; - } - - - private String createRefreshingLabel() { - if (isRefreshEnabled()) { - return createStringResource("autoRefreshPanel.refreshingEach", getRefreshInterval() / 1000).getString(); - } else { - return createStringResource("autoRefreshPanel.noRefreshing").getString(); - } - } - - private String createResumePauseButtonLabel() { - if (isRefreshEnabled()) { - return "fa fa-pause"; - } - return "fa fa-play"; - } - - @Override - protected AbstractObjectMainPanel createMainPanel(String id) { - return new TaskMainPanel(id, getObjectModel(), this); - } - - TaskType getTask(){ - return getObjectWrapper().getObject().asObjectable(); - } - - @Override - protected Class getRestartResponsePage() { - return PageTasks.class; - } - - @Override - public void continueEditing(AjaxRequestTarget target) { - - } - - @Override - public int getRefreshInterval() { - return REFRESH_INTERVAL; - } - - private boolean isNotRunning(){ - return !WebComponentUtil.isRunningTask(getTask()); - } - - public boolean isRefreshEnabled() { - if (refreshEnabled == null) { - return WebComponentUtil.isRunningTask(getTask()); - } - - return refreshEnabled; - - } -} +package com.evolveum.midpoint.web.page.admin.server; + +import java.io.InputStream; +import java.util.Collection; +import java.util.Collections; + +import com.evolveum.midpoint.model.api.util.ModelContextUtil; +import com.evolveum.midpoint.schema.ObjectDeltaOperation; + +import org.apache.wicket.Page; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.behavior.AttributeAppender; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.repeater.RepeatingView; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.request.mapper.parameter.PageParameters; + +import com.evolveum.midpoint.gui.api.GuiStyleConstants; +import com.evolveum.midpoint.gui.api.prism.PrismObjectWrapper; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; +import com.evolveum.midpoint.gui.impl.prism.PrismPropertyWrapper; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismProperty; +import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.report.api.ReportConstants; +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.MiscUtil; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.logging.LoggingUtils; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.web.application.AuthorizationAction; +import com.evolveum.midpoint.web.application.PageDescriptor; +import com.evolveum.midpoint.web.application.Url; +import com.evolveum.midpoint.web.component.AjaxButton; +import com.evolveum.midpoint.web.component.AjaxDownloadBehaviorFromStream; +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.refresh.Refreshable; +import com.evolveum.midpoint.web.component.util.VisibleBehaviour; +import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; +import com.evolveum.midpoint.web.page.admin.PageAdminObjectDetails; +import com.evolveum.midpoint.web.page.admin.reports.PageCreatedReports; +import com.evolveum.midpoint.web.util.OnePageParameterEncoder; +import com.evolveum.midpoint.web.util.TaskOperationUtils; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; + +@PageDescriptor( + urls = { + @Url(mountUrl = "/admin/task", matchUrlForSecurity = "/admin/task") + }, + encoder = OnePageParameterEncoder.class, + action = { + @AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_USERS_ALL_URL, + label = "PageAdminUsers.auth.usersAll.label", + description = "PageAdminUsers.auth.usersAll.description"), + @AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_USER_URL, + label = "PageUser.auth.user.label", + description = "PageUser.auth.user.description") + }) +public class PageTask extends PageAdminObjectDetails implements Refreshable { + private static final long serialVersionUID = 1L; + + private static final transient Trace LOGGER = TraceManager.getTrace(PageTask.class); + private static final String DOT_CLASS = PageTask.class.getName() + "."; + protected static final String OPERATION_EXECUTE_TASK_CHANGES = DOT_CLASS + "executeTaskChanges"; + private static final String OPERATION_LOAD_REPORT_OUTPUT = DOT_CLASS + "loadReport"; + + private static final int REFRESH_INTERVAL = 2000; + + private Boolean refreshEnabled; + + public PageTask() { + initialize(null); + } + + public PageTask(PageParameters parameters) { + getPageParameters().overwriteWith(parameters); + initialize(null); + } + + public PageTask(final PrismObject taskToEdit) { + initialize(taskToEdit); + } + + public PageTask(final PrismObject taskToEdit, boolean isNewObject) { + initialize(taskToEdit, isNewObject); + } + + @Override + public Class getCompileTimeClass() { + return TaskType.class; + } + + @Override + protected TaskType createNewObject() { + return new TaskType(); + } + + @Override + protected ObjectSummaryPanel createSummaryPanel(IModel summaryModel) { + return new TaskSummaryPanel(ID_SUMMARY_PANEL, summaryModel, this, this); + } + + @Override + protected Collection> buildGetOptions() { + //TODO use full options as defined in TaskDtoProviderOptions.fullOptions() + + return getOperationOptionsBuilder() + // retrieve + .item(TaskType.F_SUBTASK_REF).retrieve() + .item(TaskType.F_NODE_AS_OBSERVED).retrieve() + .item(TaskType.F_NEXT_RUN_START_TIMESTAMP).retrieve() + .item(TaskType.F_NEXT_RETRY_TIMESTAMP).retrieve() + .item(TaskType.F_RESULT).retrieve() // todo maybe only when it is to be displayed + .build(); + } + + protected void initOperationalButtons(RepeatingView repeatingView) { + super.initOperationalButtons(repeatingView); + + createSuspendButton(repeatingView); + createResumeButton(repeatingView); + createRunNowButton(repeatingView); + + createManageLivesyncTokenButton(repeatingView); + createDownloadReportButton(repeatingView); + createCleanupPerformanceButton(repeatingView); + createCleanupResultsButton(repeatingView); + + createRefreshNowIconButton(repeatingView); + createResumePauseButton(repeatingView); + + + +// AjaxIconButton cleanupErrors = new AjaxIconButton(repeatingView.newChildId(), new Model<>(GuiStyleConstants.CLASS_ICON_TRASH), +// createStringResource("operationalButtonsPanel.cleanupErrors")) { +// +// @Override +// public void onClick(AjaxRequestTarget target) { +// refresh(target); +// } +// }; +// cleanupErrors.add(AttributeAppender.append("class", "btn btn-default btn-margin-left btn-sm")); +// cleanupErrors.add(new VisibleBehaviour(this::isNotRunning)); +// repeatingView.add(cleanupErrors); + + setOutputMarkupId(true); + + final Label status = new Label(repeatingView.newChildId(), this::createRefreshingLabel); + status.setOutputMarkupId(true); + repeatingView.add(status); + + } + + private void createSuspendButton(RepeatingView repeatingView) { + AjaxButton suspend = new AjaxButton(repeatingView.newChildId(), createStringResource("pageTaskEdit.button.suspend")) { + @Override + public void onClick(AjaxRequestTarget target) { + String taskOid = getObjectWrapper().getOid(); + OperationResult result = TaskOperationUtils.suspendPerformed(getTaskService(), Collections.singletonList(taskOid), PageTask.this); + afterOperation(target, result); + } + }; + suspend.add(new VisibleBehaviour(() -> WebComponentUtil.canSuspendTask(getTask(), PageTask.this))); + suspend.add(AttributeAppender.append("class", "btn-danger")); + repeatingView.add(suspend); + } + + private void createResumeButton(RepeatingView repeatingView) { + AjaxButton resume = new AjaxButton(repeatingView.newChildId(), createStringResource("pageTaskEdit.button.resume")) { + @Override + public void onClick(AjaxRequestTarget target) { + String oid = getObjectWrapper().getOid(); + OperationResult result = TaskOperationUtils.resumePerformed(getTaskService(), Collections.singletonList(oid), PageTask.this); + afterOperation(target, result); + } + }; + resume.add(AttributeAppender.append("class", "btn-primary")); + resume.add(new VisibleBehaviour(() -> WebComponentUtil.canResumeTask(getTask(), PageTask.this))); + repeatingView.add(resume); + } + + private void createRunNowButton(RepeatingView repeatingView) { + AjaxButton runNow = new AjaxButton(repeatingView.newChildId(), createStringResource("pageTaskEdit.button.runNow")) { + @Override + public void onClick(AjaxRequestTarget target) { + String oid = getObjectWrapper().getOid(); + refreshEnabled = Boolean.TRUE; + OperationResult result = TaskOperationUtils.runNowPerformed(getTaskService(), Collections.singletonList(oid), PageTask.this); + afterOperation(target, result); + } + }; + runNow.add(AttributeAppender.append("class", "btn-success")); + runNow.add(new VisibleBehaviour(() -> WebComponentUtil.canRunNowTask(getTask(), PageTask.this))); + repeatingView.add(runNow); + } + + private void createManageLivesyncTokenButton(RepeatingView repeatingView) { + AjaxButton manageLivesyncToken = new AjaxButton(repeatingView.newChildId(), createStringResource("PageTask.livesync.token")) { + + @Override + public void onClick(AjaxRequestTarget ajaxRequestTarget) { + LivesyncTokenEditorPanel tokenEditor = new LivesyncTokenEditorPanel(PageTask.this.getMainPopupBodyId(), getObjectModel()) { + + @Override + protected void saveTokenPerformed(ObjectDelta tokenDelta, AjaxRequestTarget target) { + saveTaskChanges(target, tokenDelta); + } + }; + tokenEditor.setOutputMarkupId(true); + PageTask.this.showMainPopup(tokenEditor, ajaxRequestTarget); + } + }; + manageLivesyncToken.add(new VisibleEnableBehaviour() { + @Override + public boolean isVisible() { + return WebComponentUtil.isLiveSync(getTask()) && isNotRunning() && getTask().asPrismObject().findProperty(LivesyncTokenEditorPanel.PATH_TOKEN) != null; + } + + @Override + public boolean isEnabled() { + return isNotRunning(); + } + }); + manageLivesyncToken.add(AttributeAppender.append("class", "btn-default")); + manageLivesyncToken.setOutputMarkupId(true); + repeatingView.add(manageLivesyncToken); + } + + private void createDownloadReportButton(RepeatingView repeatingView) { + final AjaxDownloadBehaviorFromStream ajaxDownloadBehavior = new AjaxDownloadBehaviorFromStream() { + private static final long serialVersionUID = 1L; + + @Override + protected InputStream initStream() { + ReportOutputType reportObject = getReportOutput(); + if (reportObject != null) { + return PageCreatedReports.createReport(reportObject, this, PageTask.this); + } else { + return null; + } + } + + + @Override + public String getFileName() { + ReportOutputType reportObject = getReportOutput(); + return PageCreatedReports.getReportFileName(reportObject); + } + }; + add(ajaxDownloadBehavior); + + AjaxButton download = new AjaxButton(repeatingView.newChildId(), createStringResource("PageTask.download.report")) { + + private static final long serialVersionUID = 1L; + + @Override + public void onClick(AjaxRequestTarget target) { + ajaxDownloadBehavior.initiate(target); + } + }; + download.add(new VisibleBehaviour(() -> isDownloadReportVisible())); + download.add(AttributeAppender.append("class", "btn-primary")); + repeatingView.add(download); + } + + private boolean isDownloadReportVisible() { + return WebComponentUtil.isReport(getTask()) + && getReportOutputProperty() != null; + } + + private ReportOutputType getReportOutput() { + PrismProperty reportOutput = getReportOutputProperty(); + if (reportOutput == null) { + return null; + } + + String reportOutputOid = reportOutput.getRealValue(); + if (reportOutputOid == null) { + return null; + } + + Task opTask = createSimpleTask(OPERATION_LOAD_REPORT_OUTPUT); + OperationResult result = opTask.getResult(); + + PrismObject report = WebModelServiceUtils.loadObject(ReportOutputType.class, reportOutputOid, this, opTask, result); + if (report == null) { + return null; + } + result.computeStatusIfUnknown(); + showResult(result, false); + + return report.asObjectable(); + + } + + private PrismProperty getReportOutputProperty() { + PrismObject task = getTask().asPrismObject(); + return task.findProperty(ItemPath.create(TaskType.F_EXTENSION, ReportConstants.REPORT_OUTPUT_OID_PROPERTY_NAME)); + } + + private void createRefreshNowIconButton(RepeatingView repeatingView) { + AjaxIconButton refreshNow = new AjaxIconButton(repeatingView.newChildId(), new Model<>("fa fa-refresh"), createStringResource("autoRefreshPanel.refreshNow")) { + + @Override + public void onClick(AjaxRequestTarget target) { + refresh(target); + } + }; + refreshNow.add(AttributeAppender.append("class", "btn btn-default btn-sm")); + repeatingView.add(refreshNow); + } + + private void createResumePauseButton(RepeatingView repeatingView) { + AjaxIconButton resumePauseRefreshing = new AjaxIconButton(repeatingView.newChildId(), (IModel) this::createResumePauseButtonLabel, createStringResource("autoRefreshPanel.resumeRefreshing")) { + + @Override + public void onClick(AjaxRequestTarget target) { + refreshEnabled = !isRefreshEnabled(); + refresh(target); + } + }; + resumePauseRefreshing.add(AttributeAppender.append("class", "btn btn-default btn-margin-left btn-sm")); + repeatingView.add(resumePauseRefreshing); + } + + private void createCleanupPerformanceButton(RepeatingView repeatingView) { + AjaxIconButton cleanupPerformance = new AjaxIconButton(repeatingView.newChildId(), new Model<>(GuiStyleConstants.CLASS_ICON_TRASH), + createStringResource("operationalButtonsPanel.cleanupEnvironmentalPerformance")) { + + @Override + public void onClick(AjaxRequestTarget target) { + try { + getObjectWrapper().findProperty(ItemPath.create(TaskType.F_OPERATION_STATS, + OperationStatsType.F_ENVIRONMENTAL_PERFORMANCE_INFORMATION)).getValue().setRealValue(null); + } catch (SchemaException e){ + LOGGER.error("Cannot clear task results: {}", e.getMessage()); + } + saveTaskChanges(target); + } + }; + cleanupPerformance.add(AttributeAppender.append("class", "btn btn-default btn-margin-left btn-sm")); + cleanupPerformance.add(new VisibleBehaviour(this::isNotRunning)); + repeatingView.add(cleanupPerformance); + } + + private void createCleanupResultsButton(RepeatingView repeatingView) { + AjaxIconButton cleanupResults = new AjaxIconButton(repeatingView.newChildId(), new Model<>(GuiStyleConstants.CLASS_ICON_TRASH), + createStringResource("operationalButtonsPanel.cleanupResults")) { + + @Override + public void onClick(AjaxRequestTarget target) { + try { + getObjectWrapper().findProperty(TaskType.F_RESULT).getValue().setRealValue(null); + getObjectWrapper().findProperty(TaskType.F_RESULT_STATUS).getValue().setRealValue(null); + } catch (SchemaException e){ + LOGGER.error("Cannot clear task results: {}", e.getMessage()); + } + saveTaskChanges(target); + refresh(target); + } + }; + cleanupResults.add(new VisibleBehaviour(this::isNotRunning)); + cleanupResults.add(AttributeAppender.append("class", "btn btn-default btn-margin-left btn-sm")); + repeatingView.add(cleanupResults); + } + + private void saveTaskChanges(AjaxRequestTarget target) { + try { + ObjectDelta taskDelta = getObjectWrapper().getObjectDelta(); + saveTaskChanges(target, taskDelta); + } catch (SchemaException e) { + LoggingUtils.logUnexpectedException(LOGGER, "Cannot get task delta.", e); + getSession().error("Cannot save changes, there were problems with computing changes: " + e.getMessage()); + target.add(getFeedbackPanel()); + } + } + + private void saveTaskChanges(AjaxRequestTarget target, ObjectDelta taskDelta){ + if (taskDelta.isEmpty()) { + getSession().warn("Nothing to save, no changes were made."); + return; + } + + OperationResult result = new OperationResult(OPERATION_EXECUTE_TASK_CHANGES); + Task task = createSimpleTask(OPERATION_EXECUTE_TASK_CHANGES); + + try { + 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); + } + afterOperation(target, result); + } + + private void afterOperation(AjaxRequestTarget target, OperationResult result) { + showResult(result); + getObjectModel().reset(); + refresh(target); + } + + public void saveAndRunPerformed(AjaxRequestTarget target) { + PrismObjectWrapper taskWrapper = getObjectWrapper(); + try { + PrismPropertyWrapper executionStatus = taskWrapper.findProperty(ItemPath.create(TaskType.F_EXECUTION_STATUS)); + executionStatus.getValue().setRealValue(TaskExecutionStatusType.RUNNABLE); + } catch (SchemaException e) { + LoggingUtils.logUnexpectedException(LOGGER, "Error while setting task execution status", e); + target.add(getFeedbackPanel()); + return; + } + + if (!checkScheduleFilledForReccurentTask(taskWrapper)) { + getSession().error("Cannot run recurring task without setting scheduling for it."); + target.add(getFeedbackPanel()); + return; + } + + super.savePerformed(target); + } + + @Override + public void finishProcessing(AjaxRequestTarget target, Collection> executedDeltas, boolean returningFromAsync, OperationResult result) { + if (isPreviewRequested()) { + super.finishProcessing(target, executedDeltas, returningFromAsync, result); + return; + } + + if (result.isSuccess() && executedDeltas != null) { + //TODO change to inProgress result, so there is a link to existing task + String taskOid = ObjectDeltaOperation.findFocusDeltaOidInCollection(executedDeltas); + if (taskOid != null) { + result.recordInProgress(); + result.setBackgroundTaskOid(taskOid); + } + } + super.finishProcessing(target, executedDeltas, returningFromAsync, result); + } + + private boolean checkScheduleFilledForReccurentTask(PrismObjectWrapper taskWrapper) { + PrismObject task = taskWrapper.getObject(); + + PrismProperty recurrenceType = task.findProperty(ItemPath.create(TaskType.F_RECURRENCE)); + if (recurrenceType == null) { + return true; + } + + TaskRecurrenceType recurenceValue = recurrenceType.getRealValue(); + if (recurenceValue == null || TaskRecurrenceType.SINGLE == recurenceValue) { + return true; + } + + ScheduleType schedule = task.asObjectable().getSchedule(); + //if schedule is not set and task is recurring, show warning. + return schedule.getCronLikePattern() != null || schedule.getEarliestStartTime() != null + || schedule.getInterval() != null || schedule.getLatestFinishTime() != null + || schedule.getLatestStartTime() != null || schedule.getMisfireAction() != null; + } + + + private String createRefreshingLabel() { + if (isRefreshEnabled()) { + return createStringResource("autoRefreshPanel.refreshingEach", getRefreshInterval() / 1000).getString(); + } else { + return createStringResource("autoRefreshPanel.noRefreshing").getString(); + } + } + + private String createResumePauseButtonLabel() { + if (isRefreshEnabled()) { + return "fa fa-pause"; + } + return "fa fa-play"; + } + + @Override + protected AbstractObjectMainPanel createMainPanel(String id) { + return new TaskMainPanel(id, getObjectModel(), this); + } + + TaskType getTask(){ + return getObjectWrapper().getObject().asObjectable(); + } + + @Override + protected Class getRestartResponsePage() { + return PageTasks.class; + } + + @Override + public void continueEditing(AjaxRequestTarget target) { + + } + + @Override + public int getRefreshInterval() { + return REFRESH_INTERVAL; + } + + private boolean isNotRunning(){ + return !WebComponentUtil.isRunningTask(getTask()); + } + + public boolean isRefreshEnabled() { + if (refreshEnabled == null) { + return WebComponentUtil.isRunningTask(getTask()); + } + + return refreshEnabled; + + } +}