Skip to content

Commit

Permalink
Short messages for policy constraints. Work in progress.
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Oct 12, 2017
1 parent 559be14 commit 683765b
Show file tree
Hide file tree
Showing 33 changed files with 389 additions and 79 deletions.
Expand Up @@ -76,6 +76,10 @@ public static void create(List<EvaluatedTriggerDto> resultList, EvaluatedPolicyR
}
}

public static void sort(List<EvaluatedTriggerDto> triggers) {
// TODO
}

private static boolean alreadyShown(List<AlreadyShownTriggerRecord> triggersAlreadyShown, EvaluatedTriggerDto newTriggerDto) {
EvaluatedPolicyRuleTriggerType anonymizedTrigger = newTriggerDto.trigger.clone().ruleName(null);
for (AlreadyShownTriggerRecord alreadyShown : triggersAlreadyShown) {
Expand Down
Expand Up @@ -57,6 +57,7 @@ public static EvaluatedTriggerGroupDto createFrom(List<EvaluatedPolicyRuleType>
EvaluatedTriggerDto.create(group.getTriggers(), trigger, highlighted, triggersAlreadyShown);
}
}
EvaluatedTriggerDto.sort(group.getTriggers());
return group;
}
}
Expand Up @@ -533,10 +533,13 @@ public abstract class SchemaConstants {

public static final String OBJECT_TYPE_KEY_PREFIX = "ObjectType.";
public static final String DEFAULT_POLICY_CONSTRAINT_KEY_PREFIX = "DefaultPolicyConstraint.";
public static final String DEFAULT_POLICY_CONSTRAINT_SHORT_MESSAGE_KEY_PREFIX = "DefaultPolicyConstraint.Short.";
public static final String POLICY_CONSTRAINT_KEY_PREFIX = "PolicyConstraint.";
public static final String POLICY_CONSTRAINT_SHORT_MESSAGE_KEY_PREFIX = "PolicyConstraint.Short.";
public static final String POLICY_CONSTRAINTS_BEFORE_KEY = "PolicyConstraints.before";
public static final String POLICY_CONSTRAINTS_AFTER_KEY = "PolicyConstraints.after";
public static final String TECHNICAL_OBJECT_SPECIFICATION_KEY = "TechnicalObjectSpecification";
public static final String OBJECT_SPECIFICATION_KEY = "ObjectSpecification";
public static final String POLICY_VIOLATION_EXCEPTION_AGGREGATE_KEY = "PolicyViolationException.message.aggregate";

// // resetPassword
Expand Down
Expand Up @@ -349,6 +349,8 @@ public static boolean triggerCollectionsEqual(Collection<EvaluatedPolicyRuleTrig
&& Objects.equals(st1.getConstraintKind(), st2.getConstraintKind())
&& Objects.equals(st1.getConstraint(), st2.getConstraint())
&& Objects.equals(st1.getMessage(), st2.getMessage())
&& Objects.equals(st1.getShortMessage(), st2.getShortMessage())
&& Objects.equals(st1.getPresentationOrder(), st2.getPresentationOrder())
&& Objects.equals(st1.getAssignmentPath(), st2.getAssignmentPath())
&& Objects.equals(st1.getDirectOwnerRef(), st2.getDirectOwnerRef())
&& Objects.equals(st1.getDirectOwnerDisplayName(), st2.getDirectOwnerDisplayName())
Expand Down
31 changes: 30 additions & 1 deletion infra/schema/src/main/resources/localization/schema.properties
Expand Up @@ -404,6 +404,7 @@ ExclusionPolicyType.ENFORCE=Enforce
ExclusionPolicyType.APPROVE=Approve
ExclusionPolicyType.REPORT=Report
TechnicalObjectSpecification={0} {1} (OID {2})
ObjectSpecification={0} {1}
DefaultPolicyConstraint.assignmentModification.toBeAdded=Assignment of {0} (relation {1}) is to be added
DefaultPolicyConstraint.assignmentModification.wasAdded=Assignment of {0} (relation {1}) was added
DefaultPolicyConstraint.assignmentModification.toBeDeleted=Assignment of {0} (relation {1}) is to be deleted
Expand Down Expand Up @@ -436,4 +437,32 @@ DefaultPolicyConstraint.transition=Transition policy constraint matched
DefaultPolicyConstraint.situation=Situation policy constraint matched
PolicyViolationException.message.aggregate={0} policy violations occurred
PolicyRuleEvaluationTargetType.OBJECT=Object
PolicyRuleEvaluationTargetType.ASSIGNMENT=Assignment
PolicyRuleEvaluationTargetType.ASSIGNMENT=Assignment
DefaultPolicyConstraint.Short.assignmentModification.toBeAdded=Assigning {0} to {1}
DefaultPolicyConstraint.Short.assignmentModification.wasAdded=Assigned {0} to {1}
DefaultPolicyConstraint.Short.assignmentModification.toBeDeleted=Unassigning {0} to {1}
DefaultPolicyConstraint.Short.assignmentModification.wasDeleted=Unassigned {0} to {1}
DefaultPolicyConstraint.Short.assignmentModification.toBeModified=Modifying assignment of {0} to {1}
DefaultPolicyConstraint.Short.assignmentModification.wasModified=Modified assignment of {0} to {1}
DefaultPolicyConstraint.Short.objectModification.toBeAdded=Adding {0}
DefaultPolicyConstraint.Short.objectModification.wasAdded=Added {0}
DefaultPolicyConstraint.Short.objectModification.toBeDeleted=Deleting {0}
DefaultPolicyConstraint.Short.objectModification.wasDeleted=Deleted {0}
DefaultPolicyConstraint.Short.objectModification.toBeModified=Modifying {0}
DefaultPolicyConstraint.Short.objectModification.wasModified=Modified {0}
DefaultPolicyConstraint.Short.objectState.unnamed=Matching state: {0}
DefaultPolicyConstraint.Short.objectState.named=Matching state: {0} ('{1}')
DefaultPolicyConstraint.Short.assignmentState.unnamed=Matching state: assignment of {0}
DefaultPolicyConstraint.Short.assignmentState.named=Matching state: assignment of {0} ('{1}')
DefaultPolicyConstraint.Short.exclusion={0} excludes {1}
DefaultPolicyConstraint.Short.hasAssignment=Assignment exists for {0} ({1})
DefaultPolicyConstraint.Short.hasNoAssignment=No assignment exists for {0} {1} ({2})
DefaultPolicyConstraint.Short.multiplicityConstraint.min.object={0} requires at least {1} assignees ('{2}')
DefaultPolicyConstraint.Short.multiplicityConstraint.max.object={0} requires at most {1} assignees ('{2}')
DefaultPolicyConstraint.Short.multiplicityConstraint.min.target={0} requires at least {1} assignees ('{2}')
DefaultPolicyConstraint.Short.multiplicityConstraint.max.target={0} requires at most {1} assignees ('{2}')
DefaultPolicyConstraint.Short.and=All constraints triggered
DefaultPolicyConstraint.Short.or=At least one of constraints triggered
DefaultPolicyConstraint.Short.not=Constraints have not triggered
DefaultPolicyConstraint.Short.transition=Transition constraint matched
DefaultPolicyConstraint.Short.situation=Situation constraint matched
Expand Up @@ -504,6 +504,8 @@
</xsd:annotation>
</xsd:element>
<xsd:element name="message" type="tns:LocalizableMessageType" minOccurs="0" />
<xsd:element name="shortMessage" type="tns:LocalizableMessageType" minOccurs="0" />
<xsd:element name="presentationOrder" type="xsd:int" minOccurs="0" />
<xsd:element name="final" type="xsd:boolean" minOccurs="0" />
<xsd:element name="hidden" type="xsd:boolean" minOccurs="0" />
<xsd:element name="assignmentPath" type="tns:AssignmentPathType" minOccurs="0">
Expand Down
Expand Up @@ -361,6 +361,13 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="displayOrder" type="xsd:int" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
TODO. EXPERIMENTAL.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:long"/>
</xsd:complexType>
Expand Down
Expand Up @@ -1141,30 +1141,42 @@
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="processInstanceId" type="xsd:string">
<xsd:element name="processInstanceId" type="xsd:string" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Internal identifier of a process instance, assigned by the underlying workflow engine
(currently Activiti).
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="processName" type="xsd:string">
<xsd:element name="processName" type="xsd:string" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Name of the process definition, e.g. "ItemApproval".
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="processInstanceName" type="xsd:string">
<xsd:element name="processInstanceName" type="xsd:string" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Name of the process instance. It is defined by the code that starts
the process instance and should describe the purpose of the process
instance as precisely as possible. An example: "Approving adding Webmaster to JoeDoe".
Might be absent, if localizableProcessName is defined.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="localizableProcessInstanceName" type="tns:LocalizableMessageType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Localizable name of the process instance. To be used e.g. in GUI.
May consist of more parts. (But this situation should be avoided if possible.)
</xsd:documentation>
<xsd:appinfo>
<a:since>3.7</a:since>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="startTimestamp" type="xsd:dateTime" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Expand Down
Expand Up @@ -35,8 +35,8 @@ public class EvaluatedCompositeTrigger extends EvaluatedPolicyRuleTrigger<Policy
@NotNull private final Collection<EvaluatedPolicyRuleTrigger<?>> innerTriggers;

public EvaluatedCompositeTrigger(@NotNull PolicyConstraintKindType kind, @NotNull PolicyConstraintsType constraint,
LocalizableMessage message, @NotNull Collection<EvaluatedPolicyRuleTrigger<?>> innerTriggers) {
super(kind, constraint, message);
LocalizableMessage message, LocalizableMessage shortMessage, @NotNull Collection<EvaluatedPolicyRuleTrigger<?>> innerTriggers) {
super(kind, constraint, message, shortMessage);
this.innerTriggers = innerTriggers;
}

Expand Down
Expand Up @@ -36,9 +36,9 @@ public class EvaluatedExclusionTrigger extends EvaluatedPolicyRuleTrigger<Exclus
private final AssignmentPath conflictingPath;

public EvaluatedExclusionTrigger(@NotNull ExclusionPolicyConstraintType constraint,
LocalizableMessage message, @NotNull EvaluatedAssignment conflictingAssignment,
LocalizableMessage message, LocalizableMessage shortMessage, @NotNull EvaluatedAssignment conflictingAssignment,
ObjectType thisTarget, ObjectType conflictingTarget, AssignmentPath thisPath, AssignmentPath conflictingPath) {
super(PolicyConstraintKindType.EXCLUSION, constraint, message);
super(PolicyConstraintKindType.EXCLUSION, constraint, message, shortMessage);
this.conflictingAssignment = conflictingAssignment;
this.conflictingTarget = conflictingTarget;
this.conflictingPath = conflictingPath;
Expand Down
Expand Up @@ -26,8 +26,8 @@
public class EvaluatedHasAssignmentTrigger extends EvaluatedPolicyRuleTrigger<HasAssignmentPolicyConstraintType> {

public EvaluatedHasAssignmentTrigger(@NotNull PolicyConstraintKindType kind, @NotNull HasAssignmentPolicyConstraintType constraint,
LocalizableMessage message) {
super(kind, constraint, message);
LocalizableMessage message, LocalizableMessage shortMessage) {
super(kind, constraint, message, shortMessage);
}

@Override
Expand Down
Expand Up @@ -26,8 +26,8 @@
public class EvaluatedModificationTrigger extends EvaluatedPolicyRuleTrigger<ModificationPolicyConstraintType> {

public EvaluatedModificationTrigger(@NotNull PolicyConstraintKindType kind, @NotNull ModificationPolicyConstraintType constraint,
LocalizableMessage message) {
super(kind, constraint, message);
LocalizableMessage message, LocalizableMessage shortMessage) {
super(kind, constraint, message, shortMessage);
}

@Override
Expand Down
Expand Up @@ -26,8 +26,8 @@
public class EvaluatedMultiplicityTrigger extends EvaluatedPolicyRuleTrigger<MultiplicityPolicyConstraintType> {

public EvaluatedMultiplicityTrigger(@NotNull PolicyConstraintKindType kind, @NotNull MultiplicityPolicyConstraintType constraint,
LocalizableMessage message) {
super(kind, constraint, message);
LocalizableMessage message, LocalizableMessage shortMessage) {
super(kind, constraint, message, shortMessage);
}

@Override
Expand Down
Expand Up @@ -75,6 +75,8 @@ default boolean isTriggered() {

List<TreeNode<LocalizableMessage>> extractMessages();

List<TreeNode<LocalizableMessage>> extractShortMessages();

// BEWARE: enabled actions can be queried only after computeEnabledActions has been called
// todo think again about this

Expand Down
Expand Up @@ -37,11 +37,14 @@ public abstract class EvaluatedPolicyRuleTrigger<CT extends AbstractPolicyConstr
@NotNull private final PolicyConstraintKindType constraintKind;
@NotNull private final CT constraint;
private final LocalizableMessage message;
private final LocalizableMessage shortMessage;

public EvaluatedPolicyRuleTrigger(@NotNull PolicyConstraintKindType constraintKind, @NotNull CT constraint, LocalizableMessage message) {
public EvaluatedPolicyRuleTrigger(@NotNull PolicyConstraintKindType constraintKind, @NotNull CT constraint,
LocalizableMessage message, LocalizableMessage shortMessage) {
this.constraintKind = constraintKind;
this.constraint = constraint;
this.message = message;
this.shortMessage = shortMessage;
}

/**
Expand All @@ -67,6 +70,10 @@ public LocalizableMessage getMessage() {
return message;
}

public LocalizableMessage getShortMessage() {
return shortMessage;
}

@Override
public boolean equals(Object o) {
if (this == o)
Expand Down Expand Up @@ -139,10 +146,12 @@ public EvaluatedPolicyRuleTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRul
protected void fillCommonContent(EvaluatedPolicyRuleTriggerType tt) {
tt.setConstraintKind(constraintKind);
tt.setMessage(LocalizationUtil.createLocalizableMessageType(message));
tt.setShortMessage(LocalizationUtil.createLocalizableMessageType(shortMessage));
PolicyConstraintPresentationType presentation = constraint.getPresentation();
if (presentation != null) {
tt.setFinal(presentation.isFinal());
tt.setHidden(presentation.isHidden());
tt.setPresentationOrder(presentation.getDisplayOrder());
}
}

Expand Down
Expand Up @@ -38,8 +38,8 @@ public class EvaluatedSituationTrigger extends EvaluatedPolicyRuleTrigger<Policy
@NotNull private final Collection<EvaluatedPolicyRule> sourceRules;

public EvaluatedSituationTrigger(@NotNull PolicySituationPolicyConstraintType constraint,
LocalizableMessage message, @NotNull Collection<EvaluatedPolicyRule> sourceRules) {
super(PolicyConstraintKindType.SITUATION, constraint, message);
LocalizableMessage message, LocalizableMessage shortMessage, @NotNull Collection<EvaluatedPolicyRule> sourceRules) {
super(PolicyConstraintKindType.SITUATION, constraint, message, shortMessage);
this.sourceRules = sourceRules;
}

Expand Down
Expand Up @@ -28,8 +28,8 @@
public class EvaluatedStateTrigger extends EvaluatedPolicyRuleTrigger<StatePolicyConstraintType> {

public EvaluatedStateTrigger(@NotNull PolicyConstraintKindType kind, @NotNull StatePolicyConstraintType constraint,
LocalizableMessage message) {
super(kind, constraint, message);
LocalizableMessage message, LocalizableMessage shortMessage) {
super(kind, constraint, message, shortMessage);
}

@Override
Expand Down
Expand Up @@ -26,8 +26,8 @@
public class EvaluatedTimeValidityTrigger extends EvaluatedPolicyRuleTrigger<TimeValidityPolicyConstraintType> {

public EvaluatedTimeValidityTrigger(@NotNull PolicyConstraintKindType kind, @NotNull TimeValidityPolicyConstraintType constraint,
LocalizableMessage message) {
super(kind, constraint, message);
LocalizableMessage message, LocalizableMessage shortMessage) {
super(kind, constraint, message, shortMessage);
}

@Override
Expand Down
Expand Up @@ -33,8 +33,8 @@ public class EvaluatedTransitionTrigger extends EvaluatedPolicyRuleTrigger<Trans
@NotNull private final Collection<EvaluatedPolicyRuleTrigger<?>> innerTriggers;

public EvaluatedTransitionTrigger(@NotNull PolicyConstraintKindType kind, @NotNull TransitionPolicyConstraintType constraint,
LocalizableMessage message, @NotNull Collection<EvaluatedPolicyRuleTrigger<?>> innerTriggers) {
super(kind, constraint, message);
LocalizableMessage message, LocalizableMessage shortMessage, @NotNull Collection<EvaluatedPolicyRuleTrigger<?>> innerTriggers) {
super(kind, constraint, message, shortMessage);
this.innerTriggers = innerTriggers;
}

Expand Down
Expand Up @@ -303,33 +303,52 @@ public String toShortString() {
return sb.toString();
}

@SuppressWarnings("unchecked")
enum MessageKind { NORMAL, SHORT, /*LONG*/ }

@Override
public List<TreeNode<LocalizableMessage>> extractMessages() {
return extractMessages(MessageKind.NORMAL);
}

@Override
public List<TreeNode<LocalizableMessage>> extractShortMessages() {
return extractMessages(MessageKind.SHORT);
}

@SuppressWarnings("unchecked")
private List<TreeNode<LocalizableMessage>> extractMessages(MessageKind kind) {
TreeNode<LocalizableMessage> root = new TreeNode<>();
for (EvaluatedPolicyRuleTrigger<?> trigger : triggers) {
createMessageTreeNode(root, trigger);
createMessageTreeNode(root, trigger, kind);
}
return root.getChildren();
}

private void createMessageTreeNode(TreeNode<LocalizableMessage> root, EvaluatedPolicyRuleTrigger<?> trigger) {
private void createMessageTreeNode(TreeNode<LocalizableMessage> root, EvaluatedPolicyRuleTrigger<?> trigger, MessageKind kind) {
PolicyConstraintPresentationType presentation = trigger.getConstraint().getPresentation();
boolean hidden = presentation != null && Boolean.TRUE.equals(presentation.isHidden());
boolean isFinal = presentation != null && Boolean.TRUE.equals(presentation.isFinal());
if (!hidden) {
TreeNode<LocalizableMessage> newNode = new TreeNode<>();
newNode.setUserObject(trigger.getMessage());
newNode.setUserObject(getMessage(trigger, kind));
root.add(newNode);
root = newNode;
}
if (!isFinal) {
for (EvaluatedPolicyRuleTrigger<?> innerTrigger : trigger.getInnerTriggers()) {
createMessageTreeNode(root, innerTrigger);
createMessageTreeNode(root, innerTrigger, kind);
}
}
}

private LocalizableMessage getMessage(EvaluatedPolicyRuleTrigger<?> trigger, MessageKind kind) {
switch (kind) {
case NORMAL: return trigger.getMessage();
case SHORT: return trigger.getMessage();
default: throw new AssertionError(kind);
}
}

/**
* Honors "final" but not "hidden" flag.
* @param options
Expand Down

0 comments on commit 683765b

Please sign in to comment.