diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index c8d2cc05..f75667fd 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -38,7 +38,7 @@ jobs: - name: Setup Ballerina uses: ballerina-platform/setup-ballerina@v1.1.0 with: - version: 2201.8.1 + version: 2201.10.2 - name: Create settings.xml run: echo ' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 87b6b17f..3091f3dd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: - name: Setup Ballerina uses: ballerina-platform/setup-ballerina@v1.1.0 with: - version: 2201.8.1 + version: 2201.10.2 - name: Create settings.xml run: echo ' diff --git a/native/fhir-to-bal-lib/src/main/java/org/wso2/healthcare/fhir/ballerina/packagegen/tool/modelgen/DatatypeContextGenerator.java b/native/fhir-to-bal-lib/src/main/java/org/wso2/healthcare/fhir/ballerina/packagegen/tool/modelgen/DatatypeContextGenerator.java index f49be48f..5ec3b2d3 100644 --- a/native/fhir-to-bal-lib/src/main/java/org/wso2/healthcare/fhir/ballerina/packagegen/tool/modelgen/DatatypeContextGenerator.java +++ b/native/fhir-to-bal-lib/src/main/java/org/wso2/healthcare/fhir/ballerina/packagegen/tool/modelgen/DatatypeContextGenerator.java @@ -86,7 +86,9 @@ private void populateDatatypeContext() { if (elementDefinition.getPath().contains(".")) { String elementName = elementDefinition.getPath().substring( elementDefinition.getPath().lastIndexOf(".") + 1); - if ("id".equals(elementName) || "extension".equals(elementName)) { + if ("id".equals(elementName) || "extension".equals(elementName) + || elementDefinition.getPath().contains(".extension.")) { + //skipping for generating datatype extensions continue; } Element element = new Element(); @@ -135,8 +137,7 @@ private void populateExtendedElementsMap(Element element, DatatypeTemplateContex if (elementDataType.equals("code") && element.hasChildElements()) { extendedElement = GeneratorUtils.getInstance().populateExtendedElement(element, BallerinaDataType.Enum, elementDataType, context.getName()); - context.getExtendedElements().putIfAbsent(extendedElement.getTypeName(), extendedElement); - element.setName(extendedElement.getTypeName()); + context.getExtendedElements().putIfAbsent(element.getName(), extendedElement); element.setExtended(true); } } diff --git a/native/fhir-to-bal-lib/src/main/java/org/wso2/healthcare/fhir/ballerina/packagegen/tool/modelgen/ResourceContextGenerator.java b/native/fhir-to-bal-lib/src/main/java/org/wso2/healthcare/fhir/ballerina/packagegen/tool/modelgen/ResourceContextGenerator.java index 8a1b8b3e..f6400a0e 100644 --- a/native/fhir-to-bal-lib/src/main/java/org/wso2/healthcare/fhir/ballerina/packagegen/tool/modelgen/ResourceContextGenerator.java +++ b/native/fhir-to-bal-lib/src/main/java/org/wso2/healthcare/fhir/ballerina/packagegen/tool/modelgen/ResourceContextGenerator.java @@ -42,7 +42,6 @@ import org.wso2.healthcare.fhir.ballerina.packagegen.tool.utils.CommonUtil; import org.wso2.healthcare.fhir.ballerina.packagegen.tool.utils.GeneratorUtils; -import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -227,6 +226,10 @@ public int compare(ElementDefinition e1, ElementDefinition e2) { elementName = tempElement + CommonUtil.toCamelCase(type.getCode()); Element childElement = populateElement(rootElementName, elementName, type, isSlice, elementDefinition); + if (ToolConstants.DATA_TYPE_EXTENSION.equals(childElement.getDataType()) && !elementName.equals("extension") + && !elementName.equals("modifierExtension")) { + continue; + } if (rootElement.getChildElements() != null) { if (!rootElement.getChildElements().containsKey(elementName)) { rootElement.getChildElements().put(elementName, childElement); @@ -397,17 +400,17 @@ private void populateResourceElementMap(Element element) { } } } - markConstrainedElements(element); + checkAndAddConstraintImport(element); this.resourceTemplateContextInstance.getResourceElements().put(element.getName(), element); } } - private void markConstrainedElements(Element element) { - boolean isCardinalityConstrained = (element.getMin() >= 1) && (element.getMax() > 1); + private void checkAndAddConstraintImport(Element element) { + boolean isCardinalityConstrained = (element.getMin() >= 1 && element.getMax() > 1) || (element.isArray() && + element.getMax() > 0 && element.getMax() < Integer.MAX_VALUE); boolean isConstraintsImportExists = this.resourceTemplateContextInstance.getResourceDependencies() .stream() .anyMatch(d -> d.equals(CONSTRAINTS_LIB_IMPORT)); - if (!isConstraintsImportExists && isCardinalityConstrained) { this.resourceTemplateContextInstance.getResourceDependencies().add(CONSTRAINTS_LIB_IMPORT); } @@ -461,7 +464,6 @@ private void validateAndPopulateExtendedElement(Element element) { this.resourceTemplateContextInstance.getResourceName()); putExtendedElementIfAbsent(element, extendedElement); } else if (element.isSlice() || elementDataType.equals("BackboneElement") || (element.isExtended() && element.hasChildElements())) { - markConstrainedElements(element); extendedElement = GeneratorUtils.getInstance().populateExtendedElement(element, BallerinaDataType.Record, elementDataType, this.resourceTemplateContextInstance.getResourceName()); extendedElement.setElements(element.getChildElements()); @@ -472,7 +474,7 @@ private void validateAndPopulateExtendedElement(Element element) { if (element.hasChildElements()) { HashMap childElementAnnotations = new HashMap<>(); for (Element subElement : element.getChildElements().values()) { - markConstrainedElements(subElement); + checkAndAddConstraintImport(subElement); AnnotationElement annotationElement = GeneratorUtils.getInstance().populateAnnotationElement(subElement); childElementAnnotations.put(annotationElement.getName(), annotationElement); } @@ -502,12 +504,15 @@ private void putExtendedElementIfAbsent(Element element, ExtendedElement extende private void populateResourceSliceElementsMap(Element element) { LOG.debug("Started: Resource Slice Element Map population"); + if (ToolConstants.DATA_TYPE_EXTENSION.equals(element.getDataType()) && element.isSlice()) { + return; + } if (element.hasChildElements()) { for (Map.Entry childEntry : element.getChildElements().entrySet()) { populateResourceSliceElementsMap(childEntry.getValue()); if (element.isSlice()) { ElementDefinition elementDefinition = this.resourceTemplateContextInstance.getSnapshotElementDefinitions().get(childEntry.getValue().getPath()); - if (elementDefinition != null && "*".equals(elementDefinition.getBase().getMax()) && childEntry.getValue().getMax() != Integer.MAX_VALUE) { + if (elementDefinition != null && isElementArray(elementDefinition)) { childEntry.getValue().setArray(true); } } diff --git a/native/fhir-to-bal-lib/src/main/java/org/wso2/healthcare/fhir/ballerina/packagegen/tool/utils/GeneratorUtils.java b/native/fhir-to-bal-lib/src/main/java/org/wso2/healthcare/fhir/ballerina/packagegen/tool/utils/GeneratorUtils.java index 2b18a0b8..782e83ab 100644 --- a/native/fhir-to-bal-lib/src/main/java/org/wso2/healthcare/fhir/ballerina/packagegen/tool/utils/GeneratorUtils.java +++ b/native/fhir-to-bal-lib/src/main/java/org/wso2/healthcare/fhir/ballerina/packagegen/tool/utils/GeneratorUtils.java @@ -108,6 +108,49 @@ public class GeneratorUtils { put("'type", "AddressType"); put("use", "AddressUse"); }}); + put("ContactPoint", new HashMap<>() {{ + put("system", "ContactPointSystem"); + put("use", "ContactPointUse"); + }}); + put("Contributor", new HashMap<>() {{ + put("type", "ContributorType"); + }}); + put("ElementBinding", new HashMap<>() {{ + put("strength", "StrengthCode"); + }}); + put("ElementDiscriminator", new HashMap<>() {{ + put("type", "ElementDiscriminatorType"); + }}); + put("ElementRepeat", new HashMap<>() {{ + put("durationUnit", "Timecode"); + put("periodUnit", "Timecode"); + put("dayOfWeek", "Daycode"); + }}); + put("ElementSlicing", new HashMap<>() {{ + put("rules", "ElementSlicingRules"); + }}); + put("ElementSort", new HashMap<>() {{ + put("direction", "DirectionCode"); + }}); + put("ElementType", new HashMap<>() {{ + put("aggregation", "TypeAggregation"); + put("versioning", "TypeVersioning"); + }}); + put("HumanName", new HashMap<>() {{ + put("use", "HumanNameUse"); + }}); + put("Identifier", new HashMap<>() {{ + put("use", "IdentifierUse"); + }}); + put("Narrative", new HashMap<>() {{ + put("status", "StatusCode"); + }}); + put("ParameterDefinition", new HashMap<>() {{ + put("use", "ParameterDefinitionUse"); + }}); + put("Quantity", new HashMap<>() {{ + put("comparator", "QuantityComparatorCode"); + }}); }}; private static final GeneratorUtils instance = new GeneratorUtils(); @@ -448,4 +491,16 @@ public T getTypedValue(String value, String datatype) { public String getNewLine() { return "\n"; } + + + /** + * Check whether the element is a constrained array element + * + * @param element element + * @return true if the element is a constrained array element + */ + public boolean isConstrainedArrayElement(Element element) { + return (element.getMin() >= 1 && element.getMax() > 1) || (element.isArray() && + element.getMax() > 0 && element.getMax() < Integer.MAX_VALUE); + } } diff --git a/native/fhir-to-bal-lib/src/main/resources/templates/fhir_resource.vm b/native/fhir-to-bal-lib/src/main/resources/templates/fhir_resource.vm index 76b1fc71..a2cfad5c 100644 --- a/native/fhir-to-bal-lib/src/main/resources/templates/fhir_resource.vm +++ b/native/fhir-to-bal-lib/src/main/resources/templates/fhir_resource.vm @@ -83,16 +83,16 @@ public type $util.resolveSpecialCharacters($resourceName) record {| #set($max = 1) #set($separator = ",") ## Here we should add constraint:Array only for the Array elements and min or max is 1 -#if( $element.isArray() && ($element.getMin() == $min || $element.getMax() == $max) ) +#if( ${util.isConstrainedArrayElement($element)} ) @constraint:Array { -#if( $element.getMin() == $min ) +#if( $element.getMin() > 0 ) minLength: { value: $min$separator message: "Validation failed for $.$element.getPath() constraint. This field must be an array containing at least one item." - }#if( $element.getMax() == $max )$separator#end + }#if( $element.getMax() > 0 )$separator#end #end -#if( $element.getMax() == $max ) +#if( $element.getMax() > 0 ) maxLength: { value: $max$separator message: "Validation failed for $.$element.getPath() constraint. This field must be an array containing at most one item." @@ -158,16 +158,16 @@ public type $util.resolveSpecialCharacters($extendedElement.getTypeName()) recor #set($max = 1) #set($separator = ",") ## Here we should add constraint:Array only for the Array elements and min or max is 1 -#if( $childElement.isArray() && ($childElement.getMin() == $min || $childElement.getMax() == $max) ) +#if( ${util.isConstrainedArrayElement($childElement)} ) @constraint:Array { -#if( $childElement.getMin() == $min ) +#if( $childElement.getMin() > 0) minLength: { value: $min$separator message: "Validation failed for $.$childElement.getPath() constraint. This field must be an array containing at least one item." - }#if( $childElement.getMax() == $max )$separator#end + }#if( $childElement.getMax() > 0 )$separator#end #end -#if( $childElement.getMax() == $max ) +#if( $childElement.getMax() > 0) maxLength: { value: $max$separator message: "Validation failed for $.$childElement.getPath() constraint. This field must be an array containing at most one item." diff --git a/native/health-cli/pom.xml b/native/health-cli/pom.xml index 54f2dba7..ae9b9dd2 100644 --- a/native/health-cli/pom.xml +++ b/native/health-cli/pom.xml @@ -130,7 +130,7 @@ packageGenTests - false + true diff --git a/native/health-cli/src/main/resources/tool-config.json b/native/health-cli/src/main/resources/tool-config.json index b55f953d..1ab45e6d 100644 --- a/native/health-cli/src/main/resources/tool-config.json +++ b/native/health-cli/src/main/resources/tool-config.json @@ -9,7 +9,7 @@ "org": "healthcare", "name": "healthcare.fhir", "version": "1.0.0", - "ballerinaDistribution": "2201.8.1", + "ballerinaDistribution": "2201.10.2", "authors": [ "Ballerina" ],