From c35dcf1406730782f608da9ad3918318c9e8f099 Mon Sep 17 00:00:00 2001 From: Dave Watkins Date: Fri, 5 Apr 2024 16:07:55 +0100 Subject: [PATCH] Removed duplicate functionality for dynamically generating sql - the mkNameField code now uses the CommonTableFields rather than a st of hashmaps - the CommonTableFields have been pulled into a registry and the number of entities supported has been much increased #CTCTOWALTZ-3132 #7048 --- .../waltz/data/CommonTableFieldsRegistry.java | 450 ++++++++++++++++++ .../waltz/data/InlineSelectFieldFactory.java | 248 +++++----- .../org/finos/waltz/data/JooqUtilities.java | 256 +--------- .../AssessmentRatingDao.java | 16 +- .../data/attestation/AttestationRunDao.java | 7 +- .../waltz/data/change_set/ChangeSetDao.java | 4 +- .../data/involvement/InvolvementDao.java | 10 +- .../waltz/data/survey/SurveyInstanceDao.java | 7 +- .../survey/SurveyQuestionResponseDao.java | 3 +- .../finos/waltz/model/CommonTableFields.java | 20 +- .../extracts/AssessmentRatingExtractor.java | 15 +- .../extracts/LogicalFlowExtractor.java | 32 +- 12 files changed, 614 insertions(+), 454 deletions(-) create mode 100644 waltz-data/src/main/java/org/finos/waltz/data/CommonTableFieldsRegistry.java diff --git a/waltz-data/src/main/java/org/finos/waltz/data/CommonTableFieldsRegistry.java b/waltz-data/src/main/java/org/finos/waltz/data/CommonTableFieldsRegistry.java new file mode 100644 index 0000000000..484b27a799 --- /dev/null +++ b/waltz-data/src/main/java/org/finos/waltz/data/CommonTableFieldsRegistry.java @@ -0,0 +1,450 @@ +package org.finos.waltz.data; + +import org.finos.waltz.model.CommonTableFields; +import org.finos.waltz.model.EntityKind; +import org.finos.waltz.model.EntityLifecycleStatus; +import org.finos.waltz.model.ImmutableCommonTableFields; +import org.finos.waltz.schema.Tables; +import org.finos.waltz.schema.tables.Actor; +import org.finos.waltz.schema.tables.AllocationScheme; +import org.finos.waltz.schema.tables.Application; +import org.finos.waltz.schema.tables.ApplicationGroup; +import org.finos.waltz.schema.tables.AssessmentDefinition; +import org.finos.waltz.schema.tables.ChangeInitiative; +import org.finos.waltz.schema.tables.ChangeSet; +import org.finos.waltz.schema.tables.ComplexityKind; +import org.finos.waltz.schema.tables.CostKind; +import org.finos.waltz.schema.tables.DataType; +import org.finos.waltz.schema.tables.EndUserApplication; +import org.finos.waltz.schema.tables.EntityRelationship; +import org.finos.waltz.schema.tables.EntityStatisticDefinition; +import org.finos.waltz.schema.tables.FlowClassification; +import org.finos.waltz.schema.tables.FlowClassificationRule; +import org.finos.waltz.schema.tables.FlowDiagram; +import org.finos.waltz.schema.tables.InvolvementKind; +import org.finos.waltz.schema.tables.LegalEntity; +import org.finos.waltz.schema.tables.LegalEntityRelationship; +import org.finos.waltz.schema.tables.Licence; +import org.finos.waltz.schema.tables.LogicalDataElement; +import org.finos.waltz.schema.tables.LogicalFlow; +import org.finos.waltz.schema.tables.Measurable; +import org.finos.waltz.schema.tables.MeasurableCategory; +import org.finos.waltz.schema.tables.MeasurableRating; +import org.finos.waltz.schema.tables.OrganisationalUnit; +import org.finos.waltz.schema.tables.Person; +import org.finos.waltz.schema.tables.PhysicalFlow; +import org.finos.waltz.schema.tables.PhysicalSpecification; +import org.finos.waltz.schema.tables.ServerInformation; +import org.finos.waltz.schema.tables.SoftwarePackage; +import org.finos.waltz.schema.tables.SurveyQuestion; +import org.finos.waltz.schema.tables.SurveyTemplate; +import org.jooq.impl.DSL; + +import static org.finos.waltz.model.EntityKind.ACTOR; + +public class CommonTableFieldsRegistry { + + public static CommonTableFields determineCommonTableFields(EntityKind kind, String alias) { + switch (kind) { + case ACTOR: + Actor actor = alias == null ? Tables.ACTOR : Tables.ACTOR.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(ACTOR) + .table(actor) + .idField(actor.ID) + .parentIdField(null) + .nameField(actor.NAME) + .descriptionField(actor.DESCRIPTION) + .externalIdField(actor.EXTERNAL_ID) + .build(); + case ALLOCATION_SCHEME: + AllocationScheme allocScheme = alias == null ? Tables.ALLOCATION_SCHEME : Tables.ALLOCATION_SCHEME.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.ALLOCATION_SCHEME) + .table(allocScheme) + .idField(allocScheme.ID) + .parentIdField(null) + .nameField(allocScheme.NAME) + .descriptionField(allocScheme.DESCRIPTION) + .externalIdField(allocScheme.EXTERNAL_ID) + .build(); + case APPLICATION: + Application app = alias == null ? Tables.APPLICATION : Tables.APPLICATION.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.APPLICATION) + .table(app) + .idField(app.ID) + .parentIdField(null) + .nameField(app.NAME) + .descriptionField(app.DESCRIPTION) + .externalIdField(app.ASSET_CODE) + .lifecycleField(app.ENTITY_LIFECYCLE_STATUS) + .build(); + case APP_GROUP: + ApplicationGroup ag = alias == null ? Tables.APPLICATION_GROUP : Tables.APPLICATION_GROUP.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.APP_GROUP) + .table(ag) + .idField(ag.ID) + .parentIdField(null) + .nameField(ag.NAME) + .descriptionField(ag.DESCRIPTION) + .externalIdField(ag.EXTERNAL_ID) + .build(); + case ASSESSMENT_DEFINITION: + AssessmentDefinition ad = alias == null ? Tables.ASSESSMENT_DEFINITION : Tables.ASSESSMENT_DEFINITION.as("alias"); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.ASSESSMENT_DEFINITION) + .table(ad) + .idField(ad.ID) + .parentIdField(null) + .nameField(ad.NAME) + .descriptionField(ad.DESCRIPTION) + .externalIdField(ad.EXTERNAL_ID) + .build(); + case CHANGE_INITIATIVE: + ChangeInitiative ci = alias == null ? Tables.CHANGE_INITIATIVE : Tables.CHANGE_INITIATIVE.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.CHANGE_INITIATIVE) + .table(ci) + .idField(ci.ID) + .parentIdField(ci.PARENT_ID) + .nameField(ci.NAME) + .descriptionField(ci.DESCRIPTION) + .externalIdField(ci.EXTERNAL_ID) + .build(); + case CHANGE_SET: + ChangeSet cs = alias == null ? Tables.CHANGE_SET : Tables.CHANGE_SET.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.CHANGE_SET) + .table(cs) + .idField(cs.ID) + .nameField(cs.NAME) + .descriptionField(cs.DESCRIPTION) + .externalIdField(cs.EXTERNAL_ID) + .lifecycleField(cs.ENTITY_LIFECYCLE_STATUS) + .build(); + case COMPLEXITY_KIND: + ComplexityKind cxk = alias == null ? Tables.COMPLEXITY_KIND : Tables.COMPLEXITY_KIND.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.COMPLEXITY_KIND) + .table(cxk) + .idField(cxk.ID) + .parentIdField(null) + .nameField(cxk.NAME) + .descriptionField(cxk.DESCRIPTION) + .externalIdField(cxk.EXTERNAL_ID) + .build(); + case COST_KIND: + CostKind ck = alias == null ? Tables.COST_KIND : Tables.COST_KIND.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.COST_KIND) + .table(ck) + .idField(ck.ID) + .parentIdField(null) + .nameField(ck.NAME) + .descriptionField(ck.DESCRIPTION) + .externalIdField(ck.EXTERNAL_ID) + .build(); + case DATA_TYPE: + DataType dt = alias == null ? Tables.DATA_TYPE : Tables.DATA_TYPE.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.DATA_TYPE) + .table(dt) + .idField(dt.ID) + .parentIdField(dt.PARENT_ID) + .nameField(dt.NAME) + .descriptionField(dt.DESCRIPTION) + .externalIdField(dt.CODE) + .build(); + case END_USER_APPLICATION: + EndUserApplication euda = alias == null ? Tables.END_USER_APPLICATION : Tables.END_USER_APPLICATION.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.END_USER_APPLICATION) + .table(euda) + .idField(euda.ID) + .nameField(euda.NAME) + .descriptionField(euda.DESCRIPTION) + .externalIdField(euda.EXTERNAL_ID) + .build(); + case ENTITY_RELATIONSHIP: + EntityRelationship er = alias == null ? Tables.ENTITY_RELATIONSHIP : Tables.ENTITY_RELATIONSHIP.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.ENTITY_RELATIONSHIP) + .table(er) + .idField(er.ID) + .nameField(CommonTableFields.NA_FIELD_VAL) + .descriptionField(er.DESCRIPTION) + .externalIdField(CommonTableFields.NA_FIELD_VAL) + .build(); + case ENTITY_STATISTIC: + EntityStatisticDefinition esd = alias == null ? Tables.ENTITY_STATISTIC_DEFINITION : Tables.ENTITY_STATISTIC_DEFINITION.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.ENTITY_STATISTIC) + .table(esd) + .idField(esd.ID) + .parentIdField(esd.PARENT_ID) + .nameField(esd.NAME) + .descriptionField(esd.DESCRIPTION) + .externalIdField(esd.EXTERNAL_ID) + .build(); + case FLOW_CLASSIFICATION_RULE: + FlowClassificationRule fcr = alias == null ? Tables.FLOW_CLASSIFICATION_RULE : Tables.FLOW_CLASSIFICATION_RULE.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.FLOW_CLASSIFICATION_RULE) + .table(fcr) + .idField(fcr.ID) + .parentIdField(null) + .nameField(CommonTableFields.NA_FIELD_VAL) + .descriptionField(null) + .externalIdField(fcr.EXTERNAL_ID) + .build(); + case FLOW_CLASSIFICATION: + FlowClassification fc = alias == null ? Tables.FLOW_CLASSIFICATION : Tables.FLOW_CLASSIFICATION.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.FLOW_CLASSIFICATION) + .table(fc) + .idField(fc.ID) + .parentIdField(null) + .nameField(fc.NAME) + .descriptionField(fc.DESCRIPTION) + .externalIdField(fc.CODE) + .build(); + case FLOW_DIAGRAM: + FlowDiagram fd = alias == null ? Tables.FLOW_DIAGRAM : Tables.FLOW_DIAGRAM.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.FLOW_DIAGRAM) + .table(fd) + .idField(fd.ID) + .parentIdField(null) + .nameField(fd.NAME) + .descriptionField(fd.DESCRIPTION) + .externalIdField(CommonTableFields.NA_FIELD_VAL) + .build(); + case INVOLVEMENT_KIND: + InvolvementKind ik = alias == null ? Tables.INVOLVEMENT_KIND : Tables.INVOLVEMENT_KIND.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.INVOLVEMENT_KIND) + .table(ik) + .idField(ik.ID) + .parentIdField(null) + .nameField(ik.NAME) + .descriptionField(ik.DESCRIPTION) + .externalIdField(ik.EXTERNAL_ID) + .build(); + case LEGAL_ENTITY: + LegalEntity le = alias == null ? Tables.LEGAL_ENTITY : Tables.LEGAL_ENTITY.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.LEGAL_ENTITY) + .table(le) + .idField(le.ID) + .nameField(le.NAME) + .descriptionField(le.DESCRIPTION) + .externalIdField(le.EXTERNAL_ID) + .lifecycleField(le.ENTITY_LIFECYCLE_STATUS) + .build(); + case LEGAL_ENTITY_RELATIONSHIP: + LegalEntityRelationship ler = alias == null ? Tables.LEGAL_ENTITY_RELATIONSHIP : Tables.LEGAL_ENTITY_RELATIONSHIP.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.LEGAL_ENTITY_RELATIONSHIP) + .table(ler) + .idField(ler.ID) + .nameField(CommonTableFields.NA_FIELD_VAL) + .descriptionField(ler.DESCRIPTION) + .externalIdField(ler.EXTERNAL_ID) + .build(); + case LICENCE: + Licence lic = alias == null ? Tables.LICENCE : Tables.LICENCE.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.LICENCE) + .table(lic) + .idField(lic.ID) + .nameField(lic.NAME) + .descriptionField(lic.DESCRIPTION) + .externalIdField(lic.EXTERNAL_ID) + .build(); + case LOGICAL_DATA_ELEMENT: + LogicalDataElement lde = alias == null ? Tables.LOGICAL_DATA_ELEMENT : Tables.LOGICAL_DATA_ELEMENT.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.LOGICAL_DATA_ELEMENT) + .table(lde) + .idField(lde.ID) + .nameField(lde.NAME) + .descriptionField(lde.DESCRIPTION) + .externalIdField(lde.EXTERNAL_ID) + .lifecycleField(lde.ENTITY_LIFECYCLE_STATUS) + .build(); + case LOGICAL_DATA_FLOW: + LogicalFlow lf = alias == null ? Tables.LOGICAL_FLOW : Tables.LOGICAL_FLOW.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.LOGICAL_DATA_FLOW) + .table(lf) + .idField(lf.ID) + .nameField(CommonTableFields.NA_FIELD_VAL) + .descriptionField(CommonTableFields.NA_FIELD_VAL) + .externalIdField(lf.EXTERNAL_ID) + .lifecycleField(lf.ENTITY_LIFECYCLE_STATUS) + .build(); + case MEASURABLE: + Measurable m = alias == null ? Tables.MEASURABLE : Tables.MEASURABLE.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.MEASURABLE) + .table(m) + .idField(m.ID) + .parentIdField(m.PARENT_ID) + .nameField(m.NAME) + .descriptionField(m.DESCRIPTION) + .externalIdField(m.EXTERNAL_ID) + .lifecycleField(m.ENTITY_LIFECYCLE_STATUS) + .build(); + case MEASURABLE_CATEGORY: + MeasurableCategory mc = alias == null ? Tables.MEASURABLE_CATEGORY : Tables.MEASURABLE_CATEGORY.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.MEASURABLE_CATEGORY) + .table(mc) + .idField(mc.ID) + .parentIdField(null) + .nameField(mc.NAME) + .descriptionField(mc.DESCRIPTION) + .externalIdField(mc.EXTERNAL_ID) + .build(); + case MEASURABLE_RATING: + MeasurableRating mr = alias == null ? Tables.MEASURABLE_RATING : Tables.MEASURABLE_RATING.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.MEASURABLE_RATING) + .table(mr) + .idField(mr.ID) + .parentIdField(null) + .nameField(CommonTableFields.NA_FIELD_VAL) + .descriptionField(mr.DESCRIPTION) + .externalIdField(null) + .build(); + case ORG_UNIT: + OrganisationalUnit ou = alias == null ? Tables.ORGANISATIONAL_UNIT : Tables.ORGANISATIONAL_UNIT.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.ORG_UNIT) + .table(ou) + .idField(ou.ID) + .parentIdField(ou.PARENT_ID) + .nameField(ou.NAME) + .descriptionField(ou.DESCRIPTION) + .externalIdField(ou.EXTERNAL_ID) + .build(); + case PERSON: + Person p = alias == null ? Tables.PERSON : Tables.PERSON.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.PERSON) + .table(p) + .idField(p.ID) + .parentIdField(null) + .nameField(p.DISPLAY_NAME) + .descriptionField(p.EMAIL) + .externalIdField(p.EMPLOYEE_ID) + .lifecycleField(DSL.when(p.IS_REMOVED.isTrue(), EntityLifecycleStatus.REMOVED.name()).otherwise(EntityLifecycleStatus.ACTIVE.name())) + .build(); + case PHYSICAL_FLOW: + PhysicalFlow pf = alias == null ? Tables.PHYSICAL_FLOW : Tables.PHYSICAL_FLOW.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.PHYSICAL_FLOW) + .table(pf) + .idField(pf.ID) + .parentIdField(null) + .nameField(pf.NAME) + .descriptionField(pf.DESCRIPTION) + .externalIdField(pf.EXTERNAL_ID) + .lifecycleField(pf.ENTITY_LIFECYCLE_STATUS) + .build(); + case PHYSICAL_SPECIFICATION: + PhysicalSpecification ps = alias == null ? Tables.PHYSICAL_SPECIFICATION : Tables.PHYSICAL_SPECIFICATION.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.PHYSICAL_FLOW) + .table(ps) + .idField(ps.ID) + .parentIdField(null) + .nameField(ps.NAME) + .descriptionField(ps.DESCRIPTION) + .externalIdField(ps.EXTERNAL_ID) + .lifecycleField(DSL.when(ps.IS_REMOVED.isTrue(), EntityLifecycleStatus.REMOVED.name()).otherwise(EntityLifecycleStatus.ACTIVE.name())) + .build(); + case SERVER: + ServerInformation srv = alias == null ? Tables.SERVER_INFORMATION : Tables.SERVER_INFORMATION.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.SERVER) + .table(srv) + .idField(srv.ID) + .parentIdField(null) + .nameField(srv.HOSTNAME) + .descriptionField(srv.OPERATING_SYSTEM) + .externalIdField(srv.EXTERNAL_ID) + .build(); + case SOFTWARE: + SoftwarePackage sp = alias == null ? Tables.SOFTWARE_PACKAGE : Tables.SOFTWARE_PACKAGE.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.SOFTWARE) + .table(sp) + .idField(sp.ID) + .parentIdField(null) + .nameField(sp.NAME) + .descriptionField(sp.GROUP) + .externalIdField(sp.EXTERNAL_ID) + .build(); + case SURVEY_QUESTION: + SurveyQuestion sq = alias == null ? Tables.SURVEY_QUESTION : Tables.SURVEY_QUESTION.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.SURVEY_QUESTION) + .table(sq) + .idField(sq.ID) + .parentIdField(null) + .nameField(sq.LABEL) + .descriptionField(sq.HELP_TEXT) + .externalIdField(sq.EXTERNAL_ID) + .build(); + case SURVEY_TEMPLATE: + SurveyTemplate st = alias == null ? Tables.SURVEY_TEMPLATE : Tables.SURVEY_TEMPLATE.as(alias); + return ImmutableCommonTableFields + .builder() + .entityKind(EntityKind.SURVEY_TEMPLATE) + .table(st) + .idField(st.ID) + .parentIdField(null) + .nameField(st.NAME) + .descriptionField(st.DESCRIPTION) + .externalIdField(st.EXTERNAL_ID) + .build(); + default: + throw new UnsupportedOperationException("Cannot determine table fields for entity kind:" + kind); + } + } +} diff --git a/waltz-data/src/main/java/org/finos/waltz/data/InlineSelectFieldFactory.java b/waltz-data/src/main/java/org/finos/waltz/data/InlineSelectFieldFactory.java index 17eac5a5c0..245b8f0613 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/InlineSelectFieldFactory.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/InlineSelectFieldFactory.java @@ -18,32 +18,23 @@ package org.finos.waltz.data; +import org.finos.waltz.common.SetUtilities; +import org.finos.waltz.model.CommonTableFields; import org.finos.waltz.model.EntityKind; -import org.finos.waltz.model.EntityLifecycleStatus; import org.jooq.CaseConditionStep; import org.jooq.Condition; import org.jooq.Field; import org.jooq.Record1; -import org.jooq.Select; -import org.jooq.Table; +import org.jooq.SelectConditionStep; import org.jooq.impl.DSL; import org.jooq.lambda.tuple.Tuple2; -import org.jooq.lambda.tuple.Tuple3; -import java.util.*; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; -import static org.finos.waltz.schema.Tables.*; -import static org.finos.waltz.schema.tables.Actor.ACTOR; -import static org.finos.waltz.schema.tables.Application.APPLICATION; -import static org.finos.waltz.schema.tables.ApplicationGroup.APPLICATION_GROUP; -import static org.finos.waltz.schema.tables.ChangeInitiative.CHANGE_INITIATIVE; -import static org.finos.waltz.schema.tables.DataType.DATA_TYPE; -import static org.finos.waltz.schema.tables.EndUserApplication.END_USER_APPLICATION; -import static org.finos.waltz.schema.tables.EntityStatisticDefinition.ENTITY_STATISTIC_DEFINITION; -import static org.finos.waltz.schema.tables.MeasurableCategory.MEASURABLE_CATEGORY; -import static org.finos.waltz.schema.tables.OrganisationalUnit.ORGANISATIONAL_UNIT; -import static org.finos.waltz.schema.tables.Person.PERSON; -import static org.finos.waltz.schema.tables.PhysicalSpecification.PHYSICAL_SPECIFICATION; import static java.util.stream.Collectors.toList; import static org.finos.waltz.common.Checks.checkNotNull; import static org.jooq.impl.DSL.val; @@ -51,17 +42,80 @@ public class InlineSelectFieldFactory { + private static final Set DEFAULT_LIFECYCLE_ENTITIES = SetUtilities.asSet( + EntityKind.ACTOR, + EntityKind.APPLICATION, + EntityKind.CHANGE_INITIATIVE, + EntityKind.DATA_TYPE, + EntityKind.LEGAL_ENTITY, + EntityKind.LOGICAL_DATA_ELEMENT, + EntityKind.LOGICAL_DATA_FLOW, + EntityKind.MEASURABLE, + EntityKind.PHYSICAL_FLOW); + + private static final Set DEFAULT_EXTERNAL_ID_ENTITIES = SetUtilities.asSet( + EntityKind.ACTOR, + EntityKind.APPLICATION, + EntityKind.CHANGE_INITIATIVE, + EntityKind.CHANGE_SET, + EntityKind.DATA_TYPE, + EntityKind.END_USER_APPLICATION, + EntityKind.LOGICAL_DATA_FLOW, + EntityKind.LEGAL_ENTITY, + EntityKind.MEASURABLE, + EntityKind.MEASURABLE_CATEGORY, + EntityKind.PERSON, + EntityKind.PHYSICAL_FLOW, + EntityKind.PHYSICAL_SPECIFICATION, + EntityKind.SERVER, + EntityKind.SOFTWARE); + + private static final Set DEFAULT_NAME_ENTITIES = SetUtilities.asSet( + EntityKind.ACTOR, + EntityKind.ALLOCATION_SCHEME, + EntityKind.APPLICATION, + EntityKind.APP_GROUP, + EntityKind.CHANGE_INITIATIVE, + EntityKind.CHANGE_SET, + EntityKind.DATA_TYPE, + EntityKind.END_USER_APPLICATION, + EntityKind.ENTITY_RELATIONSHIP, + EntityKind.ENTITY_STATISTIC, + EntityKind.FLOW_CLASSIFICATION_RULE, + EntityKind.FLOW_DIAGRAM, + EntityKind.INVOLVEMENT_KIND, + EntityKind.LEGAL_ENTITY, + EntityKind.LEGAL_ENTITY_RELATIONSHIP, + EntityKind.LICENCE, + EntityKind.LOGICAL_DATA_FLOW, + EntityKind.MEASURABLE, + EntityKind.MEASURABLE_RATING, + EntityKind.MEASURABLE_CATEGORY, + EntityKind.ORG_UNIT, + EntityKind.PERSON, + EntityKind.PHYSICAL_FLOW, + EntityKind.PHYSICAL_SPECIFICATION, + EntityKind.SERVER, + EntityKind.SOFTWARE); + // --- Name public static Field mkNameField(Field idCompareField, Field kindCompareField, Collection searchEntityKinds) { - return NAME_RESOLVER.mkField(idCompareField, kindCompareField, searchEntityKinds); + return mkField( + idCompareField, + kindCompareField, + searchEntityKinds, + CommonTableFields::nameField); } public static Field mkNameField(Field idCompareField, Field kindCompareField) { - return NAME_RESOLVER.mkField(idCompareField, kindCompareField, NAME_RESOLVER.getSupportedEntityKinds()); + return mkNameField( + idCompareField, + kindCompareField, + DEFAULT_NAME_ENTITIES); } @@ -70,12 +124,19 @@ public static Field mkNameField(Field idCompareField, public static Field mkExternalIdField(Field idCompareField, Field kindCompareField, Collection searchEntityKinds) { - return EXTERNAL_ID_RESOLVER.mkField(idCompareField, kindCompareField, searchEntityKinds); + return mkField( + idCompareField, + kindCompareField, + searchEntityKinds, + CommonTableFields::externalIdField); } public static Field mkExternalIdField(Field idCompareField, Field kindCompareField) { - return EXTERNAL_ID_RESOLVER.mkField(idCompareField, kindCompareField, EXTERNAL_ID_RESOLVER.getSupportedEntityKinds()); + return mkExternalIdField( + idCompareField, + kindCompareField, + DEFAULT_EXTERNAL_ID_ENTITIES); } @@ -84,92 +145,22 @@ public static Field mkExternalIdField(Field idCompareField, public static Field mkEntityLifecycleField(Field idCompareField, Field kindCompareField, Collection searchEntityKinds) { - return LIFECYCLE_RESOLVER.mkField(idCompareField, kindCompareField, searchEntityKinds); + return mkField( + idCompareField, + kindCompareField, + searchEntityKinds, + CommonTableFields::lifecycleField); } public static Field mkEntityLifecycleField(Field idCompareField, Field kindCompareField) { - return LIFECYCLE_RESOLVER.mkField(idCompareField, kindCompareField, LIFECYCLE_RESOLVER.getSupportedEntityKinds()); + return mkEntityLifecycleField( + idCompareField, + kindCompareField, + DEFAULT_LIFECYCLE_ENTITIES); } - // --- Internals ---------------------- - - private static final InlineSelectFieldFactory NAME_RESOLVER = new InlineSelectFieldFactory(mkNameFieldMappings()); - private static final InlineSelectFieldFactory EXTERNAL_ID_RESOLVER = new InlineSelectFieldFactory(mkExternalIdMappings()); - private static final InlineSelectFieldFactory LIFECYCLE_RESOLVER = new InlineSelectFieldFactory(mkLifecycleFieldMappings()); - - private static Map, Field>> mkNameFieldMappings() { - Map, Field>> mappings = new HashMap<>(); - mappings.put(EntityKind.ACTOR, tuple(ACTOR, ACTOR.ID, ACTOR.NAME)); - mappings.put(EntityKind.ALLOCATION_SCHEME, tuple(ALLOCATION_SCHEME, ALLOCATION_SCHEME.ID, ALLOCATION_SCHEME.NAME)); - mappings.put(EntityKind.APPLICATION, tuple(APPLICATION, APPLICATION.ID, APPLICATION.NAME)); - mappings.put(EntityKind.APP_GROUP, tuple(APPLICATION_GROUP, APPLICATION_GROUP.ID, APPLICATION_GROUP.NAME)); - mappings.put(EntityKind.CHANGE_INITIATIVE, tuple(CHANGE_INITIATIVE, CHANGE_INITIATIVE.ID, CHANGE_INITIATIVE.NAME)); - mappings.put(EntityKind.CHANGE_SET, tuple(CHANGE_SET, CHANGE_SET.ID, CHANGE_SET.NAME)); - mappings.put(EntityKind.DATA_TYPE, tuple(DATA_TYPE, DATA_TYPE.ID, DATA_TYPE.NAME)); - mappings.put(EntityKind.END_USER_APPLICATION, tuple(END_USER_APPLICATION, END_USER_APPLICATION.ID, END_USER_APPLICATION.NAME)); - mappings.put(EntityKind.ENTITY_RELATIONSHIP, tuple(ENTITY_RELATIONSHIP, ENTITY_RELATIONSHIP.ID, DSL.val("Entity Relationship"))); - mappings.put(EntityKind.ENTITY_STATISTIC, tuple(ENTITY_STATISTIC_DEFINITION, ENTITY_STATISTIC_DEFINITION.ID, ENTITY_STATISTIC_DEFINITION.NAME)); - mappings.put(EntityKind.FLOW_CLASSIFICATION_RULE, tuple(FLOW_CLASSIFICATION_RULE, FLOW_CLASSIFICATION_RULE.ID, DSL.val("Flow Classification Rule"))); - mappings.put(EntityKind.FLOW_DIAGRAM, tuple(FLOW_DIAGRAM, FLOW_DIAGRAM.ID, FLOW_DIAGRAM.NAME)); - mappings.put(EntityKind.INVOLVEMENT_KIND, tuple(INVOLVEMENT_KIND, INVOLVEMENT_KIND.ID, INVOLVEMENT_KIND.NAME)); - mappings.put(EntityKind.LEGAL_ENTITY, tuple(LEGAL_ENTITY, LEGAL_ENTITY.ID, LEGAL_ENTITY.NAME)); - mappings.put(EntityKind.LEGAL_ENTITY_RELATIONSHIP, tuple(LEGAL_ENTITY_RELATIONSHIP, LEGAL_ENTITY_RELATIONSHIP.ID, DSL.val("Legal Entity Relationship"))); - mappings.put(EntityKind.LICENCE, tuple(LICENCE, LICENCE.ID, LICENCE.NAME)); - mappings.put(EntityKind.LOGICAL_DATA_FLOW, tuple(LOGICAL_FLOW, LOGICAL_FLOW.ID, DSL.val("Logical Flow"))); - mappings.put(EntityKind.MEASURABLE, tuple(MEASURABLE, MEASURABLE.ID, MEASURABLE.NAME)); - mappings.put(EntityKind.MEASURABLE_RATING, tuple(MEASURABLE_RATING, MEASURABLE_RATING.ID, DSL.val("Measurable Rating"))); - mappings.put(EntityKind.MEASURABLE_CATEGORY, tuple(MEASURABLE_CATEGORY, MEASURABLE_CATEGORY.ID, MEASURABLE_CATEGORY.NAME)); - mappings.put(EntityKind.ORG_UNIT, tuple(ORGANISATIONAL_UNIT, ORGANISATIONAL_UNIT.ID, ORGANISATIONAL_UNIT.NAME)); - mappings.put(EntityKind.PERSON, tuple(PERSON, PERSON.ID, PERSON.DISPLAY_NAME)); - mappings.put(EntityKind.PHYSICAL_FLOW, tuple(PHYSICAL_FLOW, PHYSICAL_FLOW.ID, DSL.val("Physical Flow"))); - mappings.put(EntityKind.PHYSICAL_SPECIFICATION, tuple(PHYSICAL_SPECIFICATION, PHYSICAL_SPECIFICATION.ID, PHYSICAL_SPECIFICATION.NAME)); - mappings.put(EntityKind.SERVER, tuple(SERVER_INFORMATION, SERVER_INFORMATION.ID, SERVER_INFORMATION.HOSTNAME)); - mappings.put(EntityKind.SOFTWARE, tuple(SOFTWARE_PACKAGE, SOFTWARE_PACKAGE.ID, SOFTWARE_PACKAGE.NAME)); - return mappings; - } - - private static Map, Field>> mkLifecycleFieldMappings() { - Map, Field>> mappings = new HashMap<>(); - mappings.put(EntityKind.ACTOR, tuple(ACTOR, ACTOR.ID, DSL.val(EntityLifecycleStatus.ACTIVE.name()))); - mappings.put(EntityKind.APPLICATION, tuple(APPLICATION, APPLICATION.ID, APPLICATION.ENTITY_LIFECYCLE_STATUS)); - mappings.put(EntityKind.CHANGE_INITIATIVE, tuple(CHANGE_INITIATIVE, CHANGE_INITIATIVE.ID, DSL.val(EntityLifecycleStatus.ACTIVE.name()))); - mappings.put(EntityKind.DATA_TYPE, tuple(DATA_TYPE, DATA_TYPE.ID, DSL.val(EntityLifecycleStatus.ACTIVE.name()))); - mappings.put(EntityKind.LEGAL_ENTITY, tuple(LEGAL_ENTITY, LEGAL_ENTITY.ID, LEGAL_ENTITY.ENTITY_LIFECYCLE_STATUS)); - mappings.put(EntityKind.LOGICAL_DATA_ELEMENT, tuple(LOGICAL_DATA_ELEMENT, LOGICAL_DATA_ELEMENT.ID, LOGICAL_DATA_ELEMENT.ENTITY_LIFECYCLE_STATUS)); - mappings.put(EntityKind.LOGICAL_DATA_FLOW, tuple(LOGICAL_FLOW, LOGICAL_FLOW.ID, LOGICAL_FLOW.ENTITY_LIFECYCLE_STATUS)); - mappings.put(EntityKind.MEASURABLE, tuple(MEASURABLE, MEASURABLE.ID, MEASURABLE.ENTITY_LIFECYCLE_STATUS)); - mappings.put(EntityKind.PHYSICAL_FLOW, tuple(PHYSICAL_FLOW, PHYSICAL_FLOW.ID, PHYSICAL_FLOW.ENTITY_LIFECYCLE_STATUS)); - return mappings; - } - - private static Map,Field>> mkExternalIdMappings() { - Map, Field>> mappings = new HashMap<>(); - mappings.put(EntityKind.ACTOR, tuple(ACTOR, ACTOR.ID, ACTOR.EXTERNAL_ID)); - mappings.put(EntityKind.APPLICATION, tuple(APPLICATION, APPLICATION.ID, APPLICATION.ASSET_CODE)); - mappings.put(EntityKind.CHANGE_INITIATIVE, tuple(CHANGE_INITIATIVE, CHANGE_INITIATIVE.ID, CHANGE_INITIATIVE.EXTERNAL_ID)); - mappings.put(EntityKind.CHANGE_SET, tuple(CHANGE_SET, CHANGE_SET.ID, CHANGE_SET.EXTERNAL_ID)); - mappings.put(EntityKind.DATA_TYPE, tuple(DATA_TYPE, DATA_TYPE.ID, DATA_TYPE.CODE)); - mappings.put(EntityKind.END_USER_APPLICATION, tuple(END_USER_APPLICATION, END_USER_APPLICATION.ID, END_USER_APPLICATION.EXTERNAL_ID)); - mappings.put(EntityKind.LOGICAL_DATA_FLOW, tuple(LOGICAL_FLOW, LOGICAL_FLOW.ID, LOGICAL_FLOW.EXTERNAL_ID)); - mappings.put(EntityKind.LEGAL_ENTITY, tuple(LEGAL_ENTITY, LEGAL_ENTITY.ID, LEGAL_ENTITY.EXTERNAL_ID)); - mappings.put(EntityKind.MEASURABLE, tuple(MEASURABLE, MEASURABLE.ID, MEASURABLE.EXTERNAL_ID)); - mappings.put(EntityKind.MEASURABLE_CATEGORY, tuple(MEASURABLE_CATEGORY, MEASURABLE_CATEGORY.ID, MEASURABLE_CATEGORY.EXTERNAL_ID)); - mappings.put(EntityKind.PERSON, tuple(PERSON, PERSON.ID, PERSON.EMPLOYEE_ID)); - mappings.put(EntityKind.PHYSICAL_FLOW, tuple(PHYSICAL_FLOW, PHYSICAL_FLOW.ID, PHYSICAL_FLOW.EXTERNAL_ID)); - mappings.put(EntityKind.PHYSICAL_SPECIFICATION, tuple(PHYSICAL_SPECIFICATION, PHYSICAL_SPECIFICATION.ID, PHYSICAL_SPECIFICATION.EXTERNAL_ID)); - mappings.put(EntityKind.SERVER, tuple(SERVER_INFORMATION, SERVER_INFORMATION.ID, SERVER_INFORMATION.EXTERNAL_ID)); - mappings.put(EntityKind.SOFTWARE, tuple(SOFTWARE_PACKAGE, SOFTWARE_PACKAGE.ID, SOFTWARE_PACKAGE.EXTERNAL_ID)); - return mappings; - } - - private final Map, Field>> mappings; - - private InlineSelectFieldFactory(Map, Field>> mappings) { - checkNotNull(mappings, "mappings cannot be null"); - this.mappings = mappings; - } /** * Creates a derived field to fetch entity names, given fields to compare id and kinds @@ -221,25 +212,31 @@ private InlineSelectFieldFactory(Map, Fiel * @param searchEntityKinds list of expected entity kinds in the @kindCompareField * @return {@code CASE} field to fetch entity name for each record */ - private Field mkField(Field idCompareField, - Field kindCompareField, - Collection searchEntityKinds) { + private static Field mkField(Field idCompareField, + Field kindCompareField, + Collection searchEntityKinds, + Function, Field> targetFieldResolver) { checkNotNull(idCompareField, "idCompareField cannot be null"); checkNotNull(kindCompareField, "kindCompareField cannot be null"); checkNotNull(searchEntityKinds, "searchEntityKinds cannot be null"); - // create case condition and corresponding select statement pairs - List>>> caseSteps = mappings.entrySet().stream() - .filter(e -> searchEntityKinds.contains(e.getKey())) - .map(e -> tuple(kindCompareField.eq(val(e.getKey().name())), - mkFieldSelect(e.getValue(), idCompareField))) + List>>> caseSteps = searchEntityKinds + .stream() + .map(JooqUtilities::determineCommonTableFields) + .map(ctf -> tuple( + kindCompareField.eq(val(ctf.entityKind().name())), + DSL.select(Optional + .ofNullable(targetFieldResolver.apply(ctf)) + .orElse(CommonTableFields.NA_FIELD_VAL)) + .from(ctf.table()) + .where(ctf.idField().eq(idCompareField)))) .collect(toList()); // form the where condition field // jOOQ doesn't seem to allow creation of case statements // through a clean factory method, hence this logic CaseConditionStep caseField = null; - for (Tuple2>> caseStep : caseSteps) { + for (Tuple2>> caseStep : caseSteps) { if (caseField == null) { caseField = DSL.when(caseStep.v1(), caseStep.v2()); } else { @@ -250,37 +247,4 @@ private Field mkField(Field idCompareField, return caseField; } - - /** - * Similar to the three arg version except this one tries all supported entities. - * As such there is a minor performance penalty - but gives maximum flexibility. - * @param idCompareField - * @param kindCompareField - * @return - */ - private Field mkField(Field idCompareField, - Field kindCompareField) { - return mkField(idCompareField, kindCompareField, getSupportedEntityKinds()); - } - - - private Select> mkFieldSelect(Tuple3, Field> mapping, - Field idCompareField) { - // form the query to fetch entity names - // - // v1: entity table - // v3: name field in the entity table - // v2: id field in the entity table - // - // eg: select name from application where id = entity_statistic_value.entity_id - // - return DSL.select(mapping.v3()) - .from(mapping.v1()) - .where(mapping.v2().eq(idCompareField)); - } - - - private Set getSupportedEntityKinds() { - return mappings.keySet(); - } } diff --git a/waltz-data/src/main/java/org/finos/waltz/data/JooqUtilities.java b/waltz-data/src/main/java/org/finos/waltz/data/JooqUtilities.java index 3ed57cba21..cb499eb785 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/JooqUtilities.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/JooqUtilities.java @@ -24,32 +24,11 @@ import org.finos.waltz.model.EndOfLifeStatus; import org.finos.waltz.model.EntityKind; import org.finos.waltz.model.EntityReference; -import org.finos.waltz.model.ImmutableCommonTableFields; import org.finos.waltz.model.ImmutableEntityReference; import org.finos.waltz.model.tally.ImmutableOrderedTally; import org.finos.waltz.model.tally.ImmutableTally; import org.finos.waltz.model.tally.OrderedTally; import org.finos.waltz.model.tally.Tally; -import org.finos.waltz.schema.Tables; -import org.finos.waltz.schema.tables.Actor; -import org.finos.waltz.schema.tables.Application; -import org.finos.waltz.schema.tables.ApplicationGroup; -import org.finos.waltz.schema.tables.AssessmentDefinition; -import org.finos.waltz.schema.tables.ChangeInitiative; -import org.finos.waltz.schema.tables.ComplexityKind; -import org.finos.waltz.schema.tables.CostKind; -import org.finos.waltz.schema.tables.DataType; -import org.finos.waltz.schema.tables.EntityStatisticDefinition; -import org.finos.waltz.schema.tables.FlowClassification; -import org.finos.waltz.schema.tables.FlowClassificationRule; -import org.finos.waltz.schema.tables.InvolvementKind; -import org.finos.waltz.schema.tables.Measurable; -import org.finos.waltz.schema.tables.MeasurableCategory; -import org.finos.waltz.schema.tables.MeasurableRating; -import org.finos.waltz.schema.tables.OrganisationalUnit; -import org.finos.waltz.schema.tables.PhysicalFlow; -import org.finos.waltz.schema.tables.SurveyQuestion; -import org.finos.waltz.schema.tables.SurveyTemplate; import org.finos.waltz.schema.tables.records.ChangeLogRecord; import org.jooq.Batch; import org.jooq.CommonTableExpression; @@ -424,246 +403,13 @@ public static int summarizeResults(int[] rcs) { } - public static CommonTableFields determineCommonTableFields(EntityKind kind) { return determineCommonTableFields(kind, null); } public static CommonTableFields determineCommonTableFields(EntityKind kind, String alias) { - switch (kind) { - case ACTOR: - Actor actor = alias == null ? Tables.ACTOR : Tables.ACTOR.as(alias); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.ACTOR) - .table(actor) - .idField(actor.ID) - .parentIdField(null) - .nameField(actor.NAME) - .descriptionField(actor.DESCRIPTION) - .externalIdField(actor.EXTERNAL_ID) - .build(); - case APPLICATION: - Application app = alias == null ? Tables.APPLICATION : Tables.APPLICATION.as(alias); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.APPLICATION) - .table(app) - .idField(app.ID) - .parentIdField(null) - .nameField(app.NAME) - .descriptionField(app.DESCRIPTION) - .externalIdField(app.ASSET_CODE) - .build(); - case APP_GROUP: - ApplicationGroup ag = alias == null ? Tables.APPLICATION_GROUP : Tables.APPLICATION_GROUP.as(alias); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.APP_GROUP) - .table(ag) - .idField(ag.ID) - .parentIdField(null) - .nameField(ag.NAME) - .descriptionField(ag.DESCRIPTION) - .externalIdField(ag.EXTERNAL_ID) - .build(); - case ASSESSMENT_DEFINITION: - AssessmentDefinition ad = alias == null ? Tables.ASSESSMENT_DEFINITION : Tables.ASSESSMENT_DEFINITION.as("alias"); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.ASSESSMENT_DEFINITION) - .table(ad) - .idField(ad.ID) - .parentIdField(null) - .nameField(ad.NAME) - .descriptionField(ad.DESCRIPTION) - .externalIdField(ad.EXTERNAL_ID) - .build(); - case CHANGE_INITIATIVE: - ChangeInitiative ci = alias == null ? Tables.CHANGE_INITIATIVE : Tables.CHANGE_INITIATIVE.as(alias); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.CHANGE_INITIATIVE) - .table(ci) - .idField(ci.ID) - .parentIdField(ci.PARENT_ID) - .nameField(ci.NAME) - .descriptionField(ci.DESCRIPTION) - .externalIdField(ci.EXTERNAL_ID) - .build(); - case COMPLEXITY_KIND: - ComplexityKind cxk = alias == null ? Tables.COMPLEXITY_KIND : Tables.COMPLEXITY_KIND.as(alias); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.COMPLEXITY_KIND) - .table(cxk) - .idField(cxk.ID) - .parentIdField(null) - .nameField(cxk.NAME) - .descriptionField(cxk.DESCRIPTION) - .externalIdField(cxk.EXTERNAL_ID) - .build(); - case COST_KIND: - CostKind ck = alias == null ? Tables.COST_KIND : Tables.COST_KIND.as(alias); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.COST_KIND) - .table(ck) - .idField(ck.ID) - .parentIdField(null) - .nameField(ck.NAME) - .descriptionField(ck.DESCRIPTION) - .externalIdField(ck.EXTERNAL_ID) - .build(); - case DATA_TYPE: - DataType dt = alias == null ? Tables.DATA_TYPE : Tables.DATA_TYPE.as(alias); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.DATA_TYPE) - .table(dt) - .idField(dt.ID) - .parentIdField(dt.PARENT_ID) - .nameField(dt.NAME) - .descriptionField(dt.DESCRIPTION) - .externalIdField(dt.CODE) - .build(); - case ENTITY_STATISTIC: - EntityStatisticDefinition esd = alias == null ? Tables.ENTITY_STATISTIC_DEFINITION : Tables.ENTITY_STATISTIC_DEFINITION.as(alias); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.ENTITY_STATISTIC) - .table(esd) - .idField(esd.ID) - .parentIdField(esd.PARENT_ID) - .nameField(esd.NAME) - .descriptionField(esd.DESCRIPTION) - .externalIdField(esd.EXTERNAL_ID) - .build(); - case FLOW_CLASSIFICATION_RULE: - FlowClassificationRule fcr = alias == null ? Tables.FLOW_CLASSIFICATION_RULE : Tables.FLOW_CLASSIFICATION_RULE.as(alias); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.FLOW_CLASSIFICATION_RULE) - .table(fcr) - .idField(fcr.ID) - .parentIdField(null) - .nameField(null) - .descriptionField(null) - .externalIdField(null) - .build(); - case FLOW_CLASSIFICATION: - FlowClassification fc = alias == null ? Tables.FLOW_CLASSIFICATION : Tables.FLOW_CLASSIFICATION.as(alias); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.FLOW_CLASSIFICATION) - .table(fc) - .idField(fc.ID) - .parentIdField(null) - .nameField(fc.NAME) - .descriptionField(fc.DESCRIPTION) - .externalIdField(fc.CODE) - .build(); - case INVOLVEMENT_KIND: - InvolvementKind ik = alias == null ? Tables.INVOLVEMENT_KIND : Tables.INVOLVEMENT_KIND.as(alias); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.INVOLVEMENT_KIND) - .table(ik) - .idField(ik.ID) - .parentIdField(null) - .nameField(ik.NAME) - .descriptionField(ik.DESCRIPTION) - .externalIdField(ik.EXTERNAL_ID) - .build(); - case MEASURABLE: - Measurable m = alias == null ? Tables.MEASURABLE : Tables.MEASURABLE.as(alias); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.MEASURABLE) - .table(m) - .idField(m.ID) - .parentIdField(m.PARENT_ID) - .nameField(m.NAME) - .descriptionField(m.DESCRIPTION) - .externalIdField(m.EXTERNAL_ID) - .build(); - case MEASURABLE_CATEGORY: - MeasurableCategory mc = alias == null ? Tables.MEASURABLE_CATEGORY : Tables.MEASURABLE_CATEGORY.as(alias); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.MEASURABLE_CATEGORY) - .table(mc) - .idField(mc.ID) - .parentIdField(null) - .nameField(mc.NAME) - .descriptionField(mc.DESCRIPTION) - .externalIdField(mc.EXTERNAL_ID) - .build(); - case MEASURABLE_RATING: - MeasurableRating mr = alias == null ? Tables.MEASURABLE_RATING : Tables.MEASURABLE_RATING.as(alias); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.MEASURABLE_RATING) - .table(mr) - .idField(mr.ID) - .parentIdField(null) - .nameField(null) - .descriptionField(mr.DESCRIPTION) - .externalIdField(null) - .build(); - case ORG_UNIT: - OrganisationalUnit ou = alias == null ? Tables.ORGANISATIONAL_UNIT : Tables.ORGANISATIONAL_UNIT.as(alias); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.ORG_UNIT) - .table(ou) - .idField(ou.ID) - .parentIdField(ou.PARENT_ID) - .nameField(ou.NAME) - .descriptionField(ou.DESCRIPTION) - .externalIdField(ou.EXTERNAL_ID) - .build(); - case SURVEY_QUESTION: - SurveyQuestion sq = alias == null ? Tables.SURVEY_QUESTION : Tables.SURVEY_QUESTION.as(alias); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.SURVEY_QUESTION) - .table(sq) - .idField(sq.ID) - .parentIdField(null) - .nameField(sq.QUESTION_TEXT) - .descriptionField(sq.HELP_TEXT) - .externalIdField(sq.EXTERNAL_ID) - .build(); - case SURVEY_TEMPLATE: - SurveyTemplate st = alias == null ? Tables.SURVEY_TEMPLATE : Tables.SURVEY_TEMPLATE.as(alias); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.SURVEY_TEMPLATE) - .table(st) - .idField(st.ID) - .parentIdField(null) - .nameField(st.NAME) - .descriptionField(st.DESCRIPTION) - .externalIdField(st.EXTERNAL_ID) - .build(); - case PHYSICAL_FLOW: - PhysicalFlow pf = alias == null ? Tables.PHYSICAL_FLOW : Tables.PHYSICAL_FLOW.as(alias); - return ImmutableCommonTableFields - .builder() - .entityKind(EntityKind.PHYSICAL_FLOW) - .table(pf) - .idField(pf.ID) - .parentIdField(null) - .nameField(pf.NAME) - .descriptionField(pf.DESCRIPTION) - .externalIdField(pf.EXTERNAL_ID) - .build(); - default: - throw new UnsupportedOperationException("Cannot determine table fields for entity kind:" + kind); - } + return CommonTableFieldsRegistry.determineCommonTableFields(kind, alias); } - } diff --git a/waltz-data/src/main/java/org/finos/waltz/data/assessment_rating/AssessmentRatingDao.java b/waltz-data/src/main/java/org/finos/waltz/data/assessment_rating/AssessmentRatingDao.java index 1fb0073513..1c00f8c5fe 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/assessment_rating/AssessmentRatingDao.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/assessment_rating/AssessmentRatingDao.java @@ -74,9 +74,12 @@ import static org.finos.waltz.common.Checks.checkNotNull; import static org.finos.waltz.common.CollectionUtilities.isEmpty; import static org.finos.waltz.common.DateTimeUtilities.toLocalDateTime; -import static org.finos.waltz.common.ListUtilities.newArrayList; import static org.finos.waltz.common.MapUtilities.groupBy; -import static org.finos.waltz.common.SetUtilities.*; +import static org.finos.waltz.common.SetUtilities.asSet; +import static org.finos.waltz.common.SetUtilities.intersection; +import static org.finos.waltz.common.SetUtilities.map; +import static org.finos.waltz.common.SetUtilities.maybeAdd; +import static org.finos.waltz.common.SetUtilities.union; import static org.finos.waltz.common.StringUtilities.mkSafe; import static org.finos.waltz.common.StringUtilities.notEmpty; import static org.finos.waltz.common.StringUtilities.sanitizeCharacters; @@ -98,18 +101,15 @@ public class AssessmentRatingDao { private static final Field ENTITY_NAME_FIELD = InlineSelectFieldFactory.mkNameField( ar.ENTITY_ID, - ar.ENTITY_KIND, - newArrayList(EntityKind.values())).as("entity_name"); + ar.ENTITY_KIND).as("entity_name"); private static final Field ENTITY_LIFECYCLE_FIELD = InlineSelectFieldFactory.mkEntityLifecycleField( ar.ENTITY_ID, - ar.ENTITY_KIND, - newArrayList(EntityKind.values())).as("entity_lifecycle_status"); + ar.ENTITY_KIND).as("entity_lifecycle_status"); private static final Field ENTITY_EXTID_FIELD = InlineSelectFieldFactory.mkExternalIdField( ar.ENTITY_ID, - ar.ENTITY_KIND, - newArrayList(EntityKind.values())).as("entity_external_id"); + ar.ENTITY_KIND).as("entity_external_id"); private static final RecordMapper TO_DOMAIN_MAPPER = r -> { AssessmentRatingRecord record = r.into(ar); diff --git a/waltz-data/src/main/java/org/finos/waltz/data/attestation/AttestationRunDao.java b/waltz-data/src/main/java/org/finos/waltz/data/attestation/AttestationRunDao.java index 84cc7d6214..8bbe1eadee 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/attestation/AttestationRunDao.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/attestation/AttestationRunDao.java @@ -60,7 +60,6 @@ import static org.finos.waltz.common.DateTimeUtilities.nowUtcTimestamp; import static org.finos.waltz.common.DateTimeUtilities.toLocalDate; import static org.finos.waltz.common.DateTimeUtilities.toSqlDate; -import static org.finos.waltz.common.ListUtilities.newArrayList; import static org.finos.waltz.schema.tables.AttestationInstance.ATTESTATION_INSTANCE; import static org.finos.waltz.schema.tables.AttestationInstanceRecipient.ATTESTATION_INSTANCE_RECIPIENT; import static org.finos.waltz.schema.tables.AttestationRun.ATTESTATION_RUN; @@ -71,14 +70,12 @@ public class AttestationRunDao { private static final Field ENTITY_NAME_FIELD = InlineSelectFieldFactory.mkNameField( ATTESTATION_RUN.SELECTOR_ENTITY_ID, - ATTESTATION_RUN.SELECTOR_ENTITY_KIND, - newArrayList(EntityKind.values())) + ATTESTATION_RUN.SELECTOR_ENTITY_KIND) .as("entity_name"); private static final Field ATTESTED_ENTITY_NAME_FIELD = InlineSelectFieldFactory.mkNameField( ATTESTATION_RUN.ATTESTED_ENTITY_ID, - ATTESTATION_RUN.ATTESTED_ENTITY_KIND, - newArrayList(EntityKind.values())) + ATTESTATION_RUN.ATTESTED_ENTITY_KIND) .as("attested_entity_name"); private static final Field COMPLETE_SUM = DSL.sum(DSL diff --git a/waltz-data/src/main/java/org/finos/waltz/data/change_set/ChangeSetDao.java b/waltz-data/src/main/java/org/finos/waltz/data/change_set/ChangeSetDao.java index 8683bbf63d..567d079542 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/change_set/ChangeSetDao.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/change_set/ChangeSetDao.java @@ -42,7 +42,6 @@ import static org.finos.waltz.common.Checks.checkNotNull; import static org.finos.waltz.common.DateTimeUtilities.toLocalDateTime; -import static org.finos.waltz.common.ListUtilities.newArrayList; import static org.finos.waltz.schema.Tables.CHANGE_SET; import static org.finos.waltz.schema.Tables.INVOLVEMENT; @@ -54,8 +53,7 @@ public class ChangeSetDao { private static final Field ENTITY_NAME_FIELD = InlineSelectFieldFactory.mkNameField( CHANGE_SET.PARENT_ENTITY_ID, - CHANGE_SET.PARENT_ENTITY_KIND, - newArrayList(EntityKind.values())) + CHANGE_SET.PARENT_ENTITY_KIND) .as("entity_name"); public static final RecordMapper TO_DOMAIN_MAPPER = r -> { diff --git a/waltz-data/src/main/java/org/finos/waltz/data/involvement/InvolvementDao.java b/waltz-data/src/main/java/org/finos/waltz/data/involvement/InvolvementDao.java index 6d6c48eee4..073d704815 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/involvement/InvolvementDao.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/involvement/InvolvementDao.java @@ -51,9 +51,12 @@ import java.util.function.Function; import java.util.stream.IntStream; -import static java.util.stream.Collectors.*; +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.mapping; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toSet; import static org.finos.waltz.common.Checks.checkNotNull; -import static org.finos.waltz.common.ListUtilities.newArrayList; import static org.finos.waltz.schema.Tables.CHANGE_INITIATIVE; import static org.finos.waltz.schema.Tables.END_USER_APPLICATION; import static org.finos.waltz.schema.tables.Involvement.INVOLVEMENT; @@ -69,8 +72,7 @@ public class InvolvementDao { private static final Field ENTITY_NAME_FIELD = InlineSelectFieldFactory .mkNameField( INVOLVEMENT.ENTITY_ID, - INVOLVEMENT.ENTITY_KIND, - newArrayList(EntityKind.values())) + INVOLVEMENT.ENTITY_KIND) .as("entity_name"); private final RecordMapper TO_MODEL_MAPPER = r -> { diff --git a/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyInstanceDao.java b/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyInstanceDao.java index 403b0917e1..d9d02ff0de 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyInstanceDao.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyInstanceDao.java @@ -81,7 +81,6 @@ import static org.finos.waltz.common.DateTimeUtilities.toLocalDate; import static org.finos.waltz.common.DateTimeUtilities.toSqlDate; import static org.finos.waltz.common.DateTimeUtilities.today; -import static org.finos.waltz.common.ListUtilities.newArrayList; import static org.finos.waltz.common.StringUtilities.lower; import static org.finos.waltz.data.JooqUtilities.maybeReadRef; import static org.finos.waltz.model.EntityReference.mkRef; @@ -116,15 +115,13 @@ public class SurveyInstanceDao { private static final Field ENTITY_NAME_FIELD = InlineSelectFieldFactory .mkNameField( si.ENTITY_ID, - si.ENTITY_KIND, - newArrayList(EntityKind.values())) + si.ENTITY_KIND) .as("entity_name"); private static final Field EXTERNAL_ID_FIELD = InlineSelectFieldFactory .mkExternalIdField( si.ENTITY_ID, - si.ENTITY_KIND, - newArrayList(EntityKind.values())) + si.ENTITY_KIND) .as("external_id"); diff --git a/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyQuestionResponseDao.java b/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyQuestionResponseDao.java index bd572a0d38..0672f32139 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyQuestionResponseDao.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/survey/SurveyQuestionResponseDao.java @@ -92,8 +92,7 @@ public class SurveyQuestionResponseDao { private static final Field EXTERNAL_ID_FIELD = InlineSelectFieldFactory.mkExternalIdField( SURVEY_QUESTION_LIST_RESPONSE.ENTITY_ID, - SURVEY_QUESTION_LIST_RESPONSE.ENTITY_KIND, - newArrayList(EntityKind.values())); + SURVEY_QUESTION_LIST_RESPONSE.ENTITY_KIND); private static final RecordMapper TO_DOMAIN_MAPPER = r -> { SurveyQuestionResponseRecord record = r.into(SURVEY_QUESTION_RESPONSE); diff --git a/waltz-model/src/main/java/org/finos/waltz/model/CommonTableFields.java b/waltz-model/src/main/java/org/finos/waltz/model/CommonTableFields.java index ff83e5280b..4a30ee302b 100644 --- a/waltz-model/src/main/java/org/finos/waltz/model/CommonTableFields.java +++ b/waltz-model/src/main/java/org/finos/waltz/model/CommonTableFields.java @@ -2,13 +2,18 @@ import org.immutables.value.Value; import org.jooq.Condition; +import org.jooq.Field; +import org.jooq.Param; import org.jooq.Record; import org.jooq.Table; -import org.jooq.TableField; import org.jooq.impl.DSL; @Value.Immutable public interface CommonTableFields { + + Param NA_FIELD_VAL = DSL.val("n/a"); + Param ALWAYS_ACTIVE_FIELD_VAL = DSL.val(EntityLifecycleStatus.ACTIVE.name()); + EntityKind entityKind(); default boolean hierarchical() { @@ -17,19 +22,22 @@ default boolean hierarchical() { Table table(); - TableField idField(); + Field idField(); @Nullable - TableField nameField(); + Field nameField(); @Nullable - TableField descriptionField(); + Field descriptionField(); @Nullable - TableField parentIdField(); + Field parentIdField(); @Nullable - TableField externalIdField(); + Field externalIdField(); + + @Value.Default + default Field lifecycleField() { return ALWAYS_ACTIVE_FIELD_VAL; }; @Value.Default default Condition isActiveCondition() { diff --git a/waltz-web/src/main/java/org/finos/waltz/web/endpoints/extracts/AssessmentRatingExtractor.java b/waltz-web/src/main/java/org/finos/waltz/web/endpoints/extracts/AssessmentRatingExtractor.java index 49208164c9..a3b9a23834 100644 --- a/waltz-web/src/main/java/org/finos/waltz/web/endpoints/extracts/AssessmentRatingExtractor.java +++ b/waltz-web/src/main/java/org/finos/waltz/web/endpoints/extracts/AssessmentRatingExtractor.java @@ -20,7 +20,6 @@ import org.finos.waltz.data.InlineSelectFieldFactory; import org.finos.waltz.data.assessment_definition.AssessmentDefinitionDao; -import org.finos.waltz.model.EntityKind; import org.finos.waltz.model.assessment_definition.AssessmentDefinition; import org.finos.waltz.web.WebUtilities; import org.jooq.DSLContext; @@ -34,8 +33,9 @@ import java.sql.Timestamp; -import static org.finos.waltz.common.SetUtilities.asSet; -import static org.finos.waltz.schema.Tables.*; +import static org.finos.waltz.schema.Tables.ASSESSMENT_DEFINITION; +import static org.finos.waltz.schema.Tables.ASSESSMENT_RATING; +import static org.finos.waltz.schema.Tables.RATING_SCHEME_ITEM; import static spark.Spark.post; @@ -46,18 +46,15 @@ public class AssessmentRatingExtractor extends DirectQueryBasedDataExtractor { private final Field entityNameField = InlineSelectFieldFactory.mkNameField( ASSESSMENT_RATING.ENTITY_ID, - ASSESSMENT_RATING.ENTITY_KIND, - asSet(EntityKind.values())); + ASSESSMENT_RATING.ENTITY_KIND); private final Field entityExtIdField = InlineSelectFieldFactory.mkExternalIdField( ASSESSMENT_RATING.ENTITY_ID, - ASSESSMENT_RATING.ENTITY_KIND, - asSet(EntityKind.values())); + ASSESSMENT_RATING.ENTITY_KIND); private final Field entityLifecycleField = InlineSelectFieldFactory.mkEntityLifecycleField( ASSESSMENT_RATING.ENTITY_ID, - ASSESSMENT_RATING.ENTITY_KIND, - asSet(EntityKind.values())); + ASSESSMENT_RATING.ENTITY_KIND); private final AssessmentDefinitionDao assessmentDefinitionDao; diff --git a/waltz-web/src/main/java/org/finos/waltz/web/endpoints/extracts/LogicalFlowExtractor.java b/waltz-web/src/main/java/org/finos/waltz/web/endpoints/extracts/LogicalFlowExtractor.java index a42dd061a6..8f329659f7 100644 --- a/waltz-web/src/main/java/org/finos/waltz/web/endpoints/extracts/LogicalFlowExtractor.java +++ b/waltz-web/src/main/java/org/finos/waltz/web/endpoints/extracts/LogicalFlowExtractor.java @@ -45,6 +45,7 @@ import static java.util.stream.Collectors.toList; import static org.finos.waltz.common.ListUtilities.isEmpty; import static org.finos.waltz.common.ListUtilities.newArrayList; +import static org.finos.waltz.data.InlineSelectFieldFactory.mkExternalIdField; import static org.finos.waltz.data.InlineSelectFieldFactory.mkNameField; import static org.finos.waltz.model.EntityLifecycleStatus.REMOVED; import static org.finos.waltz.schema.Tables.*; @@ -67,6 +68,16 @@ public class LogicalFlowExtractor extends CustomDataExtractor { LOGICAL_FLOW.TARGET_ENTITY_KIND, newArrayList(EntityKind.APPLICATION, EntityKind.ACTOR)); + private static final Field SOURCE_EXT_ID_FIELD = mkExternalIdField( + LOGICAL_FLOW.SOURCE_ENTITY_ID, + LOGICAL_FLOW.SOURCE_ENTITY_KIND, + newArrayList(EntityKind.APPLICATION, EntityKind.ACTOR)); + + private static final Field TARGET_EXT_ID_FIELD = mkExternalIdField( + LOGICAL_FLOW.TARGET_ENTITY_ID, + LOGICAL_FLOW.TARGET_ENTITY_KIND, + newArrayList(EntityKind.APPLICATION, EntityKind.ACTOR)); + private static List staticHeaders = newArrayList( "Source", "Source Asset Code", @@ -115,25 +126,22 @@ private SelectConditionStep prepareQuery(DSLContext dsl, IdSelectionOpti Field sourceFlowId = LOGICAL_FLOW.ID.as("sourceFlowId"); Field targetFlowId = LOGICAL_FLOW.ID.as("targetFlowId"); - Select> sourceAppFlows = DSL.select(sourceFlowId) + Select> sourceAppFlows = DSL + .select(sourceFlowId) .from(LOGICAL_FLOW) .innerJoin(APPLICATION) .on(LOGICAL_FLOW.SOURCE_ENTITY_ID.eq(APPLICATION.ID)) .where(LOGICAL_FLOW.SOURCE_ENTITY_KIND.eq(EntityKind.APPLICATION.name())) .and(APPLICATION.ID.in(appIdSelector)); - Select> targetAppFlows = DSL.select(targetFlowId) + Select> targetAppFlows = DSL + .select(targetFlowId) .from(LOGICAL_FLOW) .innerJoin(APPLICATION) .on(LOGICAL_FLOW.TARGET_ENTITY_ID.eq(APPLICATION.ID)) .where(LOGICAL_FLOW.TARGET_ENTITY_KIND.eq(EntityKind.APPLICATION.name())) .and(APPLICATION.ID.in(appIdSelector)); - Field sourceAssetCodeField = DSL - .when(LOGICAL_FLOW.SOURCE_ENTITY_KIND.eq(EntityKind.APPLICATION.name()), - DSL.select(APPLICATION.ASSET_CODE) - .from(APPLICATION) - .where(APPLICATION.ID.eq(LOGICAL_FLOW.SOURCE_ENTITY_ID))); Field sourceOrgUnitNameField = DSL .when(LOGICAL_FLOW.SOURCE_ENTITY_KIND.eq(EntityKind.APPLICATION.name()), @@ -143,12 +151,6 @@ private SelectConditionStep prepareQuery(DSLContext dsl, IdSelectionOpti .on(ORGANISATIONAL_UNIT.ID.eq(APPLICATION.ORGANISATIONAL_UNIT_ID)) .where(APPLICATION.ID.eq(LOGICAL_FLOW.SOURCE_ENTITY_ID))); - Field targetAssetCodeField = DSL - .when(LOGICAL_FLOW.TARGET_ENTITY_KIND.eq(EntityKind.APPLICATION.name()), - DSL.select(APPLICATION.ASSET_CODE) - .from(APPLICATION) - .where(APPLICATION.ID.eq(LOGICAL_FLOW.TARGET_ENTITY_ID))); - Field targetOrgUnitNameField = DSL .when(LOGICAL_FLOW.TARGET_ENTITY_KIND.eq(EntityKind.APPLICATION.name()), DSL.select(ORGANISATIONAL_UNIT.NAME) @@ -159,10 +161,10 @@ private SelectConditionStep prepareQuery(DSLContext dsl, IdSelectionOpti return dsl .select(SOURCE_NAME_FIELD.as("Source"), - sourceAssetCodeField.as("Source Asset Code"), + SOURCE_EXT_ID_FIELD.as("Source Asset Code"), sourceOrgUnitNameField.as("Source Org Unit")) .select(TARGET_NAME_FIELD.as("Target"), - targetAssetCodeField.as("Target Asset Code"), + TARGET_EXT_ID_FIELD.as("Target Asset Code"), targetOrgUnitNameField.as("Target Org Unit")) .select(DATA_TYPE.NAME.as("Data Type")) .select(ENUM_VALUE.DISPLAY_NAME.as("Authoritativeness"))