diff --git a/shapechange-app/src/docs/asciidoc/transformations/Flattener.adoc b/shapechange-app/src/docs/asciidoc/transformations/Flattener.adoc index 851c725f..d036677c 100644 --- a/shapechange-app/src/docs/asciidoc/transformations/Flattener.adoc +++ b/shapechange-app/src/docs/asciidoc/transformations/Flattener.adoc @@ -1792,7 +1792,10 @@ Behavior: This parameter allows to identify the union types that shall NOT be flattened. The value of this parameter contains a (Java compliant) regular expression which, if it matches the name of a union type, marks -it to be excluded from type flattening. +it to be excluded from type flattening. Excluded union types are not +flattened and also not removed at the end of processing +_rule-trf-prop-flatten-types_, so properties that have such a union as +value type keep it - whether or not any property uses the union. NOTE: If you only want to flatten a certain set of union types from the schemas selected for processing, then you can use 'negative lookahead' diff --git a/shapechange-app/src/integrationtests/flattener/flattenTypes_excludeUnionTypes/reference/results/step1/flat.xsd b/shapechange-app/src/integrationtests/flattener/flattenTypes_excludeUnionTypes/reference/results/step1/flat.xsd new file mode 100644 index 00000000..9fc41202 --- /dev/null +++ b/shapechange-app/src/integrationtests/flattener/flattenTypes_excludeUnionTypes/reference/results/step1/flat.xsd @@ -0,0 +1,714 @@ + + + + + + + + + + + + + + + + + + + + + + + + CurveGeomAlias: CurveGeometryInfo FC definition. +NOTE CurveGeometryInfo FC definition. + + + + + + + + + + prop15Alias.valueOrReason-value-S: Prop15 AC definition. + + + + + prop15Alias.valueOrReason-value-I.L: Prop15 AC definition. + + + + + prop15Alias.valueOrReason-value-I.U: Prop15 AC definition. + + + + + prop15Alias.valueOrReason-reason: Prop15 AC definition. + + + + + + + + + + + + + + + + + + 1: enum1 of EnumerationA VC definition. + + + + + 2: enum2 of EnumerationA VC definition. + + + + + 3: enum3 of EnumerationA VC definition. + + + + + + + + + A: EnumA of EnumerationB VC definition. + + + + + B: EnumB of EnumerationB VC definition. + + + + + + + + + 1: enum1 of EnumerationX VC definition. + + + + + 2: enum2 of EnumerationX VC definition. + + + + + + + + + 1: enum1 of EnumerationY VC definition. + + + + + 2: enum2 of EnumerationY VC definition. + + + + + + + FeatureAttMetadataALIAS: FeatureAttMetadata FC definition. + + + + + + + + + propSourceInfoAlias: PropSourceInfo AC definition. +NOTE PropSourceInfo AC description! + + + + + + + + + + + + + + + + + + + + + + + + + + FT: FeatureEntity FC definition. +NOTE FeatureEntity FC description! + + + + + + + + + propInformationAlias: PropInformation AC definition. +NOTE PropInformation AC description! + + + + + + + + + + + + + + + propEnumerationAAlias.valueOrReason-reason: PropEnumerationA AC Definition. + + + + + propEnumerationAAlias.valueOrReason-value: PropEnumerationA AC Definition. + + + + + prop3Alias.valueOrReason-value: Prop3 AC definition. + + + + + prop3Alias.valueOrReason-reason: Prop3 AC definition. + + + + + propGeometryAlias.valueOrReason-reason: PropGeometry AC definition. + + + + + propGeometryAlias.valueOrReason-value: PropGeometry AC definition. + + + + + + + + + + + + + + + propMaxOccTestAlias.valueOrReason-value: PropMaxOccursTest AC definition. +NOTE PropMaxOccursTest AC description! + + + + + propMaxOccTestAlias.valueOrReason-reason: PropMaxOccursTest AC definition. +NOTE PropMaxOccursTest AC description! + + + + + propSourceInfoAlias: PropSourceInfo AC definition. +NOTE PropSourceInfo AC description! + + + + + + + + + + + + + + + + + + + + + + + + + + FT1: FEatureType1 FC definition. + + + + + + + + + prop20Alias.valueOrReason-reason: Prop20 AC definition. + + + + + prop20Alias.valueOrReason-value: Prop20 AC definition. + + + + + prop21Alias.valueOrReason-value: Prop21 AC definition. + + + + + prop21Alias.valueOrReason-reason: Prop21 AC definition. + + + + + + + + + + + + + + + + FT2: FeatureType2 FC definition. +NOTE FeatureType2 FC description! + + + + + + + + + prop30Alias.valueOrReason-reason: Prop30 AC definition +NOTE Prop30 AC description! + + + + + prop30Alias.valueOrReason-value: Prop30 AC definition +NOTE Prop30 AC description! + + + + + prop31Alias.valueOrReason-value: Prop31 AC definition. + + + + + prop31Alias.valueOrReason-reason: Prop31 AC definition. + + + + + prop32Alias.valueOrReason-value-S: Prop32 AC definition. +NOTE Prop32 AC description! + + + + + prop32Alias.valueOrReason-value-I.L: Prop32 AC definition. +NOTE Prop32 AC description! + + + + + prop32Alias.valueOrReason-value-I.U: Prop32 AC definition. +NOTE Prop32 AC description! + + + + + prop32Alias.valueOrReason-reason: Prop32 AC definition. +NOTE Prop32 AC description! + + + + + + + + + + + + + + + + + GeometryInfoAlias: GeometryInfo FC definition. +NOTE GeometryInfo FC description! + + + + + + + + + prop12Alias.valueOrReason-value: Prop12 AC definition. + + + + + prop12Alias.valueOrReason-reason: Prop12 AC definition. + + + + + propEnumerationBAlias.valueOrReason-reason: EnumerationB AC definition. + + + + + propEnumerationBAlias.valueOrReason-value: EnumerationB AC definition. + + + + + prop11Alias.valueOrReason: Prop11 AC definition. + + + + + + + + + + + + + + + + ZI005: Information FC definition. + + + + + + + + + prop7Alias.valueOrReason: Prop7 AC definition. + + + + + prop8Alias.valueOrReason-value: Prop8 AC Definition. + + + + + prop8Alias.valueOrReason-reason: Prop8 AC Definition. + + + + + + + + + + + + + + + + + + + + + + + + + + + + MultiCurveGeomAlias: MultiCurveGeometryInfo FC definition. + + + + + + + + + + + + + + + + + + + + + MultiPointGeomAlias: MultiPointGeometryInfo FC definition. + + + + + + + + + + + + + + + + + + + + + MultiSolidGeomAlias: MultiSolidGeometryInfo FC definition. + + + + + + + + + + + + + + + + + + + + + MultiSurfaceGeomAlias: MultiSurfaceGeometryInfo FC definition. + + + + + + + + + + + + + + + + + + + + + PointGeomAlias: PointGeometryInfo FC definition. +NOTE PointGeometryInfo FC definition. + + + + + + + + + + prop15Alias.valueOrReason-value-S: Prop15 AC definition. + + + + + prop15Alias.valueOrReason-value-I.L: Prop15 AC definition. + + + + + prop15Alias.valueOrReason-value-I.U: Prop15 AC definition. + + + + + prop15Alias.valueOrReason-reason: Prop15 AC definition. + + + + + + + + + + + + + + + + SolidGeomAlias: SolidGeometryInfo FC definition. + + + + + + + + + + + + + + + + + + + + + SourceInfoALIAS: SourceInfo FC definition. + + + + + + + + + prop9Alias: Prop9 AC definition. + + + + + prop10Alias-value: Prop10 AC definition +NOTE Prop10 AC description! + + + + + prop10Alias-reason: Prop10 AC definition +NOTE Prop10 AC description! + + + + + + + + + + + + + + + + + + + + + + + SurfaceGeomAlias: SurfaceGeometryInfo FC definition. +NOTE SurfaceGeometryInfo FC definition. + + + + + + + + + + + + + + + + + + + + + + + -999999: No Information + + + + + 0: Unknown + + + + + 995: The use of this enumerant depends on the choice of modeling implementation for 'Union' datatypes. Where the 'Union' may not be directly expressed and instead two 'storage locations' are specified, then it becomes necessary that the 'reason storage location' should be able to unambiguously express that the 'value storage location' does, indeed, have a value specified. Where the 'Union' may be directly expressed as a single 'storage location' then it is unnecessary (and not physically possible) to express that the 'value is specified' at the same time that a value is, indeed, specified. + + + + + 997: Unpopulated + + + + + 998: Not Applicable + + + + + 999: Other + + + + + diff --git a/shapechange-app/src/integrationtests/flattener/flattenTypes_excludeUnionTypes/testEA_Flattening_excludeUnionTypes.xml b/shapechange-app/src/integrationtests/flattener/flattenTypes_excludeUnionTypes/testEA_Flattening_excludeUnionTypes.xml new file mode 100644 index 00000000..0a73d8db --- /dev/null +++ b/shapechange-app/src/integrationtests/flattener/flattenTypes_excludeUnionTypes/testEA_Flattening_excludeUnionTypes.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shapechange-app/src/integrationtests/flattener/flattenTypes_excludeUnionTypes/testEA_Flattening_excludeUnionTypes_runWithSCXML.xml b/shapechange-app/src/integrationtests/flattener/flattenTypes_excludeUnionTypes/testEA_Flattening_excludeUnionTypes_runWithSCXML.xml new file mode 100644 index 00000000..ddc92511 --- /dev/null +++ b/shapechange-app/src/integrationtests/flattener/flattenTypes_excludeUnionTypes/testEA_Flattening_excludeUnionTypes_runWithSCXML.xml @@ -0,0 +1,642 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shapechange-app/src/test/java/de/interactive_instruments/shapechange/app/FlattenerTest.java b/shapechange-app/src/test/java/de/interactive_instruments/shapechange/app/FlattenerTest.java index 6b1dcd4f..7d9b80b8 100644 --- a/shapechange-app/src/test/java/de/interactive_instruments/shapechange/app/FlattenerTest.java +++ b/shapechange-app/src/test/java/de/interactive_instruments/shapechange/app/FlattenerTest.java @@ -211,4 +211,17 @@ public void test_flatten_removePackages() { multiTest("src/integrationtests/flattener/removePackages/test_flattener_removePackages.xml", new String[] { "xsd" }, "testResults/flattening/removePackages/results", "src/integrationtests/flattener/removePackages/reference/results"); } + + @Test + public void test_flattenTypes_excludeUnionTypes() { + /* + * A union excluded from flattening via flattenUnionTypesExcludeRegex must stay in + * the model, since properties still have it as value type; a union that is not + * excluded, and that no property uses, is still removed. + */ + multiTest( + "src/integrationtests/flattener/flattenTypes_excludeUnionTypes/testEA_Flattening_excludeUnionTypes.xml", + new String[] { "xsd" }, "testResults/flattening/flattenTypes_excludeUnionTypes/results", + "src/integrationtests/flattener/flattenTypes_excludeUnionTypes/reference/results"); + } } diff --git a/shapechange-core/src/main/java/de/interactive_instruments/shapechange/core/transformation/flattening/Flattener.java b/shapechange-core/src/main/java/de/interactive_instruments/shapechange/core/transformation/flattening/Flattener.java index d0986122..dd5ae1f3 100644 --- a/shapechange-core/src/main/java/de/interactive_instruments/shapechange/core/transformation/flattening/Flattener.java +++ b/shapechange-core/src/main/java/de/interactive_instruments/shapechange/core/transformation/flattening/Flattener.java @@ -4099,8 +4099,9 @@ && representsReflexiveRelationship(genPi, genModel)) { * Now that all data types, object types and unions should have either been * flattened or replaced (via type mappings) in the app schema, remove them from * the model. Remove object types if flattenObjectTypes is true or if they match - * the inclusion regex. Remove data types unless they have been excluded (via - * configuration parameter). + * the inclusion regex. Remove data types and unions unless they have been + * excluded (via configuration parameter), and keep unions that represent feature + * type sets if so configured. */ if (this.excludeDataTypePattern != null) { @@ -4150,8 +4151,13 @@ && representsReflexiveRelationship(genPi, genModel)) { if (genCi.category() == Options.UNION) { - if (!ignoreUnionsRepresentingFeatureTypeSets - || !Boolean.parseBoolean(genCi.taggedValue("representsFeatureTypeSet"))) { + /* + * A union excluded from flattening via PARAM_FLATTEN_UNIONTYPES_EXCLUDE_REGEX + * is still the value type of the properties that reference it, so it stays in + * the model, like a union that represents a feature type set. + */ + if (!isExcludedUnionType(genCi) && (!ignoreUnionsRepresentingFeatureTypeSets + || !Boolean.parseBoolean(genCi.taggedValue("representsFeatureTypeSet")))) { genModel.remove(genCi); } } @@ -4206,6 +4212,18 @@ private boolean representsReflexiveRelationship(GenericPropertyInfo genPi, Gener * @return a map with types to be processed in flatten types rule; can be empty * but not null */ + /** + * @param ci the class to test + * @return true if the name of the class matches the regular + * expression given by parameter + * {@value #PARAM_FLATTEN_UNIONTYPES_EXCLUDE_REGEX}, i.e. if + * rule-trf-prop-flatten-types shall neither flatten nor remove the + * union; else false + */ + private boolean isExcludedUnionType(ClassInfo ci) { + return excludeUnionTypePattern != null && excludeUnionTypePattern.matcher(ci.name()).matches(); + } + private TreeMap computeTypesToProcessForFlattenTypes(GenericModel genModel, TransformerConfiguration trfConfig) { @@ -4294,9 +4312,7 @@ private TreeMap computeTypesToProcessForFlattenTypes(G if (excludeUnionTypeRegex != null) { - Matcher m = excludeUnionTypePattern.matcher(typeCi.name()); - - if (m.matches()) { + if (isExcludedUnionType(typeCi)) { processType = false; result.addDebug(this, 20344, typeCi.name(), excludeUnionTypeRegex, PARAM_FLATTEN_UNIONTYPES_EXCLUDE_REGEX);