Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Evolveum/midpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
KaterynaHonchar committed Jan 19, 2022
2 parents 070b68f + 7a82a09 commit 63bd77e
Show file tree
Hide file tree
Showing 56 changed files with 2,370 additions and 184 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2831,7 +2831,18 @@ public static <AR extends AbstractRoleType> IModel<String> createAbstractRoleCon
}
String members = atLeastOneWithMembers ? ".members" : "";
ObjectTypes objectType = ObjectTypes.getObjectType(abstractRoleTable.getType());
String propertyKeyPrefix = ObjectTypes.SERVICE.equals(objectType) ? "pageServices" : "pageRoles";
String propertyKeyPrefix = "";
switch (objectType) {
case SERVICE:
propertyKeyPrefix = "pageServices";
break;
case ROLE:
propertyKeyPrefix = "pageRoles";
break;
case ORG:
propertyKeyPrefix = "pageOrgs";
break;
}

if (action.getRowModel() == null) {
return pageBase.createStringResource(propertyKeyPrefix + ".message.confirmationMessageForMultipleObject" + members,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (C) 2022 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.gui.impl.page.admin.cases.component;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

import com.evolveum.midpoint.prism.Item;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.xml.ns._public.common.common_3.IdMatchCorrelationContextType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.IdMatchCorrelationPotentialMatchType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAttributesType;

public class CorrelationContextDto implements Serializable {

private final List<String> matchHeaders = new ArrayList<>();
private final List<ItemPath> attributes = new ArrayList<>();
private final List<PotentialMatchDto> potentialMatches = new ArrayList<>();

private PotentialMatchDto origin;

public CorrelationContextDto(IdMatchCorrelationContextType idMatchCorrelationContext) {
List<IdMatchCorrelationPotentialMatchType> idMatches = idMatchCorrelationContext.getPotentialMatch();
loadPotentialMatchesHeader(idMatches);
}

private void loadPotentialMatchesHeader(List<IdMatchCorrelationPotentialMatchType> potentialMatchTypes) {

int i = 1;
for (IdMatchCorrelationPotentialMatchType potentialMatch : potentialMatchTypes) {
if (SchemaConstants.CORRELATION_NONE_URI.equals(potentialMatch.getUri())) {
origin = new PotentialMatchDto(potentialMatch);
origin.setOrigin(true);
} else {
parsePotentialMatch(potentialMatch, i);
i++;
}

}

matchHeaders.add(0, "Origin");
parseAttributeNames(origin);
potentialMatches.add(0, origin);
}

public boolean match(Serializable value, ItemPath path) {
Serializable originValue = origin.getAttributeValue(path);
return Objects.equals(value, originValue);
}

private void parsePotentialMatch(IdMatchCorrelationPotentialMatchType potentialMatch, int iterator) {
PotentialMatchDto potentialMatchDto = new PotentialMatchDto(potentialMatch);

matchHeaders.add("Suggestion " + iterator);
potentialMatches.add(potentialMatchDto);
}

private void parseAttributeNames(PotentialMatchDto origin) {
if (origin == null) {
return;
}
ShadowAttributesType shadowAttributes = origin.getShadowAttributesType();
if (shadowAttributes == null) {
return;
}
Collection<Item<?, ?>> items = shadowAttributes.asPrismContainerValue().getItems();
for (Item item : items) {
attributes.add(item.getElementName());
}
}

public List<PotentialMatchDto> getPotentialMatches() {
return potentialMatches;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2022 Evolveum
~
~ This work is dual-licensed under the Apache License 2.0
~ and European Union Public License. See LICENSE file for details.
-->

<wicket:panel xmlns:wicket="http://wicket.apache.org">
<table class="table table-bordered">
<tr>
<th></th>
<wicket:container wicket:id="headers">
<th><span wicket:id="header"></span></th>
</wicket:container>
</tr>
<tr>
<th>Action</th>
<wicket:container wicket:id="actions">
<td><a class="btn btn-primary btn-sm" wicket:id="action">
<span wicket:id="actionLabel"></span>
</a></td>
</wicket:container>
</tr>
<tr>
<th>Reference ID</th>
<wicket:container wicket:id="referenceIds">
<td wicket:id="referenceId"></td>
</wicket:container>
</tr>
<wicket:container wicket:id="rows">
<tr>
<th><span wicket:id="attrName"></span></th>
<wicket:container wicket:id="columns">
<td wicket:id="column"></td>
</wicket:container>
</tr>
</wicket:container>
</table>
</wicket:panel>
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
* Copyright (C) 2022 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.gui.impl.page.admin.cases.component;

import java.io.Serializable;
import java.util.List;

import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.WorkItemId;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.exception.*;
import com.evolveum.midpoint.web.component.AjaxButton;

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.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;

import com.evolveum.midpoint.gui.api.model.ReadOnlyModel;
import com.evolveum.midpoint.gui.impl.page.admin.AbstractObjectMainPanel;
import com.evolveum.midpoint.gui.impl.page.admin.cases.CaseDetailsModels;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.web.application.PanelDisplay;
import com.evolveum.midpoint.web.application.PanelInstance;
import com.evolveum.midpoint.web.application.PanelType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

@PanelType(name = "correlationContext")
@PanelInstance(identifier = "correlationContext",
display = @PanelDisplay(label = "PageCase.correlationContextPanel", order = 40))
public class CorrelationContextPanel extends AbstractObjectMainPanel<CaseType, CaseDetailsModels> {

private static final String ID_ACTIONS = "actions";
private static final String ID_ACTION = "action";
private static final String ID_REFERENCE_IDS = "referenceIds";
private static final String ID_REFERENCE_ID = "referenceId";

public CorrelationContextPanel(String id, CaseDetailsModels model, ContainerPanelConfigurationType config) {
super(id, model, config);
}

@Override
protected void initLayout() {
IModel<CorrelationContextDto> correlationCtxModel = createCorrelationContextModel();

ListView<String> headers = new ListView<>("headers", new PropertyModel<>(correlationCtxModel, "matchHeaders")) {

@Override
protected void populateItem(ListItem<String> item) {
item.add(new Label("header", item.getModel()));
}
};
add(headers);

ListView<PotentialMatchDto> actions = new ListView<>(ID_ACTIONS, new PropertyModel<>(correlationCtxModel, "potentialMatches")) {

@Override
protected void populateItem(ListItem<PotentialMatchDto> item) {
AjaxButton actionButton = new AjaxButton(ID_ACTION) {

@Override
public void onClick(AjaxRequestTarget target) {
CaseType correlationCase = getObjectDetailsModels().getObjectType();
WorkItemId workItemId = WorkItemId.of(correlationCase.getWorkItem().get(0));
AbstractWorkItemOutputType output = new AbstractWorkItemOutputType()
.outcome(item.getModelObject().getUri());

Task task = getPageBase().createSimpleTask("DecideCorrelation");
OperationResult result = task.getResult();
try {
getPageBase().getWorkflowService().completeWorkItem(workItemId, output, task, result);
result.computeStatusIfUnknown();
} catch (Throwable e) {
result.recordFatalError("Cannot finish correlation process, " + e.getMessage(), e);
}
getPageBase().showResult(result);
target.add(getPageBase().getFeedbackPanel());
}
};

actionButton.add(new Label("actionLabel", item.getModelObject().isOrigin() ? "Create new account" : "Use this account"));
item.add(actionButton);
}
};
add(actions);

ListView<PotentialMatchDto> referenceIds = new ListView<>(ID_REFERENCE_IDS, new PropertyModel<>(correlationCtxModel, "potentialMatches")) {

@Override
protected void populateItem(ListItem<PotentialMatchDto> item) {
item.add(new Label(ID_REFERENCE_ID, item.getModelObject().getReferenceId()));
}
};
add(referenceIds);

ListView<ItemPath> a = new ListView<>("rows", new PropertyModel<>(correlationCtxModel, "attributes")) {

@Override
protected void populateItem(ListItem<ItemPath> item) {
item.add(new Label("attrName", item.getModel()));
item.add(createAttributeValueColumns(correlationCtxModel, item));
}
};
add(a);

}

private IModel<CorrelationContextDto> createCorrelationContextModel() {
return new ReadOnlyModel<>(() -> {
CorrelationContextType correlationContext = getObjectDetailsModels().getObjectType().getCorrelationContext();
if (correlationContext == null) {
return null;
}

AbstractCorrelationContextType ctx = correlationContext.getCorrelatorPart();

IdMatchCorrelationContextType idMatchCorrelationContext;
if (ctx instanceof IdMatchCorrelationContextType) {
idMatchCorrelationContext = (IdMatchCorrelationContextType) ctx;
} else {
return null;
}

return new CorrelationContextDto(idMatchCorrelationContext);
});
}

private ListView<PotentialMatchDto> createAttributeValueColumns(IModel<CorrelationContextDto> modelObject, ListItem<ItemPath> item) {
return new ListView<>("columns", new PropertyModel<>(modelObject, "potentialMatches")) {
@Override
protected void populateItem(ListItem<PotentialMatchDto> columnItem) {
Serializable value = columnItem.getModelObject().getAttributeValue(item.getModelObject());
boolean equals = modelObject.getObject().match(value, item.getModelObject());
Label label = new Label("column", value != null ? value : "");
if (!columnItem.getModelObject().isOrigin()) {
label.add(AttributeAppender.append("class", equals ? "bg-green disabled color-palette" : "bg-red disabled color-palette"));
}
columnItem.add(label);
}
};
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright (C) 2022 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.gui.impl.page.admin.cases.component;

import com.evolveum.midpoint.prism.Item;
import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.prism.path.ItemName;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.util.QNameUtil;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.IdMatchCorrelationPotentialMatchType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAttributesType;
import com.evolveum.prism.xml.ns._public.types_3.RawType;

import java.io.Serializable;

public class PotentialMatchDto implements Serializable {

private ShadowAttributesType shadowAttributesType;
private String referenceId;
private String uri;
private boolean origin = false;

public PotentialMatchDto(IdMatchCorrelationPotentialMatchType potentialMatchType) {
this.referenceId = potentialMatchType.getReferenceId();
this.uri = potentialMatchType.getUri();
this.shadowAttributesType = potentialMatchType.getAttributes();
}

public void setOrigin(boolean origin) {
this.origin = origin;
}

public Serializable getAttributeValue(ItemPath path) {
Item pItem = findMatchingItem(path);
Serializable value = pItem == null ? null : (Serializable) pItem.getRealValue();
// String realValue;
if (value instanceof RawType) {
try {
value = ((RawType) value).getParsedRealValue(String.class);
} catch (SchemaException e) {
///TODO
}
}
return value;
}

/**
* This method falls back to case-insensitive search. This is needed if we try to compare
* midPoint shadow with options returned from ID Match (a kind of apples-vs-oranges situation,
* because COmanage Match does not support uppercase characters in attribute names). But when midPoint
* is switched to provide ID Match-returned value for the basis of comparison, then the case
* ignorance is not necessary.
*/
private Item findMatchingItem(ItemPath path) {
Item exactMatch = shadowAttributesType.asPrismContainerValue().findItem(path);
if (exactMatch != null) {
return exactMatch;
}
ItemName name = path.asSingleName();
if (name == null) {
// Not bothering with the general case; we don't have nested attributes anyway
return null;
}

for (Item<?, ?> item : ((PrismContainerValue<?>) shadowAttributesType.asPrismContainerValue()).getItems()) {
if (QNameUtil.match(name, item.getElementName(), true)) {
return item;
}
}
return null;
}

public ShadowAttributesType getShadowAttributesType() {
return shadowAttributesType;
}

public boolean isOrigin() {
return origin;
}

public String getReferenceId() {
return referenceId;
}

public String getUri() {
return uri;
}
}

0 comments on commit 63bd77e

Please sign in to comment.