Skip to content

Commit

Permalink
Implemented reviewer expressions.
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Feb 27, 2017
1 parent 0544d1f commit bfaf585
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 48 deletions.
Expand Up @@ -7,10 +7,7 @@
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.web.component.prism.ReferenceWrapper;
import com.evolveum.midpoint.web.component.prism.ValueStatus;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationDefinitionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationReviewerSpecificationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationStageDefinitionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import java.io.Serializable;
import java.util.List;
Expand Down Expand Up @@ -44,6 +41,7 @@ public class AccessCertificationReviewerDto implements Serializable {
private boolean useObjectManagerPresent;
private ReferenceWrapper defaultReviewers;
private ReferenceWrapper additionalReviewers;
private List<ExpressionType> reviewerExpressionList;

public AccessCertificationReviewerDto(AccessCertificationReviewerSpecificationType reviewerType, PrismContext prismContext) throws SchemaException {
final PrismReference defaultReviewersReference;
Expand All @@ -57,6 +55,7 @@ public AccessCertificationReviewerDto(AccessCertificationReviewerSpecificationTy
useObjectApprover = Boolean.TRUE.equals(reviewerType.isUseObjectApprover());
useObjectManager = new ManagerSearchDto(reviewerType.getUseObjectManager());
useObjectManagerPresent = reviewerType.getUseObjectManager() != null;
reviewerExpressionList = reviewerType.getReviewerExpression();
defaultReviewersReference = reviewerType.asPrismContainerValue().findOrCreateReference(AccessCertificationReviewerSpecificationType.F_DEFAULT_REVIEWER_REF);
additionalReviewersReference = reviewerType.asPrismContainerValue().findOrCreateReference(AccessCertificationReviewerSpecificationType.F_ADDITIONAL_REVIEWER_REF);
} else {
Expand Down Expand Up @@ -139,7 +138,16 @@ public void setUseObjectManager(ManagerSearchDto useObjectManager) {
this.useObjectManager = useObjectManager;
}

public ReferenceWrapper getDefaultReviewers() {
public List<ExpressionType> getReviewerExpressionList() {
return reviewerExpressionList;
}

public void setReviewerExpressionList(
List<ExpressionType> reviewerExpressionList) {
this.reviewerExpressionList = reviewerExpressionList;
}

public ReferenceWrapper getDefaultReviewers() {
return defaultReviewers;
}

Expand Down
Expand Up @@ -22,6 +22,7 @@
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismReferenceValue;
import com.evolveum.midpoint.prism.marshaller.QueryConvertor;
import com.evolveum.midpoint.prism.util.CloneUtil;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.schema.constants.ObjectTypes;
import com.evolveum.midpoint.schema.util.CertCampaignTypeUtil;
Expand Down Expand Up @@ -349,6 +350,7 @@ private AccessCertificationReviewerSpecificationType createAccessCertificationRe
if (reviewerDto.isUseObjectManagerPresent()) {
reviewerObject.setUseObjectManager(createManagerSearchType(reviewerDto.getUseObjectManager()));
}
reviewerObject.getReviewerExpression().addAll(CloneUtil.cloneCollectionMembers(reviewerDto.getReviewerExpressionList()));
reviewerObject.getDefaultReviewerRef().clear();
reviewerObject.getDefaultReviewerRef().addAll(reviewerDto.getDefaultReviewersAsObjectReferenceList(prismContext));
reviewerObject.getAdditionalReviewerRef().clear();
Expand Down
Expand Up @@ -65,11 +65,16 @@ public class ExpressionConstants {
*/
public static final QName VAR_ITERATION_TOKEN = new QName(SchemaConstants.NS_C, "iterationToken");

// Variables used in object mergign expressions
// Variables used in object merging expressions
public static final QName VAR_SIDE = new QName(SchemaConstants.NS_C, "side");
public static final QName VAR_OBJECT_LEFT = new QName(SchemaConstants.NS_C, "objectLeft");
public static final QName VAR_OBJECT_RIGHT = new QName(SchemaConstants.NS_C, "objectRight");

public static final QName OUTPUT_ELMENT_NAME = new QName(SchemaConstants.NS_C, "output");

public static final QName OUTPUT_ELEMENT_NAME = new QName(SchemaConstants.NS_C, "output");

// "case" would collide with java keyword
public static final QName VAR_CERTIFICATION_CASE = new QName(SchemaConstants.NS_C, "certificationCase");
public static final QName VAR_CAMPAIGN = new QName(SchemaConstants.NS_C, "campaign");
public static final QName VAR_REVIEWER_SPECIFICATION = new QName(SchemaConstants.NS_C, "reviewerSpecification");

}
Expand Up @@ -323,11 +323,11 @@
<xsd:element name="reviewerExpression" type="tns:ExpressionType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
The most general way of specifying the reviewer. TODO describe inputs for such an expression
If present, takes precedence over useXXX settings as well as over defaultReviewerRef;
additionalReviewerRef still applies.

NOT IMPLEMENTED YET
The most general way of specifying the reviewer. Inputs for such expressions are:
- certificationCase (current certification case),
- campaign (certification campaign object),
- reviewerSpecification (current reviewer specification).
Output is a collection of parent-less reviewer references (of type ObjectReferenceType).
</xsd:documentation>
</xsd:annotation>
</xsd:element>
Expand Down
Expand Up @@ -21,10 +21,7 @@
import com.evolveum.midpoint.model.common.expression.ExpressionFactory;
import com.evolveum.midpoint.model.common.expression.ExpressionVariables;
import com.evolveum.midpoint.model.impl.expr.ModelExpressionThreadLocalHolder;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismPropertyDefinition;
import com.evolveum.midpoint.prism.PrismPropertyDefinitionImpl;
import com.evolveum.midpoint.prism.PrismPropertyValue;
import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple;
import com.evolveum.midpoint.prism.xml.XsdTypeMapper;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
Expand All @@ -38,6 +35,7 @@
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

Expand Down Expand Up @@ -91,6 +89,40 @@ private <T> List<T> evaluateExpression(Class<T> resultClass, ExpressionType expr
return retval;
}

public List<ObjectReferenceType> evaluateRefExpressionChecked(ExpressionType expressionType,
ExpressionVariables expressionVariables, String shortDesc, Task task, OperationResult result) {

try {
return evaluateRefExpression(expressionType, expressionVariables, shortDesc, task, result);
} catch (ObjectNotFoundException|SchemaException|ExpressionEvaluationException e) {
LoggingUtils.logException(LOGGER, "Couldn't evaluate {} {}", e, shortDesc, expressionType);
result.recordFatalError("Couldn't evaluate " + shortDesc, e);
throw new SystemException(e);
}
}

private List<ObjectReferenceType> evaluateRefExpression(ExpressionType expressionType, ExpressionVariables expressionVariables,
String shortDesc, Task task, OperationResult result)
throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException {

QName resultName = new QName(SchemaConstants.NS_C, "result");
PrismReferenceDefinition resultDef = new PrismReferenceDefinitionImpl(resultName, ObjectReferenceType.COMPLEX_TYPE, prismContext);

Expression<PrismReferenceValue,PrismReferenceDefinition> expression = expressionFactory.makeExpression(expressionType, resultDef, shortDesc, task, result);
ExpressionEvaluationContext params = new ExpressionEvaluationContext(null, expressionVariables, shortDesc, task, result);

PrismValueDeltaSetTriple<PrismReferenceValue> exprResult =
ModelExpressionThreadLocalHolder.evaluateRefExpressionInContext(expression, params, task, result);

List<ObjectReferenceType> retval = new ArrayList<>();
for (PrismReferenceValue value : exprResult.getZeroSet()) {
ObjectReferenceType ort = new ObjectReferenceType();
ort.setupReferenceValue(value);
retval.add(ort);
}
return retval;
}

public boolean evaluateBooleanExpressionChecked(ExpressionType expressionType, ExpressionVariables expressionVariables,
String shortDesc, Task task, OperationResult result) {

Expand Down
Expand Up @@ -17,11 +17,13 @@
package com.evolveum.midpoint.certification.impl;

import com.evolveum.midpoint.model.api.expr.OrgStructFunctions;
import com.evolveum.midpoint.model.common.expression.ExpressionVariables;
import com.evolveum.midpoint.model.impl.expr.ExpressionEnvironment;
import com.evolveum.midpoint.model.impl.expr.ModelExpressionThreadLocalHolder;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.repo.api.RepositoryService;
import com.evolveum.midpoint.schema.constants.ExpressionConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.CertCampaignTypeUtil;
import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
Expand All @@ -45,15 +47,13 @@
@Component
public class AccCertReviewersHelper {

@Autowired
private OrgStructFunctions orgStructFunctions;

@Autowired
@Qualifier("cacheRepositoryService")
private RepositoryService repositoryService;

@Autowired
private PrismContext prismContext;
@Autowired private OrgStructFunctions orgStructFunctions;
@Autowired private PrismContext prismContext;
@Autowired private AccCertExpressionHelper expressionHelper;

public AccessCertificationReviewerSpecificationType findReviewersSpecification(AccessCertificationCampaignType campaign,
int stage, Task task, OperationResult result) {
Expand Down Expand Up @@ -84,7 +84,15 @@ public void setupReviewersForCase(AccessCertificationCaseType _case, AccessCerti
if (reviewerSpec.getUseObjectManager() != null) {
cloneAndMerge(_case.getCurrentReviewerRef(), getObjectManagers(_case, reviewerSpec.getUseObjectManager(), task, result));
}
// TODO evaluate reviewer expressions
for (ExpressionType reviewerExpression : reviewerSpec.getReviewerExpression()) {
ExpressionVariables variables = new ExpressionVariables();
variables.addVariableDefinition(ExpressionConstants.VAR_CERTIFICATION_CASE, _case);
variables.addVariableDefinition(ExpressionConstants.VAR_CAMPAIGN, campaign);
variables.addVariableDefinition(ExpressionConstants.VAR_REVIEWER_SPECIFICATION, reviewerSpec);
List<ObjectReferenceType> refList = expressionHelper
.evaluateRefExpressionChecked(reviewerExpression, variables, "reviewer expression", task, result);
cloneAndMerge(_case.getCurrentReviewerRef(), refList);
}
if (_case.getCurrentReviewerRef().isEmpty()) {
cloneAndMerge(_case.getCurrentReviewerRef(), reviewerSpec.getDefaultReviewerRef());
}
Expand Down
Expand Up @@ -78,7 +78,14 @@ Superuser-Dummy: - -> A jack:A,administrator:nul
<number>1</number>
<duration>P14D</duration>
<reviewerSpecification>
<useObjectOwner>true</useObjectOwner>
<reviewerExpression>
<script>
<code>
role = midpoint.resolveReference(certificationCase.objectRef)
role.ownerRef?.clone()
</code>
</script>
</reviewerExpression>
</reviewerSpecification>
<outcomeStrategy>acceptedIfNotDenied</outcomeStrategy>
<outcomeIfNoReviewers>accept</outcomeIfNoReviewers>
Expand Down
Expand Up @@ -723,7 +723,7 @@ private static <V extends PrismValue> V evaluateExpression(ExpressionVariables v
}

if (outputDefinition == null) {
outputDefinition = new PrismPropertyDefinitionImpl(ExpressionConstants.OUTPUT_ELMENT_NAME,
outputDefinition = new PrismPropertyDefinitionImpl(ExpressionConstants.OUTPUT_ELEMENT_NAME,
DOMUtil.XSD_STRING, prismContext);
}

Expand Down Expand Up @@ -770,7 +770,7 @@ private static Collection<String> evaluateStringExpression(ExpressionVariables v
throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException {

PrismPropertyDefinitionImpl<String> outputDefinition = new PrismPropertyDefinitionImpl(
ExpressionConstants.OUTPUT_ELMENT_NAME, DOMUtil.XSD_STRING, prismContext);
ExpressionConstants.OUTPUT_ELEMENT_NAME, DOMUtil.XSD_STRING, prismContext);
outputDefinition.setMaxOccurs(-1);
Expression<PrismPropertyValue<String>, PrismPropertyDefinition<String>> expression = expressionFactory
.makeExpression(expressionType, outputDefinition, shortDesc, task, parentResult);
Expand Down Expand Up @@ -798,7 +798,7 @@ public static PrismPropertyValue<Boolean> evaluateCondition(ExpressionVariables
OperationResult parentResult)
throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException {
ItemDefinition outputDefinition = new PrismPropertyDefinitionImpl(
ExpressionConstants.OUTPUT_ELMENT_NAME, DOMUtil.XSD_BOOLEAN,
ExpressionConstants.OUTPUT_ELEMENT_NAME, DOMUtil.XSD_BOOLEAN,
expressionFactory.getPrismContext());
return (PrismPropertyValue<Boolean>) evaluateExpression(variables, outputDefinition, expressionType,
expressionFactory, shortDesc, task, parentResult);
Expand Down
Expand Up @@ -87,7 +87,8 @@ public void testIterationCondition() throws Exception {
ExpressionType expressionType = PrismTestUtil.parseAtomicValue(
EXPRESSION_ITERATION_CONDITION_FILE, ExpressionType.COMPLEX_TYPE);

PrismPropertyDefinition<Boolean> outputDefinition = new PrismPropertyDefinitionImpl<Boolean>(ExpressionConstants.OUTPUT_ELMENT_NAME,
PrismPropertyDefinition<Boolean> outputDefinition = new PrismPropertyDefinitionImpl<>(
ExpressionConstants.OUTPUT_ELEMENT_NAME,
DOMUtil.XSD_BOOLEAN, prismContext);
Expression<PrismPropertyValue<Boolean>,PrismPropertyDefinition<Boolean>> expression = expressionFactory.makeExpression(expressionType, outputDefinition , TEST_NAME, null, result);

Expand Down
Expand Up @@ -163,8 +163,8 @@ public void testExistenceBefore() throws Exception {

builder.setNow(TIME_PAST);

PrismPropertyDefinition<Boolean> existenceDef = new PrismPropertyDefinitionImpl<Boolean>(
ExpressionConstants.OUTPUT_ELMENT_NAME,
PrismPropertyDefinition<Boolean> existenceDef = new PrismPropertyDefinitionImpl<>(
ExpressionConstants.OUTPUT_ELEMENT_NAME,
DOMUtil.XSD_BOOLEAN, evaluator.getPrismContext());
builder.setDefaultTargetDefinition(existenceDef);

Expand Down Expand Up @@ -194,8 +194,8 @@ public void testExistenceAfter() throws Exception {

builder.setNow(TIME_FUTURE);

PrismPropertyDefinition<Boolean> existenceDef = new PrismPropertyDefinitionImpl<Boolean>(
ExpressionConstants.OUTPUT_ELMENT_NAME,
PrismPropertyDefinition<Boolean> existenceDef = new PrismPropertyDefinitionImpl<>(
ExpressionConstants.OUTPUT_ELEMENT_NAME,
DOMUtil.XSD_BOOLEAN, evaluator.getPrismContext());
builder.setDefaultTargetDefinition(existenceDef);

Expand Down Expand Up @@ -231,8 +231,8 @@ public void testNoReferenceTime() throws Exception {

builder.setNow(TIME_PAST);

PrismPropertyDefinition<Boolean> existenceDef = new PrismPropertyDefinitionImpl<Boolean>(
ExpressionConstants.OUTPUT_ELMENT_NAME,
PrismPropertyDefinition<Boolean> existenceDef = new PrismPropertyDefinitionImpl<>(
ExpressionConstants.OUTPUT_ELEMENT_NAME,
DOMUtil.XSD_BOOLEAN, evaluator.getPrismContext());
builder.setDefaultTargetDefinition(existenceDef);

Expand Down Expand Up @@ -271,8 +271,8 @@ public void testSetReferenceTimeBefore() throws Exception {

builder.setNow(TIME_PAST);

PrismPropertyDefinition<Boolean> existenceDef = new PrismPropertyDefinitionImpl<Boolean>(
ExpressionConstants.OUTPUT_ELMENT_NAME,
PrismPropertyDefinition<Boolean> existenceDef = new PrismPropertyDefinitionImpl<>(
ExpressionConstants.OUTPUT_ELEMENT_NAME,
DOMUtil.XSD_BOOLEAN, evaluator.getPrismContext());
builder.setDefaultTargetDefinition(existenceDef);

Expand Down Expand Up @@ -310,8 +310,8 @@ public void testSetReferenceTimeAfter() throws Exception {

builder.setNow(TIME_FUTURE);

PrismPropertyDefinition<Boolean> existenceDef = new PrismPropertyDefinitionImpl<Boolean>(
ExpressionConstants.OUTPUT_ELMENT_NAME,
PrismPropertyDefinition<Boolean> existenceDef = new PrismPropertyDefinitionImpl<>(
ExpressionConstants.OUTPUT_ELEMENT_NAME,
DOMUtil.XSD_BOOLEAN, evaluator.getPrismContext());
builder.setDefaultTargetDefinition(existenceDef);

Expand Down
Expand Up @@ -76,7 +76,7 @@ public String evaluateExpression(ShadowType shadow, ExpressionType expressionTyp

ExpressionVariables variables = getDefaultXPathVariables(null, shadow, resource);

PrismPropertyDefinition<String> outputDefinition = new PrismPropertyDefinitionImpl<>(ExpressionConstants.OUTPUT_ELMENT_NAME,
PrismPropertyDefinition<String> outputDefinition = new PrismPropertyDefinitionImpl<>(ExpressionConstants.OUTPUT_ELEMENT_NAME,
DOMUtil.XSD_STRING, prismContext);
Expression<PrismPropertyValue<String>,PrismPropertyDefinition<String>> expression = expressionFactory.makeExpression(expressionType,
outputDefinition, shortDesc, task, result);
Expand Down Expand Up @@ -108,7 +108,7 @@ public boolean evaluateConfirmationExpression(UserType user, ShadowType shadow,
ExpressionVariables variables = getDefaultXPathVariables(user, shadow, resource);
String shortDesc = "confirmation expression for "+resource.asPrismObject();

PrismPropertyDefinition<Boolean> outputDefinition = new PrismPropertyDefinitionImpl<>(ExpressionConstants.OUTPUT_ELMENT_NAME,
PrismPropertyDefinition<Boolean> outputDefinition = new PrismPropertyDefinitionImpl<>(ExpressionConstants.OUTPUT_ELEMENT_NAME,
DOMUtil.XSD_BOOLEAN, prismContext);
Expression<PrismPropertyValue<Boolean>,PrismPropertyDefinition<Boolean>> expression = expressionFactory.makeExpression(expressionType,
outputDefinition, shortDesc, task, result);
Expand Down

0 comments on commit bfaf585

Please sign in to comment.