Skip to content

Commit

Permalink
repo-sqale: mapping registry configuration uses mapping suppliers
Browse files Browse the repository at this point in the history
Details about parent (..) mapping are now hidden inside mapping classes
that own the mappings.
  • Loading branch information
virgo47 committed Jul 9, 2021
1 parent de59e12 commit f2e788b
Show file tree
Hide file tree
Showing 20 changed files with 210 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -121,27 +121,30 @@ public SqaleRepoContext sqlRepoContext(
repositoryConfiguration, dataSource, schemaService, mappingRegistry);

// Registered mapping needs repository context which needs registry. Now we can fill it.
// Mappings are ordered objects first to have parent mapping for containers initialized,
// e.g. assignment holder before assignment, then alphabetically inside the block.
// Mappings without schema type are at the end.
QAccessCertificationCampaignMapping accessCertificationCampaignMapping =
QAccessCertificationCampaignMapping.init(repositoryContext);
QAssignmentHolderMapping<?, ?, ?> assignmentHolderMapping =
QAssignmentHolderMapping.init(repositoryContext);
QCaseMapping caseMapping = QCaseMapping.init(repositoryContext);
QLookupTableMapping lookupTableMapping = QLookupTableMapping.init(repositoryContext);
QObjectMapping<?, ?, ?> objectMapping = QObjectMapping.initObjectMapping(repositoryContext);
// Mappings are ordered alphabetically here, mappings without schema type are at the end.

mappingRegistry
.register(AbstractRoleType.COMPLEX_TYPE,
QAbstractRoleMapping.initAbstractRoleMapping(repositoryContext))
.register(AccessCertificationCampaignType.COMPLEX_TYPE,
QAccessCertificationCampaignMapping
.initAccessCertificationCampaignMapping(repositoryContext))
.register(AccessCertificationCaseType.COMPLEX_TYPE,
QAccessCertificationCaseMapping
.initAccessCertificationCaseMapping(repositoryContext))
.register(AccessCertificationDefinitionType.COMPLEX_TYPE,
QAccessCertificationDefinitionMapping.init(repositoryContext))
.register(AccessCertificationCampaignType.COMPLEX_TYPE,
accessCertificationCampaignMapping)
.register(ArchetypeType.COMPLEX_TYPE, QArchetypeMapping.initArchetypeMapping(repositoryContext))
.register(AssignmentHolderType.COMPLEX_TYPE, assignmentHolderMapping)
.register(CaseType.COMPLEX_TYPE, caseMapping)
.register(AccessCertificationWorkItemType.COMPLEX_TYPE,
QAccessCertificationWorkItemMapping.init(repositoryContext))
.register(ArchetypeType.COMPLEX_TYPE,
QArchetypeMapping.initArchetypeMapping(repositoryContext))
.register(AssignmentHolderType.COMPLEX_TYPE,
QAssignmentHolderMapping.initAssignmentHolderMapping(repositoryContext))
.register(AssignmentType.COMPLEX_TYPE,
QAssignmentMapping.initAssignmentMapping(repositoryContext))
.register(CaseType.COMPLEX_TYPE, QCaseMapping.initCaseMapping(repositoryContext))
.register(CaseWorkItemType.COMPLEX_TYPE,
QCaseWorkItemMapping.initCaseWorkItemMapping(repositoryContext))
.register(DashboardType.COMPLEX_TYPE, QDashboardMapping.init(repositoryContext))
.register(FocusType.COMPLEX_TYPE, QFocusMapping.initFocusMapping(repositoryContext))
.register(FormType.COMPLEX_TYPE, QFormMapping.init(repositoryContext))
Expand All @@ -152,13 +155,18 @@ public SqaleRepoContext sqlRepoContext(
QConnectorHostMapping.init(repositoryContext))
.register(GenericObjectType.COMPLEX_TYPE,
QGenericObjectMapping.init(repositoryContext))
.register(LookupTableType.COMPLEX_TYPE, lookupTableMapping)
.register(LookupTableType.COMPLEX_TYPE, QLookupTableMapping.init(repositoryContext))
.register(LookupTableRowType.COMPLEX_TYPE,
QLookupTableRowMapping.init(repositoryContext))
.register(NodeType.COMPLEX_TYPE, QNodeMapping.init(repositoryContext))
.register(ObjectType.COMPLEX_TYPE, objectMapping)
.register(ObjectType.COMPLEX_TYPE,
QObjectMapping.initObjectMapping(repositoryContext))
.register(ObjectCollectionType.COMPLEX_TYPE,
QObjectCollectionMapping.init(repositoryContext))
.register(ObjectTemplateType.COMPLEX_TYPE,
QObjectTemplateMapping.initObjectTemplateMapping(repositoryContext))
.register(OperationExecutionType.COMPLEX_TYPE,
QOperationExecutionMapping.init(repositoryContext))
.register(OrgType.COMPLEX_TYPE, QOrgMapping.initOrgMapping(repositoryContext))
.register(ReportType.COMPLEX_TYPE, QReportMapping.init(repositoryContext))
.register(ReportDataType.COMPLEX_TYPE, QReportDataMapping.init(repositoryContext))
Expand All @@ -168,39 +176,14 @@ public SqaleRepoContext sqlRepoContext(
QSecurityPolicyMapping.init(repositoryContext))
.register(SequenceType.COMPLEX_TYPE, QSequenceMapping.init(repositoryContext))
.register(ServiceType.COMPLEX_TYPE, QServiceMapping.init(repositoryContext))
.register(ShadowType.COMPLEX_TYPE, QShadowMapping.initShadowMapping(repositoryContext))
.register(ShadowType.COMPLEX_TYPE,
QShadowMapping.initShadowMapping(repositoryContext))
.register(SystemConfigurationType.COMPLEX_TYPE,
QSystemConfigurationMapping.init(repositoryContext))
.register(TaskType.COMPLEX_TYPE, QTaskMapping.init(repositoryContext))
.register(TriggerType.COMPLEX_TYPE, QTriggerMapping.init(repositoryContext))
.register(UserType.COMPLEX_TYPE, QUserMapping.initUserMapping(repositoryContext))
.register(ValuePolicyType.COMPLEX_TYPE, QValuePolicyMapping.init(repositoryContext))

