Skip to content

Commit

Permalink
Preliminary version of custom forms in approvals
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Jan 28, 2017
1 parent eb32c45 commit e47ef8d
Show file tree
Hide file tree
Showing 27 changed files with 258 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.FormDefinitionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FormFieldGroupType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FormItemDisplayType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FormItemsType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.prism.xml.ns._public.types_3.ItemPathType;
import com.evolveum.midpoint.schema.util.FormTypeUtil;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,9 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractFormItemType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FormDefinitionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FormFieldGroupType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FormFieldType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FormType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.VariableBindingDefinitionType;
import com.evolveum.prism.xml.ns._public.types_3.ItemPathType;
import com.evolveum.midpoint.schema.util.FocusTypeUtil;
import com.evolveum.midpoint.schema.util.FormTypeUtil;

public class DynamicFormPanel<O extends ObjectType> extends BasePanel<ObjectWrapper<O>> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.evolveum.midpoint.gui.api.model.LoadableModel;
import com.evolveum.midpoint.model.api.WorkflowService;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.prism.query.builder.QueryBuilder;
Expand Down Expand Up @@ -82,8 +83,9 @@ public class PageWorkItem extends PageAdminWorkItems {
private static final String ID_WORK_ITEM_PANEL = "workItemPanel";

private static final Trace LOGGER = TraceManager.getTrace(PageWorkItem.class);
private static final String ID_MAIN_FORM = "mainForm";

private LoadableModel<WorkItemDto> workItemDtoModel;
private LoadableModel<WorkItemDto> workItemDtoModel;
private String taskId;

public PageWorkItem(PageParameters parameters) {
Expand Down Expand Up @@ -171,7 +173,7 @@ private void initLayout() {
new PropertyModel<>(workItemDtoModel, WorkItemDto.F_WORK_ITEM), workItemDtoModel);
add(summaryPanel);

Form mainForm = new Form("mainForm");
Form mainForm = new Form(ID_MAIN_FORM);
mainForm.setMultiPart(true);
add(mainForm);

Expand All @@ -180,6 +182,10 @@ private void initLayout() {
initButtons(mainForm);
}

public WorkItemPanel getWorkItemPanel() {
return (WorkItemPanel) get(ID_MAIN_FORM).get(ID_WORK_ITEM_PANEL);
}

private void initButtons(Form mainForm) {

VisibleEnableBehaviour isAllowedToSubmit = new VisibleEnableBehaviour() {
Expand Down Expand Up @@ -298,7 +304,8 @@ private void savePerformed(AjaxRequestTarget target, boolean decision) {

try {
WorkItemDto dto = workItemDtoModel.getObject();
getWorkflowService().approveOrRejectWorkItem(dto.getWorkItemId(), decision, dto.getApproverComment(), result);
ObjectDelta delta = getWorkItemPanel().getDeltaFromForm();
getWorkflowService().approveOrRejectWorkItem(dto.getWorkItemId(), decision, dto.getApproverComment(), delta, result);
} catch (Exception ex) {
result.recordFatalError("Couldn't save work item.", ex);
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't save work item", ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ private void approveOrRejectWorkItemsPerformed(AjaxRequestTarget target, boolean
for (WorkItemDto workItemDto : workItemDtoList) {
OperationResult result = mainResult.createSubresult(OPERATION_APPROVE_OR_REJECT_ITEM);
try {
workflowService.approveOrRejectWorkItem(workItemDto.getWorkItemId(), approve, null, result);
workflowService.approveOrRejectWorkItem(workItemDto.getWorkItemId(), approve, null, null, result);
result.computeStatus();
} catch (Exception e) {
result.recordPartialError("Couldn't approve/reject work item due to an unexpected exception.", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
import com.evolveum.midpoint.gui.api.page.PageBase;
import com.evolveum.midpoint.gui.api.util.WebComponentUtil;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.schema.util.WfContextUtil;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.web.component.prism.DynamicFormPanel;
Expand All @@ -35,8 +37,10 @@
import com.evolveum.midpoint.web.session.UserProfileStorage;
import com.evolveum.midpoint.web.util.OnePageParameterEncoder;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ApprovalLevelType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
Expand Down Expand Up @@ -192,8 +196,12 @@ public void onClick(AjaxRequestTarget target) {
ApprovalLevelType level = WfContextUtil.getCurrentApprovalLevel(dto.getWorkflowContext());
if (level != null && level.getFormRef() != null && level.getFormRef().getOid() != null) {
String formOid = level.getFormRef().getOid();
ObjectType focus = dto.getFocus(pageBase);
if (focus == null) {
focus = new UserType(pageBase.getPrismContext()); // TODO FIXME
}
DynamicFormPanel<UserType> customForm = new DynamicFormPanel<>(ID_CUSTOM_FORM,
(PrismObject<UserType>) new UserType(pageBase.getPrismContext()).asPrismObject(),
(PrismObject<UserType>) focus.asPrismObject(),
formOid, mainForm, false, pageBase);
add(customForm);
} else {
Expand All @@ -203,4 +211,12 @@ public void onClick(AjaxRequestTarget target) {
add(new TextArea<>(ID_APPROVER_COMMENT, new PropertyModel<String>(getModel(), WorkItemDto.F_APPROVER_COMMENT)));
}

public ObjectDelta getDeltaFromForm() throws SchemaException {
Component formPanel = get(ID_CUSTOM_FORM);
if (formPanel instanceof DynamicFormPanel) {
return ((DynamicFormPanel) formPanel).getObjectDelta();
} else {
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,34 @@

package com.evolveum.midpoint.web.page.admin.workflow.dto;

import com.evolveum.midpoint.gui.api.page.PageBase;
import com.evolveum.midpoint.gui.api.util.WebComponentUtil;
import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils;
import com.evolveum.midpoint.model.api.ModelInteractionService;
import com.evolveum.midpoint.model.api.visualizer.Scene;
import com.evolveum.midpoint.prism.Objectable;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.polystring.PolyString;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.schema.DeltaConvertor;
import com.evolveum.midpoint.schema.ObjectTreeDeltas;
import com.evolveum.midpoint.schema.constants.ObjectTypes;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.WfContextUtil;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SystemException;
import com.evolveum.midpoint.web.component.DateLabelComponent;
import com.evolveum.midpoint.web.component.prism.show.SceneDto;
import com.evolveum.midpoint.web.component.prism.show.SceneUtil;
import com.evolveum.midpoint.web.component.util.Selectable;
import com.evolveum.midpoint.web.page.admin.server.dto.TaskChangesDto;
import com.evolveum.midpoint.web.page.admin.server.dto.TaskDto;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import com.evolveum.prism.xml.ns._public.types_3.ChangeTypeType;
import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -80,12 +90,14 @@ public class WorkItemDto extends Selectable {
//
// Depending on expected use (work item list vs. work item details)

protected WorkItemType workItem;
protected TaskType taskType;
protected List<TaskType> relatedTasks;
@Deprecated protected SceneDto deltas;
protected TaskChangesDto changes;
protected String approverComment;
private WorkItemType workItem;
private TaskType taskType;
private List<TaskType> relatedTasks;
@Deprecated private SceneDto deltas;
private TaskChangesDto changes;
private String approverComment;

private ObjectType focus;

public WorkItemDto(WorkItemType workItem) {
this(workItem, null, null);
Expand Down Expand Up @@ -116,7 +128,7 @@ public void prepareDeltaVisualization(String sceneNameKey, PrismContext prismCon
}

@Nullable
protected TaskType getTaskType() {
private TaskType getTaskType() {
if (taskType == null) {
taskType = WebComponentUtil.getObjectFromReference(workItem.getTaskRef(), TaskType.class);
}
Expand Down Expand Up @@ -321,4 +333,44 @@ public String getStageInfo() {
public List<InformationType> getAdditionalInformation() {
return workItem.getAdditionalInformation();
}

// Expects that we deal with primary changes of the focus (i.e. not of projections)
public ObjectType getFocus(PageBase pageBase) {
if (focus != null) {
return focus;
}
WfContextType wfc = getWorkflowContext();
WfPrimaryChangeProcessorStateType state = WfContextUtil.getPrimaryChangeProcessorState(wfc);
if (state == null || state.getDeltasToProcess() == null || state.getDeltasToProcess().getFocusPrimaryDelta() == null) {
return null;
}
ObjectDeltaType delta = state.getDeltasToProcess().getFocusPrimaryDelta();
if (delta.getChangeType() == ChangeTypeType.ADD) {
focus = (ObjectType) delta.getObjectToAdd();
} else if (delta.getChangeType() != ChangeTypeType.MODIFY) {
} else {
String oid = delta.getOid();
if (oid == null) {
throw new IllegalStateException("No OID in object modify delta: " + delta);
}
if (delta.getObjectType() == null) {
throw new IllegalStateException("No object type in object modify delta: " + delta);
}
Class<? extends ObjectType> clazz = ObjectTypes.getObjectTypeFromTypeQName(delta.getObjectType())
.getClassDefinition();
Task task = pageBase.createSimpleTask("getObject");
PrismObject<?> object = WebModelServiceUtils.loadObject(clazz, oid, pageBase, task, task.getResult());
if (object != null) {
focus = (ObjectType) object.asObjectable();
try {
ObjectDelta<Objectable> objectDelta = DeltaConvertor.createObjectDelta(delta, pageBase.getPrismContext());
objectDelta.applyTo(focus.asPrismObject());
} catch (SchemaException e) {
throw new SystemException("Cannot apply delta to focus object: " + e.getMessage(), e);
}
focus = (ObjectType) object.asObjectable();
}
}
return focus;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTreeDeltasType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ProjectionObjectDeltaType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;
import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType;
import org.apache.commons.lang.Validate;
import org.jetbrains.annotations.NotNull;

Expand Down Expand Up @@ -242,4 +243,20 @@ public void merge(ObjectTreeDeltas<F> deltasToMerge) throws SchemaException {
}
}
}

public static ObjectTreeDeltasType mergeDeltas(ObjectTreeDeltasType deltaTree, ObjectDeltaType deltaToMerge,
PrismContext prismContext) throws SchemaException {
if (deltaToMerge == null) {
return deltaTree;
}
ObjectTreeDeltasType deltaTreeToMerge = new ObjectTreeDeltasType();
deltaTreeToMerge.setFocusPrimaryDelta(deltaToMerge);
if (deltaTree == null) {
return deltaTreeToMerge;
}
ObjectTreeDeltas tree = fromObjectTreeDeltasType(deltaTree, prismContext);
ObjectTreeDeltas treeToMerge = fromObjectTreeDeltasType(deltaTreeToMerge, prismContext);
tree.merge(treeToMerge);
return tree.toObjectTreeDeltasType();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,15 @@ public static ItemApprovalProcessStateType getItemApprovalProcessInfo(WfContextT
(ItemApprovalProcessStateType) processSpecificState : null;
}

public static WfPrimaryChangeProcessorStateType getPrimaryChangeProcessorState(WfContextType wfc) {
if (wfc == null) {
return null;
}
WfProcessorSpecificStateType state = wfc.getProcessorSpecificState();
return state instanceof WfPrimaryChangeProcessorStateType ?
(WfPrimaryChangeProcessorStateType) state : null;
}

public static ItemApprovalWorkItemPartType getItemApprovalWorkItemInfo(WorkItemType workItem) {
return workItem.getProcessSpecificPart() instanceof ItemApprovalWorkItemPartType ?
(ItemApprovalWorkItemPartType) workItem.getProcessSpecificPart() : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -927,7 +927,13 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>

<xsd:element name="additionalDelta" type="t:ObjectDeltaType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
TODO
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="decisionType" type="tns:DecisionType" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.evolveum.midpoint.model.api;

import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
Expand All @@ -12,12 +13,14 @@ public interface WorkflowService {

/**
* Approves or rejects a work item (without supplying any further information).
* @param taskId identifier of activiti task backing the work item
* @param decision true = approve, false = reject
* @param parentResult
* @param comment
*/
void approveOrRejectWorkItem(String workItemId, boolean decision, String comment, OperationResult parentResult) throws SecurityViolationException;
* @param taskId identifier of activiti task backing the work item
* @param decision true = approve, false = reject
* @param comment
* @param additionalDelta
* @param parentResult
*/
void approveOrRejectWorkItem(String workItemId, boolean decision, String comment, ObjectDelta additionalDelta,
OperationResult parentResult) throws SecurityViolationException, SchemaException;

void stopProcessInstance(String instanceId, String username, OperationResult parentResult)
throws SchemaException, ObjectNotFoundException, SecurityViolationException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1993,9 +1993,10 @@ private void authorizeNodeCollectionOperation(ModelAuthorizationAction action, C

//region Workflow-related operations
@Override
public void approveOrRejectWorkItem(String workItemId, boolean decision, String comment, OperationResult parentResult)
throws SecurityViolationException {
getWorkflowManagerChecked().approveOrRejectWorkItem(workItemId, decision, comment, parentResult);
public void approveOrRejectWorkItem(String workItemId, boolean decision, String comment, ObjectDelta additionalDelta,
OperationResult parentResult)
throws SecurityViolationException, SchemaException {
getWorkflowManagerChecked().approveOrRejectWorkItem(workItemId, decision, comment, additionalDelta, parentResult);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.SearchResultList;
Expand Down Expand Up @@ -63,13 +64,14 @@ <T extends Containerable> SearchResultList<T> searchContainers(Class<T> type, Ob

/**
* Approves or rejects a work item (without supplying any further information).
*
* @param taskId identifier of activiti task backing the work item
* @param taskId identifier of activiti task backing the work item
* @param decision true = approve, false = reject
* @param comment
* @param additionalDelta
* @param parentResult
*/
void approveOrRejectWorkItem(String taskId, boolean decision, String comment, OperationResult parentResult) throws SecurityViolationException;
void approveOrRejectWorkItem(String taskId, boolean decision, String comment, ObjectDelta additionalDelta,
OperationResult parentResult) throws SecurityViolationException, SchemaException;

void claimWorkItem(String workItemId, OperationResult result) throws ObjectNotFoundException, SecurityViolationException;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.SearchResultList;
Expand Down Expand Up @@ -150,9 +151,10 @@ public <T extends Containerable> SearchResultList<T> searchContainers(Class<T> t
}

@Override
public void approveOrRejectWorkItem(String taskId, boolean decision, String comment, OperationResult parentResult)
throws SecurityViolationException {
workItemManager.completeWorkItem(taskId, ApprovalUtils.approvalStringValue(decision), comment, parentResult);
public void approveOrRejectWorkItem(String taskId, boolean decision, String comment, ObjectDelta additionalDelta,
OperationResult parentResult)
throws SecurityViolationException, SchemaException {
workItemManager.completeWorkItem(taskId, ApprovalUtils.approvalStringValue(decision), comment, additionalDelta, parentResult);
}

@Override
Expand Down
Loading

0 comments on commit e47ef8d

Please sign in to comment.