Skip to content

Commit

Permalink
Replace use=embedded/leftJoin/innerJoin
Browse files Browse the repository at this point in the history
The new form of configuration is:

resultHandling:
  multipleValues : embedInParentRow / splitParentRow
  noValues : keepParentRow / removeParentRow
  • Loading branch information
mederly committed Feb 27, 2023
1 parent 28a8e09 commit b959d7f
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 58 deletions.
101 changes: 78 additions & 23 deletions infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,7 @@
<xsd:annotation>
<xsd:documentation>
Provisioning policy, which is applied to shadows, which have this tag assigned.

If shadow have multiple tags with provisioning policy applied, the strongest effect is applied.
</xsd:documentation>
<xsd:appinfo>
Expand Down Expand Up @@ -17998,14 +17998,14 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="use" type="tns:SubreportUseType" minOccurs="0" default="embedded">
<xsd:element name="resultHandling" type="tns:SubreportResultHandlingType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
How should be the values of subreport used with regard to the parent report row:
embedded to it or joined with it. Mostly useful for subreports that produce more values.
How should we handle the situations when the sub-report produces either multiple values,
or no values at all?
</xsd:documentation>
<xsd:appinfo>
<a:displayName>SubreportParameterType.asRow</a:displayName>
<a:displayName>SubreportParameterType.resultHandling</a:displayName>
<a:since>4.7</a:since>
</xsd:appinfo>
</xsd:annotation>
Expand All @@ -18015,48 +18015,103 @@
</xsd:complexContent>
</xsd:complexType>

<xsd:simpleType name="SubreportUseType">
<xsd:complexType name="SubreportResultHandlingType">
<xsd:annotation>
<xsd:documentation>
How is the result of a sub-report used.
How should we handle the situations when a sub-report produces either either multiple values, or no values at all?
</xsd:documentation>
<xsd:appinfo>
<a:container>true</a:container>
<a:since>4.7</a:since>
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="multipleValues" type="tns:MultipleSubreportResultValuesHandlingType" minOccurs="0"
default="embedInParentRow">
<xsd:annotation>
<xsd:documentation>
How should we handle the situations when a sub-report produces multiple values?
</xsd:documentation>
<xsd:appinfo>
<a:displayName>SubreportResultHandlingType.multipleValues</a:displayName>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="noValues" type="tns:NoSubreportResultValuesHandlingType" minOccurs="0" default="keepParentRow">
<xsd:annotation>
<xsd:documentation>
How should we handle the situations when a sub-report produces no values?
</xsd:documentation>
<xsd:appinfo>
<a:displayName>SubreportResultHandlingType.noValues</a:displayName>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:complexType>

<xsd:simpleType name="MultipleSubreportResultValuesHandlingType">
<xsd:annotation>
<xsd:documentation>
How should we handle the situations when a sub-report produces multiple values?
</xsd:documentation>
<xsd:appinfo>
<a:since>4.7</a:since>
</xsd:appinfo>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="embedded">
<xsd:enumeration value="embedInParentRow">
<xsd:annotation>
<xsd:documentation>
The value(s) of the sub-report are used within the parent result row.
The values of the sub-report are used within the parent row. No row manipulation is done.
</xsd:documentation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="EMBEDDED"/>
<jaxb:typesafeEnumMember name="EMBED_IN_PARENT_ROW"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="leftJoin">
<xsd:enumeration value="splitParentRow">
<xsd:annotation>
<xsd:documentation>
The N value(s) of the sub-report are "joined" (in the relational terms) with the parent row,
producing N rows (if N > 0) or 1 row (if N = 0).
The N > 1 value(s) of the sub-report are "joined" (in the relational terms) with the parent row,
producing N rows. In each of these rows the value of the respective element is provided as a variable
named as specified in this subreport.
</xsd:documentation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="SPLIT_PARENT_ROW"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
</xsd:restriction>
</xsd:simpleType>

In each generated row the value of the respective element is provided as a variable named
as specified in this subreport. If N = 0, the value of this variable is null.
<xsd:simpleType name="NoSubreportResultValuesHandlingType">
<xsd:annotation>
<xsd:documentation>
How should we handle the situations when a sub-report produces no values?
</xsd:documentation>
<xsd:appinfo>
<a:since>4.7</a:since>
</xsd:appinfo>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="keepParentRow">
<xsd:annotation>
<xsd:documentation>
The parent row is kept intact. The respective variable (named after the subreport) is null.
</xsd:documentation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="LEFT_JOIN"/>
<jaxb:typesafeEnumMember name="KEEP_PARENT_ROW"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="innerJoin">
<xsd:enumeration value="removeParentRow">
<xsd:annotation>
<xsd:documentation>
The N value(s) of the sub-report are "joined" (in the relational terms) with the parent row,
producing N rows. If N = 0, the parent row is eliminated.
The parent row is removed. No further evaluation of subreports nor columns is done.
</xsd:documentation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="INNER_JOIN"/>
<jaxb:typesafeEnumMember name="REMOVE_PARENT_ROW"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
Expand Down Expand Up @@ -19883,9 +19938,9 @@
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<!--
<!--
If false: (like protected)
Inbound / outbound mapping changes are disabled
Inbound / outbound mapping changes are disabled
do not run clockwork (SynchronizationServiceImpl)
do not run inbounds
do not run outbounds
Expand All @@ -19897,5 +19952,5 @@
<xsd:element name="delete" type="tns:OperationPolicyConfigurationType" minOccurs="0" />
</xsd:sequence>
</xsd:complexType>

</xsd:schema>
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

import static com.evolveum.midpoint.report.impl.controller.GenericSupport.evaluateCondition;
import static com.evolveum.midpoint.util.MiscUtil.configNonNull;
import static com.evolveum.midpoint.util.MiscUtil.stateCheck;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.SubreportUseType.*;