// registering container mappings with parent table/mapping configuration
.register(AccessCertificationCaseType.COMPLEX_TYPE,
QAccessCertificationCaseMapping.init(repositoryContext),
accessCertificationCampaignMapping,
(accs, acc) -> accs.ownerOid.eq(acc.oid))
.register(AccessCertificationWorkItemType.COMPLEX_TYPE,
QAccessCertificationWorkItemMapping.init(repositoryContext),
QAccessCertificationCaseMapping.get(),
(acwi, accs) -> acwi.ownerOid.eq(accs.ownerOid)
.and(acwi.accessCertCaseCid.eq(accs.cid)))
.register(AssignmentType.COMPLEX_TYPE,
QAssignmentMapping.initAssignment(repositoryContext),
// Adding and(a.ownerType.eq(ah.objectType) doesn't help the planner.
assignmentHolderMapping, (a, ah) -> a.ownerOid.eq(ah.oid))
.register(CaseWorkItemType.COMPLEX_TYPE,
QCaseWorkItemMapping.init(repositoryContext),
caseMapping, (cswi, cs) -> cswi.ownerOid.eq(cs.oid))
.register(LookupTableRowType.COMPLEX_TYPE,
QLookupTableRowMapping.init(repositoryContext),
lookupTableMapping, (ltr, lt) -> ltr.ownerOid.eq(lt.oid))
.register(OperationExecutionType.COMPLEX_TYPE,
QOperationExecutionMapping.init(repositoryContext),
objectMapping, (opex, o) -> opex.ownerOid.eq(o.oid))
.register(TriggerType.COMPLEX_TYPE, QTriggerMapping.init(repositoryContext),
objectMapping, (trg, o) -> trg.ownerOid.eq(o.oid))

.register(QContainerMapping.initContainerMapping(repositoryContext))
.register(QReferenceMapping.init(repositoryContext))
.seal();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public ContainerTableUpdateContext<TS, TQ, TR, R> resolve(
+ " segments with PCV ID as the second");
}
QContainerMapping<TS, TQ, TR, R> containerMapping =
(QContainerMapping<TS, TQ, TR, R>) this.targetMapping;
(QContainerMapping<TS, TQ, TR, R>) targetMappingSupplier.get();
TR row = containerMapping.newRowObject(context.row());
//noinspection ConstantConditions
row.cid = (long) itemPath.getSegment(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@
import com.evolveum.midpoint.repo.sqlbase.SqlQueryContext;
import com.evolveum.midpoint.repo.sqlbase.mapping.ItemRelationResolver;
import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping;
import com.evolveum.midpoint.repo.sqlbase.mapping.TableRelationResolver;

/**
* Resolver that knows how to traverse from reference table to the reference target.
* The resolver uses mapping lazily via supplier to avoid call cycles during mapping initialization,
* otherwise it's functionally equivalent to {@link TableRelationResolver}.
* The resolver uses mapping lazily via supplier to avoid call cycles during mapping initialization.
*
* Ideal mapping type provided by the supplier is to be found in the schema inside
* `<a:objectReferenceTargetType>` element for the reference, using more generic type means
Expand Down Expand Up @@ -59,8 +57,7 @@ public ResolutionResult<TQ, TR> resolve(SqlQueryContext<?, Q, R> context) {
return new ResolutionResult<>(subcontext, subcontext.mapping());
*/

SqlQueryContext<?, TQ, TR> subcontext = context.subquery(
targetMappingSupplier.get());
SqlQueryContext<?, TQ, TR> subcontext = context.subquery(targetMappingSupplier.get());
SQLQuery<?> subquery = subcontext.sqlQuery();
subquery.where(context.path().targetOid.eq(subcontext.path().oid));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignType.*;

import java.util.List;
import java.util.Objects;

import org.jetbrains.annotations.NotNull;

Expand All @@ -29,10 +30,20 @@ public class QAccessCertificationCampaignMapping
QAccessCertificationCampaign, MAccessCertificationCampaign> {

public static final String DEFAULT_ALIAS_NAME = "acc";
private static QAccessCertificationCampaignMapping instance;

public static QAccessCertificationCampaignMapping init(
// Explanation in class Javadoc for SqaleTableMapping
public static QAccessCertificationCampaignMapping initAccessCertificationCampaignMapping(
@NotNull SqaleRepoContext repositoryContext) {
return new QAccessCertificationCampaignMapping(repositoryContext);
if (instance == null) {
instance = new QAccessCertificationCampaignMapping(repositoryContext);
}
return instance;
}

// Explanation in class Javadoc for SqaleTableMapping
public static QAccessCertificationCampaignMapping getAccessCertificationCampaignMapping() {
return Objects.requireNonNull(instance);
}

private QAccessCertificationCampaignMapping(@NotNull SqaleRepoContext repositoryContext) {
Expand All @@ -59,7 +70,7 @@ private QAccessCertificationCampaignMapping(@NotNull SqaleRepoContext repository
addItemMapping(F_STATE, enumMapper(q -> q.state));

addContainerTableMapping(F_CASE,
QAccessCertificationCaseMapping.init(repositoryContext),
QAccessCertificationCaseMapping.initAccessCertificationCaseMapping(repositoryContext),
joinOn((o, acase) -> o.oid.eq(acase.ownerOid)));
}

Expand Down Expand Up @@ -109,7 +120,7 @@ public void storeRelatedEntities(
List<AccessCertificationCaseType> cases = schemaObject.getCase();
if (!cases.isEmpty()) {
for (AccessCertificationCaseType c : cases) {
QAccessCertificationCaseMapping.get().insert(c, row, jdbcSession);
QAccessCertificationCaseMapping.getAccessCertificationCaseMapping().insert(c, row, jdbcSession);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
import com.querydsl.core.types.Path;
import org.jetbrains.annotations.NotNull;

import com.evolveum.midpoint.prism.PrismConstants;
import com.evolveum.midpoint.prism.PrismContainer;
import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainerMapping;
import com.evolveum.midpoint.repo.sqale.update.SqaleUpdateContext;
import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
import com.evolveum.midpoint.repo.sqlbase.mapping.TableRelationResolver;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.SelectorOptions;
import com.evolveum.midpoint.util.MiscUtil;
Expand All @@ -42,22 +44,30 @@ public class QAccessCertificationCaseMapping

private static QAccessCertificationCaseMapping instance;

public static QAccessCertificationCaseMapping init(
// Explanation in class Javadoc for SqaleTableMapping
public static QAccessCertificationCaseMapping initAccessCertificationCaseMapping(
@NotNull SqaleRepoContext repositoryContext) {
if (instance == null) {
instance = new QAccessCertificationCaseMapping(repositoryContext);
}
return get();
return instance;
}

public static QAccessCertificationCaseMapping get() {
// Explanation in class Javadoc for SqaleTableMapping
public static QAccessCertificationCaseMapping getAccessCertificationCaseMapping() {
return Objects.requireNonNull(instance);
}

private QAccessCertificationCaseMapping(@NotNull SqaleRepoContext repositoryContext) {
super(QAccessCertificationCase.TABLE_NAME, DEFAULT_ALIAS_NAME,
AccessCertificationCaseType.class, QAccessCertificationCase.class, repositoryContext);

addRelationResolver(PrismConstants.T_PARENT,
// mapping supplier is used to avoid cycles in the initialization code
new TableRelationResolver<>(
QAccessCertificationCampaignMapping::getAccessCertificationCampaignMapping,
(q, p) -> q.ownerOid.eq(p.oid)));

addNestedMapping(F_ACTIVATION, ActivationType.class)
.addItemMapping(ActivationType.F_ADMINISTRATIVE_STATUS,
enumMapper(q -> q.administrativeStatus))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@

import org.jetbrains.annotations.NotNull;

import com.evolveum.midpoint.prism.PrismConstants;
import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainerMapping;
import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
import com.evolveum.midpoint.repo.sqlbase.mapping.TableRelationResolver;
import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractWorkItemOutputType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationWorkItemType;
Expand Down Expand Up @@ -46,6 +48,13 @@ private QAccessCertificationWorkItemMapping(@NotNull SqaleRepoContext repository
super(QAccessCertificationWorkItem.TABLE_NAME, DEFAULT_ALIAS_NAME,
AccessCertificationWorkItemType.class, QAccessCertificationWorkItem.class, repositoryContext);

addRelationResolver(PrismConstants.T_PARENT,
// mapping supplier is used to avoid cycles in the initialization code
new TableRelationResolver<>(
QAccessCertificationCaseMapping::getAccessCertificationCaseMapping,
(q, p) -> q.ownerOid.eq(p.ownerOid)
.and(q.accessCertCaseCid.eq(p.cid))));

addItemMapping(F_CLOSE_TIMESTAMP, timestampMapper(q -> q.closeTimestamp));
// TODO: iteration -> campaignIteration
addItemMapping(F_ITERATION, integerMapper(q -> q.campaignIteration));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@

import org.jetbrains.annotations.NotNull;

import com.evolveum.midpoint.prism.PrismConstants;
import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.qmodel.common.MContainerType;
import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainerMapping;
import com.evolveum.midpoint.repo.sqale.qmodel.ext.MExtItemHolderType;
import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject;
import com.evolveum.midpoint.repo.sqale.qmodel.object.QAssignmentHolderMapping;
import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
import com.evolveum.midpoint.repo.sqlbase.mapping.TableRelationResolver;
import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;
Expand All @@ -46,30 +49,34 @@ public class QAssignmentMapping<OR extends MObject>
/** Inducement mapping instance, this must be used for inserting inducements. */
private static QAssignmentMapping<?> instanceInducement;

// Explanation in class Javadoc for SqaleTableMapping
public static <OR extends MObject> QAssignmentMapping<OR>
initAssignment(@NotNull SqaleRepoContext repositoryContext) {
initAssignmentMapping(@NotNull SqaleRepoContext repositoryContext) {
if (instanceAssignment == null) {
instanceAssignment = new QAssignmentMapping<>(
MContainerType.ASSIGNMENT, repositoryContext);
}
return getAssignment();
return getAssignmentMapping();
}

public static <OR extends MObject> QAssignmentMapping<OR> getAssignment() {
// Explanation in class Javadoc for SqaleTableMapping
public static <OR extends MObject> QAssignmentMapping<OR> getAssignmentMapping() {
//noinspection unchecked
return (QAssignmentMapping<OR>) Objects.requireNonNull(instanceAssignment);
}

// Explanation in class Javadoc for SqaleTableMapping
public static <OR extends MObject> QAssignmentMapping<OR>
initInducement(@NotNull SqaleRepoContext repositoryContext) {
initInducementMapping(@NotNull SqaleRepoContext repositoryContext) {
if (instanceInducement == null) {
instanceInducement = new QAssignmentMapping<>(
MContainerType.INDUCEMENT, repositoryContext);
}
return getInducement();
return getInducementMapping();
}

public static <OR extends MObject> QAssignmentMapping<OR> getInducement() {
// Explanation in class Javadoc for SqaleTableMapping
public static <OR extends MObject> QAssignmentMapping<OR> getInducementMapping() {
//noinspection unchecked
return (QAssignmentMapping<OR>) Objects.requireNonNull(instanceInducement);
}
Expand All @@ -85,6 +92,12 @@ private QAssignmentMapping(
AssignmentType.class, (Class) QAssignment.class, repositoryContext);
this.containerType = containerType;

addRelationResolver(PrismConstants.T_PARENT,
// mapping supplier is used to avoid cycles in the initialization code
new TableRelationResolver<>(QAssignmentHolderMapping::getAssignmentHolderMapping,
// Adding and(q.ownerType.eq(p.objectType) doesn't help the planner.
(q, p) -> q.ownerOid.eq(p.oid)));

// TODO OWNER_TYPE is new thing and can help avoid join to concrete object table
// But this will likely require special treatment/heuristic.
addItemMapping(F_LIFECYCLE_STATE, stringMapper(q -> q.lifecycleState));
Expand Down

0 comments on commit f2e788b

Please sign in to comment.