import static java.util.Objects.requireNonNull;

Expand Down Expand Up @@ -327,32 +325,48 @@ private void evaluateFromSubreport(int index, OperationResult result) throws Con
getSingleTypedValue(
ReportBeans.get().reportService.evaluateSubreport(
report.asPrismObject(), variables, subreportDef, workerTask, result));
SubreportUseType use = Objects.requireNonNullElse(subreportDef.getUse(), EMBEDDED);
if (use == EMBEDDED) {
variables.put(subReportName, subReportResultTyped);
evaluateFromSubreport(index + 1, result);
variables.remove(subReportName);
} else {
stateCheck(
use == INNER_JOIN || use == LEFT_JOIN,
"Unsupported use value for %s: %s", subReportName, use);
List<?> subReportValues = getAsList(subReportResultTyped);
for (Object subReportValue : subReportValues) {
variables.put(
subReportName,
TypedValue.of(getRealValue(subReportValue), Object.class));
List<?> subReportValues = getAsList(subReportResultTyped);

if (subReportValues.isEmpty()) {
if (shouldRemoveParentIfNoValues(subreportDef)) {
// Doing nothing
} else {
// Null is the best alternative to represent "no element" generated from the subreport.
variables.put(subReportName, null, Object.class);
evaluateFromSubreport(index + 1, result);
variables.remove(subReportName);
}
if (subReportValues.isEmpty() && use == LEFT_JOIN) {
// Null is the best alternative to represent "no element" generated from the joined subreport.
variables.put(subReportName, null, Object.class);
} else {
// 1-N values are present
if (shouldSplitParentOnMultipleValues(subreportDef)) {
// We do this iteration also for single-value collection because the downstream expressions expect the value,
// not the single-valued collection.
for (Object subReportValue : subReportValues) {
variables.put(
subReportName,
TypedValue.of(getRealValue(subReportValue), Object.class));
evaluateFromSubreport(index + 1, result);
variables.remove(subReportName);
}
} else {
// Using the result "as is"
variables.put(subReportName, subReportResultTyped);
evaluateFromSubreport(index + 1, result);
variables.remove(subReportName);
}
}
}

private boolean shouldRemoveParentIfNoValues(SubreportParameterType definition) {
SubreportResultHandlingType handling = definition.getResultHandling();
return handling != null && handling.getNoValues() == NoSubreportResultValuesHandlingType.REMOVE_PARENT_ROW;
}

private boolean shouldSplitParentOnMultipleValues(SubreportParameterType definition) {
SubreportResultHandlingType handling = definition.getResultHandling();
return handling != null && handling.getMultipleValues() == MultipleSubreportResultValuesHandlingType.SPLIT_PARENT_ROW;
}

// Quite a hackery, for now. Should be reconsidered some day.
private Object getRealValue(Object value) {
if (value instanceof Item) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@
</code>
</script>
</expression>
<use>innerJoin</use>
<resultHandling>
<!-- "inner join" -->
<multipleValues>splitParentRow</multipleValues>
<noValues>removeParentRow</noValues>
</resultHandling>
</subreport>
</objectCollection>
</report>
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@
</code>
</script>
</expression>
<use>leftJoin</use>
<resultHandling>
<multipleValues>splitParentRow</multipleValues>
</resultHandling>
</subreport>
</objectCollection>
</report>
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
-->
<name>data</name>
<order>1</order>
<use>leftJoin</use>
<resultHandling>
<multipleValues>splitParentRow</multipleValues>
</resultHandling>
<expression>
<script>
<objectVariableMode>prismReference</objectVariableMode>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@
</script>
</expression>
<order>10</order>
<use>leftJoin</use>
<resultHandling>
<multipleValues>splitParentRow</multipleValues>
</resultHandling>
</subreport>
<subreport>
<name>objectDelta</name>
Expand All @@ -113,7 +115,9 @@
</script>
</expression>
<order>20</order>
<use>leftJoin</use>
<resultHandling>
<multipleValues>splitParentRow</multipleValues>
</resultHandling>
</subreport>
<subreport>
<name>assignment</name>
Expand Down Expand Up @@ -160,7 +164,9 @@
</script>
</expression>
<order>30</order>
<use>leftJoin</use>
<resultHandling>
<multipleValues>splitParentRow</multipleValues>
</resultHandling>
</subreport>
</objectCollection>
</report>
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@
</code>
</script>
</expression>
<use>leftJoin</use>
<resultHandling>
<multipleValues>splitParentRow</multipleValues>
</resultHandling>
</subreport>
</objectCollection>
</report>
Original file line number Diff line number Diff line change
Expand Up @@ -309,10 +309,12 @@
</script>
</expression>
<order>10</order>
<use>leftJoin</use>
<resultHandling>
<multipleValues>splitParentRow</multipleValues>
</resultHandling>
</subreport>
<subreport>
<!-- Special hack to eliminate rows with no details if requested so -->
<!-- Eliminates rows with no details - if requested so -->
<name>detailsPresent</name>
<type>xsd:boolean</type>
<expression>
Expand All @@ -321,7 +323,9 @@
</script>
</expression>
<order>20</order>
<use>innerJoin</use>
<resultHandling>
<noValues>removeParentRow</noValues>
</resultHandling>
</subreport>
<subreport>
<name>relatedAssignment</name>
Expand All @@ -332,7 +336,9 @@
</script>
</expression>
<order>30</order>
<use>leftJoin</use>
<resultHandling>
<multipleValues>splitParentRow</multipleValues>
</resultHandling>
</subreport>
</objectCollection>
</report>

0 comments on commit b959d7f

Please sign in to comment.